Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken maximum\minimum queries when default orderBy is defined #11213

Open
1 of 18 tasks
KharchenkoDmitriy opened this issue Dec 30, 2024 · 2 comments
Open
1 of 18 tasks

Comments

@KharchenkoDmitriy
Copy link

Issue description

When you define orderBy for entity, its also added to min/max queries which leads to "QueryFailedError"

Expected Behavior

Min/Max queries should not contain "ORDER BY" clause even if entity define the default one

Actual Behavior

Default "ORDER BY" is added to Min/Max queries which leads to "QueryFailedError"
Query example

SELECT MAX("cost") AS "MAX" FROM "offer" "Offer" ORDER BY "Offer"."cost" DESC

Steps to reproduce

import {
    Column,
    Entity,
    Index,
    PrimaryGeneratedColumn,
} from "typeorm";
    
@Entity({ orderBy: { cost: "DESC" } })
export default class Offer {
    @PrimaryGeneratedColumn("uuid")
    declare id: string;

    @Index()
    @Column("float", { nullable: false, default: 0 })
    declare cost: number;
}

// Run this somewhere in your code
await repo.maximum("cost")

My Environment

Dependency Version
Operating System Ubuntu 24.04.1 LTS
Node.js version v20.12.2
Typescript version 5.4.3
TypeORM version 0.3.20

Additional Context

No response

Relevant Database Driver(s)

  • aurora-mysql
  • aurora-postgres
  • better-sqlite3
  • cockroachdb
  • cordova
  • expo
  • mongodb
  • mysql
  • nativescript
  • oracle
  • postgres
  • react-native
  • sap
  • spanner
  • sqlite
  • sqlite-abstract
  • sqljs
  • sqlserver

Are you willing to resolve this issue by submitting a Pull Request?

Yes, I have the time, but I don't know how to start. I would need guidance.

@KharchenkoDmitriy
Copy link
Author

The base idea for fix was to remove ordering inside callAggregateFun, but it leads me to another bug #9902

@KharchenkoDmitriy
Copy link
Author

Solution I came to is to add .setOption("disable-global-order") inside callAggregateFun from EntityManager

What we have today:

async callAggregateFun(entityClass, fnName, columnName, where = {}) {
        const metadata = this.connection.getMetadata(entityClass);
        const column = metadata.columns.find((item) => item.propertyPath === columnName);
        if (!column) {
            throw new error_1.TypeORMError(`Column "${columnName}" was not found in table "${metadata.name}"`);
        }
        const result = await this.createQueryBuilder(entityClass, metadata.name)
            .setFindOptions({ where })
            .select(`${fnName}(${this.connection.driver.escape(column.databaseName)})`, fnName)
            .getRawOne();
        return result[fnName] === null ? null : parseFloat(result[fnName]);
    }

What I suggest

async callAggregateFun(entityClass, fnName, columnName, where = {}) {
        const metadata = this.connection.getMetadata(entityClass);
        const column = metadata.columns.find((item) => item.propertyPath === columnName);
        if (!column) {
            throw new error_1.TypeORMError(`Column "${columnName}" was not found in table "${metadata.name}"`);
        }
        const result = await this.createQueryBuilder(entityClass, metadata.name)
            .setFindOptions({ where })
            .setOption("disable-global-order")
            .select(`${fnName}(${this.connection.driver.escape(column.databaseName)})`, fnName)
            .getRawOne();
        return result[fnName] === null ? null : parseFloat(result[fnName]);
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant