Skip to content

Commit 6a74c34

Browse files
committed
Add support for model based optimizing IsDistinctFrom/IsNotDistinctFrom
Change-type: minor
1 parent 9f2de98 commit 6a74c34

File tree

2 files changed

+148
-0
lines changed

2 files changed

+148
-0
lines changed

src/AbstractSQLOptimiser.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,16 @@ const typeRules: Dictionary<MatchFn> = {
586586

587587
return ['NotExists', getAbstractSqlQuery(args, valueIndex)];
588588
}),
589+
Helper<OptimisationMatchFn>((args) => {
590+
checkArgs('IsDistinctFrom', args, 2);
591+
if (
592+
isNotNullable(getAbstractSqlQuery(args, 0)) &&
593+
isNotNullable(getAbstractSqlQuery(args, 1))
594+
) {
595+
return ['Equals', ...args];
596+
}
597+
return false;
598+
}),
589599
matchArgs('IsNotDistinctFrom', AnyValue, AnyValue),
590600
),
591601
IsDistinctFrom: tryMatches(
@@ -602,6 +612,16 @@ const typeRules: Dictionary<MatchFn> = {
602612

603613
return ['Exists', getAbstractSqlQuery(args, valueIndex)];
604614
}),
615+
Helper<OptimisationMatchFn>((args) => {
616+
checkArgs('IsDistinctFrom', args, 2);
617+
if (
618+
isNotNullable(getAbstractSqlQuery(args, 0)) &&
619+
isNotNullable(getAbstractSqlQuery(args, 1))
620+
) {
621+
return ['NotEquals', ...args];
622+
}
623+
return false;
624+
}),
605625
matchArgs('IsDistinctFrom', AnyValue, AnyValue),
606626
),
607627
Add: MathOp('Add'),

test/abstract-sql/models-based-optimizations.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,131 @@ it('should optimize NotExists for a non nullable field', () => {
110110
).to.have.nested.property('rules[0].sql').that.equals(`\
111111
SELECT 1 AS "result";`);
112112
});
113+
114+
it('should optimize IsDistinctFrom for two non nullable fields', () => {
115+
expect(
116+
AbstractSQLCompiler.postgres.compileSchema({
117+
synonyms: {},
118+
relationships: {},
119+
tables: {
120+
test: {
121+
name: 'test',
122+
resourceName: 'test',
123+
idField: 'id',
124+
fields: [
125+
{
126+
fieldName: 'id',
127+
dataType: 'Integer',
128+
required: true,
129+
index: 'PRIMARY KEY',
130+
},
131+
{
132+
fieldName: 'num',
133+
dataType: 'Integer',
134+
required: true,
135+
},
136+
],
137+
indexes: [],
138+
primitive: false,
139+
},
140+
},
141+
rules: [
142+
[
143+
'Rule',
144+
[
145+
'Body',
146+
[
147+
'Not',
148+
[
149+
'Exists',
150+
[
151+
'SelectQuery',
152+
['Select', []],
153+
['From', ['test', 'test.0']],
154+
[
155+
'Where',
156+
[
157+
'IsDistinctFrom',
158+
['ReferencedField', 'test.0', 'id'],
159+
['ReferencedField', 'test.0', 'num'],
160+
],
161+
],
162+
],
163+
],
164+
],
165+
] as AbstractSQLCompiler.AbstractSqlQuery,
166+
['StructuredEnglish', 'Test rule'],
167+
],
168+
],
169+
}),
170+
).to.have.nested.property('rules[0].sql').that.equals(`\
171+
SELECT NOT EXISTS (
172+
SELECT 1
173+
FROM "test" AS "test.0"
174+
WHERE "test.0"."id" != "test.0"."num"
175+
) AS "result";`);
176+
});
177+
178+
it('should optimize IsNotDistinctFrom for two non nullable fields', () => {
179+
expect(
180+
AbstractSQLCompiler.postgres.compileSchema({
181+
synonyms: {},
182+
relationships: {},
183+
tables: {
184+
test: {
185+
name: 'test',
186+
resourceName: 'test',
187+
idField: 'id',
188+
fields: [
189+
{
190+
fieldName: 'id',
191+
dataType: 'Integer',
192+
required: true,
193+
index: 'PRIMARY KEY',
194+
},
195+
{
196+
fieldName: 'num',
197+
dataType: 'Integer',
198+
required: true,
199+
},
200+
],
201+
indexes: [],
202+
primitive: false,
203+
},
204+
},
205+
rules: [
206+
[
207+
'Rule',
208+
[
209+
'Body',
210+
[
211+
'Not',
212+
[
213+
'Exists',
214+
[
215+
'SelectQuery',
216+
['Select', []],
217+
['From', ['test', 'test.0']],
218+
[
219+
'Where',
220+
[
221+
'IsNotDistinctFrom',
222+
['ReferencedField', 'test.0', 'id'],
223+
['ReferencedField', 'test.0', 'num'],
224+
],
225+
],
226+
],
227+
],
228+
],
229+
] as AbstractSQLCompiler.AbstractSqlQuery,
230+
['StructuredEnglish', 'Test rule'],
231+
],
232+
],
233+
}),
234+
).to.have.nested.property('rules[0].sql').that.equals(`\
235+
SELECT NOT EXISTS (
236+
SELECT 1
237+
FROM "test" AS "test.0"
238+
WHERE "test.0"."id" = "test.0"."num"
239+
) AS "result";`);
240+
});

0 commit comments

Comments
 (0)