Skip to content

Commit

Permalink
fix(GH-2648): deep smart query with fk as pk
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcel Link committed Jan 20, 2022
1 parent a615559 commit 82ca875
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
16 changes: 14 additions & 2 deletions packages/core/src/utils/QueryHelper.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Reference } from '../entity/Reference';
import { Utils } from './Utils';
import type { AnyEntity, Dictionary, EntityMetadata, EntityProperty, FilterDef, ObjectQuery, FilterQuery } from '../typings';
import { ARRAY_OPERATORS, GroupOperator } from '../enums';
import { ARRAY_OPERATORS, GroupOperator, ReferenceType } from '../enums';
import type { Platform } from '../platforms';
import type { MetadataStorage } from '../metadata/MetadataStorage';
import { JsonType } from '../types';
Expand Down Expand Up @@ -56,7 +56,19 @@ export class QueryHelper {
}

if (meta.primaryKeys.every(pk => pk in where) && Utils.getObjectKeysSize(where) === meta.primaryKeys.length) {
return !GroupOperator[key as string] && Object.keys(where).every(k => !Utils.isPlainObject(where[k]) || Object.keys(where[k]).every(v => !Utils.isOperator(v, false)));
return !GroupOperator[key as string] && Object.keys(where).every(k => !Utils.isPlainObject(where[k]) || Object.keys(where[k]).every(v => {
if (Utils.isOperator(v, false)) {
return false;
}

// Only the owning side of OneToOne can be a primary
if ([ReferenceType.ONE_TO_ONE, ReferenceType.MANY_TO_ONE].includes(meta.properties[k].reference)) {
const meta2 = metadata.find(meta.properties[k]?.type) || meta;
return this.inlinePrimaryKeyObjects(where[k], meta2, metadata, v);
}

return true;
}));
}

Object.keys(where).forEach(k => {
Expand Down
13 changes: 12 additions & 1 deletion packages/knex/src/query/ObjectCriteriaNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,18 @@ export class ObjectCriteriaNode extends CriteriaNode {
const embeddable = this.prop.reference === ReferenceType.EMBEDDED;
const knownKey = [ReferenceType.SCALAR, ReferenceType.MANY_TO_ONE, ReferenceType.EMBEDDED].includes(this.prop.reference) || (this.prop.reference === ReferenceType.ONE_TO_ONE && this.prop.owner);
const operatorKeys = knownKey && Object.keys(this.payload).every(key => Utils.isOperator(key, false));
const primaryKeys = knownKey && Object.keys(this.payload).every(key => this.metadata.find(this.entityName)!.primaryKeys.includes(key));
const primaryKeys = knownKey && Object.keys(this.payload).every(key => {
const meta = this.metadata.find(this.entityName)!;
if (!meta.primaryKeys.includes(key)) {
return false;
}
if (!Utils.isPlainObject(this.payload[key].payload) || ![ReferenceType.ONE_TO_ONE, ReferenceType.MANY_TO_ONE].includes(meta.properties[key].reference)) {
return true;
}
const meta2 = this.metadata.find(meta.properties[key]?.type) || meta;
const keys = Object.keys(this.payload[key].payload);
return keys.every(k => meta2.primaryKeys.includes(k));
});

return !primaryKeys && !nestedAlias && !operatorKeys && !embeddable;
}
Expand Down

0 comments on commit 82ca875

Please sign in to comment.