@finos/legend-query-builder 4.14.71 → 4.14.72

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 (53) hide show
  1. package/lib/components/QueryLoader.d.ts.map +1 -1
  2. package/lib/components/QueryLoader.js +12 -34
  3. package/lib/components/QueryLoader.js.map +1 -1
  4. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.d.ts.map +1 -1
  5. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js +10 -3
  6. package/lib/components/fetch-structure/QueryBuilderPostFilterPanel.js.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.d.ts.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js +2 -2
  9. package/lib/components/fetch-structure/QueryBuilderResultModifierPanel.js.map +1 -1
  10. package/lib/components/fetch-structure/QueryBuilderTDSPanel.d.ts.map +1 -1
  11. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js +6 -2
  12. package/lib/components/fetch-structure/QueryBuilderTDSPanel.js.map +1 -1
  13. package/lib/components/filter/QueryBuilderFilterPanel.d.ts.map +1 -1
  14. package/lib/components/filter/QueryBuilderFilterPanel.js +5 -1
  15. package/lib/components/filter/QueryBuilderFilterPanel.js.map +1 -1
  16. package/lib/components/result/tds/QueryBuilderTDSGridResult.d.ts.map +1 -1
  17. package/lib/components/result/tds/QueryBuilderTDSGridResult.js +5 -2
  18. package/lib/components/result/tds/QueryBuilderTDSGridResult.js.map +1 -1
  19. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts +3 -0
  20. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.d.ts.map +1 -1
  21. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js +92 -2
  22. package/lib/components/result/tds/QueryBuilderTDSSimpleGridResult.js.map +1 -1
  23. package/lib/index.css +2 -2
  24. package/lib/index.css.map +1 -1
  25. package/lib/package.json +1 -1
  26. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts +1 -1
  27. package/lib/stores/QueryBuilderValueSpecificationHelper.d.ts.map +1 -1
  28. package/lib/stores/QueryBuilderValueSpecificationHelper.js +1 -0
  29. package/lib/stores/QueryBuilderValueSpecificationHelper.js.map +1 -1
  30. package/lib/stores/QueryLoaderState.d.ts +8 -6
  31. package/lib/stores/QueryLoaderState.d.ts.map +1 -1
  32. package/lib/stores/QueryLoaderState.js +30 -7
  33. package/lib/stores/QueryLoaderState.js.map +1 -1
  34. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.d.ts +4 -1
  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 +22 -11
  37. package/lib/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.js.map +1 -1
  38. package/lib/stores/filter/QueryBuilderFilterState.d.ts +1 -1
  39. package/lib/stores/filter/QueryBuilderFilterState.d.ts.map +1 -1
  40. package/lib/stores/filter/QueryBuilderFilterState.js +8 -4
  41. package/lib/stores/filter/QueryBuilderFilterState.js.map +1 -1
  42. package/package.json +3 -3
  43. package/src/components/QueryLoader.tsx +37 -54
  44. package/src/components/fetch-structure/QueryBuilderPostFilterPanel.tsx +24 -2
  45. package/src/components/fetch-structure/QueryBuilderResultModifierPanel.tsx +6 -2
  46. package/src/components/fetch-structure/QueryBuilderTDSPanel.tsx +10 -2
  47. package/src/components/filter/QueryBuilderFilterPanel.tsx +10 -1
  48. package/src/components/result/tds/QueryBuilderTDSGridResult.tsx +8 -2
  49. package/src/components/result/tds/QueryBuilderTDSSimpleGridResult.tsx +106 -1
  50. package/src/stores/QueryBuilderValueSpecificationHelper.ts +2 -1
  51. package/src/stores/QueryLoaderState.ts +43 -17
  52. package/src/stores/fetch-structure/tds/post-filter/QueryBuilderPostFilterState.ts +39 -10
  53. package/src/stores/filter/QueryBuilderFilterState.ts +11 -3
@@ -61,6 +61,10 @@ import {
61
61
  Dialog,
62
62
  CustomSelectorInput,
63
63
  } from '@finos/legend-art';
64
+ import {
65
+ getTDSColumnCustomizations,
66
+ MAXIMUM_FRACTION_DIGITS,
67
+ } from './QueryBuilderTDSSimpleGridResult.js';
64
68
 
