@finos/legend-query-builder 4.15.41 → 4.15.43

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. package/lib/graph/QueryBuilderMetaModelConst.d.ts +5 -0
  2. package/lib/graph/QueryBuilderMetaModelConst.d.ts.map +1 -1
  3. package/lib/graph/QueryBuilderMetaModelConst.js +5 -0
  4. package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
  5. package/lib/index.css +1 -1
  6. package/lib/package.json +3 -3
  7. package/lib/stores/QueryBuilderStateBuilder.d.ts +2 -1
  8. package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
  9. package/lib/stores/QueryBuilderStateBuilder.js +15 -2
  10. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  11. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.d.ts +7 -8
  12. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.d.ts.map +1 -1
  13. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js +46 -48
  14. package/lib/stores/data-cube/QueryBuilderDataCubeEngine.js.map +1 -1
  15. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts +1 -0
  16. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts.map +1 -1
  17. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js +26 -2
  18. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js.map +1 -1
  19. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
  20. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +3 -75
  21. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
  22. package/lib/stores/fetch-structure/tds/result-modifier/ResultModifierValueSpecificationBuilder.d.ts +74 -0
  23. package/lib/stores/fetch-structure/tds/result-modifier/ResultModifierValueSpecificationBuilder.d.ts.map +1 -0
  24. package/lib/stores/fetch-structure/tds/result-modifier/ResultModifierValueSpecificationBuilder.js +213 -0
  25. package/lib/stores/fetch-structure/tds/result-modifier/ResultModifierValueSpecificationBuilder.js.map +1 -0
  26. package/package.json +9 -9
  27. package/src/graph/QueryBuilderMetaModelConst.ts +5 -1
  28. package/src/stores/QueryBuilderStateBuilder.ts +21 -3
  29. package/src/stores/data-cube/QueryBuilderDataCubeEngine.ts +86 -86
  30. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.ts +64 -1
  31. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +16 -146
  32. package/src/stores/fetch-structure/tds/result-modifier/ResultModifierValueSpecificationBuilder.ts +337 -0
  33. package/tsconfig.json +1 -0
@@ -25,7 +25,6 @@ import {
25
25
  V1_RawLambda,
26
26
  V1_serializeValueSpecification,
27
27
  type GraphManagerState,
28
- type PureModel,
29
28
  type V1_ValueSpecification,
30
29
  type ParameterValue,
31
30
  LAMBDA_PIPE,
@@ -79,53 +78,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
79
78
  this.parameters = selectQuery.parameters;
80
79
  }
81
80
 
