forked from directus/directus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Basic filters for PostgreSQL driver (directus#19005)
* conversion to abstract sql * greater than for where clause in pg driver * refactoring * forward targets again * more filter options and fixes * added filters, moved operator mapping into driver * removed trim * add changeset * removed first type approach * enhanced abstract sql * value and set comparison in abstract query * split up where and intersect again * preps for where comparison to a set * typedocs * fix linter * The random things we did, who knows * adding logical conditions (WIP) Co-authored-by: Rijk van Zanten <[email protected]> Co-authored-by: Nicola Krumschmidt <[email protected]> * Push values to parameters directly * Fix convert test * Fix convert filter tests * Implement filter conversion for logical and negate nodes * Fix where tests * Add logical where stringification * Negate comparison operators directly * Remove some unneeded parentheses * Improve parameter index generator type * Fix formatter issues * Add todo statements * Remove unused node type * Removed unneeded check * One more unnecessary check --------- Co-authored-by: rijkvanzanten <[email protected]> Co-authored-by: Nicola Krumschmidt <[email protected]> Co-authored-by: Nicola Krumschmidt <[email protected]>
- Loading branch information
1 parent
66f9169
commit 84bd5d0
Showing
16 changed files
with
970 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'@directus/data-driver-postgres': minor | ||
'@directus/data-sql': minor | ||
'@directus/data': minor | ||
--- | ||
|
||
Added basic filters for PostgreSQL driver |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
import type { AbstractSqlQuery, AbstractSqlQueryWhereConditionNode, CompareValueNode } from '@directus/data-sql'; | ||
import { beforeEach, describe, expect, test } from 'vitest'; | ||
import { where, getComparison } from './where.js'; | ||
import { randomIdentifier, randomInteger } from '@directus/random'; | ||
|
||
let sample: { | ||
statement: AbstractSqlQuery; | ||
}; | ||
|
||
describe('Where clause:', () => { | ||
beforeEach(() => { | ||
sample = { | ||
statement: { | ||
select: [ | ||
{ | ||
type: 'primitive', | ||
column: randomIdentifier(), | ||
table: randomIdentifier(), | ||
as: randomIdentifier(), | ||
}, | ||
], | ||
from: randomIdentifier(), | ||
where: { | ||
type: 'condition', | ||
operation: 'gt', | ||
negate: false, | ||
target: { | ||
type: 'primitive', | ||
column: randomIdentifier(), | ||
table: randomIdentifier(), | ||
}, | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [0], | ||
}, | ||
}, | ||
parameters: [randomInteger(1, 10)], | ||
}, | ||
}; | ||
}); | ||
|
||
test('Where clause', () => { | ||
expect(where(sample.statement)).toStrictEqual( | ||
`WHERE "${(sample.statement.where as AbstractSqlQueryWhereConditionNode).target.table}"."${ | ||
(sample.statement.where as AbstractSqlQueryWhereConditionNode).target.column | ||
}" > $${ | ||
((sample.statement.where as AbstractSqlQueryWhereConditionNode).compareTo as CompareValueNode) | ||
.parameterIndexes[0]! + 1 | ||
}` | ||
); | ||
}); | ||
|
||
test('Where clause with negation', () => { | ||
sample.statement.where!.negate = true; | ||
|
||
expect(where(sample.statement)).toStrictEqual( | ||
`WHERE "${(sample.statement.where as AbstractSqlQueryWhereConditionNode).target.table}"."${ | ||
(sample.statement.where as AbstractSqlQueryWhereConditionNode).target.column | ||
}" <= $${ | ||
((sample.statement.where as AbstractSqlQueryWhereConditionNode).compareTo as CompareValueNode) | ||
.parameterIndexes[0]! + 1 | ||
}` | ||
); | ||
}); | ||
}); | ||
|
||
describe('Where clause operator mapping and parameter index insertion: ', () => { | ||
let compareTo: CompareValueNode; | ||
|
||
beforeEach(() => { | ||
compareTo = { | ||
type: 'value', | ||
parameterIndexes: [randomInteger(1, 10)], | ||
}; | ||
}); | ||
|
||
test('eq', () => { | ||
expect(getComparison('eq', compareTo)).toStrictEqual(`= $${compareTo.parameterIndexes[0]! + 1}`); | ||
}); | ||
|
||
test('gt', () => { | ||
expect(getComparison('gt', compareTo)).toStrictEqual(`> $${compareTo.parameterIndexes[0]! + 1}`); | ||
}); | ||
|
||
test('gte', () => { | ||
expect(getComparison('gte', compareTo)).toStrictEqual(`>= $${compareTo.parameterIndexes[0]! + 1}`); | ||
}); | ||
|
||
test('lt', () => { | ||
expect(getComparison('lt', compareTo)).toStrictEqual(`< $${compareTo.parameterIndexes[0]! + 1}`); | ||
}); | ||
|
||
test('lte', () => { | ||
expect(getComparison('lte', compareTo)).toStrictEqual(`<= $${compareTo.parameterIndexes[0]! + 1}`); | ||
}); | ||
|
||
test('contains', () => { | ||
expect(getComparison('contains', compareTo)).toStrictEqual(`LIKE '%$${compareTo.parameterIndexes[0]! + 1}%'`); | ||
}); | ||
|
||
test('starts_with', () => { | ||
expect(getComparison('starts_with', compareTo)).toStrictEqual(`LIKE '$${compareTo.parameterIndexes[0]! + 1}%'`); | ||
}); | ||
|
||
test('ends_with', () => { | ||
expect(getComparison('ends_with', compareTo)).toStrictEqual(`LIKE '%$${compareTo.parameterIndexes[0]! + 1}'`); | ||
}); | ||
|
||
test('in', () => { | ||
compareTo = { | ||
type: 'value', | ||
parameterIndexes: [randomInteger(1, 10), randomInteger(1, 10)], | ||
}; | ||
|
||
expect(getComparison('in', compareTo)).toStrictEqual( | ||
`IN ($${compareTo.parameterIndexes[0]! + 1}, $${compareTo.parameterIndexes[1]! + 1})` | ||
); | ||
}); | ||
}); | ||
|
||
test('Convert filter with logical', () => { | ||
const randomTable = randomIdentifier(); | ||
const randomColumn = randomIdentifier(); | ||
|
||
const firstColumn = randomIdentifier(); | ||
const secondColumn = randomIdentifier(); | ||
const firstValue = randomInteger(1, 100); | ||
const secondValue = randomInteger(1, 100); | ||
|
||
const statement: AbstractSqlQuery = { | ||
select: [ | ||
{ | ||
type: 'primitive', | ||
table: randomTable, | ||
column: randomColumn, | ||
}, | ||
], | ||
from: randomTable, | ||
where: { | ||
type: 'logical', | ||
operator: 'or', | ||
negate: false, | ||
childNodes: [ | ||
{ | ||
type: 'condition', | ||
negate: false, | ||
target: { | ||
type: 'primitive', | ||
table: randomTable, | ||
column: firstColumn, | ||
}, | ||
operation: 'gt', | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [0], | ||
}, | ||
}, | ||
{ | ||
type: 'condition', | ||
negate: false, | ||
target: { | ||
type: 'primitive', | ||
table: randomTable, | ||
column: secondColumn, | ||
}, | ||
operation: 'eq', | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [1], | ||
}, | ||
}, | ||
], | ||
}, | ||
parameters: [firstValue, secondValue], | ||
}; | ||
|
||
expect(where(statement)).toStrictEqual( | ||
`WHERE "${randomTable}"."${firstColumn}" > $1 OR "${randomTable}"."${secondColumn}" = $2` | ||
); | ||
}); | ||
|
||
test('Convert filter nested and with negation', () => { | ||
const randomTable = randomIdentifier(); | ||
const randomColumn = randomIdentifier(); | ||
|
||
const firstColumn = randomIdentifier(); | ||
const secondColumn = randomIdentifier(); | ||
const thirdColumn = randomIdentifier(); | ||
const fourthColumn = randomIdentifier(); | ||
|
||
const firstValue = randomInteger(1, 100); | ||
const secondValue = randomInteger(1, 100); | ||
const thirdValue = randomInteger(1, 100); | ||
const fourthValue = randomInteger(1, 100); | ||
|
||
const statement: AbstractSqlQuery = { | ||
select: [ | ||
{ | ||
type: 'primitive', | ||
table: randomTable, | ||
column: randomColumn, | ||
}, | ||
], | ||
from: randomTable, | ||
where: { | ||
type: 'logical', | ||
operator: 'or', | ||
negate: false, | ||
childNodes: [ | ||
{ | ||
type: 'condition', | ||
negate: false, | ||
target: { | ||
type: 'primitive', | ||
table: randomTable, | ||
column: firstColumn, | ||
}, | ||
operation: 'gt', | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [0], | ||
}, | ||
}, | ||
{ | ||
type: 'condition', | ||
negate: true, | ||
target: { | ||
type: 'primitive', | ||
table: randomTable, | ||
column: secondColumn, | ||
}, | ||
operation: 'eq', | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [1], | ||
}, | ||
}, | ||
{ | ||
type: 'logical', | ||
operator: 'and', | ||
negate: true, | ||
childNodes: [ | ||
{ | ||
type: 'condition', | ||
negate: true, | ||
target: { | ||
type: 'primitive', | ||
table: randomTable, | ||
column: thirdColumn, | ||
}, | ||
operation: 'lt', | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [2], | ||
}, | ||
}, | ||
{ | ||
type: 'condition', | ||
negate: false, | ||
target: { | ||
type: 'primitive', | ||
table: randomTable, | ||
column: fourthColumn, | ||
}, | ||
operation: 'eq', | ||
compareTo: { | ||
type: 'value', | ||
parameterIndexes: [3], | ||
}, | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
parameters: [firstValue, secondValue, thirdValue, fourthValue], | ||
}; | ||
|
||
expect(where(statement)).toStrictEqual( | ||
`WHERE "${randomTable}"."${firstColumn}" > $1 OR "${randomTable}"."${secondColumn}" != $2 OR NOT ("${randomTable}"."${thirdColumn}" >= $3 AND "${randomTable}"."${fourthColumn}" = $4)` | ||
); | ||
}); |
Oops, something went wrong.