65
69
  export const enum QueryBuilderDataGridCustomAggregationFunction {
66
70
  wavg = 'wavg',
@@ -109,7 +113,7 @@ const QueryResultCellRenderer = observer(
109
113
  const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
110
114
  if (isNumber(cellValue)) {
111
115
  return Intl.NumberFormat(DEFAULT_LOCALE, {
112
- maximumFractionDigits: 4,
116
+ maximumFractionDigits: MAXIMUM_FRACTION_DIGITS,
113
117
  }).format(Number(cellValue));
114
118
  } else if (isBoolean(cellValue)) {
115
119
  return String(cellValue);
@@ -173,6 +177,7 @@ const getLocalColDefs = (
173
177
  tdsExecutionResult: executionResult,
174
178
  },
175
179
  ...getAggregationTDSColumnCustomizations(executionResult, colName),
180
+ ...getTDSColumnCustomizations(executionResult, colName),
176
181
  } as DataGridColumnDefinition;
177
182
  const persistedColumn = resultState.gridConfig?.columns.find(
178
183
  (c) => c.colId === colName,
@@ -207,8 +212,8 @@ const getFilterTDSColumnCustomizations = (
207
212
  };
208
213
  case PRIMITIVE_TYPE.DECIMAL:
209
214
  case PRIMITIVE_TYPE.INTEGER:
210
- case PRIMITIVE_TYPE.FLOAT:
211
215
  case PRIMITIVE_TYPE.NUMBER:
216
+ case PRIMITIVE_TYPE.FLOAT:
212
217
  return {
213
218
  filter: 'agNumberColumnFilter',
214
219
  };
@@ -241,6 +246,7 @@ const getColDefs = (
241
246
  tdsExecutionResult: executionResult,
242
247
  },
243
248
  ...getFilterTDSColumnCustomizations(executionResult, colName),
249
+ ...getTDSColumnCustomizations(executionResult, colName),
244
250
  }) as DataGridColumnDefinition,
245
251
  );
246
252
 
@@ -19,6 +19,7 @@ import { observer } from 'mobx-react-lite';
19
19
  import type { QueryBuilderState } from '../../../stores/QueryBuilderState.js';
20
20
  import {
21
21
  getTDSRowRankByColumnInAsc,
22
+ PRIMITIVE_TYPE,
22
23
  TDSExecutionResult,
23
24
  } from '@finos/legend-graph';