82
- get sourceLabel(): string {
83
- return `Query Builder Report`;
84
- }
85
-
86
- get graph(): PureModel {
87
- return this.graphState.graph;
88
- }
89
-
90
- private getSourceFunctionExpression() {
91
- let srcFuncExp = V1_deserializeValueSpecification(
92
- this.graphState.graphManager.serializeRawValueSpecification(
93
- this.selectInitialQuery,
94
- ),
95
- [],
96
- );
97
- // We could do a further check here to ensure the experssion is an applied funciton
98
- // this is because data cube expects an expression to be able to built further upon the queery
99
- if (
100
- srcFuncExp instanceof V1_Lambda &&
101
- srcFuncExp.body.length === 1 &&
102
- srcFuncExp.body[0]
103
- ) {
104
- srcFuncExp = srcFuncExp.body[0];
105
- }
106
- return srcFuncExp;
107
- }
108
-
109
- async generateInitialQuery() {
110
- const srcFuncExp = this.getSourceFunctionExpression();
111
- const fromFuncExp = new V1_AppliedFunction();
112
- fromFuncExp.function = _functionName(SUPPORTED_FUNCTIONS.FROM);
113
- fromFuncExp.parameters = [srcFuncExp];
114
- if (this.mappingPath) {
115
- fromFuncExp.parameters.push(_elementPtr(this.mappingPath));
116
- }
117
- if (this.runtimePath) {
118
- fromFuncExp.parameters.push(_elementPtr(this.runtimePath));
119
- }
120
- const columns = (await this.getRelationType(this.selectInitialQuery))
121
- .columns;
122
- const query = new DataCubeQuery();
123
- query.query = `~[${columns.map((e) => `'${e.name}'`)}]->select()`;
124
-
125
- return query;
126
- }
127
-
128
- async processQuerySource(value: PlainObject) {
81
+ override async processQuerySource(value: PlainObject) {
129
82
  // TODO: this is an abnormal usage of this method, this is the place
130
83
  // where we can enforce which source this engine supports, instead
131
84
  // of hardcoding the logic like this.
@@ -140,17 +93,30 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
140
93
  return source;
141
94
  }
142
95
 
143
- private buildRawLambdaFromValueSpec(query: V1_Lambda): RawLambda {
144
- const json = guaranteeType(
145
- V1_deserializeRawValueSpecification(
146
- V1_serializeValueSpecification(query, []),
96
+ override async parseValueSpecification(
97
+ code: string,
98
+ returnSourceInformation?: boolean,
99
+ ) {
100
+ return V1_deserializeValueSpecification(
101
+ await this.graphState.graphManager.pureCodeToValueSpecification(
102
+ code,
103
+ returnSourceInformation,
147
104
  ),
148
- V1_RawLambda,
105
+ [],
106
+ );
107
+ }
108
+
109
+ override async getValueSpecificationCode(
110
+ value: V1_ValueSpecification,
111
+ pretty?: boolean | undefined,
112
+ ) {
113
+ return this.graphState.graphManager.valueSpecificationToPureCode(
114
+ V1_serializeValueSpecification(value, []),
115
+ pretty,
149
116
  );
150
- return new RawLambda(json.parameters, json.body);
151
117
  }
152
118
 
153
- async getQueryTypeahead(
119
+ override async getQueryTypeahead(
154
120
  code: string,
155
121
  baseQuery: V1_Lambda,
156
122
  source: DataCubeSource,
@@ -166,42 +132,17 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
166
132
  );
167
133
  const result = await this.graphState.graphManager.getCodeComplete(
168
134
  finalCode,
169
- this.graph,
135
+ this.graphState.graph,
170
136
  offset,
171
137
  );
172
138
  return result.completions as CompletionItem[];
173
139
  }
174
140
 
175
- override async parseValueSpecification(
176
- code: string,
177
- returnSourceInformation?: boolean,
178
- ) {
179
- return V1_deserializeValueSpecification(
180
- await this.graphState.graphManager.pureCodeToValueSpecification(
181
- code,
182
- returnSourceInformation,
183
- ),
184
- [],
185
- );
186
- }
187
-
188
- override async getValueSpecificationCode(
189
- value: V1_ValueSpecification,
190
- pretty?: boolean | undefined,
141
+ override async getQueryRelationReturnType(
142
+ query: V1_Lambda,
143
+ source: DataCubeSource,
191
144
  ) {
192
- return this.graphState.graphManager.valueSpecificationToPureCode(
193
- V1_serializeValueSpecification(value, []),
194
- pretty,
195
- );
196
- }
197
-
198
- async getRelationType(query: RawLambda) {
199
- const relationType =
200
- await this.graphState.graphManager.getLambdaRelationType(
201
- query,
202
- this.graph,
203
- );
204
- return relationType;
145
+ return this.getRelationType(this.buildRawLambdaFromValueSpec(query));
205
146
  }
206
147
 
207
148
  override async getQueryCodeRelationReturnType(
@@ -227,7 +168,7 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
227
168
  lambda,
228
169
  undefined,
229
170
  undefined,
230
- this.graph,
171
+ this.graphState.graph,
231
172
  {
232
173
  parameterValues: this.parameterValues ?? [],
233
174
  },
@@ -268,4 +209,63 @@ export class QueryBuilderDataCubeEngine extends DataCubeEngine {
268
209
  }
269
210
  return undefined;
270
211
  }
212
+
213
+ // ---------------------------------- UTILITIES ----------------------------------
214
+
215
+ private buildRawLambdaFromValueSpec(query: V1_Lambda): RawLambda {
216
+ const json = guaranteeType(
217
+ V1_deserializeRawValueSpecification(
218
+ V1_serializeValueSpecification(query, []),
219
+ ),
220
+ V1_RawLambda,
221
+ );
222
+ return new RawLambda(json.parameters, json.body);
223
+ }
224
+
225
+ private getSourceFunctionExpression() {
226
+ let srcFuncExp = V1_deserializeValueSpecification(
227
+ this.graphState.graphManager.serializeRawValueSpecification(
228
+ this.selectInitialQuery,
229
+ ),
230
+ [],
231
+ );
232
+ // We could do a further check here to ensure the experssion is an applied funciton
233
+ // this is because data cube expects an expression to be able to built further upon the queery
234
+ if (
235
+ srcFuncExp instanceof V1_Lambda &&
236
+ srcFuncExp.body.length === 1 &&
237
+ srcFuncExp.body[0]
238
+ ) {
239
+ srcFuncExp = srcFuncExp.body[0];
240
+ }
241
+ return srcFuncExp;
242
+ }
243
+
244
+ async generateInitialQuery() {
245
+ const srcFuncExp = this.getSourceFunctionExpression();
246
+ const fromFuncExp = new V1_AppliedFunction();
247
+ fromFuncExp.function = _functionName(SUPPORTED_FUNCTIONS.FROM);
248
+ fromFuncExp.parameters = [srcFuncExp];
249
+ if (this.mappingPath) {
250
+ fromFuncExp.parameters.push(_elementPtr(this.mappingPath));
251
+ }
252
+ if (this.runtimePath) {
253
+ fromFuncExp.parameters.push(_elementPtr(this.runtimePath));
254
+ }
255
+ const columns = (await this.getRelationType(this.selectInitialQuery))
256
+ .columns;
257
+ const query = new DataCubeQuery();
258
+ query.query = `~[${columns.map((e) => `'${e.name}'`)}]->select()`;
259
+
260
+ return query;
261
+ }
262
+
263
+ async getRelationType(query: RawLambda) {
264
+ const relationType =
265
+ await this.graphState.graphManager.getLambdaRelationType(
266
+ query,
267
+ this.graphState.graph,
268
+ );
269
+ return relationType;
270
+ }
271
271
  }
@@ -29,6 +29,7 @@ import {
29
29
  VariableExpression,
30
30
  PrimitiveInstanceValue,
31
31
  LambdaFunctionInstanceValue,
32
+ ColSpecInstanceValue,
32
33
  } from '@finos/legend-graph';
33
34
  import {
34
35
  assertNonNullable,
@@ -603,7 +604,7 @@ export const processTDSSortDirectionExpression = (
603
604
  // check parameters
604
605
  assertTrue(
605
606
  expression.parametersValues.length === 1,
606
- `Can't process ${functionName}() expression: ${functionName}() expects no argument`,
607
+ `Can't process ${functionName}() expression: ${functionName}() expects one argument`,
607
608
  );
608
609
 
609
610
  // build state
@@ -633,3 +634,65 @@ export const processTDSSortDirectionExpression = (
633
634
  }
634
635
  }
635
636
  };
637
+
638
+ export const processRelationSortDirectionExpression = (
639
+ expression: SimpleFunctionExpression,
640
+ parentExpression: SimpleFunctionExpression | undefined,
641
+ queryBuilderState: QueryBuilderState,
642
+ ): void => {
643
+ const functionName = expression.functionName;
644
+
645
+ // check parent expression
646
+ assertTrue(
647
+ Boolean(
648
+ parentExpression &&
649
+ matchFunctionName(
650
+ parentExpression.functionName,
651
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_SORT,
652
+ ),
653
+ ),
654
+ `Can't process ${functionName}() expression: only support ${functionName}() used within a sort() expression`,
655
+ );
656
+
657
+ // check parameters
658
+ assertTrue(
659
+ expression.parametersValues.length === 1,
660
+ `Can't process ${functionName}() expression: ${functionName}() expects one argument`,
661
+ );
662
+
663
+ // build state
664
+ if (
665
+ queryBuilderState.fetchStructureState.implementation instanceof
666
+ QueryBuilderTDSState
667
+ ) {
668
+ const projectionState =
669
+ queryBuilderState.fetchStructureState.implementation;
670
+ const value = guaranteeType(
671
+ expression.parametersValues[0],
672
+ ColSpecInstanceValue,
673
+ );
674
+ assertTrue(
675
+ value.values.length === 1,
676
+ `Can't process ${functionName}() expression: Col Spec Instance Value expects one value`,
677
+ );
678
+ const sortColumnName = guaranteeNonNullable(
679
+ value.values[0],
680
+ `Col Spec value expected in Col Spec Instance Value`,
681
+ ).name;
682
+ const queryBuilderProjectionColumnState = projectionState.tdsColumns.find(
683
+ (e) => e.columnName === sortColumnName,
684
+ );
685
+ if (queryBuilderProjectionColumnState) {
686
+ const sortColumnState = new SortColumnState(
687
+ queryBuilderProjectionColumnState,
688
+ );
689
+ sortColumnState.sortType = matchFunctionName(
690
+ functionName,
691
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.RELATION_ASC,
692
+ )
693
+ ? COLUMN_SORT_TYPE.ASC
694
+ : COLUMN_SORT_TYPE.DESC;
695
+ projectionState.resultSetModifierState.addSortColumn(sortColumnState);
696
+ }
697
+ }
698
+ };
@@ -27,7 +27,6 @@ import {
27
27
  V1_serializeRawValueSpecification,
28
28
  V1_transformRawLambda,
29
29
  V1_GraphTransformerContextBuilder,
30
- matchFunctionName,
31
30
  PrimitiveType,
32
31
  LambdaFunctionInstanceValue,
33
32
  } from '@finos/legend-graph';
@@ -42,10 +41,6 @@ import {
42
41
  QueryBuilderSimpleProjectionColumnState,
43
42
  } from './QueryBuilderProjectionColumnState.js';
44
43
  import type { QueryBuilderTDSState } from '../QueryBuilderTDSState.js';
45
- import {
46
- type QueryResultSetModifierState,
47
- type SortColumnState,
48
- } from '../QueryResultSetModifierState.js';
49
44
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../../graph/QueryBuilderMetaModelConst.js';
50
45
  import { buildGenericLambdaFunctionInstanceValue } from '../../../QueryBuilderValueSpecificationHelper.js';
51
46
  import {
@@ -54,139 +49,9 @@ import {
54
49
  } from '../../../QueryBuilderValueSpecificationBuilderHelper.js';
55
50
  import { appendOLAPGroupByState } from '../window/QueryBuilderWindowValueSpecificationBuilder.js';
56
51
  import { appendPostFilter } from '../post-filter/QueryBuilderPostFilterValueSpecificationBuilder.js';
57
- import { buildTDSSortTypeExpression } from '../QueryBuilderTDSHelper.js';
58
52
  import { buildRelationProjection } from './QueryBuilderRelationProjectValueSpecBuidler.js';
59
53
  import { QueryBuilderAggregateOperator_Wavg } from '../aggregation/operators/QueryBuilderAggregateOperator_Wavg.js';
60
-
61
- const buildSortExpression = (
62
- sortColumnState: SortColumnState,
63
- ): SimpleFunctionExpression =>
64
- buildTDSSortTypeExpression(
65
- sortColumnState.sortType,
66
- sortColumnState.columnState.columnName,
67
- );
68
-
69
- const appendResultSetModifier = (
70
- resultModifierState: QueryResultSetModifierState,
71
- lambdaFunction: LambdaFunction,
72
- options?:
73
- | {
74
- overridingLimit?: number | undefined;
75
- withDataOverflowCheck?: boolean | undefined;
76
- }
77
- | undefined,
78
- ): LambdaFunction => {
79
- if (lambdaFunction.expressionSequence.length === 1) {
80
- const func = lambdaFunction.expressionSequence[0];
81
- if (func instanceof SimpleFunctionExpression) {
82
- if (
83
- matchFunctionName(func.functionName, [
84
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_PROJECT,
85
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_GROUP_BY,
86
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_FILTER,
87
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.OLAP_GROUPBY,
88
- ])
89
- ) {
90
- let currentExpression = func;
91
-
92
- // build distinct()
93
- if (resultModifierState.distinct) {
94
- const distinctFunction = new SimpleFunctionExpression(
95
- extractElementNameFromPath(
96
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_DISTINCT,
97
- ),
98
- );
99
- distinctFunction.parametersValues[0] = currentExpression;
100
- currentExpression = distinctFunction;
101
- }
102
-
103
- // build sort()
104
- if (resultModifierState.sortColumns.length) {
105
- const sortFunction = new SimpleFunctionExpression(
106
- extractElementNameFromPath(
107
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_SORT,
108
- ),
109
- );
110
- const multiplicity =
111
- resultModifierState.tdsState.queryBuilderState.graphManagerState.graph.getMultiplicity(
112
- resultModifierState.sortColumns.length,
113
- resultModifierState.sortColumns.length,
114
- );
115
- const collection = new CollectionInstanceValue(
116
- multiplicity,
117
- undefined,
118
- );
119
- collection.values =
120
- resultModifierState.sortColumns.map(buildSortExpression);
121
- sortFunction.parametersValues[0] = currentExpression;
122
- sortFunction.parametersValues[1] = collection;
123
- currentExpression = sortFunction;
124
- }
125
-
126
- // build take()
127
- if (resultModifierState.limit || options?.overridingLimit) {
128
- const limit = new PrimitiveInstanceValue(
129
- GenericTypeExplicitReference.create(
130
- new GenericType(PrimitiveType.INTEGER),
131
- ),
132
- );
133
- limit.values = [
134
- Math.min(
135
- resultModifierState.limit
136
- ? options?.withDataOverflowCheck
137
- ? resultModifierState.limit + 1
138
- : resultModifierState.limit
139
- : Number.MAX_SAFE_INTEGER,
140
- options?.overridingLimit
141
- ? options.withDataOverflowCheck
142
- ? options.overridingLimit + 1
143
- : options.overridingLimit
144
- : Number.MAX_SAFE_INTEGER,
145
- ),
146
- ];
147
- const takeFunction = new SimpleFunctionExpression(
148
- extractElementNameFromPath(
149
- QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_TAKE,
150
- ),
151
- );
152
- takeFunction.parametersValues[0] = currentExpression;
153
- takeFunction.parametersValues[1] = limit;
154
- currentExpression = takeFunction;
155
- }
156
- // build slice()
157
- if (resultModifierState.slice) {
158
- const sliceStart = resultModifierState.slice[0];
159
- const sliceEnd = resultModifierState.slice[1];
160
- const startVal = new PrimitiveInstanceValue(
161
- GenericTypeExplicitReference.create(
162
- new GenericType(PrimitiveType.INTEGER),
163
- ),
164
- );
165
- const endVal = new PrimitiveInstanceValue(
166
- GenericTypeExplicitReference.create(
167
- new GenericType(PrimitiveType.INTEGER),
168
- ),
169
- );
170
- startVal.values = [sliceStart];
171
- endVal.values = [sliceEnd];
172
- const sliceFunction = new SimpleFunctionExpression(
173
- extractElementNameFromPath(QUERY_BUILDER_SUPPORTED_FUNCTIONS.SLICE),
174
- );
175
- sliceFunction.parametersValues = [
176
- currentExpression,
177
- startVal,
178
- endVal,
179
- ];
180
- currentExpression = sliceFunction;
181
- }
182
-
183
- lambdaFunction.expressionSequence[0] = currentExpression;
184
- return lambdaFunction;
185
- }
186
- }
187
- }
188
- return lambdaFunction;
189
- };
54
+ import { appendResultSetModifier } from '../result-modifier/ResultModifierValueSpecificationBuilder.js';
190
55
 
191
56
  const buildProjectColFunc = (
192
57
  tdsState: QueryBuilderTDSState,
@@ -542,14 +407,19 @@ export const appendProjection = (
542
407
  appendPostFilter(tdsState.postFilterState, lambdaFunction);
543
408
 
544
409
  // build result set modifiers
545
- appendResultSetModifier(tdsState.resultSetModifierState, lambdaFunction, {
546
- overridingLimit:
547
- options?.isBuildingExecutionQuery && !options.isExportingResult
548
- ? queryBuilderState.resultState.previewLimit
549
- : undefined,
550
- withDataOverflowCheck:
551
- options?.isBuildingExecutionQuery && !options.isExportingResult
552
- ? options.withDataOverflowCheck
553
- : undefined,
554
- });
410
+ appendResultSetModifier(
411
+ tdsState.resultSetModifierState,
412
+ lambdaFunction,
413
+ tdsState.queryBuilderState.isFetchStructureTyped,
414
+ {
415
+ overridingLimit:
416
+ options?.isBuildingExecutionQuery && !options.isExportingResult
417
+ ? queryBuilderState.resultState.previewLimit
418
+ : undefined,
419
+ withDataOverflowCheck:
420
+ options?.isBuildingExecutionQuery && !options.isExportingResult
421
+ ? options.withDataOverflowCheck
422
+ : undefined,
423
+ },
424
+ );
555
425
  };