@finos/legend-query-builder 4.9.4 → 4.10.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.
Files changed (103) hide show
  1. package/lib/__lib__/QueryBuilderTesting.d.ts +3 -1
  2. package/lib/__lib__/QueryBuilderTesting.d.ts.map +1 -1
  3. package/lib/__lib__/QueryBuilderTesting.js +4 -1
  4. package/lib/__lib__/QueryBuilderTesting.js.map +1 -1
  5. package/lib/components/QueryBuilderResultPanel.d.ts.map +1 -1
  6. package/lib/components/QueryBuilderResultPanel.js +36 -33
  7. package/lib/components/QueryBuilderResultPanel.js.map +1 -1
  8. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts +1 -0
  9. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.d.ts.map +1 -1
  10. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +13 -1
  11. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  12. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts +2 -2
  13. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  14. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +42 -24
  15. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  16. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  17. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +1 -1
  18. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  19. package/lib/index.css +16 -0
  20. package/lib/package.json +1 -1
  21. package/lib/stores/QueryBuilderConstantsState.d.ts +5 -1
  22. package/lib/stores/QueryBuilderConstantsState.d.ts.map +1 -1
  23. package/lib/stores/QueryBuilderConstantsState.js +14 -1
  24. package/lib/stores/QueryBuilderConstantsState.js.map +1 -1
  25. package/lib/stores/QueryBuilderStateHashUtils.d.ts +2 -0
  26. package/lib/stores/QueryBuilderStateHashUtils.d.ts.map +1 -1
  27. package/lib/stores/QueryBuilderStateHashUtils.js +2 -0
  28. package/lib/stores/QueryBuilderStateHashUtils.js.map +1 -1
  29. package/lib/stores/QueryBuilderValueSpecificationBuilder.d.ts.map +1 -1
  30. package/lib/stores/QueryBuilderValueSpecificationBuilder.js +3 -23
  31. package/lib/stores/QueryBuilderValueSpecificationBuilder.js.map +1 -1
  32. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js +1 -1
  33. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.js.map +1 -1
  34. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +31 -5
  35. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts.map +1 -1
  36. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js +125 -30
  37. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  38. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.d.ts.map +1 -1
  39. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js +21 -8
  40. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.js.map +1 -1
  41. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts +3 -1
  42. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.d.ts.map +1 -1
  43. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js +20 -17
  44. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js.map +1 -1
  45. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.d.ts.map +1 -1
  46. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js +4 -6
  47. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.js.map +1 -1
  48. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.d.ts.map +1 -1
  49. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js +4 -6
  50. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.js.map +1 -1
  51. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts +1 -1
  52. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.d.ts.map +1 -1
  53. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js +10 -10
  54. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.js.map +1 -1
  55. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.d.ts.map +1 -1
  56. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js +10 -10
  57. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.js.map +1 -1
  58. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.d.ts.map +1 -1
  59. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.js +5 -5
  60. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.js.map +1 -1
  61. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.d.ts +1 -1
  62. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.d.ts.map +1 -1
  63. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js +32 -27
  64. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.js.map +1 -1
  65. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.d.ts.map +1 -1
  66. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js +10 -5
  67. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.js.map +1 -1
  68. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.d.ts.map +1 -1
  69. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js +10 -10
  70. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.js.map +1 -1
  71. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.d.ts.map +1 -1
  72. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.js +5 -5
  73. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.js.map +1 -1
  74. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.d.ts.map +1 -1
  75. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js +4 -6
  76. package/lib/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.js.map +1 -1
  77. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.d.ts.map +1 -1
  78. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js +17 -3
  79. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.js.map +1 -1
  80. package/package.json +4 -4
  81. package/src/__lib__/QueryBuilderTesting.ts +4 -1
  82. package/src/components/QueryBuilderResultPanel.tsx +64 -59
  83. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +25 -1
  84. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +102 -49
  85. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +6 -2
  86. package/src/stores/QueryBuilderConstantsState.ts +30 -0
  87. package/src/stores/QueryBuilderStateHashUtils.ts +2 -0
  88. package/src/stores/QueryBuilderValueSpecificationBuilder.ts +4 -50
  89. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterOperator.ts +1 -1
  90. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +180 -34
  91. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterStateBuilder.ts +38 -9
  92. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.ts +36 -20
  93. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Contain.ts +5 -6
  94. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_EndWith.ts +6 -6
  95. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_Equal.ts +12 -13
  96. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThan.ts +10 -9
  97. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_GreaterThanEqual.ts +5 -4
  98. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_In.ts +48 -43
  99. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_IsEmpty.ts +12 -4
  100. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThan.ts +10 -9
  101. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_LessThanEqual.ts +5 -4
  102. package/src/stores/fetch-structure/tds/post-filter/operators/QueryBuilderPostFilterOperator_StartWith.ts +6 -6
  103. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionColumnState.ts +26 -4