24
25
  import {
@@ -47,6 +48,109 @@ import type {
47
48
  } from '../../../stores/QueryBuilderResultState.js';
48
49
  import { QUERY_BUILDER_TEST_ID } from '../../../__lib__/QueryBuilderTesting.js';
49
50
 
51
+ export const MAXIMUM_FRACTION_DIGITS = 4;
52
+
53
+ export const getFloatGridColumnCustomHeader = (): string =>
54
+ `<div class="ag-cell-label-container" role="presentation">
55
+ <span
56
+ data-ref="eMenu"
57
+ class="ag-header-icon ag-header-cell-menu-button"
58
+ ></span>
59
+ <span
60
+ data-ref="eFilterButton"
61
+ class="ag-header-icon ag-header-cell-filter-button"
62
+ ></span>
63
+ <div data-ref="eLabel" class="ag-header-cell-label" role="presentation">
64
+ <span
65
+ data-ref="eSortOrder"
66
+ class="ag-header-icon ag-sort-order ag-hidden"
67
+ ></span>
68
+ <span
69
+ data-ref="eSortAsc"
70
+ class="ag-header-icon ag-sort-ascending-icon ag-hidden"
71
+ ></span>
72
+ <span
73
+ data-ref="eSortDesc"
74
+ class="ag-header-icon ag-sort-descending-icon ag-hidden"
75
+ ></span>
76
+ <span
77
+ data-ref="eSortMixed"
78
+ class="ag-header-icon ag-sort-mixed-icon ag-hidden"
79
+ ></span>
80
+ <span
81
+ data-ref="eSortNone"
82
+ class="ag-header-icon ag-sort-none-icon ag-hidden"
83
+ ></span>
84
+ <span
85
+ data-ref="eText"
86
+ class="ag-header-cell-text"
87
+ role="columnheader"
88
+ ></span>
89
+ <span data-ref="eFilter" class="ag-header-icon ag-filter-icon"></span>
90
+ </div>
91
+ <div
92
+ data-testid="query__builder__result__grid__custom-header"
93
+ class="query-builder__result__values__table__custom-header"
94
+ >
95
+ <div
96
+ class="query-builder__result__values__table__custom-header__icon"
97
+ title="some values have been rounded using en-us format in this preview grid (defaults to max 4 decimal places)"
98
+ >
99
+ <svg
100
+ stroke="currentColor"
101
+ fill="currentColor"
102
+ stroke-width="0"
103
+ viewBox="0 0 576 512"
104
+ height="1em"
105
+ width="1em"
106
+ xmlns="http://www.w3.org/2000/svg"
107
+ >
108
+ <path d="M569.517 440.013C587.975 472.007 564.806 512 527.94 512H48.054c-36.937 0-59.999-40.055-41.577-71.987L246.423 23.985c18.467-32.009 64.72-31.951 83.154 0l239.94 416.028zM288 354c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"></path>
109
+ </svg>
110
+ </div>
111
+ </div>
112
+ </div>`;
113
+
114
+ export const getTDSColumnCustomizations = (
115
+ result: TDSExecutionResult,
116
+ columnName: string,
117
+ ): object => {
118
+ const index = result.builder.columns.findIndex(
119
+ (col) => col.name === columnName,
120
+ );
121
+ if (index >= 0) {
122
+ const columnType = result.builder.columns[index]?.type;
123
+ const colValues = result.result.rows.map((r) => r.values[index]);
124
+ const isTruncated = (
125
+ vals: (string | number | boolean | null | undefined)[],
126
+ ): boolean =>
127
+ Boolean(
128
+ vals.some((val) => {
129
+ if (val) {
130
+ const decimalPart = val.toString().split('.')[1];
131
+ return decimalPart && decimalPart.length > MAXIMUM_FRACTION_DIGITS;
132
+ }
133
+ return false;
134
+ }),
135
+ );
136
+ switch (columnType) {
137
+ case PRIMITIVE_TYPE.NUMBER:
138
+ case PRIMITIVE_TYPE.DECIMAL:
139
+ case PRIMITIVE_TYPE.FLOAT:
140
+ return isTruncated(colValues)
141
+ ? {
142
+ headerComponentParams: {
143
+ template: getFloatGridColumnCustomHeader(),
144
+ },
145
+ }
146
+ : {};
147
+ default:
148
+ return {};
149
+ }
150
+ }
151
+ return {};
152
+ };
153
+
50
154
  const QueryResultCellRenderer = observer(
51
155
  (params: IQueryRendererParamsWithGridType) => {
52
156
  const resultState = params.resultState;
@@ -62,7 +166,7 @@ const QueryResultCellRenderer = observer(
62
166
  const formattedCellValue = (): QueryBuilderTDSResultCellDataType => {
63
167
  if (isNumber(cellValue)) {
64
168
  return Intl.NumberFormat(DEFAULT_LOCALE, {
65
- maximumFractionDigits: 4,
169
+ maximumFractionDigits: MAXIMUM_FRACTION_DIGITS,
66
170
  }).format(Number(cellValue));
67
171
  } else if (isBoolean(cellValue)) {
68
172
  return String(cellValue);
@@ -368,6 +472,7 @@ export const QueryBuilderTDSSimpleGridResult = observer(
368
472
  resizable: true,
369
473
  field: colName,
370
474
  flex: 1,
475
+ ...getTDSColumnCustomizations(executionResult, colName),
371
476
  cellRenderer: QueryResultCellRenderer,
372
477
  cellRendererParams: {
373
478
  resultState: resultState,
@@ -213,7 +213,7 @@ export const isPropertyExpressionChainOptional = (
213
213
 
214
214
  export const isTypeCompatibleForAssignment = (
215
215
  type: Type | undefined,
216
- assignmentType: Type,
216
+ assignmentType: Type | undefined,
217
217
  ): boolean => {
218
218
  const NUMERIC_PRIMITIVE_TYPES = [
219
219
  PRIMITIVE_TYPE.NUMBER,
@@ -231,6 +231,7 @@ export const isTypeCompatibleForAssignment = (
231
231
  // When changing the return type for LHS, the RHS value should be adjusted accordingly.
232
232
  return (
233
233
  type !== undefined &&
234
+ assignmentType !== undefined &&
234
235
  // Numeric value is handled loosely because of autoboxing
235
236
  // e.g. LHS (integer) = RHS (float) is acceptable
236
237
  ((NUMERIC_PRIMITIVE_TYPES.includes(type.path) &&
@@ -19,17 +19,18 @@ import {
19
19
  type GenericLegendApplicationStore,
20
20
  } from '@finos/legend-application';
21
21
  import {
22
- QuerySearchSpecification,
23
- GRAPH_MANAGER_EVENT,
24
22
  type QueryInfo,
25
23
  type LightQuery,
26
24
  type BasicGraphManagerState,
27
25
  type Query,
28
26
  type RawLambda,
27
+ QuerySearchSpecification,
28
+ GRAPH_MANAGER_EVENT,
29
+ QuerySearchSortBy,
29
30
  } from '@finos/legend-graph';
30
31
  import {
31
- ActionState,
32
32
  type GeneratorFn,
33
+ ActionState,
33
34
  assertErrorThrown,
34
35
  guaranteeNonNullable,
35
36
  LogEvent,
@@ -51,7 +52,7 @@ export enum SORT_BY_OPTIONS {
51
52
  SORT_BY_UPDATE = 'Last Updated',
52
53
  }
53
54
 
54
- export type SortByOption = { label: string; value: string };
55
+ export type SortByOption = { label: SORT_BY_OPTIONS; value: SORT_BY_OPTIONS };
55
56
 
56
57
  export class QueryLoaderState {
57
58
  readonly applicationStore: GenericLegendApplicationStore;
@@ -92,7 +93,7 @@ export class QueryLoaderState {
92
93
  showingDefaultQueries = true;
93
94
  showPreviewViewer = false;
94
95
  queryPreviewContent?: QueryInfo | { name: string; content: string };
95
- sortBy = '';
96
+ sortBy = SORT_BY_OPTIONS.SORT_BY_VIEW;
96
97
 
97
98
  constructor(
98
99
  applicationStore: GenericLegendApplicationStore,
@@ -158,10 +159,23 @@ export class QueryLoaderState {
158
159
  this.isCuratedTemplateToggled = val;
159
160
  }
160
161
 
161
- setSortBy(val: string): void {
162
+ setSortBy(val: SORT_BY_OPTIONS): void {
162
163
  this.sortBy = val;
163
164
  }
164
165
 
166
+ getQuerySearchSortBy(sortByValue: string): QuerySearchSortBy | undefined {
167
+ switch (sortByValue) {
168
+ case SORT_BY_OPTIONS.SORT_BY_CREATE:
169
+ return QuerySearchSortBy.SORT_BY_CREATE;
170
+ case SORT_BY_OPTIONS.SORT_BY_UPDATE:
171
+ return QuerySearchSortBy.SORT_BY_UPDATE;
172
+ case SORT_BY_OPTIONS.SORT_BY_VIEW:
173
+ return QuerySearchSortBy.SORT_BY_VIEW;
174
+ default:
175
+ return undefined;
176
+ }
177
+ }
178
+
165
179
  setSearchText(val: string): void {
166
180
  this.searchText = val;
167
181
  }
@@ -171,7 +185,16 @@ export class QueryLoaderState {
171
185
  }
172
186
 
173
187
  setQueries(val: LightQuery[]): void {
174
- this.queries = val.sort((a, b) => a.name.localeCompare(b.name));
188
+ this.queries = val;
189
+ }
190
+
191
+ // search query using search specification
192
+ canPerformAdvancedSearch(searchText: string): boolean {
193
+ return !(
194
+ searchText.length < DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH &&
195
+ !this.showCurrentUserQueriesOnly &&
196
+ Array.from(this.extraFilters.values()).every((value) => value === false)
197
+ );
175
198
  }
176
199
 
177
200
  setShowPreviewViewer(val: boolean): void {
@@ -226,11 +249,7 @@ export class QueryLoaderState {
226
249
  }
227
250
 
228
251
  *searchQueries(searchText: string): GeneratorFn<void> {
229
- if (
230
- searchText.length < DEFAULT_TYPEAHEAD_SEARCH_MINIMUM_SEARCH_LENGTH &&
231
- !this.showCurrentUserQueriesOnly &&
232
- Array.from(this.extraFilters.values()).every((value) => value === false)
233
- ) {
252
+ if (!this.canPerformAdvancedSearch(searchText)) {
234
253
  // if no search text is specified, use fetch the default queries
235
254
  if (!searchText) {
236
255
  this.showingDefaultQueries = true;
@@ -268,6 +287,10 @@ export class QueryLoaderState {
268
287
  searchSpecification.limit = QUERY_LOADER_TYPEAHEAD_SEARCH_LIMIT + 1;
269
288
  searchSpecification.showCurrentUserQueriesOnly =
270
289
  this.showCurrentUserQueriesOnly;
290
+ const querySearchSortBy = this.getQuerySearchSortBy(this.sortBy);
291
+ if (querySearchSortBy) {
292
+ searchSpecification.sortByOption = querySearchSortBy;
293
+ }
271
294
  if (this.queryBuilderState) {
272
295
  Array.from(this.extraFilters.entries()).forEach(([key, value]) => {
273
296
  if (value) {
@@ -288,11 +311,14 @@ export class QueryLoaderState {
288
311
  searchSpecification =
289
312
  this.decorateSearchSpecification?.(searchSpecification) ??
290
313
  searchSpecification;
291
- this.queries = (
292
- (yield this.graphManagerState.graphManager.searchQueries(
293
- searchSpecification,
294
- )) as LightQuery[]
295
- ).sort((a, b) => a.name.localeCompare(b.name));
314
+ this.queries = (yield this.graphManagerState.graphManager.searchQueries(
315
+ searchSpecification,
316
+ )) as LightQuery[];
317
+ if (!querySearchSortBy) {
318
+ this.queries = this.queries.sort((a, b) =>
319
+ a.name.localeCompare(b.name),
320
+ );
321
+ }
296
322
  this.searchQueriesState.pass();
297
323
  } catch (error) {
298
324
  assertErrorThrown(error);
@@ -20,12 +20,12 @@ import {
20
20
  type Type,
21
21
  type ValueSpecification,
22
22
  type ExecutionResult,
23
- type VariableExpression,
24
23
  type SimpleFunctionExpression,
25
24
  observe_ValueSpecification,
26
25
  PrimitiveType,
27
26
  CollectionInstanceValue,
28
27
  InstanceValue,
28
+ VariableExpression,
29
29
  } from '@finos/legend-graph';
30
30
  import {
31
31
  type GeneratorFn,
@@ -74,11 +74,13 @@ import type { QueryBuilderTDSColumnState } from '../QueryBuilderTDSColumnState.j
74
74
  import {
75
75
  getCollectionValueSpecificationType,
76
76
  getNonCollectionValueSpecificationType,
77
+ isTypeCompatibleForAssignment,
77
78
  isValidInstanceValue,
78
79
  isValueExpressionReferencedInValue,
79
80
  } from '../../../QueryBuilderValueSpecificationHelper.js';
80
81
  import { buildtdsPropertyExpressionFromColState } from './operators/QueryBuilderPostFilterOperatorValueSpecificationBuilder.js';
81
82
  import { TDS_COLUMN_GETTER } from '../../../../graph/QueryBuilderMetaModelConst.js';
83
+ import type { QueryBuilderFilterTreeNodeData } from '../../../filter/QueryBuilderFilterState.js';
82
84
 
83
85
  export enum QUERY_BUILDER_POST_FILTER_DND_TYPE {
84
86
  GROUP_CONDITION = 'QUERY_BUILDER_POST_FILTER_DND_TYPE.GROUP_CONDITION',
@@ -1011,15 +1013,45 @@ export class QueryBuilderPostFilterState
1011
1013
  );
1012
1014
  }
1013
1015
 
1016
+ isInvalidValueSpecPostFilterValue(
1017
+ node: QueryBuilderPostFilterTreeNodeData,
1018
+ ): boolean {
1019
+ return (
1020
+ node instanceof QueryBuilderPostFilterTreeConditionNodeData &&
1021
+ node.condition.rightConditionValue instanceof
1022
+ PostFilterValueSpecConditionValueState &&
1023
+ ((node.condition.rightConditionValue.value instanceof InstanceValue &&
1024
+ !isValidInstanceValue(node.condition.rightConditionValue.value)) ||
1025
+ (node.condition.rightConditionValue.value instanceof
1026
+ VariableExpression &&
1027
+ !isTypeCompatibleForAssignment(
1028
+ node.condition.leftConditionValue.getColumnType(),
1029
+ node.condition.rightConditionValue.type,
1030
+ )))
1031
+ );
1032
+ }
1033
+
1034
+ isInvalidTDSColumnPostFilterValue(
1035
+ node: QueryBuilderFilterTreeNodeData,
1036
+ ): boolean {
1037
+ return (
1038
+ node instanceof QueryBuilderPostFilterTreeConditionNodeData &&
1039
+ node.condition.rightConditionValue instanceof
1040
+ PostFilterTDSColumnValueConditionValueState &&
1041
+ !isTypeCompatibleForAssignment(
1042
+ node.condition.leftConditionValue.getColumnType(),
1043
+ node.condition.rightConditionValue.type,
1044
+ )
1045
+ );
1046
+ }
1047
+
1014
1048
  get allValidationIssues(): string[] {
1015
1049
  const validationIssues: string[] = [];
1016
1050
  Array.from(this.nodes.values()).forEach((node) => {
1017
1051
  if (node instanceof QueryBuilderPostFilterTreeConditionNodeData) {
1018
1052
  if (
1019
- node.condition.rightConditionValue instanceof
1020
- PostFilterValueSpecConditionValueState &&
1021
- node.condition.rightConditionValue.value instanceof InstanceValue &&
1022
- !isValidInstanceValue(node.condition.rightConditionValue.value)
1053
+ this.isInvalidValueSpecPostFilterValue(node) ||
1054
+ this.isInvalidTDSColumnPostFilterValue(node)
1023
1055
  ) {
1024
1056
  validationIssues.push(
1025
1057
  `Filter value for ${node.condition.leftConditionValue.columnName} is missing or invalid`,
@@ -1042,11 +1074,8 @@ export class QueryBuilderPostFilterState
1042
1074
  get hasInvalidFilterValues(): boolean {
1043
1075
  return Array.from(this.nodes.values()).some(
1044
1076
  (node) =>
1045
- node instanceof QueryBuilderPostFilterTreeConditionNodeData &&
1046
- node.condition.rightConditionValue instanceof
1047
- PostFilterValueSpecConditionValueState &&
1048
- node.condition.rightConditionValue.value instanceof InstanceValue &&
1049
- !isValidInstanceValue(node.condition.rightConditionValue.value),
1077
+ this.isInvalidValueSpecPostFilterValue(node) ||
1078
+ this.isInvalidTDSColumnPostFilterValue(node),
1050
1079
  );
1051
1080
  }
1052
1081
 
@@ -40,12 +40,12 @@ import {
40
40
  type ExecutionResult,
41
41
  AbstractPropertyExpression,
42
42
  type ValueSpecification,
43
- type VariableExpression,
44
43
  type Type,
45
44
  observe_ValueSpecification,
46
45
  CollectionInstanceValue,
47
46
  InstanceValue,
48
47
  SimpleFunctionExpression,
48
+ VariableExpression,
49
49
  matchFunctionName,
50
50
  } from '@finos/legend-graph';
51
51
  import { DEFAULT_LAMBDA_VARIABLE_NAME } from '../QueryBuilderConfig.js';
@@ -61,6 +61,7 @@ import { QUERY_BUILDER_STATE_HASH_STRUCTURE } from '../QueryBuilderStateHashUtil
61
61
  import {
62
62
  getCollectionValueSpecificationType,
63
63
  getNonCollectionValueSpecificationType,
64
+ isTypeCompatibleForAssignment,
64
65
  isValidInstanceValue,
65
66
  isValueExpressionReferencedInValue,
66
67
  } from '../QueryBuilderValueSpecificationHelper.js';
@@ -1185,8 +1186,15 @@ export class QueryBuilderFilterState
1185
1186
  node instanceof QueryBuilderFilterTreeConditionNodeData &&
1186
1187
  node.condition.rightConditionValue instanceof
1187
1188
  FilterValueSpecConditionValueState &&
1188
- node.condition.rightConditionValue.value instanceof InstanceValue &&
1189
- !isValidInstanceValue(node.condition.rightConditionValue.value)
1189
+ ((node.condition.rightConditionValue.value instanceof InstanceValue &&
1190
+ !isValidInstanceValue(node.condition.rightConditionValue.value)) ||
1191
+ (node.condition.rightConditionValue.value instanceof
1192
+ VariableExpression &&
1193
+ !isTypeCompatibleForAssignment(
1194
+ node.condition.propertyExpressionState.propertyExpression.func.value
1195
+ .genericType.value.rawType,
1196
+ node.condition.rightConditionValue.value.genericType?.value.rawType,
1197
+ )))
1190
1198
  );
1191
1199
  }
1192
1200