@finos/legend-query-builder 4.15.41 → 4.15.43

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.
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
  };