@finos/legend-query-builder 4.1.15 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts +6 -1
- package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
- package/lib/components/filter/QueryBuilderFilterPanel.js +189 -13
- package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.d.ts +1 -0
- package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
- package/lib/stores/QueryBuilderStateHashUtils.js +1 -0
- package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.d.ts +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterOperator.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.d.ts +16 -5
- package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterState.js +78 -18
- package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js +125 -2
- package/lib/stores/filter/QueryBuilderFilterStateBuilder.js.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js +62 -3
- package/lib/stores/filter/QueryBuilderFilterValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.js +12 -192
- package/lib/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Contain.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_EndWith.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_Equal.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_In.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThan.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.js.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts +2 -2
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.d.ts.map +1 -1
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js +4 -4
- package/lib/stores/filter/operators/QueryBuilderFilterOperator_StartWith.js.map +1 -1
- package/package.json +1 -1
- package/src/components/filter/QueryBuilderFilterPanel.tsx +355 -24
- package/src/stores/QueryBuilderStateHashUtils.ts +1 -0
- package/src/stores/filter/QueryBuilderFilterOperator.ts +1 -0
- package/src/stores/filter/QueryBuilderFilterState.ts +115 -27
- package/src/stores/filter/QueryBuilderFilterStateBuilder.ts +244 -0
- package/src/stores/filter/QueryBuilderFilterValueSpecificationBuilder.ts +94 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperatorValueSpecificationBuilder.ts +37 -377
- package/src/stores/filter/operators/QueryBuilderFilterOperator_Contain.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_EndWith.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_Equal.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThan.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_GreaterThanEqual.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_In.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_IsEmpty.ts +7 -1
- package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThan.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_LessThanEqual.ts +2 -0
- package/src/stores/filter/operators/QueryBuilderFilterOperator_StartWith.ts +7 -1
|
@@ -19,217 +19,36 @@ import {
|
|
|
19
19
|
extractElementNameFromPath,
|
|
20
20
|
matchFunctionName,
|
|
21
21
|
LambdaFunctionInstanceValue,
|
|
22
|
-
VariableExpression,
|
|
23
22
|
AbstractPropertyExpression,
|
|
24
23
|
SimpleFunctionExpression,
|
|
25
|
-
|
|
24
|
+
LambdaFunction,
|
|
26
25
|
} from '@finos/legend-graph';
|
|
27
26
|
import {
|
|
28
27
|
guaranteeType,
|
|
29
28
|
guaranteeNonNullable,
|
|
30
29
|
assertTrue,
|
|
31
|
-
generateEnumerableNameFromToken,
|
|
32
30
|
} from '@finos/legend-shared';
|
|
33
31
|
import {
|
|
34
32
|
FilterConditionState,
|
|
35
33
|
type QueryBuilderFilterState,
|
|
36
34
|
} from '../QueryBuilderFilterState.js';
|
|
37
35
|
import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../graph/QueryBuilderMetaModelConst.js';
|
|
38
|
-
import {
|
|
39
|
-
buildGenericLambdaFunctionInstanceValue,
|
|
40
|
-
simplifyValueExpression,
|
|
41
|
-
} from '../../QueryBuilderValueSpecificationHelper.js';
|
|
36
|
+
import { simplifyValueExpression } from '../../QueryBuilderValueSpecificationHelper.js';
|
|
42
37
|
import type { QueryBuilderFilterOperator } from '../QueryBuilderFilterOperator.js';
|
|
43
38
|
import { buildPropertyExpressionChain } from '../../QueryBuilderValueSpecificationBuilderHelper.js';
|
|
44
39
|
|
|
45
|
-
const getPropertyExpressionChainVariable = (
|
|
46
|
-
propertyExpression: AbstractPropertyExpression,
|
|
47
|
-
): VariableExpression => {
|
|
48
|
-
let currentExpression: ValueSpecification = propertyExpression;
|
|
49
|
-
while (currentExpression instanceof AbstractPropertyExpression) {
|
|
50
|
-
currentExpression = guaranteeNonNullable(
|
|
51
|
-
currentExpression.parametersValues[0],
|
|
52
|
-
);
|
|
53
|
-
// Take care of chains of subtype (a pattern that is not useful, but we want to support and rectify)
|
|
54
|
-
// $x.employees->subType(@Person)->subType(@Staff)
|
|
55
|
-
while (
|
|
56
|
-
currentExpression instanceof SimpleFunctionExpression &&
|
|
57
|
-
matchFunctionName(
|
|
58
|
-
currentExpression.functionName,
|
|
59
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
|
60
|
-
)
|
|
61
|
-
) {
|
|
62
|
-
currentExpression = guaranteeNonNullable(
|
|
63
|
-
currentExpression.parametersValues[0],
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return guaranteeType(currentExpression, VariableExpression);
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const buildFilterConditionExpressionWithExists = (
|
|
71
|
-
filterConditionState: FilterConditionState,
|
|
72
|
-
operatorFunctionFullPath: string,
|
|
73
|
-
): ValueSpecification => {
|
|
74
|
-
assertTrue(
|
|
75
|
-
filterConditionState.propertyExpressionState.requiresExistsHandling,
|
|
76
|
-
);
|
|
77
|
-
// 1. Decompose property expression
|
|
78
|
-
const expressions: (AbstractPropertyExpression | SimpleFunctionExpression)[] =
|
|
79
|
-
[];
|
|
80
|
-
let currentPropertyExpression: ValueSpecification =
|
|
81
|
-
buildPropertyExpressionChain(
|
|
82
|
-
filterConditionState.propertyExpressionState.propertyExpression,
|
|
83
|
-
filterConditionState.propertyExpressionState.queryBuilderState,
|
|
84
|
-
filterConditionState.filterState.lambdaParameterName,
|
|
85
|
-
);
|
|
86
|
-
while (
|
|
87
|
-
currentPropertyExpression instanceof AbstractPropertyExpression ||
|
|
88
|
-
(currentPropertyExpression instanceof SimpleFunctionExpression &&
|
|
89
|
-
matchFunctionName(
|
|
90
|
-
currentPropertyExpression.functionName,
|
|
91
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
|
92
|
-
))
|
|
93
|
-
) {
|
|
94
|
-
let exp: AbstractPropertyExpression | SimpleFunctionExpression;
|
|
95
|
-
if (currentPropertyExpression instanceof SimpleFunctionExpression) {
|
|
96
|
-
exp = new SimpleFunctionExpression(
|
|
97
|
-
extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE),
|
|
98
|
-
);
|
|
99
|
-
} else {
|
|
100
|
-
exp = new AbstractPropertyExpression('');
|
|
101
|
-
exp.func = currentPropertyExpression.func;
|
|
102
|
-
}
|
|
103
|
-
// NOTE: we must retain the rest of the parameters as those are derived property parameters
|
|
104
|
-
exp.parametersValues =
|
|
105
|
-
currentPropertyExpression.parametersValues.length > 1
|
|
106
|
-
? currentPropertyExpression.parametersValues.slice(1)
|
|
107
|
-
: [];
|
|
108
|
-
expressions.push(exp);
|
|
109
|
-
currentPropertyExpression = guaranteeNonNullable(
|
|
110
|
-
currentPropertyExpression.parametersValues[0],
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
const rootVariable = guaranteeType(
|
|
114
|
-
currentPropertyExpression,
|
|
115
|
-
VariableExpression,
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
// 2. Traverse the list of decomposed property expression backward, every time we encounter a property of
|
|
119
|
-
// multiplicity many, create a new property expression and keep track of it to later form the lambda chain
|
|
120
|
-
const existsLambdaParamNames = [
|
|
121
|
-
...filterConditionState.existsLambdaParamNames,
|
|
122
|
-
];
|
|
123
|
-
const existsLambdaPropertyChains: ValueSpecification[] = [rootVariable];
|
|
124
|
-
let currentParamNameIndex = 0;
|
|
125
|
-
|
|
126
|
-
for (let i = expressions.length - 1; i >= 0; --i) {
|
|
127
|
-
const exp = expressions[i] as
|
|
128
|
-
| AbstractPropertyExpression
|
|
129
|
-
| SimpleFunctionExpression;
|
|
130
|
-
// just keep adding to the property chain
|
|
131
|
-
exp.parametersValues.unshift(
|
|
132
|
-
existsLambdaPropertyChains[
|
|
133
|
-
existsLambdaPropertyChains.length - 1
|
|
134
|
-
] as ValueSpecification,
|
|
135
|
-
);
|
|
136
|
-
existsLambdaPropertyChains[existsLambdaPropertyChains.length - 1] = exp;
|
|
137
|
-
// ... but if the property is of multiplicity multiple, start a new property chain
|
|
138
|
-
if (
|
|
139
|
-
exp instanceof AbstractPropertyExpression &&
|
|
140
|
-
(exp.func.value.multiplicity.upperBound === undefined ||
|
|
141
|
-
exp.func.value.multiplicity.upperBound > 1)
|
|
142
|
-
) {
|
|
143
|
-
// NOTE: we need to find/generate the property chain variable name
|
|
144
|
-
// here, by doing this, we try our best to respect original/user-input variable name
|
|
145
|
-
if (currentParamNameIndex > existsLambdaParamNames.length - 1) {
|
|
146
|
-
existsLambdaParamNames.push(
|
|
147
|
-
generateEnumerableNameFromToken(
|
|
148
|
-
existsLambdaParamNames,
|
|
149
|
-
filterConditionState.filterState.lambdaParameterName,
|
|
150
|
-
),
|
|
151
|
-
);
|
|
152
|
-
assertTrue(currentParamNameIndex === existsLambdaParamNames.length - 1);
|
|
153
|
-
}
|
|
154
|
-
existsLambdaPropertyChains.push(
|
|
155
|
-
new VariableExpression(
|
|
156
|
-
existsLambdaParamNames[currentParamNameIndex] as string,
|
|
157
|
-
Multiplicity.ONE,
|
|
158
|
-
),
|
|
159
|
-
);
|
|
160
|
-
currentParamNameIndex++;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// 3. Build each property chain into an exists() simple function expression
|
|
165
|
-
const simpleFunctionExpressions: SimpleFunctionExpression[] = [];
|
|
166
|
-
for (let i = 0; i < existsLambdaPropertyChains.length - 1; ++i) {
|
|
167
|
-
const simpleFunctionExpression = new SimpleFunctionExpression(
|
|
168
|
-
extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS),
|
|
169
|
-
);
|
|
170
|
-
simpleFunctionExpression.parametersValues.push(
|
|
171
|
-
existsLambdaPropertyChains[i] as ValueSpecification,
|
|
172
|
-
);
|
|
173
|
-
simpleFunctionExpressions.push(simpleFunctionExpression);
|
|
174
|
-
}
|
|
175
|
-
// build the leaf simple function expression which uses the operator
|
|
176
|
-
const operatorEpression = new SimpleFunctionExpression(
|
|
177
|
-
extractElementNameFromPath(operatorFunctionFullPath),
|
|
178
|
-
);
|
|
179
|
-
operatorEpression.parametersValues.push(
|
|
180
|
-
existsLambdaPropertyChains[
|
|
181
|
-
existsLambdaPropertyChains.length - 1
|
|
182
|
-
] as ValueSpecification,
|
|
183
|
-
);
|
|
184
|
-
// NOTE: there are simple operators which do not require any params (e.g. isEmpty)
|
|
185
|
-
if (filterConditionState.value) {
|
|
186
|
-
operatorEpression.parametersValues.push(filterConditionState.value);
|
|
187
|
-
}
|
|
188
|
-
simpleFunctionExpressions.push(operatorEpression);
|
|
189
|
-
|
|
190
|
-
// 4. Build the exists() lambda chain
|
|
191
|
-
assertTrue(simpleFunctionExpressions.length >= 2);
|
|
192
|
-
for (let i = simpleFunctionExpressions.length - 2; i >= 0; --i) {
|
|
193
|
-
const currentSFE = simpleFunctionExpressions[i] as SimpleFunctionExpression;
|
|
194
|
-
const childSFE = simpleFunctionExpressions[
|
|
195
|
-
i + 1
|
|
196
|
-
] as SimpleFunctionExpression;
|
|
197
|
-
// build child SFE lambda
|
|
198
|
-
const _existsLambdaVariable = childSFE.parametersValues[0];
|
|
199
|
-
const existsLambdaVariable =
|
|
200
|
-
_existsLambdaVariable instanceof AbstractPropertyExpression
|
|
201
|
-
? getPropertyExpressionChainVariable(_existsLambdaVariable)
|
|
202
|
-
: guaranteeType(_existsLambdaVariable, VariableExpression);
|
|
203
|
-
const existsLambda = buildGenericLambdaFunctionInstanceValue(
|
|
204
|
-
existsLambdaVariable.name,
|
|
205
|
-
[childSFE],
|
|
206
|
-
filterConditionState.filterState.queryBuilderState.graphManagerState
|
|
207
|
-
.graph,
|
|
208
|
-
);
|
|
209
|
-
// add the child SFE lambda to the current SFE parameters
|
|
210
|
-
currentSFE.parametersValues.push(existsLambda);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return simpleFunctionExpressions[0] as SimpleFunctionExpression;
|
|
214
|
-
};
|
|
215
|
-
|
|
216
40
|
export const buildFilterConditionExpression = (
|
|
217
41
|
filterConditionState: FilterConditionState,
|
|
218
42
|
operatorFunctionFullPath: string,
|
|
43
|
+
lambdaParameterName?: string | undefined,
|
|
219
44
|
): ValueSpecification => {
|
|
220
|
-
if (filterConditionState.propertyExpressionState.requiresExistsHandling) {
|
|
221
|
-
return buildFilterConditionExpressionWithExists(
|
|
222
|
-
filterConditionState,
|
|
223
|
-
operatorFunctionFullPath,
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
45
|
const expression = new SimpleFunctionExpression(
|
|
227
46
|
extractElementNameFromPath(operatorFunctionFullPath),
|
|
228
47
|
);
|
|
229
48
|
const propertyExpression = buildPropertyExpressionChain(
|
|
230
49
|
filterConditionState.propertyExpressionState.propertyExpression,
|
|
231
50
|
filterConditionState.propertyExpressionState.queryBuilderState,
|
|
232
|
-
filterConditionState.filterState.lambdaParameterName,
|
|
51
|
+
lambdaParameterName ?? filterConditionState.filterState.lambdaParameterName,
|
|
233
52
|
);
|
|
234
53
|
expression.parametersValues.push(guaranteeNonNullable(propertyExpression));
|
|
235
54
|
// NOTE: there are simple operators which do not require any params (e.g. isEmpty)
|
|
@@ -239,182 +58,6 @@ export const buildFilterConditionExpression = (
|
|
|
239
58
|
return expression;
|
|
240
59
|
};
|
|
241
60
|
|
|
242
|
-
/**
|
|
243
|
-
* Handling exists() lambda found in the filter condition expression.
|
|
244
|
-
* The general approach for handling exists() is we will flat out the chain
|
|
245
|
-
* of exists() expressions into a normal filter condition state.
|
|
246
|
-
*
|
|
247
|
-
* When we build the condition function expression from the filter condition state,
|
|
248
|
-
* we walk the property expression chain, find property with multiplitiy upper bound
|
|
249
|
-
* other than 1 and create an exists() lambda there
|
|
250
|
-
*
|
|
251
|
-
* NOTE: to ensure we respect user's choice of variable name, as we build the state
|
|
252
|
-
* we record the lambda parameter names, so we can use those while re-building the function
|
|
253
|
-
* If for some reason, this list is stale, we can start adding our own parameter names
|
|
254
|
-
*/
|
|
255
|
-
const buildFilterConditionStateWithExists = (
|
|
256
|
-
filterState: QueryBuilderFilterState,
|
|
257
|
-
parentExpression: SimpleFunctionExpression,
|
|
258
|
-
operatorFunctionFullPath: string,
|
|
259
|
-
): [FilterConditionState | undefined, SimpleFunctionExpression | undefined] => {
|
|
260
|
-
if (
|
|
261
|
-
matchFunctionName(
|
|
262
|
-
parentExpression.functionName,
|
|
263
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS,
|
|
264
|
-
)
|
|
265
|
-
) {
|
|
266
|
-
// 1. Decompose the exists() lambda chain into property expression chains
|
|
267
|
-
const existsLambdaParameterNames: string[] = [];
|
|
268
|
-
|
|
269
|
-
// `existsLambdaExpressions` should be a list of `AbstractPropertyExpression`
|
|
270
|
-
// e.g. |Firm.all()->filter(x|$x.employees->exists(x_1|$x_1->subType(@Develper).id->exists(x_2|$x_2 == 1))
|
|
271
|
-
// In the first exists() lambda, `$x_1->subType(@Develper).id` is an `AbstractPropertyExpression`.
|
|
272
|
-
const existsLambdaExpressions: AbstractPropertyExpression[] = [];
|
|
273
|
-
let mainFilterExpression: SimpleFunctionExpression = parentExpression;
|
|
274
|
-
while (
|
|
275
|
-
matchFunctionName(
|
|
276
|
-
mainFilterExpression.functionName,
|
|
277
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS,
|
|
278
|
-
)
|
|
279
|
-
) {
|
|
280
|
-
const existsLambda = guaranteeNonNullable(
|
|
281
|
-
guaranteeType(
|
|
282
|
-
mainFilterExpression.parametersValues[1],
|
|
283
|
-
LambdaFunctionInstanceValue,
|
|
284
|
-
).values[0],
|
|
285
|
-
`Can't process exists() expression: exists() lambda is missing`,
|
|
286
|
-
);
|
|
287
|
-
assertTrue(
|
|
288
|
-
existsLambda.expressionSequence.length === 1,
|
|
289
|
-
`Can't process exists() expression: exists() lambda body should hold an expression`,
|
|
290
|
-
);
|
|
291
|
-
mainFilterExpression = guaranteeType(
|
|
292
|
-
existsLambda.expressionSequence[0],
|
|
293
|
-
SimpleFunctionExpression,
|
|
294
|
-
`Can't process exists() expression: exists() lambda body should hold an expression`,
|
|
295
|
-
);
|
|
296
|
-
|
|
297
|
-
// record the lambda parameter name
|
|
298
|
-
assertTrue(
|
|
299
|
-
existsLambda.functionType.parameters.length === 1,
|
|
300
|
-
`Can't process exists() expression: exists() lambda should have 1 parameter`,
|
|
301
|
-
);
|
|
302
|
-
existsLambdaParameterNames.push(
|
|
303
|
-
guaranteeType(
|
|
304
|
-
existsLambda.functionType.parameters[0],
|
|
305
|
-
VariableExpression,
|
|
306
|
-
`Can't process exists() expression: exists() lambda should have 1 parameter`,
|
|
307
|
-
).name,
|
|
308
|
-
);
|
|
309
|
-
|
|
310
|
-
// record the lambda property expression
|
|
311
|
-
if (
|
|
312
|
-
mainFilterExpression.parametersValues[0] instanceof
|
|
313
|
-
AbstractPropertyExpression
|
|
314
|
-
) {
|
|
315
|
-
existsLambdaExpressions.push(mainFilterExpression.parametersValues[0]);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
// NOTE: make sure that the inner most function expression is the one we support
|
|
319
|
-
if (
|
|
320
|
-
!matchFunctionName(
|
|
321
|
-
mainFilterExpression.functionName,
|
|
322
|
-
operatorFunctionFullPath,
|
|
323
|
-
)
|
|
324
|
-
) {
|
|
325
|
-
return [undefined, undefined];
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// 2. Build the property expression
|
|
329
|
-
const initialPropertyExpression = guaranteeType(
|
|
330
|
-
parentExpression.parametersValues[0],
|
|
331
|
-
AbstractPropertyExpression,
|
|
332
|
-
);
|
|
333
|
-
let flattenedPropertyExpressionChain = new AbstractPropertyExpression('');
|
|
334
|
-
flattenedPropertyExpressionChain.func = initialPropertyExpression.func;
|
|
335
|
-
flattenedPropertyExpressionChain.parametersValues = [
|
|
336
|
-
...initialPropertyExpression.parametersValues,
|
|
337
|
-
];
|
|
338
|
-
|
|
339
|
-
for (const expression of existsLambdaExpressions) {
|
|
340
|
-
// when rebuilding the property expression chain, disregard the initial variable that starts the chain
|
|
341
|
-
const expressions: (
|
|
342
|
-
| AbstractPropertyExpression
|
|
343
|
-
| SimpleFunctionExpression
|
|
344
|
-
)[] = [];
|
|
345
|
-
let currentExpression: ValueSpecification = expression;
|
|
346
|
-
while (
|
|
347
|
-
currentExpression instanceof AbstractPropertyExpression ||
|
|
348
|
-
(currentExpression instanceof SimpleFunctionExpression &&
|
|
349
|
-
matchFunctionName(
|
|
350
|
-
currentExpression.functionName,
|
|
351
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
|
352
|
-
))
|
|
353
|
-
) {
|
|
354
|
-
if (currentExpression instanceof SimpleFunctionExpression) {
|
|
355
|
-
const functionExpression = new SimpleFunctionExpression(
|
|
356
|
-
extractElementNameFromPath(
|
|
357
|
-
QUERY_BUILDER_SUPPORTED_FUNCTIONS.SUBTYPE,
|
|
358
|
-
),
|
|
359
|
-
);
|
|
360
|
-
functionExpression.parametersValues.unshift(
|
|
361
|
-
guaranteeNonNullable(currentExpression.parametersValues[1]),
|
|
362
|
-
);
|
|
363
|
-
expressions.push(functionExpression);
|
|
364
|
-
} else if (currentExpression instanceof AbstractPropertyExpression) {
|
|
365
|
-
const propertyExpression = new AbstractPropertyExpression('');
|
|
366
|
-
propertyExpression.func = currentExpression.func;
|
|
367
|
-
// NOTE: we must retain the rest of the parameters as those are derived property parameters
|
|
368
|
-
propertyExpression.parametersValues =
|
|
369
|
-
currentExpression.parametersValues.length > 1
|
|
370
|
-
? currentExpression.parametersValues.slice(1)
|
|
371
|
-
: [];
|
|
372
|
-
expressions.push(propertyExpression);
|
|
373
|
-
}
|
|
374
|
-
currentExpression = guaranteeNonNullable(
|
|
375
|
-
currentExpression.parametersValues[0],
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
assertTrue(
|
|
379
|
-
expressions.length > 0,
|
|
380
|
-
`Can't process exists() expression: exists() usage with non-chain property expression is not supported`,
|
|
381
|
-
);
|
|
382
|
-
for (let i = 0; i < expressions.length - 1; ++i) {
|
|
383
|
-
(
|
|
384
|
-
expressions[i] as
|
|
385
|
-
| AbstractPropertyExpression
|
|
386
|
-
| SimpleFunctionExpression
|
|
387
|
-
).parametersValues.unshift(
|
|
388
|
-
expressions[i + 1] as
|
|
389
|
-
| AbstractPropertyExpression
|
|
390
|
-
| SimpleFunctionExpression,
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
(
|
|
394
|
-
expressions[expressions.length - 1] as
|
|
395
|
-
| AbstractPropertyExpression
|
|
396
|
-
| SimpleFunctionExpression
|
|
397
|
-
).parametersValues.unshift(flattenedPropertyExpressionChain);
|
|
398
|
-
flattenedPropertyExpressionChain = guaranteeType(
|
|
399
|
-
expressions[0],
|
|
400
|
-
AbstractPropertyExpression,
|
|
401
|
-
`Can't process exists() expression: can't flatten to a property expression`,
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// 3. Build the filter condition state with the simplified property expression
|
|
406
|
-
const filterConditionState = new FilterConditionState(
|
|
407
|
-
filterState,
|
|
408
|
-
flattenedPropertyExpressionChain,
|
|
409
|
-
);
|
|
410
|
-
existsLambdaParameterNames.forEach((paramName) =>
|
|
411
|
-
filterConditionState.addExistsLambdaParamNames(paramName),
|
|
412
|
-
);
|
|
413
|
-
return [filterConditionState, mainFilterExpression];
|
|
414
|
-
}
|
|
415
|
-
return [undefined, undefined];
|
|
416
|
-
};
|
|
417
|
-
|
|
418
61
|
export const buildFilterConditionState = (
|
|
419
62
|
filterState: QueryBuilderFilterState,
|
|
420
63
|
expression: SimpleFunctionExpression,
|
|
@@ -451,17 +94,6 @@ export const buildFilterConditionState = (
|
|
|
451
94
|
)}() expression: expects property expression in lambda body`,
|
|
452
95
|
);
|
|
453
96
|
|
|
454
|
-
const variableName =
|
|
455
|
-
getPropertyExpressionChainVariable(propertyExpression).name;
|
|
456
|
-
assertTrue(
|
|
457
|
-
filterState.lambdaParameterName === variableName,
|
|
458
|
-
`Can't process ${extractElementNameFromPath(
|
|
459
|
-
operatorFunctionFullPath,
|
|
460
|
-
)}() expression: expects variable used in lambda body '${variableName}' to match lambda parameter '${
|
|
461
|
-
filterState.lambdaParameterName
|
|
462
|
-
}'`,
|
|
463
|
-
);
|
|
464
|
-
|
|
465
97
|
filterConditionState = new FilterConditionState(
|
|
466
98
|
filterState,
|
|
467
99
|
propertyExpression,
|
|
@@ -473,12 +105,40 @@ export const buildFilterConditionState = (
|
|
|
473
105
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.EXISTS,
|
|
474
106
|
)
|
|
475
107
|
) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
108
|
+
const lambdaFunctionInstance = guaranteeType(
|
|
109
|
+
expression.parametersValues[1],
|
|
110
|
+
LambdaFunctionInstanceValue,
|
|
111
|
+
);
|
|
112
|
+
const lambdaFunction = guaranteeType(
|
|
113
|
+
lambdaFunctionInstance.values[0],
|
|
114
|
+
LambdaFunction,
|
|
115
|
+
);
|
|
116
|
+
const filterExpression = guaranteeType(
|
|
117
|
+
lambdaFunction.expressionSequence[0],
|
|
118
|
+
SimpleFunctionExpression,
|
|
119
|
+
);
|
|
120
|
+
assertTrue(
|
|
121
|
+
filterExpression.parametersValues.length === (hasNoValue ? 1 : 2),
|
|
122
|
+
`Can't process ${extractElementNameFromPath(
|
|
480
123
|
operatorFunctionFullPath,
|
|
481
|
-
)
|
|
124
|
+
)}() expression: ${extractElementNameFromPath(
|
|
125
|
+
operatorFunctionFullPath,
|
|
126
|
+
)}() expects ${hasNoValue ? 'no argument' : '1 argument'}`,
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
const propertyExpression = guaranteeType(
|
|
130
|
+
filterExpression.parametersValues[0],
|
|
131
|
+
AbstractPropertyExpression,
|
|
132
|
+
`Can't process ${extractElementNameFromPath(
|
|
133
|
+
operatorFunctionFullPath,
|
|
134
|
+
)}() expression: expects property expression in lambda body`,
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
filterConditionState = new FilterConditionState(
|
|
138
|
+
filterState,
|
|
139
|
+
propertyExpression,
|
|
140
|
+
);
|
|
141
|
+
mainExpressionWithOperator = filterExpression;
|
|
482
142
|
}
|
|
483
143
|
|
|
484
144
|
// Post-build check: make sure the simple filter condition LHS, RHS, and operator are compatible
|
|
@@ -98,10 +98,12 @@ export class QueryBuilderFilterOperator_Contain
|
|
|
98
98
|
|
|
99
99
|
buildFilterConditionExpression(
|
|
100
100
|
filterConditionState: FilterConditionState,
|
|
101
|
+
lambdaParameterName?: string | undefined,
|
|
101
102
|
): ValueSpecification {
|
|
102
103
|
return buildFilterConditionExpression(
|
|
103
104
|
filterConditionState,
|
|
104
105
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.CONTAINS,
|
|
106
|
+
lambdaParameterName,
|
|
105
107
|
);
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -131,9 +133,13 @@ export class QueryBuilderFilterOperator_NotContain extends QueryBuilderFilterOpe
|
|
|
131
133
|
|
|
132
134
|
override buildFilterConditionExpression(
|
|
133
135
|
filterConditionState: FilterConditionState,
|
|
136
|
+
lambdaParameterName?: string | undefined,
|
|
134
137
|
): ValueSpecification {
|
|
135
138
|
return buildNotExpression(
|
|
136
|
-
super.buildFilterConditionExpression(
|
|
139
|
+
super.buildFilterConditionExpression(
|
|
140
|
+
filterConditionState,
|
|
141
|
+
lambdaParameterName,
|
|
142
|
+
),
|
|
137
143
|
);
|
|
138
144
|
}
|
|
139
145
|
|
|
@@ -98,10 +98,12 @@ export class QueryBuilderFilterOperator_EndWith
|
|
|
98
98
|
|
|
99
99
|
buildFilterConditionExpression(
|
|
100
100
|
filterConditionState: FilterConditionState,
|
|
101
|
+
lambdaParameterName?: string | undefined,
|
|
101
102
|
): ValueSpecification {
|
|
102
103
|
return buildFilterConditionExpression(
|
|
103
104
|
filterConditionState,
|
|
104
105
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.ENDS_WITH,
|
|
106
|
+
lambdaParameterName,
|
|
105
107
|
);
|
|
106
108
|
}
|
|
107
109
|
|
|
@@ -131,9 +133,13 @@ export class QueryBuilderFilterOperator_NotEndWith extends QueryBuilderFilterOpe
|
|
|
131
133
|
|
|
132
134
|
override buildFilterConditionExpression(
|
|
133
135
|
filterConditionState: FilterConditionState,
|
|
136
|
+
lambdaParameterName?: string | undefined,
|
|
134
137
|
): ValueSpecification {
|
|
135
138
|
return buildNotExpression(
|
|
136
|
-
super.buildFilterConditionExpression(
|
|
139
|
+
super.buildFilterConditionExpression(
|
|
140
|
+
filterConditionState,
|
|
141
|
+
lambdaParameterName,
|
|
142
|
+
),
|
|
137
143
|
);
|
|
138
144
|
}
|
|
139
145
|
|
|
@@ -165,6 +165,7 @@ export class QueryBuilderFilterOperator_Equal
|
|
|
165
165
|
|
|
166
166
|
buildFilterConditionExpression(
|
|
167
167
|
filterConditionState: FilterConditionState,
|
|
168
|
+
lambdaParameterName?: string | undefined,
|
|
168
169
|
): ValueSpecification {
|
|
169
170
|
return buildFilterConditionExpression(
|
|
170
171
|
filterConditionState,
|
|
@@ -174,6 +175,7 @@ export class QueryBuilderFilterOperator_Equal
|
|
|
174
175
|
PRIMITIVE_TYPE.DATETIME
|
|
175
176
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_DAY
|
|
176
177
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.EQUAL,
|
|
178
|
+
lambdaParameterName,
|
|
177
179
|
);
|
|
178
180
|
}
|
|
179
181
|
|
|
@@ -208,9 +210,13 @@ export class QueryBuilderFilterOperator_NotEqual extends QueryBuilderFilterOpera
|
|
|
208
210
|
|
|
209
211
|
override buildFilterConditionExpression(
|
|
210
212
|
filterConditionState: FilterConditionState,
|
|
213
|
+
lambdaParameterName?: string | undefined,
|
|
211
214
|
): ValueSpecification {
|
|
212
215
|
return buildNotExpression(
|
|
213
|
-
super.buildFilterConditionExpression(
|
|
216
|
+
super.buildFilterConditionExpression(
|
|
217
|
+
filterConditionState,
|
|
218
|
+
lambdaParameterName,
|
|
219
|
+
),
|
|
214
220
|
);
|
|
215
221
|
}
|
|
216
222
|
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_GreaterThan
|
|
|
123
123
|
|
|
124
124
|
buildFilterConditionExpression(
|
|
125
125
|
filterConditionState: FilterConditionState,
|
|
126
|
+
lambdaParameterName?: string | undefined,
|
|
126
127
|
): ValueSpecification {
|
|
127
128
|
return buildFilterConditionExpression(
|
|
128
129
|
filterConditionState,
|
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_GreaterThan
|
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_AFTER_DAY
|
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.GREATER_THAN,
|
|
136
|
+
lambdaParameterName,
|
|
135
137
|
);
|
|
136
138
|
}
|
|
137
139
|
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_GreaterThanEqual
|
|
|
123
123
|
|
|
124
124
|
buildFilterConditionExpression(
|
|
125
125
|
filterConditionState: FilterConditionState,
|
|
126
|
+
lambdaParameterName?: string | undefined,
|
|
126
127
|
): ValueSpecification {
|
|
127
128
|
return buildFilterConditionExpression(
|
|
128
129
|
filterConditionState,
|
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_GreaterThanEqual
|
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_OR_AFTER_DAY
|
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.GREATER_THAN_EQUAL,
|
|
136
|
+
lambdaParameterName,
|
|
135
137
|
);
|
|
136
138
|
}
|
|
137
139
|
|
|
@@ -135,10 +135,12 @@ export class QueryBuilderFilterOperator_In
|
|
|
135
135
|
|
|
136
136
|
buildFilterConditionExpression(
|
|
137
137
|
filterConditionState: FilterConditionState,
|
|
138
|
+
lambdaParameterName?: string | undefined,
|
|
138
139
|
): ValueSpecification {
|
|
139
140
|
return buildFilterConditionExpression(
|
|
140
141
|
filterConditionState,
|
|
141
142
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.IN,
|
|
143
|
+
lambdaParameterName,
|
|
142
144
|
);
|
|
143
145
|
}
|
|
144
146
|
|
|
@@ -166,9 +168,13 @@ export class QueryBuilderFilterOperator_NotIn extends QueryBuilderFilterOperator
|
|
|
166
168
|
|
|
167
169
|
override buildFilterConditionExpression(
|
|
168
170
|
filterConditionState: FilterConditionState,
|
|
171
|
+
lambdaParameterName?: string | undefined,
|
|
169
172
|
): ValueSpecification {
|
|
170
173
|
return buildNotExpression(
|
|
171
|
-
super.buildFilterConditionExpression(
|
|
174
|
+
super.buildFilterConditionExpression(
|
|
175
|
+
filterConditionState,
|
|
176
|
+
lambdaParameterName,
|
|
177
|
+
),
|
|
172
178
|
);
|
|
173
179
|
}
|
|
174
180
|
|
|
@@ -80,10 +80,12 @@ export class QueryBuilderFilterOperator_IsEmpty
|
|
|
80
80
|
|
|
81
81
|
buildFilterConditionExpression(
|
|
82
82
|
filterConditionState: FilterConditionState,
|
|
83
|
+
lambdaParameterName?: string | undefined,
|
|
83
84
|
): ValueSpecification {
|
|
84
85
|
return buildFilterConditionExpression(
|
|
85
86
|
filterConditionState,
|
|
86
87
|
QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_EMPTY,
|
|
88
|
+
lambdaParameterName,
|
|
87
89
|
);
|
|
88
90
|
}
|
|
89
91
|
|
|
@@ -114,9 +116,13 @@ export class QueryBuilderFilterOperator_IsNotEmpty extends QueryBuilderFilterOpe
|
|
|
114
116
|
|
|
115
117
|
override buildFilterConditionExpression(
|
|
116
118
|
filterConditionState: FilterConditionState,
|
|
119
|
+
lambdaParameterName?: string | undefined,
|
|
117
120
|
): ValueSpecification {
|
|
118
121
|
return buildNotExpression(
|
|
119
|
-
super.buildFilterConditionExpression(
|
|
122
|
+
super.buildFilterConditionExpression(
|
|
123
|
+
filterConditionState,
|
|
124
|
+
lambdaParameterName,
|
|
125
|
+
),
|
|
120
126
|
);
|
|
121
127
|
}
|
|
122
128
|
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_LessThan
|
|
|
123
123
|
|
|
124
124
|
buildFilterConditionExpression(
|
|
125
125
|
filterConditionState: FilterConditionState,
|
|
126
|
+
lambdaParameterName?: string | undefined,
|
|
126
127
|
): ValueSpecification {
|
|
127
128
|
return buildFilterConditionExpression(
|
|
128
129
|
filterConditionState,
|
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_LessThan
|
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_BEFORE_DAY
|
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.LESS_THAN,
|
|
136
|
+
lambdaParameterName,
|
|
135
137
|
);
|
|
136
138
|
}
|
|
137
139
|
|
|
@@ -123,6 +123,7 @@ export class QueryBuilderFilterOperator_LessThanEqual
|
|
|
123
123
|
|
|
124
124
|
buildFilterConditionExpression(
|
|
125
125
|
filterConditionState: FilterConditionState,
|
|
126
|
+
lambdaParameterName?: string | undefined,
|
|
126
127
|
): ValueSpecification {
|
|
127
128
|
return buildFilterConditionExpression(
|
|
128
129
|
filterConditionState,
|
|
@@ -132,6 +133,7 @@ export class QueryBuilderFilterOperator_LessThanEqual
|
|
|
132
133
|
PRIMITIVE_TYPE.DATETIME
|
|
133
134
|
? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_OR_BEFORE_DAY
|
|
134
135
|
: QUERY_BUILDER_SUPPORTED_FUNCTIONS.LESS_THAN_EQUAL,
|
|
136
|
+
lambdaParameterName,
|
|
135
137
|
);
|
|
136
138
|
}
|
|
137
139
|
|