@@ -21,10 +21,12 @@ import {
21
21
  type ValueSpecification,
22
22
  type ExecutionResult,
23
23
  type VariableExpression,
24
+ type SimpleFunctionExpression,
24
25
  Enumeration,
25
26
  PRIMITIVE_TYPE,
26
27
  observe_ValueSpecification,
27
28
  PrimitiveType,
29
+ CollectionInstanceValue,
28
30
  } from '@finos/legend-graph';
29
31
  import {
30
32
  type GeneratorFn,
@@ -70,7 +72,12 @@ import { QUERY_BUILDER_GROUP_OPERATION } from '../../../QueryBuilderGroupOperati
70
72
  import type { QueryBuilderTDSState } from '../QueryBuilderTDSState.js';
71
73
  import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from '../../../QueryBuilderStateHashUtils.js';
72
74
  import type { QueryBuilderTDSColumnState } from '../QueryBuilderTDSColumnState.js';
73
- import { isValueExpressionReferencedInValue } from '../../../QueryBuilderValueSpecificationHelper.js';
75
+ import {
76
+ getCollectionValueSpecificationType,
77
+ getNonCollectionValueSpecificationType,
78
+ isValueExpressionReferencedInValue,
79
+ } from '../../../QueryBuilderValueSpecificationHelper.js';
80
+ import { buildtdsPropertyExpressionFromColState } from './operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js';
74
81
 
75
82
  export enum QUERY_BUILDER_POST_FILTER_DND_TYPE {
76
83
  GROUP_CONDITION = 'GROUP_CONDITION',
@@ -207,8 +214,8 @@ export class QueryBuilderPostFilterTreeGroupNodeData
207
214
  super(parentId);
208
215
  makeObservable(this, {
209
216
  groupOperation: observable,
210
- childrenIds: observable,
211
217
  setGroupOperation: action,
218
+ childrenIds: observable,
212
219
  addChildNode: action,
213
220
  removeChildNode: action,
214
221
  dragPreviewLabel: computed,
@@ -307,10 +314,130 @@ export class QueryBuilderPostFilterTreeBlankConditionNodeData
307
314
  }
308
315
  }
309
316
 
317
+ export abstract class PostFilterConditionValueState implements Hashable {
318
+ conditionState: PostFilterConditionState;
319
+
320
+ constructor(conditionState: PostFilterConditionState) {
321
+ this.conditionState = conditionState;
322
+ }
323
+
324
+ get type(): Type | undefined {
325
+ return undefined;
326
+ }
327
+
328
+ get isCollection(): boolean {
329
+ return false;
330
+ }
331
+
332
+ get hashCode(): string {
333
+ return hashArray([
334
+ QUERY_BUILDER_STATE_HASH_STRUCTURE.POST_FILTER_CONDITION_RIGHT_VALUE,
335
+ ]);
336
+ }
337
+
338
+ abstract appendConditionValue(expressionVal: SimpleFunctionExpression): void;
339
+ }
340
+
341
+ export class PostFilterValueSpecConditionValueState extends PostFilterConditionValueState {
342
+ value?: ValueSpecification | undefined;
343
+
344
+ constructor(
345
+ conditionState: PostFilterConditionState,
346
+ value?: ValueSpecification | undefined,
347
+ ) {
348
+ super(conditionState);
349
+ makeObservable(this, {
350
+ value: observable,
351
+ setValue: action,
352
+ });
353
+ this.value = this.setValue(value);
354
+ }
355
+
356
+ override get type(): Type | undefined {
357
+ if (this.value instanceof CollectionInstanceValue) {
358
+ return getCollectionValueSpecificationType(
359
+ this.conditionState.postFilterState.tdsState.queryBuilderState
360
+ .graphManagerState.graph,
361
+ this.value.values,
362
+ );
363
+ }
364
+ return this.value
365
+ ? getNonCollectionValueSpecificationType(this.value)
366
+ : undefined;
367
+ }
368
+
369
+ setValue(
370
+ val: ValueSpecification | undefined,
371
+ ): ValueSpecification | undefined {
372
+ this.value = val
373
+ ? observe_ValueSpecification(
374
+ val,
375
+ this.conditionState.postFilterState.tdsState.queryBuilderState
376
+ .observerContext,
377
+ )
378
+ : undefined;
379
+ return this.value;
380
+ }
381
+ override appendConditionValue(expressionVal: SimpleFunctionExpression): void {
382
+ if (this.value) {
383
+ expressionVal.parametersValues.push(this.value);
384
+ }
385
+ }
386
+
387
+ override get isCollection(): boolean {
388
+ return this.value instanceof CollectionInstanceValue;
389
+ }
390
+
391
+ override get hashCode(): string {
392
+ return hashArray([
393
+ QUERY_BUILDER_STATE_HASH_STRUCTURE.POST_FILTER_CONDITION_RIGHT_VALUE_SPEC,
394
+ this.value,
395
+ ]);
396
+ }
397
+ }
398
+
399
+ export class PostFilterTDSColumnValueConditionValueState extends PostFilterConditionValueState {
400
+ tdsColumn: QueryBuilderTDSColumnState;
401
+
402
+ constructor(
403
+ conditionState: PostFilterConditionState,
404
+ tdsColumn: QueryBuilderTDSColumnState,
405
+ ) {
406
+ super(conditionState);
407
+ makeObservable(this, {
408
+ tdsColumn: observable,
409
+ changeCol: action,
410
+ });
411
+ this.tdsColumn = tdsColumn;
412
+ }
413
+
414
+ override get type(): Type | undefined {
415
+ return this.tdsColumn.getColumnType();
416
+ }
417
+
418
+ override get isCollection(): boolean {
419
+ return false;
420
+ }
421
+ override appendConditionValue(expressionVal: SimpleFunctionExpression): void {
422
+ const tdsPropertyExpression = buildtdsPropertyExpressionFromColState(
423
+ this.conditionState,
424
+ this.tdsColumn,
425
+ this.conditionState.postFilterState.tdsState.queryBuilderState
426
+ .graphManagerState.graph,
427
+ undefined,
428
+ );
429
+ expressionVal.parametersValues.push(tdsPropertyExpression);
430
+ }
431
+
432
+ changeCol(col: QueryBuilderTDSColumnState): void {
433
+ this.tdsColumn = col;
434
+ }
435
+ }
436
+
310
437
  export class PostFilterConditionState implements Hashable {
311
438
  readonly postFilterState: QueryBuilderPostFilterState;
312
- columnState: QueryBuilderTDSColumnState;
313
- value?: ValueSpecification | undefined;
439
+ leftConditionValue: QueryBuilderTDSColumnState;
440
+ rightConditionValue: PostFilterConditionValueState;
314
441
  operator: QueryBuilderPostFilterOperator;
315
442
  typeaheadSearchResults: string[] | undefined;
316
443
  typeaheadSearchState = ActionState.create();
@@ -318,18 +445,18 @@ export class PostFilterConditionState implements Hashable {
318
445
  constructor(
319
446
  postFilterState: QueryBuilderPostFilterState,
320
447
  colState: QueryBuilderTDSColumnState,
321
- value: ValueSpecification | undefined,
322
448
  operator: QueryBuilderPostFilterOperator | undefined,
323
449
  ) {
324
450
  makeObservable(this, {
325
451
  postFilterState: observable,
326
- value: observable,
452
+ rightConditionValue: observable,
327
453
  operator: observable,
328
- columnState: observable,
454
+ leftConditionValue: observable,
329
455
  typeaheadSearchResults: observable,
330
456
  changeOperator: action,
331
457
  setColumnState: action,
332
- setValue: action,
458
+ setRightConditionVal: action,
459
+ buildFromValueSpec: action,
333
460
  setOperator: action,
334
461
  changeColumn: flow,
335
462
  handleTypeaheadSearch: flow,
@@ -338,21 +465,24 @@ export class PostFilterConditionState implements Hashable {
338
465
  });
339
466
 
340
467
  this.postFilterState = postFilterState;
341
- this.columnState = colState;
342
- this.setValue(value);
468
+ this.leftConditionValue = colState;
469
+ this.rightConditionValue = new PostFilterValueSpecConditionValueState(
470
+ this,
471
+ undefined,
472
+ );
343
473
  if (operator) {
344
474
  this.operator = operator;
345
475
  } else {
346
476
  assertTrue(
347
477
  this.operators.length !== 0,
348
- `Can't find an operator for column '${this.columnState.columnName}`,
478
+ `Can't find an operator for column '${this.leftConditionValue.columnName}`,
349
479
  );
350
480
  this.operator = guaranteeNonNullable(this.operators[0]);
351
481
  }
352
482
  }
353
483
 
354
484
  get columnName(): string {
355
- return this.columnState.columnName;
485
+ return this.leftConditionValue.columnName;
356
486
  }
357
487
 
358
488
  get operators(): QueryBuilderPostFilterOperator[] {
@@ -361,23 +491,43 @@ export class PostFilterConditionState implements Hashable {
361
491
  );
362
492
  }
363
493
 
494
+ setRightConditionVal(val: PostFilterConditionValueState): void {
495
+ this.rightConditionValue = val;
496
+ }
497
+
498
+ buildFromValueSpec(val: ValueSpecification | undefined): void {
499
+ if (
500
+ this.rightConditionValue instanceof PostFilterValueSpecConditionValueState
501
+ ) {
502
+ this.rightConditionValue.setValue(val);
503
+ return;
504
+ } else {
505
+ this.setRightConditionVal(
506
+ new PostFilterValueSpecConditionValueState(this, val),
507
+ );
508
+ }
509
+ }
364
510
  *handleTypeaheadSearch(): GeneratorFn<void> {
365
511
  try {
366
512
  this.typeaheadSearchState.inProgress();
367
513
  this.typeaheadSearchResults = undefined;
368
514
  const _columnState =
369
- this.columnState instanceof QueryBuilderProjectionColumnState ||
370
- this.columnState instanceof QueryBuilderAggregateColumnState
371
- ? this.columnState
515
+ this.leftConditionValue instanceof QueryBuilderProjectionColumnState ||
516
+ this.leftConditionValue instanceof QueryBuilderAggregateColumnState
517
+ ? this.leftConditionValue
372
518
  : undefined;
373
519
  const columnState = guaranteeNonNullable(_columnState);
374
- if (performTypeahead(this.value)) {
520
+ const rightConditionValue = guaranteeType(
521
+ this.rightConditionValue,
522
+ PostFilterValueSpecConditionValueState,
523
+ );
524
+ if (performTypeahead(rightConditionValue.value)) {
375
525
  const result =
376
526
  (yield this.postFilterState.tdsState.queryBuilderState.graphManagerState.graphManager.runQuery(
377
527
  buildProjectionColumnTypeaheadQuery(
378
528
  this.postFilterState.tdsState.queryBuilderState,
379
529
  columnState,
380
- this.value,
530
+ rightConditionValue.value,
381
531
  ),
382
532
  guaranteeNonNullable(
383
533
  this.postFilterState.tdsState.queryBuilderState
@@ -404,23 +554,15 @@ export class PostFilterConditionState implements Hashable {
404
554
  changeOperator(val: QueryBuilderPostFilterOperator): void {
405
555
  this.setOperator(val);
406
556
  if (!this.operator.isCompatibleWithConditionValue(this)) {
407
- this.setValue(this.operator.getDefaultFilterConditionValue(this));
557
+ this.buildFromValueSpec(
558
+ this.operator.getDefaultFilterConditionValue(this),
559
+ );
408
560
  }
409
561
  }
410
-
411
- setValue(val: ValueSpecification | undefined): void {
412
- this.value = val
413
- ? observe_ValueSpecification(
414
- val,
415
- this.postFilterState.tdsState.queryBuilderState.observerContext,
416
- )
417
- : undefined;
418
- }
419
-
420
562
  setColumnState(
421
563
  val: QueryBuilderProjectionColumnState | QueryBuilderAggregateColumnState,
422
564
  ): void {
423
- this.columnState = val;
565
+ this.leftConditionValue = val;
424
566
  }
425
567
 
426
568
  setOperator(val: QueryBuilderPostFilterOperator): void {
@@ -450,7 +592,9 @@ export class PostFilterConditionState implements Hashable {
450
592
 
451
593
  // value
452
594
  if (!this.operator.isCompatibleWithConditionValue(this)) {
453
- this.setValue(this.operator.getDefaultFilterConditionValue(this));
595
+ this.buildFromValueSpec(
596
+ this.operator.getDefaultFilterConditionValue(this),
597
+ );
454
598
  }
455
599
  } catch (error) {
456
600
  assertErrorThrown(error);
@@ -463,8 +607,8 @@ export class PostFilterConditionState implements Hashable {
463
607
  get hashCode(): string {
464
608
  return hashArray([
465
609
  QUERY_BUILDER_STATE_HASH_STRUCTURE.POST_FILTER_CONDITION_STATE,
466
- this.columnState,
467
- this.value ?? '',
610
+ this.leftConditionValue,
611
+ this.rightConditionValue,
468
612
  this.operator,
469
613
  ]);
470
614
  }
@@ -555,7 +699,7 @@ export class QueryBuilderPostFilterState
555
699
  return uniq(
556
700
  Array.from(this.nodes.values())
557
701
  .filter(filterByType(QueryBuilderPostFilterTreeConditionNodeData))
558
- .map((n) => n.condition.columnState),
702
+ .map((n) => n.condition.leftConditionValue),
559
703
  );
560
704
  }
561
705
 
@@ -883,7 +1027,9 @@ export class QueryBuilderPostFilterState
883
1027
  return Boolean(
884
1028
  Array.from(this.nodes.values())
885
1029
  .filter(filterByType(QueryBuilderPostFilterTreeConditionNodeData))
886
- .map((node) => node.condition.value)
1030
+ .map((node) => node.condition.rightConditionValue)
1031
+ .filter(filterByType(PostFilterValueSpecConditionValueState))
1032
+ .map((condition) => condition.value)
887
1033
  .filter(isNonNullable)
888
1034
  .find((value) => isValueExpressionReferencedInValue(variable, value)),
889
1035
  );
@@ -23,6 +23,7 @@ import {
23
23
  VariableExpression,
24
24
  FunctionExpression,
25
25
  type SimpleFunctionExpression,
26
+ type ValueSpecification,
26
27
  } from '@finos/legend-graph';
27
28
  import {
28
29
  assertTrue,
@@ -30,6 +31,7 @@ import {
30
31
  guaranteeIsString,
31
32
  guaranteeNonNullable,
32
33
  guaranteeType,
34
+ returnUndefOnError,
33
35
  UnsupportedOperationError,
34
36
  } from '@finos/legend-shared';
35
37
  import { QueryBuilderDerivationProjectionColumnState } from '../projection/QueryBuilderProjectionColumnState.js';
@@ -44,6 +46,8 @@ import {
44
46
  QueryBuilderPostFilterTreeGroupNodeData,
45
47
  TDS_COLUMN_GETTER,
46
48
  getTypeFromDerivedProperty,
49
+ PostFilterValueSpecConditionValueState,
50
+ PostFilterTDSColumnValueConditionValueState,
47
51
  } from './QueryBuilderPostFilterState.js';
48
52
  import { QUERY_BUILDER_SUPPORTED_FUNCTIONS } from '../../../../graph/QueryBuilderMetaModelConst.js';
49
53
  import type { QueryBuilderState } from '../../../QueryBuilderState.js';
@@ -102,6 +106,36 @@ const findProjectionColumnState = (
102
106
  return columnState;
103
107
  };
104
108
 
109
+ const buildPostFilterConditionValueState = (
110
+ rightVal: ValueSpecification | undefined,
111
+ conditionState: PostFilterConditionState,
112
+ ): void => {
113
+ if (rightVal instanceof AbstractPropertyExpression) {
114
+ const rightCol = returnUndefOnError(() =>
115
+ findProjectionColumnState(rightVal, conditionState.postFilterState),
116
+ );
117
+ if (rightCol) {
118
+ conditionState.setRightConditionVal(
119
+ new PostFilterTDSColumnValueConditionValueState(
120
+ conditionState,
121
+ rightCol,
122
+ ),
123
+ );
124
+ return;
125
+ }
126
+ }
127
+ const val = rightVal
128
+ ? simplifyValueExpression(
129
+ rightVal,
130
+ conditionState.postFilterState.tdsState.queryBuilderState
131
+ .observerContext,
132
+ )
133
+ : undefined;
134
+ conditionState.setRightConditionVal(
135
+ new PostFilterValueSpecConditionValueState(conditionState, val),
136
+ );
137
+ };
138
+
105
139
  export const buildPostFilterConditionState = (
106
140
  postFilterState: QueryBuilderPostFilterState,
107
141
  expression: FunctionExpression,
@@ -119,7 +153,6 @@ export const buildPostFilterConditionState = (
119
153
  postConditionState = new PostFilterConditionState(
120
154
  postFilterState,
121
155
  columnState,
122
- undefined,
123
156
  operator,
124
157
  );
125
158
  return postConditionState;
@@ -150,21 +183,17 @@ export const buildPostFilterConditionState = (
150
183
  );
151
184
 
152
185
  // get operation value specification
153
- const value = expression.parametersValues[1];
186
+ const rightSide = expression.parametersValues[1];
154
187
 
155
188
  // create state
156
189
  postConditionState = new PostFilterConditionState(
157
190
  postFilterState,
158
191
  columnState,
159
- value
160
- ? simplifyValueExpression(
161
- value,
162
- postFilterState.tdsState.queryBuilderState.observerContext,
163
- )
164
- : undefined,
165
192
  operator,
166
193
  );
167
194
 
195
+ buildPostFilterConditionValueState(rightSide, postConditionState);
196
+
168
197
  //post checks
169
198
  assertTrue(
170
199
  operator.isCompatibleWithPostFilterColumn(postConditionState),
@@ -174,7 +203,7 @@ export const buildPostFilterConditionState = (
174
203
  );
175
204
  assertTrue(
176
205
  operator.isCompatibleWithConditionValue(postConditionState),
177
- `Operator '${operator.getLabel()}' not compatible with value specification ${value?.toString()}`,
206
+ `Operator '${operator.getLabel()}' not compatible with value specification ${rightSide?.toString()}`,
178
207
  );
179
208
  }
180
209
  return postConditionState;
@@ -27,6 +27,7 @@ import {
27
27
  PropertyExplicitReference,
28
28
  Multiplicity,
29
29
  PrimitiveType,
30
+ type PureModel,
30
31
  } from '@finos/legend-graph';
31
32
  import { guaranteeNonNullable } from '@finos/legend-shared';
32
33
  import type { QueryBuilderPostFilterOperator } from '../QueryBuilderPostFilterOperator.js';
@@ -36,27 +37,19 @@ import {
36
37
  getTDSColumnDerivedProperyFromType,
37
38
  } from '../QueryBuilderPostFilterState.js';
38
39
  import { QUERY_BUILDER_PURE_PATH } from '../../../../../graph/QueryBuilderMetaModelConst.js';
40
+ import type { QueryBuilderTDSColumnState } from '../../QueryBuilderTDSColumnState.js';
39
41
 
40
- export const buildPostFilterConditionExpression = (
42
+ export const buildtdsPropertyExpressionFromColState = (
41
43
  filterConditionState: PostFilterConditionState,
42
- operator: QueryBuilderPostFilterOperator,
43
- /**
44
- * If provided, this will be used to construct the simple
45
- * function expression for the function with the specified
46
- * name. If not provided, we will fall back to use the TDS column getter function expression.
47
- * This is the case because with TDS, we are provided some filter-like operators, e.g. IS_NULL, IS_NOT_NULL, etc.
48
- */
49
- operatorFunctionFullPath: string | undefined,
50
- ): FunctionExpression => {
51
- // primitives
52
- const graph =
53
- filterConditionState.postFilterState.tdsState.queryBuilderState
54
- .graphManagerState.graph;
55
- // property expression
56
- const colState = filterConditionState.columnState;
44
+ colState: QueryBuilderTDSColumnState,
45
+ graph: PureModel,
46
+ operator: QueryBuilderPostFilterOperator | undefined,
47
+ ): AbstractPropertyExpression => {
57
48
  const tdsPropertyExpression = new AbstractPropertyExpression('');
58
49
  let tdsDerivedPropertyName: TDS_COLUMN_GETTER;
59
- const correspondingTDSDerivedProperty = operator.getTDSColumnGetter();
50
+ const correspondingTDSDerivedProperty = operator
51
+ ? operator.getTDSColumnGetter()
52
+ : undefined;
60
53
  if (correspondingTDSDerivedProperty) {
61
54
  tdsDerivedPropertyName = correspondingTDSDerivedProperty;
62
55
  } else {
@@ -79,15 +72,38 @@ export const buildPostFilterConditionExpression = (
79
72
  );
80
73
  colInstanceValue.values = [colState.columnName];
81
74
  tdsPropertyExpression.parametersValues = [variableName, colInstanceValue];
75
+ return tdsPropertyExpression;
76
+ };
77
+
78
+ export const buildPostFilterConditionExpression = (
79
+ filterConditionState: PostFilterConditionState,
80
+ operator: QueryBuilderPostFilterOperator,
81
+ /**
82
+ * If provided, this will be used to construct the simple
83
+ * function expression for the function with the specified
84
+ * name. If not provided, we will fall back to use the TDS column getter function expression.
85
+ * This is the case because with TDS, we are provided some filter-like operators, e.g. IS_NULL, IS_NOT_NULL, etc.
86
+ */
87
+ operatorFunctionFullPath: string | undefined,
88
+ ): FunctionExpression => {
89
+ // primitives
90
+ const graph =
91
+ filterConditionState.postFilterState.tdsState.queryBuilderState
92
+ .graphManagerState.graph;
93
+ // property expression
94
+ const tdsPropertyExpression = buildtdsPropertyExpressionFromColState(
95
+ filterConditionState,
96
+ filterConditionState.leftConditionValue,
97
+ graph,
98
+ operator,
99
+ );
82
100
 
83
101
  if (operatorFunctionFullPath) {
84
102
  const expression = new SimpleFunctionExpression(
85
103
  extractElementNameFromPath(operatorFunctionFullPath),
86
104
  );
87
105
  expression.parametersValues.push(tdsPropertyExpression);
88
- if (filterConditionState.value) {
89
- expression.parametersValues.push(filterConditionState.value);
90
- }
106
+ filterConditionState.rightConditionValue.appendConditionValue(expression);
91
107
  return expression;
92
108
  } else {
93
109
  return tdsPropertyExpression;
@@ -37,7 +37,6 @@ import type {
37
37
  import {
38
38
  buildNotExpression,
39
39
  generateDefaultValueForPrimitiveType,
40
- getNonCollectionValueSpecificationType,
41
40
  unwrapNotExpression,
42
41
  } from '../../../../QueryBuilderValueSpecificationHelper.js';
43
42
  import { buildPostFilterConditionExpression } from './QueryBuilderPostFilterOperatorValueSpecificationBuilder.js';
@@ -60,17 +59,17 @@ export class QueryBuilderPostFilterOperator_Contain
60
59
  isCompatibleWithConditionValue(
61
60
  postFilterConditionState: PostFilterConditionState,
62
61
  ): boolean {
63
- const type = postFilterConditionState.value
64
- ? getNonCollectionValueSpecificationType(postFilterConditionState.value)
65
- : undefined;
66
- return PrimitiveType.STRING === type;
62
+ return (
63
+ !postFilterConditionState.rightConditionValue.isCollection &&
64
+ PrimitiveType.STRING === postFilterConditionState.rightConditionValue.type
65
+ );
67
66
  }
68
67
 
69
68
  getDefaultFilterConditionValue(
70
69
  postFilterConditionState: PostFilterConditionState,
71
70
  ): ValueSpecification {
72
71
  const propertyType = guaranteeNonNullable(
73
- postFilterConditionState.columnState.getColumnType(),
72
+ postFilterConditionState.leftConditionValue.getColumnType(),
74
73
  );
75
74
  switch (propertyType.path) {
76
75
  case PRIMITIVE_TYPE.STRING: {
@@ -35,7 +35,6 @@ import type {
35
35
  import {
36
36
  buildNotExpression,
37
37
  generateDefaultValueForPrimitiveType,
38
- getNonCollectionValueSpecificationType,
39
38
  unwrapNotExpression,
40
39
  } from '../../../../QueryBuilderValueSpecificationHelper.js';
41
40
  import { buildPostFilterConditionExpression } from './QueryBuilderPostFilterOperatorValueSpecificationBuilder.js';
@@ -58,16 +57,17 @@ export class QueryBuilderPostFilterOperator_EndWith
58
57
  isCompatibleWithConditionValue(
59
58
  postFilterConditionState: PostFilterConditionState,
60
59
  ): boolean {
61
- const type = postFilterConditionState.value
62
- ? getNonCollectionValueSpecificationType(postFilterConditionState.value)
63
- : undefined;
64
- return PrimitiveType.STRING === type;
60
+ return (
61
+ !postFilterConditionState.rightConditionValue.isCollection &&
62
+ PrimitiveType.STRING === postFilterConditionState.rightConditionValue.type
63
+ );
65
64
  }
66
65
 
67
66
  getDefaultFilterConditionValue(
68
67
  postFilterConditionState: PostFilterConditionState,
69
68
  ): ValueSpecification {
70
- const propertyType = postFilterConditionState.columnState.getColumnType();
69
+ const propertyType =
70
+ postFilterConditionState.leftConditionValue.getColumnType();
71
71
  switch (propertyType?.path) {
72
72
  case PRIMITIVE_TYPE.STRING: {
73
73
  return buildPrimitiveInstanceValue(
@@ -27,6 +27,7 @@ import {
27
27
  GenericType,
28
28
  GenericTypeExplicitReference,
29
29
  PRIMITIVE_TYPE,
30
+ PrimitiveType,
30
31
  } from '@finos/legend-graph';
31
32
  import {
32
33
  guaranteeNonNullable,
@@ -36,14 +37,13 @@ import {
36
37
  } from '@finos/legend-shared';
37
38
  import { QueryBuilderPostFilterOperator } from '../QueryBuilderPostFilterOperator.js';
38
39
  import { buildPostFilterConditionState } from '../QueryBuilderPostFilterStateBuilder.js';
39
- import type {
40
- PostFilterConditionState,
41
- QueryBuilderPostFilterState,
40
+ import {
41
+ type PostFilterConditionState,
42
+ type QueryBuilderPostFilterState,
42
43
  } from '../QueryBuilderPostFilterState.js';
43
44
  import {
44
45
  buildNotExpression,
45
46
  generateDefaultValueForPrimitiveType,
46
- getNonCollectionValueSpecificationType,
47
47
  isTypeCompatibleForAssignment,
48
48
  unwrapNotExpression,
49
49
  } from '../../../../QueryBuilderValueSpecificationHelper.js';
@@ -84,12 +84,11 @@ export class QueryBuilderPostFilterOperator_Equal
84
84
  isCompatibleWithConditionValue(
85
85
  postFilterConditionState: PostFilterConditionState,
86
86
  ): boolean {
87
- const valueSpecification = postFilterConditionState.value;
88
- if (valueSpecification) {
87
+ if (!postFilterConditionState.rightConditionValue.isCollection) {
89
88
  return isTypeCompatibleForAssignment(
90
- getNonCollectionValueSpecificationType(valueSpecification),
89
+ postFilterConditionState.rightConditionValue.type,
91
90
  guaranteeNonNullable(
92
- postFilterConditionState.columnState.getColumnType(),
91
+ postFilterConditionState.leftConditionValue.getColumnType(),
93
92
  ),
94
93
  );
95
94
  }
@@ -100,7 +99,7 @@ export class QueryBuilderPostFilterOperator_Equal
100
99
  postFilterConditionState: PostFilterConditionState,
101
100
  ): ValueSpecification {
102
101
  const propertyType = guaranteeNonNullable(
103
- postFilterConditionState.columnState.getColumnType(),
102
+ postFilterConditionState.leftConditionValue.getColumnType(),
104
103
  );
105
104
  switch (propertyType.path) {
106
105
  case PRIMITIVE_TYPE.STRING:
@@ -170,10 +169,10 @@ export class QueryBuilderPostFilterOperator_Equal
170
169
  return buildPostFilterConditionExpression(
171
170
  postFilterConditionState,
172
171
  this,
173
- postFilterConditionState.columnState.getColumnType()?.path ===
174
- PRIMITIVE_TYPE.DATETIME &&
175
- postFilterConditionState.value?.genericType?.value.rawType.path !==
176
- PRIMITIVE_TYPE.DATETIME
172
+ postFilterConditionState.leftConditionValue.getColumnType() ===
173
+ PrimitiveType.DATETIME &&
174
+ postFilterConditionState.rightConditionValue.type !==
175
+ PrimitiveType.DATETIME
177
176
  ? QUERY_BUILDER_SUPPORTED_FUNCTIONS.IS_ON_DAY
178
177
  : QUERY_BUILDER_SUPPORTED_FUNCTIONS.EQUAL,
179
178
  );