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

raw() in orderBy in decorator throws error: column [raw] does not exist #5277

Closed
5 tasks done
squivix opened this issue Feb 25, 2024 · 3 comments
Closed
5 tasks done

Comments

@squivix
Copy link

squivix commented Feb 25, 2024

Describe the bug

When using the raw() helper function in the orderBy field of the decorator, it generates an invalid sql which results in an error: column [raw] does not exist.

Example:

@Entity()
export class EntityA {
    @PrimaryKey({type: types.integer})
    id!: number;

    @OneToMany({
        entity: () => EntityB, mappedBy: (entityB: EntityB) => entityB.entityA,
        orderBy: {
            [raw("LENGTH(text)")]: "asc"
        }
    })
    orderedEntityBs: Collection<EntityB> = new Collection<EntityB>(this);
}
@Entity()
export class EntityB {
    @PrimaryKey({type: types.integer})
    id!: number;

    @Property({type: types.string, length: 500})
    text!: string;

    @ManyToOne({entity: () => EntityA, inversedBy: (entityA) => entityA.entityBs, deleteRule: "cascade", updateRule: "cascade"})
    entityA!: Ref<EntityA>;
}

Then trying to query:

await em.find(EntityA, {}, {
        populate: ["orderedEntityBs"]
    });

throws error:

InvalidFieldNameException: select `e0`.*, `o1`.`id` as `o1__id`, `o1`.`text` as `o1__text`, `o1`.`entity_a_id` as `o1__entity_a_id` from `entity_a` as `e0` left join `entity_b` as `o1` on `e0`.`id` = `o1`.`entity_a_id` order by `o1`.`[raw]` asc - SQLITE_ERROR: no such column: o1.[raw]

Meanwhile using the same raw() in the orderBy of find functions works perfectly fine as seen in repro.

Note that expr in MikroORM v5 didn't have the same problem.

Reproduction

Repro

What driver are you using?

@mikro-orm/sqlite

MikroORM version

6.1.6-dev.1

Node.js version

v18.18.0

Operating system

Linux

Validations

@B4nan
Copy link
Member

B4nan commented Feb 26, 2024

I'm afraid supporting this properly might be a wontfix, the way things are currently designed allows only a single use of a raw fragment as a key, so even if we fix this, it would only work once per the whole app context, not just fork based. I'll first try to fix the single usage, and we could add a callback signature for the orderBy (as well as the where) option, that's the only way to properly fix that.

edit: Maybe there is another way around, we could allow marking raw fragments as global and those would be never removed from the map, something like raw('...', { global: true }), I'll experiment with that a bit first.
edit2: Hmm or maybe this can be even simpler, as we can detect those raw fragments are coming from the property options, looks like I was just overthinking this.


But there is an alternative approach you can use right now - with a formula property for the length that you can use for ordering:

@Formula(a => `length(${a}.text)`)
textLength!: number;

// ...

@OneToMany({
    entity: () => EntityB, mappedBy: (entityB: EntityB) => entityB.entityA,
    orderBy: {
        textLength: "asc"
    }
})
orderedEntityBs: Collection<EntityB> = new Collection<EntityB>(this);

@squivix
Copy link
Author

squivix commented Feb 26, 2024

I'm wondering why expr() worked before in v5 🤔? Was it implemented differently?

I like the @Formula workaround though.

@B4nan
Copy link
Member

B4nan commented Feb 26, 2024

expr was always just a type helper, it didnt have any effect on runtime

@B4nan B4nan closed this as completed in ed80163 Feb 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants