Skip to content

Commit

Permalink
feat(query-builder): validate unknown alias when explicitly joining
Browse files Browse the repository at this point in the history
Closes #4353
  • Loading branch information
B4nan committed May 14, 2023
1 parent ce81071 commit 8d4a83a
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 3 deletions.
10 changes: 8 additions & 2 deletions packages/knex/src/query/QueryBuilder.ts
Expand Up @@ -788,12 +788,18 @@ export class QueryBuilder<T extends object = AnyEntity> {
private joinReference(field: string, alias: string, cond: Dictionary, type: 'leftJoin' | 'innerJoin' | 'pivotJoin', path?: string): EntityProperty {
this.ensureNotFinalized();
const [fromAlias, fromField] = this.helper.splitField(field);
const entityName = this._aliases[fromAlias]?.entityName;
const q = (str: string) => `'${str}'`;

if (!this._aliases[fromAlias]) {
throw new Error(`Trying to join ${q(fromField)} with alias ${q(fromAlias)}, but ${q(fromAlias)} is not a known alias. Available aliases are: ${Object.keys(this._aliases).map(q).join(', ')}.`);
}

const entityName = this._aliases[fromAlias].entityName;
const meta = this.metadata.get(entityName);
const prop = meta.properties[fromField];

if (!prop) {
throw new Error(`Trying to join ${field}, but ${fromField} is not a defined relation on ${meta.className}`);
throw new Error(`Trying to join ${q(field)}, but ${q(fromField)} is not a defined relation on ${meta.className}.`);
}

this.createAlias(prop.type, alias);
Expand Down
8 changes: 7 additions & 1 deletion tests/QueryBuilder.test.ts
Expand Up @@ -259,11 +259,17 @@ describe('QueryBuilder', () => {
expect(qb.getParams()).toEqual([2, 1]);
});

test('validation of unknown alias', async () => {
const qb = orm.em.createQueryBuilder(FooBar2, 'fb1');
qb.select('*').joinAndSelect('fb1.baz', 'fz');
expect(() => qb.join('fb0.baz', 'b')).toThrowError(`Trying to join 'baz' with alias 'fb0', but 'fb0' is not a known alias. Available aliases are: 'fb1', 'fz'.`);
});

test('complex select with mapping of joined results', async () => {
const qb = orm.em.createQueryBuilder(FooBar2, 'fb1');
qb.select('*').joinAndSelect('fb1.baz', 'fz');

const err = `Trying to join fz.fooBar, but fooBar is not a defined relation on FooBaz2`;
const err = `Trying to join 'fz.fooBar', but 'fooBar' is not a defined relation on FooBaz2`;
expect(() => qb.leftJoinAndSelect('fz.fooBar', 'fb2')).toThrowError(err);

qb.leftJoinAndSelect('fz.bar', 'fb2')
Expand Down

0 comments on commit 8d4a83a

Please sign in to comment.