From 2d15978b620e15e8b2f835c68f405a6f443ee300 Mon Sep 17 00:00:00 2001 From: gs-gunjan <72594207+gs-gunjan@users.noreply.github.com> Date: Sat, 11 Jan 2025 12:38:31 +0530 Subject: [PATCH] datacube: building snapshot for extend + pivot operation (part 2 of roundtrip) (#3800) * Snapshot building for extend operation Adding validation operation for groupBy * Data Cube: Cleanup snapshot building for filter operations (part 2) * building snapshot for extending operation * adding pivot operation roundtrip * adding changeset --- .changeset/perfect-starfishes-cheat.md | 6 + .../core/DataCubeQuerySnapshotBuilder.ts | 74 ++-- .../core/DataCubeQuerySnapshotBuilderUtils.ts | 380 ++++++++---------- ...eryExtendSnapshotBuilder.data-cube-test.ts | 103 +++++ ...eryFilterSnapshotBuilder.data-cube-test.ts | 34 +- ...CubeQuerySnapshotBuilder.data-cube-test.ts | 4 +- .../DatacubeQuerySnapshotBuilderTestUtils.ts | 5 + .../DataCubeQueryFilterOperation__Contain.tsx | 21 +- ...ilterOperation__ContainCaseInsensitive.tsx | 36 +- .../DataCubeQueryFilterOperation__EndWith.tsx | 21 +- ...ilterOperation__EndWithCaseInsensitive.tsx | 36 +- .../DataCubeQueryFilterOperation__Equal.tsx | 98 +---- ...yFilterOperation__EqualCaseInsensitive.tsx | 36 +- ...rOperation__EqualCaseInsensitiveColumn.tsx | 43 +- ...aCubeQueryFilterOperation__EqualColumn.tsx | 28 +- ...aCubeQueryFilterOperation__GreaterThan.tsx | 21 +- ...ueryFilterOperation__GreaterThanColumn.tsx | 28 +- ...eryFilterOperation__GreaterThanOrEqual.tsx | 26 +- ...terOperation__GreaterThanOrEqualColumn.tsx | 33 +- ...ataCubeQueryFilterOperation__IsNotNull.tsx | 27 +- .../DataCubeQueryFilterOperation__IsNull.tsx | 22 +- ...DataCubeQueryFilterOperation__LessThan.tsx | 21 +- ...beQueryFilterOperation__LessThanColumn.tsx | 28 +- ...eQueryFilterOperation__LessThanOrEqual.tsx | 26 +- ...FilterOperation__LessThanOrEqualColumn.tsx | 33 +- ...taCubeQueryFilterOperation__NotContain.tsx | 30 +- ...taCubeQueryFilterOperation__NotEndWith.tsx | 30 +- ...DataCubeQueryFilterOperation__NotEqual.tsx | 30 +- ...lterOperation__NotEqualCaseInsensitive.tsx | 41 +- ...eration__NotEqualCaseInsensitiveColumn.tsx | 48 ++- ...beQueryFilterOperation__NotEqualColumn.tsx | 37 +- ...CubeQueryFilterOperation__NotStartWith.tsx | 30 +- ...ataCubeQueryFilterOperation__StartWith.tsx | 21 +- ...terOperation__StartWithCaseInsensitive.tsx | 36 +- 34 files changed, 896 insertions(+), 597 deletions(-) create mode 100644 .changeset/perfect-starfishes-cheat.md create mode 100644 packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryExtendSnapshotBuilder.data-cube-test.ts diff --git a/.changeset/perfect-starfishes-cheat.md b/.changeset/perfect-starfishes-cheat.md new file mode 100644 index 0000000000..15059a3975 --- /dev/null +++ b/.changeset/perfect-starfishes-cheat.md @@ -0,0 +1,6 @@ +--- +'@finos/legend-data-cube': patch +--- + +snapshot building for extend and pivot operation +Cleanup for filter operation diff --git a/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilder.ts b/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilder.ts index 3c338ab476..1c03f434f6 100644 --- a/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilder.ts +++ b/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilder.ts @@ -30,6 +30,7 @@ import { extractElementNameFromPath as _name, matchFunctionName, type V1_ValueSpecification, + V1_GenericTypeInstance, } from '@finos/legend-graph'; import type { DataCubeQuery } from './model/DataCubeQuery.js'; import { DataCubeQuerySnapshot } from './DataCubeQuerySnapshot.js'; @@ -46,12 +47,14 @@ import { } from './DataCubeQueryEngine.js'; import { buildDefaultConfiguration } from './DataCubeConfigurationBuilder.js'; import { - _buildFilterSnapshot, _colSpecArrayParam, _colSpecParam, _funcMatch, _lambdaParam, _param, + _extend, + _filter, + _cast, } from './DataCubeQuerySnapshotBuilderUtils.js'; import type { DataCubeSource } from './model/DataCubeSource.js'; import type { DataCubeQueryFilterOperation } from './filter/DataCubeQueryFilterOperation.js'; @@ -102,13 +105,13 @@ enum _FUNCTION_SEQUENCE_COMPOSITION_PART { LIMIT = 'limit', } -function isFunctionInValidSequence( - value: string, -): value is _FUNCTION_SEQUENCE_COMPOSITION_PART { - return Object.values(_FUNCTION_SEQUENCE_COMPOSITION_PART).includes( - value as _FUNCTION_SEQUENCE_COMPOSITION_PART, - ); -} +// function isFunctionInValidSequence( +// value: string, +// ): value is _FUNCTION_SEQUENCE_COMPOSITION_PART { +// return Object.values(_FUNCTION_SEQUENCE_COMPOSITION_PART).includes( +// value as _FUNCTION_SEQUENCE_COMPOSITION_PART, +// ); +// } // This corresponds to the function sequence that we currently support: // @@ -234,17 +237,12 @@ function extractFunctionMap( } if (currentFunc.parameters.length > supportedFunc.parameters) { const valueSpecification = currentFunc.parameters[0]; - if ( - !( - valueSpecification instanceof V1_AppliedFunction || - isFunctionInValidSequence(currentFunc.function) - ) - ) { + if (!(valueSpecification instanceof V1_AppliedFunction)) { throw new Error( `Query must be a sequence of function calls (e.g. x()->y()->z())`, ); } else if ( - currentFunc.function === _FUNCTION_SEQUENCE_COMPOSITION_PART.FILTER + matchFunctionName(currentFunc.function, [DataCubeFunction.FILTER]) ) { currentFunc.parameters = currentFunc.parameters.slice(1); sequence.unshift(currentFunc); @@ -256,7 +254,7 @@ function extractFunctionMap( } else { currentFunc.parameters = currentFunc.parameters.slice(1); sequence.unshift(currentFunc); - currentFunc = valueSpecification as V1_AppliedFunction; + currentFunc = valueSpecification; } } else { sequence.unshift(currentFunc); @@ -295,7 +293,7 @@ function extractFunctionMap( select: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SELECT), filter: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.FILTER), pivotSort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_SORT), - pivot: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST), + pivot: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT), pivotCast: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST), groupBy: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY), groupBySort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY_SORT), @@ -317,7 +315,7 @@ export function validateAndBuildQuerySnapshot( partialQuery: V1_ValueSpecification, source: DataCubeSource, baseQuery: DataCubeQuery, - filterOperations?: DataCubeQueryFilterOperation[], + filterOperations: DataCubeQueryFilterOperation[], ) { // --------------------------------- BASE --------------------------------- // Build the function call sequence and the function map to make the @@ -341,13 +339,17 @@ export function validateAndBuildQuerySnapshot( data.sourceColumns.forEach((col) => colsMap.set(col.name, col)); // --------------------------- LEAF-LEVEL EXTEND --------------------------- - /** TODO: @datacube roundtrip */ + if (funcMap.leafExtend) { + _extend(funcMap.leafExtend, data.leafExtendedColumns); + // adding new extended columns in the column map for groupby and pivot operation + data.leafExtendedColumns.forEach((col) => colsMap.set(col.name, col)); + } // --------------------------------- FILTER --------------------------------- if (funcMap.filter) { - data.filter = _buildFilterSnapshot( + data.filter = _filter( _lambdaParam(funcMap.filter, 0).body[0]!, - filterOperations!, + filterOperations, ); } @@ -360,8 +362,15 @@ export function validateAndBuildQuerySnapshot( } // --------------------------------- PIVOT --------------------------------- - /** TODO: @datacube roundtrip */ // TODO: verify groupBy agg columns, pivot agg columns and configuration agree + if (funcMap.pivot && funcMap.pivotCast) { + data.pivot = { + columns: _colSpecArrayParam(funcMap.pivot, 0).colSpecs.map((colSpec) => + _col(colSpec), + ), + castColumns: _cast(_param(funcMap.pivotCast, 0, V1_GenericTypeInstance)), + }; + } // --------------------------------- GROUP BY --------------------------------- @@ -370,13 +379,28 @@ export function validateAndBuildQuerySnapshot( columns: _colSpecArrayParam(funcMap.groupBy, 0).colSpecs.map((colSpec) => _col(colSpec), ), - // TODO: verify groupBy agg columns, pivot agg columns and configuration agree - // TODO: verify groupBy sort columns and configuration agree }; + // TODO: verify groupBy agg columns, pivot agg columns and configuration agree + // TODO: verify sort column + // TODO: use configuration information present in the baseQuery configuration? + // _isColSpecOrArray(funcMap.groupBy, 1) ? _colSpecArrayParam(funcMap.groupBy, 1).colSpecs.forEach((colSpec) => _validateAggregateColumns(colSpec, baseQuery.configuration!)) : _validateAggregateColumns(_colSpecParam(funcMap.groupBy, 1), baseQuery.configuration!); + + // _param(funcMap.groupBySort!, 0, V1_Collection).values.forEach( + // (value) => + // { + // const sortColFunc = _funcMatch(value, [ + // DataCubeFunction.ASCENDING, + // DataCubeFunction.DESCENDING, + // ]); + // _validateSortColumns(sortColFunc, baseQuery.configuration!); + // } + // ) } // --------------------------- GROUP-LEVEL EXTEND --------------------------- - /** TODO: @datacube roundtrip */ + if (funcMap.groupExtend) { + _extend(funcMap.groupExtend, data.groupExtendedColumns); + } // --------------------------------- SORT --------------------------------- diff --git a/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts b/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts index 1fdd9352eb..ea6c89a9f3 100644 --- a/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts +++ b/packages/legend-data-cube/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts @@ -33,6 +33,9 @@ import { type V1_PrimitiveValueSpecification, extractElementNameFromPath as _name, matchFunctionName, + V1_RelationType, + V1_PackageableType, + type V1_GenericTypeInstance, } from '@finos/legend-graph'; import { type DataCubeColumn } from './model/DataCubeColumn.js'; import { @@ -46,16 +49,19 @@ import { import { DataCubeFunction, DataCubeQueryFilterGroupOperator, - DataCubeQueryFilterOperator, TREE_COLUMN_VALUE_SEPARATOR, type DataCubeOperationValue, + type DataCubeQueryFilterOperator, } from './DataCubeQueryEngine.js'; import type { + DataCubeQuerySnapshotExtendedColumn, DataCubeQuerySnapshotFilter, DataCubeQuerySnapshotFilterCondition, } from './DataCubeQuerySnapshot.js'; -import { _functionName } from './DataCubeQueryBuilderUtils.js'; +import { _serializeValueSpecification } from './DataCubeQueryBuilderUtils.js'; import type { DataCubeQueryFilterOperation } from './filter/DataCubeQueryFilterOperation.js'; +import type { DataCubeConfiguration } from './model/DataCubeConfiguration.js'; +import type { DataCubeQueryAggregateOperation } from './aggregation/DataCubeQueryAggregateOperation.js'; // --------------------------------- UTILITIES --------------------------------- @@ -99,6 +105,43 @@ export function _colSpecArrayParam(func: V1_AppliedFunction, paramIdx: number) { ); } +export function _extend( + value: V1_AppliedFunction, + extendSnapshot: DataCubeQuerySnapshotExtendedColumn[], +) { + value.parameters.forEach((param) => { + if (param instanceof V1_ClassInstance) { + guaranteeType(param.value, V1_ColSpecArray).colSpecs.forEach((colSpec) => + extendSnapshot.push(_extendColumn(colSpec)), + ); + } else if ( + param instanceof V1_AppliedFunction && + matchFunctionName(param.function, DataCubeFunction.EXTEND) + ) { + if (matchFunctionName(param.function, DataCubeFunction.EXTEND)) { + _extend(param, extendSnapshot); + } else { + throw new Error( + `Can't process extend() operation: Unexpected function ${param.function}`, + ); + } + } + }); +} + +function _extendColumn(colSpec: V1_ColSpec) { + const mapFunc = _serializeValueSpecification(colSpec.function1!); + const reduceFunc = colSpec.function2 + ? _serializeValueSpecification(colSpec.function2) + : undefined; + return { + name: colSpec.name, + type: colSpec.type!, + mapFn: mapFunc, + reduceFn: reduceFunc, + }; +} + export function _funcMatch( value: V1_ValueSpecification | undefined, functionNames: string | string[], @@ -154,226 +197,97 @@ export function _pruneExpandedPaths( .sort(); } -export function _buildFilterSnapshot( - vs: V1_ValueSpecification, +export function _filter( + value: V1_ValueSpecification, filterOperations: DataCubeQueryFilterOperation[], ): DataCubeQuerySnapshotFilter { - const filterSnapshot = {} as DataCubeQuerySnapshotFilter; - const filterConditionSnapshot = []; + const group: DataCubeQuerySnapshotFilter = { + // default to AND group for case where there is only one condition + groupOperator: DataCubeQueryFilterGroupOperator.AND, + conditions: [], + }; - if (vs instanceof V1_AppliedFunction) { - switch (vs.function) { - case DataCubeQueryFilterGroupOperator.OR: - case DataCubeQueryFilterGroupOperator.AND: - filterSnapshot.groupOperator = vs.function; - break; - default: - filterSnapshot.groupOperator = DataCubeQueryFilterGroupOperator.AND; - } + if (!(value instanceof V1_AppliedFunction)) { + throw new Error( + `Can't process filter() expression: Found unexpected Value Specification`, + ); + } - if ( - vs.function === DataCubeQueryFilterGroupOperator.AND || - vs.function === DataCubeQueryFilterGroupOperator.OR - ) { - vs.parameters.forEach((param) => { - filterConditionSnapshot.push(_buildSubFilter(param, filterOperations)!); - }); - } else { - filterConditionSnapshot.push(_buildSubFilter(vs, filterOperations)!); - } + if (matchFunctionName(value.function, DataCubeFunction.AND)) { + value.parameters.forEach((param) => { + group.conditions.push(_filterCondition(param, filterOperations)!); + }); + } else if (matchFunctionName(value.function, DataCubeFunction.OR)) { + group.groupOperator = DataCubeQueryFilterGroupOperator.OR; + value.parameters.forEach((param) => { + group.conditions.push(_filterCondition(param, filterOperations)!); + }); + } else { + group.conditions.push(_filterCondition(value, filterOperations)!); } - filterSnapshot.conditions = filterConditionSnapshot; - return filterSnapshot; + return group; } -function _buildSubFilter( - vs: V1_ValueSpecification, +function _filterCondition( + value: V1_ValueSpecification, filterOperations: DataCubeQueryFilterOperation[], ): | DataCubeQuerySnapshotFilterCondition | DataCubeQuerySnapshotFilter | undefined { - if (vs instanceof V1_AppliedFunction) { - if ( - Object.values(DataCubeFunction) - .map((op) => _functionName(op)) - .includes(vs.function) && - vs.function !== _functionName(DataCubeFunction.NOT) - ) { - const condition = _buildFilterConditionSnapshot(vs)!; - return _buildDataCubeQueryFilter( - condition[0], - condition[1], - filterOperations, - ); - } else if (vs.function === _functionName(DataCubeFunction.NOT)) { - const notCondition = _buildNotFilterConditionSnapshot( - vs.parameters[0] as V1_AppliedFunction, - ); - if (notCondition) { - return _buildDataCubeQueryFilter( - notCondition[0], - notCondition[1], - filterOperations, - ); - } else { - const filterSnapshot = _buildFilterSnapshot( - vs.parameters[0] as V1_ValueSpecification, - filterOperations, - ); - filterSnapshot.not = true; - return filterSnapshot; - } - } else if (vs.parameters[0] instanceof V1_AppliedFunction) { - return _buildFilterSnapshot(vs, filterOperations); - } + if (!(value instanceof V1_AppliedFunction)) { + throw new Error( + `Can't process filter() expression: Found unexpected Value Specification`, + ); } - return undefined; -} -function _buildFilterConditionSnapshot( - af: V1_AppliedFunction, -): [V1_AppliedFunction, string] | undefined { - if (af.parameters[1] && af.parameters[1] instanceof V1_AppliedProperty) { - switch (af.function) { - case _functionName(DataCubeFunction.EQUAL): - return [af, DataCubeQueryFilterOperator.EQUAL_COLUMN]; - case _functionName(DataCubeFunction.GREATER_THAN): - return [af, DataCubeQueryFilterOperator.GREATER_THAN_COLUMN]; - case _functionName(DataCubeFunction.GREATER_THAN_OR_EQUAL): - return [af, DataCubeQueryFilterOperator.GREATER_THAN_OR_EQUAL_COLUMN]; - case _functionName(DataCubeFunction.LESS_THAN): - return [af, DataCubeQueryFilterOperator.GREATER_THAN_OR_EQUAL_COLUMN]; - case _functionName(DataCubeFunction.LESS_THAN): - return [af, DataCubeQueryFilterOperator.LESS_THAN_COLUMN]; - case _functionName(DataCubeFunction.LESS_THAN_OR_EQUAL): - return [af, DataCubeQueryFilterOperator.LESS_THAN_OR_EQUAL_COLUMN]; - default: - return undefined; - } - } else if ( - af.parameters[0] instanceof V1_AppliedFunction && - af.parameters[0].function === _functionName(DataCubeFunction.TO_LOWERCASE) - ) { - return _buildCaseInsensitiveFilterConditionSnapshot(af); - } else { - switch (af.function) { - case _functionName(DataCubeFunction.CONTAINS): - return [af, DataCubeQueryFilterOperator.CONTAIN]; - case _functionName(DataCubeFunction.ENDS_WITH): - return [af, DataCubeQueryFilterOperator.END_WITH]; - case _functionName(DataCubeFunction.EQUAL): - return [af, DataCubeQueryFilterOperator.EQUAL]; - case _functionName(DataCubeFunction.GREATER_THAN): - return [af, DataCubeQueryFilterOperator.GREATER_THAN]; - case _functionName(DataCubeFunction.GREATER_THAN_OR_EQUAL): - return [af, DataCubeQueryFilterOperator.GREATER_THAN_OR_EQUAL]; - case _functionName(DataCubeFunction.IS_EMPTY): - return [af, DataCubeQueryFilterOperator.IS_NULL]; - case _functionName(DataCubeFunction.LESS_THAN): - return [af, DataCubeQueryFilterOperator.LESS_THAN]; - case _functionName(DataCubeFunction.LESS_THAN_OR_EQUAL): - return [af, DataCubeQueryFilterOperator.LESS_THAN_OR_EQUAL]; - case _functionName(DataCubeFunction.STARTS_WITH): - return [af, DataCubeQueryFilterOperator.START_WITH]; - default: - return undefined; - } - } -} - -function _buildCaseInsensitiveFilterConditionSnapshot( - af: V1_AppliedFunction, -): [V1_AppliedFunction, string] | undefined { - const func = af; if ( - af.parameters[0] instanceof V1_AppliedFunction && - af.parameters[1] instanceof V1_AppliedFunction + matchFunctionName(value.function, [ + DataCubeFunction.AND, + DataCubeFunction.OR, + ]) ) { - func.parameters = [ - af.parameters[0].parameters[0]!, - af.parameters[1].parameters[0]!, - ]; - } - if (func.parameters[1] && func.parameters[1] instanceof V1_AppliedProperty) { - switch (af.function) { - case _functionName(DataCubeFunction.EQUAL): - return [ - func, - DataCubeQueryFilterOperator.EQUAL_CASE_INSENSITIVE_COLUMN, - ]; - default: - return undefined; + return _filter(value, filterOperations); + } else if (matchFunctionName(value.function, DataCubeFunction.NOT)) { + const notCondition = filterOperations + .map((filterOperation) => filterOperation.buildConditionSnapshot(value)) + .filter((snapshot) => snapshot !== undefined); + if (notCondition.length !== 0) { + return notCondition[0]; + } else { + const filterSnapshot = _filter( + value.parameters[0] as V1_ValueSpecification, + filterOperations, + ); + filterSnapshot.not = true; + return filterSnapshot; } } else { - switch (af.function) { - case _functionName(DataCubeFunction.CONTAINS): - return [func, DataCubeQueryFilterOperator.CONTAIN_CASE_INSENSITIVE]; - case _functionName(DataCubeFunction.ENDS_WITH): - return [func, DataCubeQueryFilterOperator.END_WITH_CASE_INSENSITIVE]; - case _functionName(DataCubeFunction.EQUAL): - return [func, DataCubeQueryFilterOperator.EQUAL_CASE_INSENSITIVE]; - case _functionName(DataCubeFunction.STARTS_WITH): - return [func, DataCubeQueryFilterOperator.START_WITH_CASE_INSENSITIVE]; - default: - return undefined; + const condition = filterOperations + .map((filterOperation) => filterOperation.buildConditionSnapshot(value)) + .filter((snapshot) => snapshot !== undefined); + if (condition.length === 0) { + // TODO: throw a better error + throw new Error( + `Can\'t process filter condition: Found unexpected operation \'${value.function}\' `, + ); } + return condition[0]; } } -function _buildNotFilterConditionSnapshot( - af: V1_AppliedFunction, -): [V1_AppliedFunction, string] | undefined { - if (af.parameters[1] && af.parameters[1] instanceof V1_AppliedProperty) { - switch (af.function) { - case _functionName(DataCubeFunction.EQUAL): - return [af, DataCubeQueryFilterOperator.NOT_EQUAL_COLUMN]; - default: - return undefined; - } - } else if ( - af.parameters[0] instanceof V1_AppliedFunction && - af.parameters[0].function === _functionName(DataCubeFunction.TO_LOWERCASE) - ) { - if (af.function === _functionName(DataCubeFunction.EQUAL)) { - const func = af; - if ( - af.parameters[0] instanceof V1_AppliedFunction && - af.parameters[1] instanceof V1_AppliedFunction - ) { - func.parameters = [ - af.parameters[0].parameters[0]!, - af.parameters[1].parameters[0]!, - ]; - } - if ( - func.parameters[1] && - func.parameters[1] instanceof V1_AppliedProperty - ) { - return [ - func, - DataCubeQueryFilterOperator.NOT_EQUAL_CASE_INSENSITIVE_COLUMN, - ]; - } - return [func, DataCubeQueryFilterOperator.NOT_EQUAL_CASE_INSENSITIVE]; - } - } else { - switch (af.function) { - case _functionName(DataCubeFunction.CONTAINS): - return [af, DataCubeQueryFilterOperator.NOT_CONTAIN]; - case _functionName(DataCubeFunction.ENDS_WITH): - return [af, DataCubeQueryFilterOperator.NOT_END_WITH]; - case _functionName(DataCubeFunction.EQUAL): - return [af, DataCubeQueryFilterOperator.NOT_EQUAL]; - case _functionName(DataCubeFunction.IS_EMPTY): - return [af, DataCubeQueryFilterOperator.IS_NOT_NULL]; - case _functionName(DataCubeFunction.STARTS_WITH): - return [af, DataCubeQueryFilterOperator.NOT_START_WITH]; - default: - return undefined; - } - } - return undefined; +export function _cast(genericTypeInstance: V1_GenericTypeInstance) { + const relationTypes = guaranteeType( + genericTypeInstance.genericType.typeArguments[0]?.rawType, + V1_RelationType, + ); + return relationTypes.columns.map((column) => { + const type = guaranteeType(column.genericType.rawType, V1_PackageableType); + return { + name: column.name, + type: type.fullPath, + }; + }); } export function _dataCubeOperationValue( @@ -403,17 +317,6 @@ export function _dataCubeOperationValue( } } -function _buildDataCubeQueryFilter( - af: V1_AppliedFunction, - operator: string, - filterOperations: DataCubeQueryFilterOperation[], -): DataCubeQuerySnapshotFilterCondition | undefined { - const filterOperation = filterOperations.find( - (op) => op.operator === operator, - ); - return filterOperation?.buildConditionSnapshot(af); -} - function _buildDataCubeOperationValue( type: string, value: unknown, @@ -434,3 +337,58 @@ export function _buildConditionSnapshotProperty( type: property.class!, // TODO: fix this in engine (missing class in V1_AppliedProperty) } as DataCubeQuerySnapshotFilterCondition; } + +// TODO: configuration should be present while building the snapshot when loading +export function _validateAggregateColumns( + colSpec: V1_ColSpec, + configuration: DataCubeConfiguration, +) { + const property = guaranteeType( + colSpec.function1?.body[0], + V1_AppliedProperty, + "Can't find property for aggregation", + ); + const propertyConfiguration = configuration.columns.findLast( + (col) => col.name === property.property, + ); + guaranteeNonNullable( + propertyConfiguration, + `Aggregation column ${property} not present in configuration`, + ); + const reduceFunction = guaranteeType( + colSpec.function2?.body[0], + V1_AppliedFunction, + "Can't find agregration function", + ); + const entry = Object.entries(DataCubeFunction).find( + ([_, val]) => val === reduceFunction.function, + )?.[0] as keyof DataCubeQueryAggregateOperation; + if (propertyConfiguration?.aggregateOperator !== entry) { + throw new Error( + `Error loading aggregations for query; convergency issue in configuration and query provided`, + ); + } +} + +export function _validateSortColumns( + sortColumn: V1_AppliedFunction, + configuration: DataCubeConfiguration, +) { + const property = guaranteeType( + _colSpecParam(sortColumn, 0).name, + V1_AppliedProperty, + "Can't find property for aggregation", + ); + const propertyConfiguration = configuration.columns.findLast( + (col) => col.name === property.property, + ); + guaranteeNonNullable( + propertyConfiguration, + `Aggregation column ${property} not present in configuration`, + ); + if (sortColumn.function !== configuration.treeColumnSortDirection) { + throw new Error( + `Error loading query: convergency issue in configuration and query provided related to the sort information`, + ); + } +} diff --git a/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryExtendSnapshotBuilder.data-cube-test.ts b/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryExtendSnapshotBuilder.data-cube-test.ts new file mode 100644 index 0000000000..be637e2ccd --- /dev/null +++ b/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryExtendSnapshotBuilder.data-cube-test.ts @@ -0,0 +1,103 @@ +/** + * Copyright (c) 2020-present, Goldman Sachs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + V1_deserializeValueSpecification, + V1_serializeValueSpecification, +} from '@finos/legend-graph'; +import { + ENGINE_TEST_SUPPORT__grammarToJSON_valueSpecification, + ENGINE_TEST_SUPPORT__JsonToGrammar_valueSpecification, +} from '@finos/legend-graph/test'; +import { unitTest } from '@finos/legend-shared/test'; +import { describe, expect, test } from '@jest/globals'; +import { validateAndBuildQuerySnapshot } from '../DataCubeQuerySnapshotBuilder.js'; +import { + _cols, + _colSpec, + _deserializeLambda, + _function, +} from '../DataCubeQueryBuilderUtils.js'; +import { DataCubeFunction } from '../DataCubeQueryEngine.js'; +import { Test__DataCubeEngine } from './Test__DataCubeEngine.js'; +import { DataCubeQuery } from '../model/DataCubeQuery.js'; +import { INTERNAL__DataCubeSource } from '../model/DataCubeSource.js'; +import type { DataCubeOperationSnapshotBuilderTestCase } from './DatacubeQuerySnapshotBuilderTestUtils.js'; + +const cases: DataCubeOperationSnapshotBuilderTestCase[] = [ + ['simple extend', '~[name:c|$c.val->toOne() + 1]->extend()'], + [ + 'extend with colSpecArray', + "~[name:c|$c.val->toOne() + 1]->extend(~[other:x|$x.str->toOne() + '_ext']->extend(~[other2:x|$x.str->toOne() + '_1']->extend()))", + ], + // TODO: add support for window functions and increase validation + // [ + // 'extend with window', + // 'extend(over(~grp), ~newCol:{p,w,r|$r.id}:y|$y->plus())', + // ], +]; + +describe(unitTest('Analyze and build filter snapshot'), () => { + test.each(cases)( + '%s', + async ( + testName: DataCubeOperationSnapshotBuilderTestCase[0], + lambda: DataCubeOperationSnapshotBuilderTestCase[1], + ) => { + const engine = new Test__DataCubeEngine(); + const partialQuery = V1_deserializeValueSpecification( + await ENGINE_TEST_SUPPORT__grammarToJSON_valueSpecification(lambda), + [], + ); + const baseQuery = new DataCubeQuery(); + const source = new INTERNAL__DataCubeSource(); + + try { + const snapshot = validateAndBuildQuerySnapshot( + partialQuery, + source, + baseQuery, + engine.filterOperations, + ); + if (snapshot.data.leafExtendedColumns.length) { + const leafExtendedFuncs = snapshot.data.leafExtendedColumns.map( + (col) => + _function(DataCubeFunction.EXTEND, [ + _cols([_colSpec(col.name, _deserializeLambda(col.mapFn))]), + ]), + ); + while (leafExtendedFuncs.length > 1) { + const last = leafExtendedFuncs.pop(); // Remove the last element + if (last) { + // Add its parameters to the second last element + const secondLast = leafExtendedFuncs.pop(); + secondLast!.parameters.push(last); + leafExtendedFuncs.push(secondLast!); + } + } + const queryString = + await ENGINE_TEST_SUPPORT__JsonToGrammar_valueSpecification( + V1_serializeValueSpecification(leafExtendedFuncs[0]!, []), + ); + expect(lambda).toEqual(queryString); + } + } catch (error: unknown) { + // console.log(error); + throw error; + } + }, + ); +}); diff --git a/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryFilterSnapshotBuilder.data-cube-test.ts b/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryFilterSnapshotBuilder.data-cube-test.ts index b29dd9cf1f..68695022ea 100644 --- a/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryFilterSnapshotBuilder.data-cube-test.ts +++ b/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQueryFilterSnapshotBuilder.data-cube-test.ts @@ -20,9 +20,8 @@ import { } from '@finos/legend-graph'; import { ENGINE_TEST_SUPPORT__grammarToJSON_valueSpecification, - ENGINE_TEST_SUPPORT__JSONToGrammar_model, + ENGINE_TEST_SUPPORT__JsonToGrammar_valueSpecification, } from '@finos/legend-graph/test'; -import { assertErrorThrown } from '@finos/legend-shared'; import { unitTest } from '@finos/legend-shared/test'; import { describe, expect, test } from '@jest/globals'; import { validateAndBuildQuerySnapshot } from '../DataCubeQuerySnapshotBuilder.js'; @@ -36,13 +35,9 @@ import { DataCubeFunction } from '../DataCubeQueryEngine.js'; import { Test__DataCubeEngine } from './Test__DataCubeEngine.js'; import { DataCubeQuery } from '../model/DataCubeQuery.js'; import { INTERNAL__DataCubeSource } from '../model/DataCubeSource.js'; +import type { DataCubeOperationSnapshotBuilderTestCase } from './DatacubeQuerySnapshotBuilderTestUtils.js'; -type FilterSnapshotAnalysisTestCase = [ - string, // name - string, // query roundtrip -]; - -const cases: FilterSnapshotAnalysisTestCase[] = [ +const cases: DataCubeOperationSnapshotBuilderTestCase[] = [ ['simple filter 1', 'filter(x|$x.Age != 27)'], ['simple filter 2', 'filter(x|!($x.Age >= 27))'], ['simple filter 3', 'filter(x|$x.Athlete->isEmpty())'], @@ -77,9 +72,10 @@ describe(unitTest('Analyze and build filter snapshot'), () => { test.each(cases)( '%s', async ( - testName: FilterSnapshotAnalysisTestCase[0], - lambda: FilterSnapshotAnalysisTestCase[1], + testName: DataCubeOperationSnapshotBuilderTestCase[0], + lambda: DataCubeOperationSnapshotBuilderTestCase[1], ) => { + const engine = new Test__DataCubeEngine(); const partialQuery = V1_deserializeValueSpecification( await ENGINE_TEST_SUPPORT__grammarToJSON_valueSpecification(lambda), [], @@ -92,26 +88,22 @@ describe(unitTest('Analyze and build filter snapshot'), () => { partialQuery, source, baseQuery, - new Test__DataCubeEngine().filterOperations, + engine.filterOperations, ); const query = _function(DataCubeFunction.FILTER, [ _lambda( [_var()], - [ - _filter( - snapshot.data.filter!, - new Test__DataCubeEngine().filterOperations, - ), - ], + [_filter(snapshot.data.filter!, engine.filterOperations)], ), ]); - const queryString = await ENGINE_TEST_SUPPORT__JSONToGrammar_model( - V1_serializeValueSpecification(query, []), - ); + const queryString = + await ENGINE_TEST_SUPPORT__JsonToGrammar_valueSpecification( + V1_serializeValueSpecification(query, []), + ); expect(lambda).toEqual(queryString); } catch (error: unknown) { // console.log(error); - assertErrorThrown(error); + throw error; } }, ); diff --git a/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQuerySnapshotBuilder.data-cube-test.ts b/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQuerySnapshotBuilder.data-cube-test.ts index 7c9e83529e..aa27a0eb49 100644 --- a/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQuerySnapshotBuilder.data-cube-test.ts +++ b/packages/legend-data-cube/src/stores/core/__tests__/DataCubeQuerySnapshotBuilder.data-cube-test.ts @@ -108,13 +108,13 @@ const cases: DataCubeQuerySnapshotBuilderTestCase[] = [ _testCase({ name: 'Valid: Usage - Extended Columns: extend()->groupBy()->extend()->sort()->limit()', query: - 'extend(~[a:x|1])->groupBy(~[a], ~[b:x|$x.b:x|$x->sum()])->extend(~b:x|2)->sort([ascending(~a)])->limit(10)', + 'extend(~[a:x|1])->groupBy(~[a], ~[b:x|$x.b:x|$x->sum()])->sort([ascending(~a)])->extend(~[b:x|2])->limit(10)', columns: ['a:String', 'b:Integer'], }), _testCase({ name: 'Valid: Usage - Filter: extend()->filter()->groupBy()->extend()->sort()->limit()', query: - 'extend(~[a:x|1])->filter(x|$x.a==1)->groupBy(~a, ~b:x|$x.a:x|$x->sum())->extend(~b:x|2)->sort([ascending(~a)])->limit(10)', + 'extend(~[a:x|1])->filter(x|$x.a==1)->groupBy(~[a], ~b:x|$x.a:x|$x->sum())->sort([ascending(~a)])->extend(~[c:x|2])->limit(10)', columns: ['a:String', 'b:Integer'], }), _testCase({ diff --git a/packages/legend-data-cube/src/stores/core/__tests__/DatacubeQuerySnapshotBuilderTestUtils.ts b/packages/legend-data-cube/src/stores/core/__tests__/DatacubeQuerySnapshotBuilderTestUtils.ts index 8ea9bbdfa4..b207656e25 100644 --- a/packages/legend-data-cube/src/stores/core/__tests__/DatacubeQuerySnapshotBuilderTestUtils.ts +++ b/packages/legend-data-cube/src/stores/core/__tests__/DatacubeQuerySnapshotBuilderTestUtils.ts @@ -24,6 +24,11 @@ export type DataCubeQuerySnapshotBuilderTestCase = [ string | undefined, // error ]; +export type DataCubeOperationSnapshotBuilderTestCase = [ + string, // name + string, // query roundtrip +]; + export function _testCase(data: { name: string; query: string; diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Contain.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Contain.tsx index 28fb75347a..922907516e 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Contain.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Contain.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -80,15 +81,19 @@ export class DataCubeQueryFilterOperation__Contain extends DataCubeQueryFilterOp } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if (matchFunctionName(expression.function, DataCubeFunction.CONTAINS)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.tsx index 195ecfaa00..349e398d99 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__ContainCaseInsensitive.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,32 @@ export class DataCubeQueryFilterOperation__ContainCaseInsensitive extends DataCu } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) && + matchFunctionName(expression.function, DataCubeFunction.CONTAINS) + ) { + const func = expression; + func.parameters = [ + expression.parameters[0].parameters[0]!, + expression.parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWith.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWith.tsx index 0c0d46728f..fc1e5ad8ab 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWith.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWith.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -80,15 +81,19 @@ export class DataCubeQueryFilterOperation__EndWith extends DataCubeQueryFilterOp } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if (matchFunctionName(expression.function, DataCubeFunction.ENDS_WITH)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.tsx index f2153be5c8..f4957e299f 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EndWithCaseInsensitive.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,32 @@ export class DataCubeQueryFilterOperation__EndWithCaseInsensitive extends DataCu } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) && + matchFunctionName(expression.function, DataCubeFunction.ENDS_WITH) + ) { + const func = expression; + func.parameters = [ + expression.parameters[0].parameters[0]!, + expression.parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Equal.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Equal.tsx index b251db48c8..869af392f7 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Equal.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__Equal.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -89,93 +90,20 @@ export class DataCubeQueryFilterOperation__Equal extends DataCubeQueryFilterOper }; } - // buildConditionSnapshot(expression: V1_AppliedFunction) { - /** TODO: @datacube roundtrip */ - // export const buildPostFilterConditionState = ( - // postFilterState: QueryBuilderPostFilterState, - // expression: FunctionExpression, - // operatorFunctionFullPath | undefined, - // operator: QueryBuilderPostFilterOperator, - // ): PostFilterConditionState | undefined => { - // let postConditionState: PostFilterConditionState | undefined; - // const tdsColumnGetter = operator.getTDSColumnGetter(); - // if ( - // tdsColumnGetter && - // expression instanceof AbstractPropertyExpression && - // expression.func.value.name === tdsColumnGetter - // ) { - // const columnState = findProjectionColumnState(expression, postFilterState); - // postConditionState = new PostFilterConditionState( - // postFilterState, - // columnState, - // operator, - // ); - // return postConditionState; - // } else if ( - // operatorFunctionFullPath && - // matchFunctionName(expression.functionName, operatorFunctionFullPath) - // ) { - // assertTrue( - // expression.parametersValues.length === 2, - // `Can't process ${extractElementNameFromPath( - // operatorFunctionFullPath, - // )}() expression: ${extractElementNameFromPath( - // operatorFunctionFullPath, - // )}() expects '1 argument'`, - // ); - - // // get projection column - // const tdsColumnPropertyExpression = guaranteeType( - // expression.parametersValues[0], - // AbstractPropertyExpression, - // `Can't process ${extractElementNameFromPath( - // operatorFunctionFullPath, - // )}() expression: expects property expression in lambda body`, - // ); - // const columnState = findProjectionColumnState( - // tdsColumnPropertyExpression, - // postFilterState, - // ); - - // // get operation value specification - // const rightSide = expression.parametersValues[1]; - - // // create state - // postConditionState = new PostFilterConditionState( - // postFilterState, - // columnState, - // operator, - // ); - - // buildPostFilterConditionValueState(rightSide, postConditionState); - - // //post checks - // assertTrue( - // operator.isCompatibleWithPostFilterColumn(postConditionState), - // `Can't process ${extractElementNameFromPath( - // operatorFunctionFullPath, - // )}() expression: property is not compatible with post-filter operator`, - // ); - // assertTrue( - // operator.isCompatibleWithConditionValue(postConditionState), - // `Operator '${operator.getLabel()}' not compatible with value specification ${rightSide?.toString()}`, - // ); - // } - // return postConditionState; - // }; - // return undefined; - // } - buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if (matchFunctionName(expression.function, DataCubeFunction.EQUAL)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.tsx index 7a02efebf3..5db46dd459 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitive.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,32 @@ export class DataCubeQueryFilterOperation__EqualCaseInsensitive extends DataCube } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) && + matchFunctionName(expression.function, DataCubeFunction.EQUAL) + ) { + const func = expression; + func.parameters = [ + expression.parameters[0].parameters[0]!, + expression.parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.tsx index 7c6ea61d45..9173a8b41e 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn.tsx @@ -33,8 +33,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_AppliedProperty, - type V1_AppliedFunction, } from '@finos/legend-graph'; import { _buildConditionSnapshotProperty } from '../DataCubeQuerySnapshotBuilderUtils.js'; @@ -75,19 +76,35 @@ export class DataCubeQueryFilterOperation__EqualCaseInsensitiveColumn extends Da } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if ( + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) && + matchFunctionName(expression.function, DataCubeFunction.EQUAL) + ) { + const func = expression; + func.parameters = [ + expression.parameters[0].parameters[0]!, + expression.parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.tsx index f80738a111..f524e05e1f 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__EqualColumn.tsx @@ -33,6 +33,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, V1_AppliedProperty, type V1_AppliedFunction, } from '@finos/legend-graph'; @@ -80,19 +81,22 @@ export class DataCubeQueryFilterOperation__EqualColumn extends DataCubeQueryFilt } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if (matchFunctionName(expression.function, DataCubeFunction.EQUAL)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.tsx index 165e5ac850..7b95dfb64b 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThan.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -88,15 +89,19 @@ export class DataCubeQueryFilterOperation__GreaterThan extends DataCubeQueryFilt } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if (matchFunctionName(expression.function, DataCubeFunction.GREATER_THAN)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.tsx index 48ba9b1bd8..db766dfd3e 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanColumn.tsx @@ -33,6 +33,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, V1_AppliedProperty, type V1_AppliedFunction, } from '@finos/legend-graph'; @@ -79,19 +80,22 @@ export class DataCubeQueryFilterOperation__GreaterThanColumn extends DataCubeQue } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if (matchFunctionName(expression.function, DataCubeFunction.GREATER_THAN)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.tsx index f5201d1da5..37ad559375 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqual.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -88,15 +89,24 @@ export class DataCubeQueryFilterOperation__GreaterThanOrEqual extends DataCubeQu } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName( + expression.function, + DataCubeFunction.GREATER_THAN_OR_EQUAL, + ) + ) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.tsx index 2242f43e91..d505605a6b 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__GreaterThanOrEqualColumn.tsx @@ -33,6 +33,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, V1_AppliedProperty, type V1_AppliedFunction, } from '@finos/legend-graph'; @@ -79,19 +80,27 @@ export class DataCubeQueryFilterOperation__GreaterThanOrEqualColumn extends Data } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if ( + matchFunctionName( + expression.function, + DataCubeFunction.GREATER_THAN_OR_EQUAL, + ) + ) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.tsx index fcbda8f8eb..7b446a2d0b 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNotNull.tsx @@ -29,9 +29,10 @@ import { _not, _property, } from '../DataCubeQueryBuilderUtils.js'; -import type { +import { + matchFunctionName, V1_AppliedFunction, - V1_AppliedProperty, + type V1_AppliedProperty, } from '@finos/legend-graph'; import { _buildConditionSnapshotProperty } from '../DataCubeQuerySnapshotBuilderUtils.js'; @@ -79,12 +80,22 @@ export class DataCubeQueryFilterOperation__IsNotNull extends DataCubeQueryFilter } buildConditionSnapshot(expression: V1_AppliedFunction) { - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - filterConditionSnapshot.value = undefined; - return filterConditionSnapshot; + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.IS_EMPTY, + ) + ) { + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0].parameters[0] as V1_AppliedProperty, + this.operator, + ); + filterConditionSnapshot.value = undefined; + return filterConditionSnapshot; + } + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNull.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNull.tsx index 77a4655daf..f4b35eacf9 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNull.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__IsNull.tsx @@ -28,9 +28,10 @@ import { _functionName, _property, } from '../DataCubeQueryBuilderUtils.js'; -import type { - V1_AppliedFunction, - V1_AppliedProperty, +import { + matchFunctionName, + type V1_AppliedFunction, + type V1_AppliedProperty, } from '@finos/legend-graph'; import { _buildConditionSnapshotProperty } from '../DataCubeQuerySnapshotBuilderUtils.js'; @@ -78,12 +79,15 @@ export class DataCubeQueryFilterOperation__IsNull extends DataCubeQueryFilterOpe } buildConditionSnapshot(expression: V1_AppliedFunction) { - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - filterConditionSnapshot.value = undefined; - return filterConditionSnapshot; + if (matchFunctionName(expression.function, DataCubeFunction.IS_EMPTY)) { + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + filterConditionSnapshot.value = undefined; + return filterConditionSnapshot; + } + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThan.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThan.tsx index 8ac101970c..dd306554f8 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThan.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThan.tsx @@ -35,6 +35,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -89,15 +90,19 @@ export class DataCubeQueryFilterOperation__LessThan extends DataCubeQueryFilterO } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if (matchFunctionName(expression.function, DataCubeFunction.LESS_THAN)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.tsx index c17ec0d5fd..b77605fb4a 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanColumn.tsx @@ -33,6 +33,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, V1_AppliedProperty, type V1_AppliedFunction, } from '@finos/legend-graph'; @@ -79,19 +80,22 @@ export class DataCubeQueryFilterOperation__LessThanColumn extends DataCubeQueryF } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if (matchFunctionName(expression.function, DataCubeFunction.LESS_THAN)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.tsx index 9f5caa6103..1d92731aa6 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqual.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -88,15 +89,24 @@ export class DataCubeQueryFilterOperation__LessThanOrEqual extends DataCubeQuery } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName( + expression.function, + DataCubeFunction.LESS_THAN_OR_EQUAL, + ) + ) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.tsx index a6db67e39c..175ad60254 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__LessThanOrEqualColumn.tsx @@ -33,6 +33,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, V1_AppliedProperty, type V1_AppliedFunction, } from '@finos/legend-graph'; @@ -79,19 +80,27 @@ export class DataCubeQueryFilterOperation__LessThanOrEqualColumn extends DataCub } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if ( + matchFunctionName( + expression.function, + DataCubeFunction.LESS_THAN_OR_EQUAL, + ) + ) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotContain.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotContain.tsx index f6ce38108c..aaec6fd081 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotContain.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotContain.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,26 @@ export class DataCubeQueryFilterOperation__NotContain extends DataCubeQueryFilte } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.CONTAINS, + ) + ) { + const value = expression.parameters[0].parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0].parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.tsx index 956acb531b..b27e78eb55 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEndWith.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,26 @@ export class DataCubeQueryFilterOperation__NotEndWith extends DataCubeQueryFilte } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.ENDS_WITH, + ) + ) { + const value = expression.parameters[0].parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0].parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.tsx index 2746474088..5a6f3f85a2 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqual.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -91,15 +92,26 @@ export class DataCubeQueryFilterOperation__NotEqual extends DataCubeQueryFilterO } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.EQUAL, + ) + ) { + const value = expression.parameters[0].parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0].parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.tsx index 7c887fd4b0..27211d760f 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitive.tsx @@ -36,8 +36,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -82,15 +83,37 @@ export class DataCubeQueryFilterOperation__NotEqualCaseInsensitive extends DataC } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[0].parameters[0] instanceof V1_AppliedFunction && + expression.parameters[0].parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.EQUAL, + ) && + matchFunctionName( + expression.parameters[0].parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) + ) { + const func = expression.parameters[0]; + func.parameters = [ + expression.parameters[0].parameters[0].parameters[0]!, + expression.parameters[0].parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.tsx index b4040a4a82..82a747dcc7 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn.tsx @@ -34,8 +34,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_AppliedProperty, - type V1_AppliedFunction, } from '@finos/legend-graph'; import { _buildConditionSnapshotProperty } from '../DataCubeQuerySnapshotBuilderUtils.js'; @@ -76,19 +77,40 @@ export class DataCubeQueryFilterOperation__NotEqualCaseInsensitiveColumn extends } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[0].parameters[0] instanceof V1_AppliedFunction && + expression.parameters[0].parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.EQUAL, + ) && + matchFunctionName( + expression.parameters[0].parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) + ) { + const func = expression.parameters[0]; + func.parameters = [ + expression.parameters[0].parameters[0].parameters[0]!, + expression.parameters[0].parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.tsx index accd10b8ba..a86b98e8e2 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotEqualColumn.tsx @@ -34,8 +34,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable, isString } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_AppliedProperty, - type V1_AppliedFunction, } from '@finos/legend-graph'; import { _buildConditionSnapshotProperty } from '../DataCubeQuerySnapshotBuilderUtils.js'; @@ -81,19 +82,29 @@ export class DataCubeQueryFilterOperation__NotEqualColumn extends DataCubeQueryF } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - - if (value instanceof V1_AppliedProperty) { - filterConditionSnapshot.value = { - value: value.property, - type: DataCubeOperationAdvancedValueType.COLUMN, - } satisfies DataCubeOperationValue; + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.EQUAL, + ) + ) { + const value = expression.parameters[0].parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0].parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_AppliedProperty) { + filterConditionSnapshot.value = { + value: value.property, + type: DataCubeOperationAdvancedValueType.COLUMN, + } satisfies DataCubeOperationValue; + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.tsx index 70d31d602f..ba4dad11d0 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__NotStartWith.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,26 @@ export class DataCubeQueryFilterOperation__NotStartWith extends DataCubeQueryFil } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + matchFunctionName(expression.function, DataCubeFunction.NOT) && + expression.parameters[0] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.STARTS_WITH, + ) + ) { + const value = expression.parameters[0].parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0].parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWith.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWith.tsx index ae7e808e3e..24964c4cef 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWith.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWith.tsx @@ -34,6 +34,7 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, V1_PrimitiveValueSpecification, type V1_AppliedFunction, type V1_AppliedProperty, @@ -80,15 +81,19 @@ export class DataCubeQueryFilterOperation__StartWith extends DataCubeQueryFilter } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if (matchFunctionName(expression.function, DataCubeFunction.STARTS_WITH)) { + const value = expression.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + expression.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) { diff --git a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.tsx b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.tsx index cf630e54df..537a0b5d1c 100644 --- a/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.tsx +++ b/packages/legend-data-cube/src/stores/core/filter/DataCubeQueryFilterOperation__StartWithCaseInsensitive.tsx @@ -35,8 +35,9 @@ import { } from '../DataCubeQueryBuilderUtils.js'; import { guaranteeNonNullable } from '@finos/legend-shared'; import { + matchFunctionName, + V1_AppliedFunction, V1_PrimitiveValueSpecification, - type V1_AppliedFunction, type V1_AppliedProperty, } from '@finos/legend-graph'; import { @@ -81,15 +82,32 @@ export class DataCubeQueryFilterOperation__StartWithCaseInsensitive extends Data } buildConditionSnapshot(expression: V1_AppliedFunction) { - const value = expression.parameters[1]; - const filterConditionSnapshot = _buildConditionSnapshotProperty( - expression.parameters[0] as V1_AppliedProperty, - this.operator, - ); - if (value instanceof V1_PrimitiveValueSpecification) { - filterConditionSnapshot.value = _dataCubeOperationValue(value); + if ( + expression.parameters[0] instanceof V1_AppliedFunction && + expression.parameters[1] instanceof V1_AppliedFunction && + matchFunctionName( + expression.parameters[0].function, + DataCubeFunction.TO_LOWERCASE, + ) && + matchFunctionName(expression.function, DataCubeFunction.STARTS_WITH) + ) { + const func = expression; + func.parameters = [ + expression.parameters[0].parameters[0]!, + expression.parameters[1].parameters[0]!, + ]; + const value = func.parameters[1]; + const filterConditionSnapshot = _buildConditionSnapshotProperty( + func.parameters[0] as V1_AppliedProperty, + this.operator, + ); + if (value instanceof V1_PrimitiveValueSpecification) { + filterConditionSnapshot.value = _dataCubeOperationValue(value); + return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + } + return undefined; } - return filterConditionSnapshot satisfies DataCubeQuerySnapshotFilterCondition; + return undefined; } buildConditionExpression(condition: DataCubeQuerySnapshotFilterCondition) {