Skip to content

Commit

Permalink
fix(sql): fix aliasing of nested composite FK queries
Browse files Browse the repository at this point in the history
  • Loading branch information
B4nan committed Mar 14, 2024
1 parent a2b3e15 commit 60b2c91
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 1 deletion.
8 changes: 7 additions & 1 deletion packages/knex/src/query/CriteriaNode.ts
Expand Up @@ -86,7 +86,13 @@ export class CriteriaNode<T extends object> implements ICriteriaNode<T> {
}

renameFieldToPK<T>(qb: IQueryBuilder<T>): string {
const joinAlias = qb.getAliasForJoinPath(this.getPath());
let joinAlias = qb.getAliasForJoinPath(this.getPath());

if (!joinAlias && this.parent && [ReferenceKind.MANY_TO_ONE, ReferenceKind.ONE_TO_ONE].includes(this.prop!.kind) && this.prop!.owner) {
joinAlias = qb.getAliasForJoinPath(this.parent.getPath());
return Utils.getPrimaryKeyHash(this.prop!.joinColumns.map(col => `${joinAlias ?? qb.alias}.${col}`));
}

const alias = joinAlias ?? qb.alias;

if (this.prop!.kind === ReferenceKind.MANY_TO_MANY) {
Expand Down
110 changes: 110 additions & 0 deletions tests/issues/GHx13.test.ts
@@ -0,0 +1,110 @@
import { Entity, ManyToOne, MikroORM, PrimaryKey, Property, Ref } from '@mikro-orm/sqlite';

abstract class Common {

@PrimaryKey()
orgId!: number;

@PrimaryKey()
id!: number;

}

@Entity()
class Form extends Common {

@Property({ nullable: false })
name!: string;

}

@Entity()
class FormSubmission extends Common {

@ManyToOne({
entity: () => Form,
ref: true,
nullable: true,
})
form?: Ref<Form>;

}

@Entity()
class FormSubmissionField extends Common {

@ManyToOne({
entity: () => FormSubmission,
ref: true,
})
submission!: Ref<FormSubmission>;

@Property({ nullable: false })
value!: string;

}

let orm: MikroORM;

beforeAll(async () => {
orm = await MikroORM.init({
dbName: ':memory:',
entities: [Form, FormSubmission, FormSubmissionField],
});
await orm.schema.refreshDatabase();
});

beforeEach(async () => {
await orm.schema.clearDatabase();

const form1 = orm.em.create(Form, {
orgId: 1,
id: 10,
name: 'Form 1',
});

const submission = orm.em.create(FormSubmission, {
orgId: 1,
id: 20,
form: form1,
});

const submissionField = orm.em.create(FormSubmissionField, {
orgId: 1,
id: 30,
submission,
value: 'James',
});

await orm.em.flush();
orm.em.clear();
});

afterAll(async () => {
await orm.close(true);
});

test('Query through nested relationship', async () => {
const submissionField = await orm.em.findOneOrFail(
FormSubmissionField,
{ id: 30 },
{ populate: ['submission.form'] },
);

expect(submissionField.submission.$.form?.$.name).toBe('Form 1');
orm.em.clear();

const submissionFields = await orm.em.find(
FormSubmissionField,
{
submission: {
form: {
orgId: 1,
id: 10,
},
},
},
);

expect(submissionFields).toHaveLength(1);
});

0 comments on commit 60b2c91

Please sign in to comment.