Skip to content

Commit

Permalink
Move union query application to applyQuery, fix where clause
Browse files Browse the repository at this point in the history
Fixes #9228
  • Loading branch information
rijkvanzanten committed Nov 4, 2021
1 parent b0f09b0 commit c39554e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 21 deletions.
19 changes: 1 addition & 18 deletions api/src/database/run-ast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,7 @@ export default async function runAST(
);

// The actual knex query builder instance. This is a promise that resolves with the raw items from the db
let dbQuery = getDBQuery(schema, knex, collection, fieldNodes, query);

if (query.union) {
const [field, keys] = query.union;

if (keys.length) {
const queries = keys.map((key) => {
return knex.select('*').from(
dbQuery
.clone()
.andWhere({ [field]: key })
.as('foo')
);
});

dbQuery = knex.unionAll(queries);
}
}
const dbQuery = getDBQuery(schema, knex, collection, fieldNodes, query);

const rawItems: Item | Item[] = await dbQuery;

Expand Down
33 changes: 30 additions & 3 deletions api/src/utils/apply-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { customAlphabet } from 'nanoid';
import validate from 'uuid-validate';
import { InvalidQueryException } from '../exceptions';
import { Relation, SchemaOverview } from '../types';
import { Aggregate, Filter, Query } from '@directus/shared/types';
import { Aggregate, Filter, LogicalFilterAND, Query } from '@directus/shared/types';
import { applyFunctionToColumnName } from './apply-function-to-column-name';
import { getColumn } from './get-column';
import { getRelationType } from './get-relation-type';
Expand Down Expand Up @@ -55,7 +55,32 @@ export default function applyQuery(
dbQuery.offset(query.limit * (query.page - 1));
}

if (query.filter) {
if (query.union) {
const [field, keys] = query.union;

if (keys.length) {
const queries = keys.map((key) => {
let filter = { [field]: { _eq: key } } as Filter;

if (query.filter) {
if ('_and' in query.filter) {
(query.filter as LogicalFilterAND)._and.push(filter);
filter = query.filter;
} else {
filter = {
_and: [query.filter, filter],
} as LogicalFilterAND;
}
}

return knex
.select('*')
.from(applyFilter(knex, schema, dbQuery.clone(), filter, collection, subQuery).as('foo'));
});

dbQuery = knex.unionAll(queries);
}
} else if (query.filter) {
applyFilter(knex, schema, dbQuery, query.filter, collection, subQuery);
}

Expand Down Expand Up @@ -118,14 +143,16 @@ export function applyFilter(
rootFilter: Filter,
collection: string,
subQuery = false
): void {
) {
const relations: Relation[] = schema.relations;

const aliasMap: Record<string, string> = {};

addJoins(rootQuery, rootFilter, collection);
addWhereClauses(knex, rootQuery, rootFilter, collection);

return rootQuery;

function addJoins(dbQuery: Knex.QueryBuilder, filter: Filter, collection: string) {
for (const [key, value] of Object.entries(filter)) {
if (key === '_or' || key === '_and') {
Expand Down

0 comments on commit c39554e

Please sign in to comment.