Skip to content

Commit

Permalink
fix(sql): fix prefixing of JSON queries nested on relations
Browse files Browse the repository at this point in the history
Closes #3242
  • Loading branch information
B4nan committed Jun 23, 2022
1 parent eb9fb34 commit 847ff46
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/core/src/metadata/MetadataDiscovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class MetadataDiscovery {
}));

for (const prop of missing) {
const target = (prop.entity?.() || prop.type) as Constructor<AnyEntity>;
const target = (prop.entity instanceof Function ? prop.entity() : prop.type) as Constructor<AnyEntity>;
await this.tryDiscoverTargets(Utils.asArray(target));
}
}
Expand Down
2 changes: 2 additions & 0 deletions packages/knex/src/query/ObjectCriteriaNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ export class ObjectCriteriaNode extends CriteriaNode {
} else {
o[key] = payload[k];
}
} else if (ObjectCriteriaNode.isCustomExpression(k)) {
o[k] = payload[k];
} else {
o[`${childAlias}.${k}`] = payload[k];
}
Expand Down
95 changes: 95 additions & 0 deletions tests/issues/GH3242.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { Collection, Entity, JsonType, ManyToOne, MikroORM, OneToMany, PrimaryKey, Property } from '@mikro-orm/core';
import { mockLogger } from '../helpers';

@Entity()
export class Author {

@PrimaryKey()
id!: string;

@OneToMany({
entity: 'Book',
mappedBy: 'author',
})
books = new Collection<Book>(this);

}

@Entity()
export class Book {

@PrimaryKey()
id!: string;

@Property({ type: JsonType })
data!: Record<string, unknown>;

@ManyToOne(() => Author)
author!: Author;

}

describe('aliasing of nested JSON queries (GH 3242)', () => {

test('sqlite', async () => {
const orm = await MikroORM.init({
entities: [Book],
dbName: ':memory:',
type: 'better-sqlite',
});
await orm.getSchemaGenerator().createSchema();

const mock = mockLogger(orm);
await orm.em.find(Author, { books: { data: { title: 'test' } } });
await orm.em.find(Author, { books: { id: 'test' } });
await orm.em.find(Book, { data: { title: 'test' } });

expect(mock.mock.calls[0][0]).toMatch("select `a0`.* from `author` as `a0` left join `book` as `b1` on `a0`.`id` = `b1`.`author_id` where json_extract(`b1`.`data`, '$.title') = 'test'");
expect(mock.mock.calls[1][0]).toMatch("select `a0`.* from `author` as `a0` left join `book` as `b1` on `a0`.`id` = `b1`.`author_id` where `b1`.`id` = 'test'");
expect(mock.mock.calls[2][0]).toMatch("select `b0`.* from `book` as `b0` where json_extract(`b0`.`data`, '$.title') = 'test'");

await orm.close(true);
});

test('mysql', async () => {
const orm = await MikroORM.init({
entities: [Book],
dbName: 'mikro_orm_test_3242',
type: 'mysql',
port: 3308,
});
await orm.getSchemaGenerator().refreshDatabase();

const mock = mockLogger(orm);
await orm.em.find(Author, { books: { data: { title: 'test' } } });
await orm.em.find(Author, { books: { id: 'test' } });
await orm.em.find(Book, { data: { title: 'test' } });

expect(mock.mock.calls[0][0]).toMatch("select `a0`.* from `author` as `a0` left join `book` as `b1` on `a0`.`id` = `b1`.`author_id` where `b1`.`data`->'$.title' = 'test'");
expect(mock.mock.calls[1][0]).toMatch("select `a0`.* from `author` as `a0` left join `book` as `b1` on `a0`.`id` = `b1`.`author_id` where `b1`.`id` = 'test'");
expect(mock.mock.calls[2][0]).toMatch("select `b0`.* from `book` as `b0` where `b0`.`data`->'$.title' = 'test'");

await orm.close(true);
});

test('postgres', async () => {
const orm = await MikroORM.init({
entities: [Book],
dbName: 'mikro_orm_test_3242',
type: 'postgresql',
});
await orm.getSchemaGenerator().refreshDatabase();

const mock = mockLogger(orm);
await orm.em.find(Author, { books: { data: { title: 'test' } } });
await orm.em.find(Author, { books: { id: 'test' } });
await orm.em.find(Book, { data: { title: 'test' } });

expect(mock.mock.calls[0][0]).toMatch(`select "a0".* from "author" as "a0" left join "book" as "b1" on "a0"."id" = "b1"."author_id" where "b1"."data"->>'title' = 'test'`);
expect(mock.mock.calls[1][0]).toMatch(`select "a0".* from "author" as "a0" left join "book" as "b1" on "a0"."id" = "b1"."author_id" where "b1"."id" = 'test'`);
expect(mock.mock.calls[2][0]).toMatch(`select "b0".* from "book" as "b0" where "b0"."data"->>'title' = 'test'`);

await orm.close(true);
});

});

0 comments on commit 847ff46

Please sign in to comment.