@finos/legend-data-cube 0.0.3 → 0.0.5
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.
- package/lib/components/editor/DataCubeEditorColumnPropertiesPanel.d.ts.map +1 -1
- package/lib/components/editor/DataCubeEditorColumnPropertiesPanel.js +7 -4
- package/lib/components/editor/DataCubeEditorColumnPropertiesPanel.js.map +1 -1
- package/lib/components/editor/DataCubeEditorGeneralPropertiesPanel.d.ts.map +1 -1
- package/lib/components/editor/DataCubeEditorGeneralPropertiesPanel.js +10 -15
- package/lib/components/editor/DataCubeEditorGeneralPropertiesPanel.js.map +1 -1
- package/lib/components/editor/DataCubeEditorSortsPanel.d.ts.map +1 -1
- package/lib/components/editor/DataCubeEditorSortsPanel.js +9 -9
- package/lib/components/editor/DataCubeEditorSortsPanel.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/core/DataCubeConfiguration.d.ts +13 -7
- package/lib/stores/core/DataCubeConfiguration.d.ts.map +1 -1
- package/lib/stores/core/DataCubeConfiguration.js +25 -15
- package/lib/stores/core/DataCubeConfiguration.js.map +1 -1
- package/lib/stores/core/DataCubeConfigurationBuilder.d.ts.map +1 -1
- package/lib/stores/core/DataCubeConfigurationBuilder.js +3 -2
- package/lib/stores/core/DataCubeConfigurationBuilder.js.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilder.js +23 -17
- package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
- package/lib/stores/core/DataCubeQueryBuilderUtils.js +2 -2
- package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
- package/lib/stores/core/DataCubeQueryEngine.d.ts +19 -11
- package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQueryEngine.js +21 -14
- package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
- package/lib/stores/core/DataCubeQuerySnapshot.d.ts +1 -1
- package/lib/stores/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQuerySnapshotBuilder.js +131 -80
- package/lib/stores/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
- package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts +6 -7
- package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts.map +1 -1
- package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js +27 -91
- package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js.map +1 -1
- package/lib/stores/core/DataCubeQuerySnapshotManager.js +1 -1
- package/lib/stores/core/DataCubeQuerySnapshotManager.js.map +1 -1
- package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.d.ts +1 -2
- package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.d.ts.map +1 -1
- package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.js +4 -6
- package/lib/stores/editor/DataCubeEditorGeneralPropertiesPanelState.js.map +1 -1
- package/lib/stores/editor/DataCubeEditorMutableConfiguration.d.ts +15 -8
- package/lib/stores/editor/DataCubeEditorMutableConfiguration.d.ts.map +1 -1
- package/lib/stores/editor/DataCubeEditorMutableConfiguration.js +50 -26
- package/lib/stores/editor/DataCubeEditorMutableConfiguration.js.map +1 -1
- package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.d.ts +30 -0
- package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.d.ts.map +1 -0
- package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.js +43 -0
- package/lib/stores/editor/DataCubeEditorPivotLayoutPanelState.js.map +1 -0
- package/lib/stores/editor/DataCubeEditorSortsPanelState.d.ts +3 -3
- package/lib/stores/editor/DataCubeEditorSortsPanelState.d.ts.map +1 -1
- package/lib/stores/editor/DataCubeEditorSortsPanelState.js +11 -11
- package/lib/stores/editor/DataCubeEditorSortsPanelState.js.map +1 -1
- package/lib/stores/editor/DataCubeEditorState.d.ts +2 -0
- package/lib/stores/editor/DataCubeEditorState.d.ts.map +1 -1
- package/lib/stores/editor/DataCubeEditorState.js +5 -0
- package/lib/stores/editor/DataCubeEditorState.js.map +1 -1
- package/lib/stores/extend/DataCubeExtendManagerState.js +1 -1
- package/lib/stores/extend/DataCubeExtendManagerState.js.map +1 -1
- package/lib/stores/grid/DataCubeGridClientEngine.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridClientEngine.js +41 -36
- package/lib/stores/grid/DataCubeGridClientEngine.js.map +1 -1
- package/lib/stores/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridConfigurationBuilder.js +39 -3
- package/lib/stores/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
- package/lib/stores/grid/DataCubeGridControllerState.d.ts +6 -3
- package/lib/stores/grid/DataCubeGridControllerState.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridControllerState.js +35 -17
- package/lib/stores/grid/DataCubeGridControllerState.js.map +1 -1
- package/lib/stores/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridMenuBuilder.js +52 -31
- package/lib/stores/grid/DataCubeGridMenuBuilder.js.map +1 -1
- package/lib/stores/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridQueryBuilder.js +3 -3
- package/lib/stores/grid/DataCubeGridQueryBuilder.js.map +1 -1
- package/lib/stores/grid/DataCubeGridQuerySnapshotBuilder.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridQuerySnapshotBuilder.js +14 -7
- package/lib/stores/grid/DataCubeGridQuerySnapshotBuilder.js.map +1 -1
- package/lib/stores/grid/DataCubeGridState.d.ts.map +1 -1
- package/lib/stores/grid/DataCubeGridState.js +9 -5
- package/lib/stores/grid/DataCubeGridState.js.map +1 -1
- package/package.json +3 -3
- package/src/components/editor/DataCubeEditorColumnPropertiesPanel.tsx +11 -5
- package/src/components/editor/DataCubeEditorGeneralPropertiesPanel.tsx +94 -101
- package/src/components/editor/DataCubeEditorSortsPanel.tsx +12 -10
- package/src/stores/core/DataCubeConfiguration.ts +33 -15
- package/src/stores/core/DataCubeConfigurationBuilder.ts +3 -2
- package/src/stores/core/DataCubeQueryBuilder.ts +33 -20
- package/src/stores/core/DataCubeQueryBuilderUtils.ts +2 -2
- package/src/stores/core/DataCubeQueryEngine.ts +22 -12
- package/src/stores/core/DataCubeQuerySnapshot.ts +1 -1
- package/src/stores/core/DataCubeQuerySnapshotBuilder.ts +135 -120
- package/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts +33 -107
- package/src/stores/core/DataCubeQuerySnapshotManager.ts +1 -1
- package/src/stores/editor/DataCubeEditorGeneralPropertiesPanelState.ts +6 -9
- package/src/stores/editor/DataCubeEditorMutableConfiguration.ts +68 -28
- package/src/stores/editor/DataCubeEditorPivotLayoutPanelState.ts +71 -0
- package/src/stores/editor/DataCubeEditorSortsPanelState.ts +11 -11
- package/src/stores/editor/DataCubeEditorState.tsx +5 -0
- package/src/stores/extend/DataCubeExtendManagerState.tsx +1 -1
- package/src/stores/grid/DataCubeGridClientEngine.ts +52 -48
- package/src/stores/grid/DataCubeGridConfigurationBuilder.tsx +45 -4
- package/src/stores/grid/DataCubeGridControllerState.ts +44 -20
- package/src/stores/grid/DataCubeGridMenuBuilder.tsx +81 -52
- package/src/stores/grid/DataCubeGridQueryBuilder.ts +3 -7
- package/src/stores/grid/DataCubeGridQuerySnapshotBuilder.ts +20 -7
- package/src/stores/grid/DataCubeGridState.ts +9 -5
- package/tsconfig.json +1 -0
|
@@ -80,6 +80,7 @@ export type DataCubeQueryFunctionMap = {
|
|
|
80
80
|
pivot?: V1_AppliedFunction | undefined;
|
|
81
81
|
pivotCast?: V1_AppliedFunction | undefined;
|
|
82
82
|
groupBy?: V1_AppliedFunction | undefined;
|
|
83
|
+
groupBySort?: V1_AppliedFunction | undefined;
|
|
83
84
|
groupExtend?: V1_AppliedFunction | undefined;
|
|
84
85
|
select?: V1_AppliedFunction | undefined;
|
|
85
86
|
sort?: V1_AppliedFunction | undefined;
|
|
@@ -96,14 +97,6 @@ export enum DataCubeNumberScale {
|
|
|
96
97
|
AUTO = 'Auto (k/m/b/t)',
|
|
97
98
|
}
|
|
98
99
|
|
|
99
|
-
export enum DataCubeSelectionStat {
|
|
100
|
-
COUNT = 'Count',
|
|
101
|
-
SUM = 'Sum',
|
|
102
|
-
MIN = 'Min',
|
|
103
|
-
MAX = 'Max',
|
|
104
|
-
AVERAGE = 'Average',
|
|
105
|
-
}
|
|
106
|
-
|
|
107
100
|
export enum DataCubeFont {
|
|
108
101
|
// sans-serif
|
|
109
102
|
ARIAL = 'Arial',
|
|
@@ -190,6 +183,19 @@ export enum DataCubeAggregateOperator {
|
|
|
190
183
|
// custom
|
|
191
184
|
}
|
|
192
185
|
|
|
186
|
+
export enum DataCubeClientSideAggregateOperator {
|
|
187
|
+
SUM = 'sum',
|
|
188
|
+
AVERAGE = 'avg',
|
|
189
|
+
MEDIAN = 'median',
|
|
190
|
+
COUNT = 'count',
|
|
191
|
+
MIN = 'min',
|
|
192
|
+
MAX = 'max',
|
|
193
|
+
VARIANCE_POPULATION = 'var',
|
|
194
|
+
VARIANCE_SAMPLE = 'var_sample',
|
|
195
|
+
STANDARD_DEVIATION_POPULATION = 'std',
|
|
196
|
+
STANDARD_DEVIATION_SAMPLE = 'std_sample',
|
|
197
|
+
}
|
|
198
|
+
|
|
193
199
|
export enum DataCubeQueryFilterOperator {
|
|
194
200
|
LESS_THAN = '<', // DONE
|
|
195
201
|
LESS_THAN_OR_EQUAL = '<=', // DONE
|
|
@@ -232,9 +238,9 @@ export enum DataCubeQueryFilterGroupOperator {
|
|
|
232
238
|
OR = 'or',
|
|
233
239
|
}
|
|
234
240
|
|
|
235
|
-
export enum
|
|
236
|
-
ASCENDING = '
|
|
237
|
-
DESCENDING = '
|
|
241
|
+
export enum DataCubeQuerySortDirection {
|
|
242
|
+
ASCENDING = 'Ascending',
|
|
243
|
+
DESCENDING = 'Descending',
|
|
238
244
|
}
|
|
239
245
|
|
|
240
246
|
export enum DataCubeColumnPinPlacement {
|
|
@@ -281,6 +287,7 @@ export function ofDataType(
|
|
|
281
287
|
}
|
|
282
288
|
|
|
283
289
|
export const PIVOT_COLUMN_NAME_VALUE_SEPARATOR = '__|__';
|
|
290
|
+
|
|
284
291
|
export function isPivotResultColumnName(columnName: string) {
|
|
285
292
|
return columnName.includes(PIVOT_COLUMN_NAME_VALUE_SEPARATOR);
|
|
286
293
|
}
|
|
@@ -296,10 +303,13 @@ export function getPivotResultColumnBaseColumnName(columnName: string) {
|
|
|
296
303
|
);
|
|
297
304
|
}
|
|
298
305
|
|
|
306
|
+
export const TREE_COLUMN_VALUE_SEPARATOR = '__/__';
|
|
299
307
|
export const DEFAULT_LAMBDA_VARIABLE_NAME = 'x';
|
|
300
308
|
|
|
301
309
|
export const DEFAULT_REPORT_NAME = 'New Report';
|
|
302
|
-
export const
|
|
310
|
+
export const DEFAULT_TREE_COLUMN_SORT_DIRECTION =
|
|
311
|
+
DataCubeQuerySortDirection.ASCENDING;
|
|
312
|
+
export const DEFAULT_PIVOT_STATISTIC_COLUMN_NAME = 'Total';
|
|
303
313
|
|
|
304
314
|
export const DEFAULT_URL_LABEL_QUERY_PARAM = 'dataCube.linkLabel';
|
|
305
315
|
export const DEFAULT_MISSING_VALUE_DISPLAY_TEXT = '';
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
} from './DataCubeQuerySnapshot.js';
|
|
41
41
|
import { assertType, guaranteeNonNullable } from '@finos/legend-shared';
|
|
42
42
|
import {
|
|
43
|
-
|
|
43
|
+
DataCubeQuerySortDirection,
|
|
44
44
|
DataCubeFunction,
|
|
45
45
|
type DataCubeQueryFunctionMap,
|
|
46
46
|
} from './DataCubeQueryEngine.js';
|
|
@@ -83,57 +83,124 @@ type FunctionSequenceCompositionGroupNodePattern =
|
|
|
83
83
|
funcs: FunctionSequenceCompositionSimpleNodePattern[];
|
|
84
84
|
};
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
86
|
+
enum _FUNCTION_SEQUENCE_COMPOSITION_PART {
|
|
87
|
+
LEAF_EXTEND = 'leaf_extend',
|
|
88
|
+
FILTER = 'filter',
|
|
89
|
+
SELECT = 'select',
|
|
90
|
+
PIVOT__GROUP = 'pivot__group',
|
|
91
|
+
PIVOT_SORT = 'pivot_sort',
|
|
92
|
+
PIVOT = 'pivot',
|
|
93
|
+
PIVOT_CAST = 'pivot_cast',
|
|
94
|
+
GROUP_BY__GROUP = 'group_by__group',
|
|
95
|
+
GROUP_BY = 'group_by',
|
|
96
|
+
GROUP_BY_SORT = 'group_by_sort',
|
|
97
|
+
GROUP_EXTEND = 'group_extend',
|
|
98
|
+
SORT = 'sort',
|
|
99
|
+
LIMIT = 'limit',
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// This corresponds to the function sequence that we currently support:
|
|
103
|
+
//
|
|
104
|
+
// -> extend()
|
|
105
|
+
// ->filter()
|
|
106
|
+
// ->select()
|
|
107
|
+
// ->sort()->pivot()->cast()
|
|
108
|
+
// ->groupBy()->sort()
|
|
109
|
+
// ->extend()
|
|
110
|
+
// ->sort()
|
|
111
|
+
// ->limit()
|
|
112
|
+
//
|
|
89
113
|
const _FUNCTION_SEQUENCE_COMPOSITION_PATTERN: (
|
|
90
114
|
| FunctionSequenceCompositionSimpleNodePattern
|
|
91
115
|
| FunctionSequenceCompositionGroupNodePattern
|
|
92
116
|
)[] = [
|
|
93
|
-
{ name: 'leaf_extend', func: DataCubeFunction.EXTEND }, // leaf-level extend
|
|
94
|
-
{ name: 'filter', func: DataCubeFunction.FILTER },
|
|
95
|
-
{ name: 'select', func: DataCubeFunction.SELECT },
|
|
96
117
|
{
|
|
97
|
-
|
|
118
|
+
// leaf-level extend
|
|
119
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.LEAF_EXTEND,
|
|
120
|
+
func: DataCubeFunction.EXTEND,
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.FILTER,
|
|
124
|
+
func: DataCubeFunction.FILTER,
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.SELECT,
|
|
128
|
+
func: DataCubeFunction.SELECT,
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT__GROUP,
|
|
132
|
+
funcs: [
|
|
133
|
+
{
|
|
134
|
+
// sort to ensure stable column ordering
|
|
135
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_SORT,
|
|
136
|
+
func: DataCubeFunction.SORT,
|
|
137
|
+
required: true,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT,
|
|
141
|
+
func: DataCubeFunction.PIVOT,
|
|
142
|
+
required: true,
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
// cast to a relation type post pivot() to enable type-checking
|
|
146
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST,
|
|
147
|
+
func: DataCubeFunction.CAST,
|
|
148
|
+
required: true,
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY__GROUP,
|
|
98
154
|
funcs: [
|
|
99
|
-
{
|
|
100
|
-
|
|
101
|
-
|
|
155
|
+
{
|
|
156
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY,
|
|
157
|
+
func: DataCubeFunction.GROUP_BY,
|
|
158
|
+
required: true,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
// sort to ensure stable row ordering
|
|
162
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY_SORT,
|
|
163
|
+
func: DataCubeFunction.SORT,
|
|
164
|
+
required: true,
|
|
165
|
+
},
|
|
102
166
|
],
|
|
103
167
|
},
|
|
104
|
-
{
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
168
|
+
{
|
|
169
|
+
// group-level extend
|
|
170
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_EXTEND,
|
|
171
|
+
func: DataCubeFunction.EXTEND,
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.SORT,
|
|
175
|
+
func: DataCubeFunction.SORT,
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: _FUNCTION_SEQUENCE_COMPOSITION_PART.LIMIT,
|
|
179
|
+
func: DataCubeFunction.LIMIT,
|
|
180
|
+
},
|
|
108
181
|
];
|
|
109
182
|
const _FUNCTION_SEQUENCE_COMPOSITION_PATTERN_REGEXP = new RegExp(
|
|
110
183
|
`^${_FUNCTION_SEQUENCE_COMPOSITION_PATTERN
|
|
111
184
|
.map((node) =>
|
|
112
185
|
'funcs' in node
|
|
113
|
-
? `(${node.funcs
|
|
114
|
-
(
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
186
|
+
? `(${node.funcs
|
|
187
|
+
.map(
|
|
188
|
+
(childNode) =>
|
|
189
|
+
`(?<${childNode.name}><${_name(childNode.func)}>____\\d+)${childNode.repeat ? '*' : !childNode.required ? '?' : ''}`,
|
|
190
|
+
)
|
|
191
|
+
.join('')})${node.repeat ? '*' : !node.required ? '?' : ''}`
|
|
192
|
+
: `(?<${node.name}><${_name(node.func)}>____\\d+)${node.repeat ? '*' : !node.required ? '?' : ''}`,
|
|
118
193
|
)
|
|
119
194
|
.join('')}$`,
|
|
120
195
|
);
|
|
121
196
|
|
|
122
|
-
type FunctionSequenceMatchingResult = {
|
|
123
|
-
sequence: V1_AppliedFunction[];
|
|
124
|
-
leafExtend: boolean;
|
|
125
|
-
pivot: boolean;
|
|
126
|
-
groupExtend: boolean;
|
|
127
|
-
sort: boolean;
|
|
128
|
-
};
|
|
129
197
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* do various basic checks for the validity, composition, and order of those functions.
|
|
198
|
+
* Turn the function sequence into a map of available functions
|
|
199
|
+
* for easier construction of the snapshot
|
|
133
200
|
*/
|
|
134
|
-
function
|
|
201
|
+
function extractFunctionMap(
|
|
135
202
|
query: V1_ValueSpecification,
|
|
136
|
-
):
|
|
203
|
+
): DataCubeQueryFunctionMap {
|
|
137
204
|
// Make sure this is a sequence of function calls
|
|
138
205
|
if (!(query instanceof V1_AppliedFunction)) {
|
|
139
206
|
throw new Error(
|
|
@@ -169,7 +236,7 @@ function extractQueryFunctionSequence(
|
|
|
169
236
|
|
|
170
237
|
// Check that sequence follows the supported pattern
|
|
171
238
|
const sequenceFormText = sequence
|
|
172
|
-
.map((func) => `<${_name(func.function)}
|
|
239
|
+
.map((func, idx) => `<${_name(func.function)}>____${idx}`)
|
|
173
240
|
.join('');
|
|
174
241
|
const matchResult = sequenceFormText.match(
|
|
175
242
|
_FUNCTION_SEQUENCE_COMPOSITION_PATTERN_REGEXP,
|
|
@@ -180,83 +247,30 @@ function extractQueryFunctionSequence(
|
|
|
180
247
|
);
|
|
181
248
|
}
|
|
182
249
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
250
|
+
const _process = (key: string): V1_AppliedFunction | undefined => {
|
|
251
|
+
const match = matchResult.groups?.[key];
|
|
252
|
+
if (!match || match.indexOf('____') === -1) {
|
|
253
|
+
return undefined;
|
|
254
|
+
}
|
|
255
|
+
const idx = Number(match.split('____')[1]);
|
|
256
|
+
if (isNaN(idx) || idx >= sequence.length) {
|
|
257
|
+
return undefined;
|
|
258
|
+
}
|
|
259
|
+
return sequence[idx];
|
|
189
260
|
};
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Turn the function sequence into a map of available functions
|
|
194
|
-
* for easier construction of the snapshot
|
|
195
|
-
*/
|
|
196
|
-
function extractFunctionMap(
|
|
197
|
-
sequenceMatchingResult: FunctionSequenceMatchingResult,
|
|
198
|
-
): DataCubeQueryFunctionMap {
|
|
199
|
-
const {
|
|
200
|
-
sequence,
|
|
201
|
-
leafExtend: hasLeafExtend,
|
|
202
|
-
groupExtend: hasGroupExtend,
|
|
203
|
-
pivot: hasPivot,
|
|
204
|
-
sort: hasSort,
|
|
205
|
-
} = sequenceMatchingResult;
|
|
206
|
-
const leafExtend = hasLeafExtend
|
|
207
|
-
? sequence.find((func) =>
|
|
208
|
-
matchFunctionName(func.function, DataCubeFunction.EXTEND),
|
|
209
|
-
)
|
|
210
|
-
: undefined;
|
|
211
|
-
const filter = sequence.find((func) =>
|
|
212
|
-
matchFunctionName(func.function, DataCubeFunction.FILTER),
|
|
213
|
-
);
|
|
214
|
-
const select = sequence.find((func) =>
|
|
215
|
-
matchFunctionName(func.function, DataCubeFunction.SELECT),
|
|
216
|
-
);
|
|
217
|
-
const pivotSort = hasPivot
|
|
218
|
-
? sequence.find((func) =>
|
|
219
|
-
matchFunctionName(func.function, DataCubeFunction.SORT),
|
|
220
|
-
)
|
|
221
|
-
: undefined;
|
|
222
|
-
const pivot = hasPivot
|
|
223
|
-
? sequence.find((func) =>
|
|
224
|
-
matchFunctionName(func.function, DataCubeFunction.PIVOT),
|
|
225
|
-
)
|
|
226
|
-
: undefined;
|
|
227
|
-
const pivotCast = hasPivot
|
|
228
|
-
? sequence.find((func) =>
|
|
229
|
-
matchFunctionName(func.function, DataCubeFunction.CAST),
|
|
230
|
-
)
|
|
231
|
-
: undefined;
|
|
232
|
-
const groupBy = sequence.find((func) =>
|
|
233
|
-
matchFunctionName(func.function, DataCubeFunction.GROUP_BY),
|
|
234
|
-
);
|
|
235
|
-
const groupExtend = hasGroupExtend
|
|
236
|
-
? sequence.find((func) =>
|
|
237
|
-
matchFunctionName(func.function, DataCubeFunction.EXTEND),
|
|
238
|
-
)
|
|
239
|
-
: undefined;
|
|
240
|
-
const sort = hasSort
|
|
241
|
-
? sequence.find((func) =>
|
|
242
|
-
matchFunctionName(func.function, DataCubeFunction.SORT),
|
|
243
|
-
)
|
|
244
|
-
: undefined;
|
|
245
|
-
const limit = sequence.find((func) =>
|
|
246
|
-
matchFunctionName(func.function, DataCubeFunction.LIMIT),
|
|
247
|
-
);
|
|
248
261
|
|
|
249
262
|
return {
|
|
250
|
-
leafExtend:
|
|
251
|
-
select,
|
|
252
|
-
filter,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
263
|
+
leafExtend: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.LEAF_EXTEND),
|
|
264
|
+
select: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SELECT),
|
|
265
|
+
filter: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.FILTER),
|
|
266
|
+
pivotSort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_SORT),
|
|
267
|
+
pivot: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST),
|
|
268
|
+
pivotCast: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.PIVOT_CAST),
|
|
269
|
+
groupBy: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY),
|
|
270
|
+
groupBySort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_BY_SORT),
|
|
271
|
+
groupExtend: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.GROUP_EXTEND),
|
|
272
|
+
sort: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.SORT),
|
|
273
|
+
limit: _process(_FUNCTION_SEQUENCE_COMPOSITION_PART.LIMIT),
|
|
260
274
|
};
|
|
261
275
|
}
|
|
262
276
|
|
|
@@ -277,8 +291,7 @@ export function validateAndBuildQuerySnapshot(
|
|
|
277
291
|
// Build the function call sequence and the function map to make the
|
|
278
292
|
// analysis more ergonomic
|
|
279
293
|
|
|
280
|
-
const
|
|
281
|
-
const funcMap = extractFunctionMap(sequenceMatchingResult);
|
|
294
|
+
const funcMap = extractFunctionMap(partialQuery);
|
|
282
295
|
const snapshot = DataCubeQuerySnapshot.create(
|
|
283
296
|
baseQuery.name,
|
|
284
297
|
baseQuery.source.runtime,
|
|
@@ -321,7 +334,7 @@ export function validateAndBuildQuerySnapshot(
|
|
|
321
334
|
|
|
322
335
|
// --------------------------------- PIVOT ---------------------------------
|
|
323
336
|
/** TODO: @datacube roundtrip */
|
|
324
|
-
// TODO: verify
|
|
337
|
+
// TODO: verify groupBy agg columns, pivot agg columns and configuration agree
|
|
325
338
|
|
|
326
339
|
// --------------------------------- GROUP BY ---------------------------------
|
|
327
340
|
|
|
@@ -330,7 +343,8 @@ export function validateAndBuildQuerySnapshot(
|
|
|
330
343
|
columns: _colSpecArrayParam(funcMap.groupBy, 0).colSpecs.map((colSpec) =>
|
|
331
344
|
_col(colSpec),
|
|
332
345
|
),
|
|
333
|
-
// TODO: verify
|
|
346
|
+
// TODO: verify groupBy agg columns, pivot agg columns and configuration agree
|
|
347
|
+
// TODO: verify groupBy sort columns and configuration agree
|
|
334
348
|
};
|
|
335
349
|
}
|
|
336
350
|
|
|
@@ -348,10 +362,10 @@ export function validateAndBuildQuerySnapshot(
|
|
|
348
362
|
]);
|
|
349
363
|
return {
|
|
350
364
|
..._col(_colSpecParam(sortColFunc, 0)),
|
|
351
|
-
|
|
365
|
+
direction:
|
|
352
366
|
_name(sortColFunc.function) === DataCubeFunction.ASC
|
|
353
|
-
?
|
|
354
|
-
:
|
|
367
|
+
? DataCubeQuerySortDirection.ASCENDING
|
|
368
|
+
: DataCubeQuerySortDirection.DESCENDING,
|
|
355
369
|
};
|
|
356
370
|
},
|
|
357
371
|
);
|
|
@@ -394,12 +408,13 @@ export function validateAndBuildQuerySnapshot(
|
|
|
394
408
|
DataCubeConfiguration.serialization.toJson(configuration);
|
|
395
409
|
/**
|
|
396
410
|
* TODO: @datacube roundtrip - implement the logic to reconcile the configuration with the query
|
|
397
|
-
* - columns (missing/extra columns - remove or generate default column configuration)
|
|
398
|
-
* - column kind
|
|
399
|
-
* - column type
|
|
400
|
-
* - base off the type, check the settings
|
|
401
|
-
* - aggregation
|
|
402
|
-
* - verify
|
|
411
|
+
* - [ ] columns (missing/extra columns - remove or generate default column configuration)
|
|
412
|
+
* - [ ] column kind
|
|
413
|
+
* - [ ] column type
|
|
414
|
+
* - [ ] base off the type, check the settings
|
|
415
|
+
* - [ ] aggregation
|
|
416
|
+
* - [ ] verify groupBy agg columns, pivot agg columns and configuration agree
|
|
417
|
+
* - [ ] verify groupBy sort columns and tree column sort direction configuration agree
|
|
403
418
|
*/
|
|
404
419
|
|
|
405
420
|
return snapshot.finalize();
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
V1_ClassInstance,
|
|
20
20
|
V1_ColSpec,
|
|
21
21
|
V1_ColSpecArray,
|
|
22
|
-
V1_Lambda,
|
|
23
22
|
extractElementNameFromPath as _name,
|
|
24
23
|
matchFunctionName,
|
|
25
24
|
type V1_ValueSpecification,
|
|
@@ -28,14 +27,11 @@ import { type DataCubeQuerySnapshotColumn } from './DataCubeQuerySnapshot.js';
|
|
|
28
27
|
import {
|
|
29
28
|
assertTrue,
|
|
30
29
|
assertType,
|
|
30
|
+
guaranteeNonNullable,
|
|
31
31
|
guaranteeType,
|
|
32
|
-
UnsupportedOperationError,
|
|
33
32
|
type Clazz,
|
|
34
33
|
} from '@finos/legend-shared';
|
|
35
|
-
import {
|
|
36
|
-
DataCubeFunction,
|
|
37
|
-
DataCubeAggregateOperator,
|
|
38
|
-
} from './DataCubeQueryEngine.js';
|
|
34
|
+
import { TREE_COLUMN_VALUE_SEPARATOR } from './DataCubeQueryEngine.js';
|
|
39
35
|
|
|
40
36
|
// --------------------------------- UTILITIES ---------------------------------
|
|
41
37
|
|
|
@@ -90,108 +86,38 @@ export function _funcMatch(
|
|
|
90
86
|
return value;
|
|
91
87
|
}
|
|
92
88
|
|
|
93
|
-
//
|
|
94
|
-
// similar to what we did with filter
|
|
95
|
-
function _aggFuncMatch(
|
|
96
|
-
value: V1_ValueSpecification | undefined,
|
|
97
|
-
functionNames: string | string[],
|
|
98
|
-
) {
|
|
99
|
-
assertType(
|
|
100
|
-
value,
|
|
101
|
-
V1_Lambda,
|
|
102
|
-
`Can't process aggregation: Found unexpected value specification type`,
|
|
103
|
-
);
|
|
104
|
-
return _funcMatch(value.body[0], functionNames);
|
|
105
|
-
}
|
|
89
|
+
// --------------------------------- BUILDING BLOCKS ---------------------------------
|
|
106
90
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
91
|
+
/**
|
|
92
|
+
* This method prunes expanded paths that are no longer valid due to changes in group by columns.
|
|
93
|
+
* It finds the last common group by column between the previous and current group by columns and
|
|
94
|
+
* prune the expanded paths beyond that point.
|
|
95
|
+
*/
|
|
96
|
+
export function _pruneExpandedPaths(
|
|
97
|
+
prevGroupByCols: DataCubeQuerySnapshotColumn[],
|
|
98
|
+
currentGroupByCols: DataCubeQuerySnapshotColumn[],
|
|
99
|
+
expandedPaths: string[],
|
|
110
100
|
) {
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
};
|
|
127
|
-
} else if (matchFunctionName(func.function, DataCubeFunction.AVERAGE)) {
|
|
128
|
-
return {
|
|
129
|
-
...column,
|
|
130
|
-
operation: DataCubeAggregateOperator.AVERAGE,
|
|
131
|
-
parameters: [],
|
|
132
|
-
};
|
|
133
|
-
} else if (matchFunctionName(func.function, DataCubeFunction.MIN)) {
|
|
134
|
-
return {
|
|
135
|
-
...column,
|
|
136
|
-
operation: DataCubeAggregateOperator.MIN,
|
|
137
|
-
parameters: [],
|
|
138
|
-
};
|
|
139
|
-
} else if (matchFunctionName(func.function, DataCubeFunction.MAX)) {
|
|
140
|
-
return {
|
|
141
|
-
...column,
|
|
142
|
-
operation: DataCubeAggregateOperator.MAX,
|
|
143
|
-
parameters: [],
|
|
144
|
-
};
|
|
145
|
-
} else if (matchFunctionName(func.function, DataCubeFunction.FIRST)) {
|
|
146
|
-
return {
|
|
147
|
-
...column,
|
|
148
|
-
operation: DataCubeAggregateOperator.FIRST,
|
|
149
|
-
parameters: [],
|
|
150
|
-
};
|
|
151
|
-
} else if (matchFunctionName(func.function, DataCubeFunction.LAST)) {
|
|
152
|
-
return {
|
|
153
|
-
...column,
|
|
154
|
-
operation: DataCubeAggregateOperator.LAST,
|
|
155
|
-
parameters: [],
|
|
156
|
-
};
|
|
157
|
-
} else if (
|
|
158
|
-
matchFunctionName(func.function, DataCubeFunction.VARIANCE_POPULATION)
|
|
159
|
-
) {
|
|
160
|
-
return {
|
|
161
|
-
...column,
|
|
162
|
-
operation: DataCubeAggregateOperator.VARIANCE_POPULATION,
|
|
163
|
-
parameters: [],
|
|
164
|
-
};
|
|
165
|
-
} else if (
|
|
166
|
-
matchFunctionName(func.function, DataCubeFunction.VARIANCE_SAMPLE)
|
|
167
|
-
) {
|
|
168
|
-
return {
|
|
169
|
-
...column,
|
|
170
|
-
operation: DataCubeAggregateOperator.VARIANCE_SAMPLE,
|
|
171
|
-
parameters: [],
|
|
172
|
-
};
|
|
173
|
-
} else if (
|
|
174
|
-
matchFunctionName(
|
|
175
|
-
func.function,
|
|
176
|
-
DataCubeFunction.STANDARD_DEVIATION_POPULATION,
|
|
177
|
-
)
|
|
178
|
-
) {
|
|
179
|
-
return {
|
|
180
|
-
...column,
|
|
181
|
-
operation: DataCubeAggregateOperator.STANDARD_DEVIATION_POPULATION,
|
|
182
|
-
parameters: [],
|
|
183
|
-
};
|
|
184
|
-
} else if (
|
|
185
|
-
matchFunctionName(func.function, DataCubeFunction.STANDARD_DEVIATION_SAMPLE)
|
|
186
|
-
) {
|
|
187
|
-
return {
|
|
188
|
-
...column,
|
|
189
|
-
operation: DataCubeAggregateOperator.STANDARD_DEVIATION_SAMPLE,
|
|
190
|
-
parameters: [],
|
|
191
|
-
};
|
|
192
|
-
} else {
|
|
193
|
-
throw new UnsupportedOperationError(
|
|
194
|
-
`Unsupported aggregate function '${func.function}'`,
|
|
195
|
-
);
|
|
101
|
+
const length = Math.min(prevGroupByCols.length, currentGroupByCols.length);
|
|
102
|
+
if (!length) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
let lastCommonIndex = -1;
|
|
106
|
+
for (let i = 0; i < length; i++) {
|
|
107
|
+
if (
|
|
108
|
+
guaranteeNonNullable(prevGroupByCols[i]).name !==
|
|
109
|
+
guaranteeNonNullable(currentGroupByCols[i]).name ||
|
|
110
|
+
guaranteeNonNullable(prevGroupByCols[i]).type !==
|
|
111
|
+
guaranteeNonNullable(currentGroupByCols[i]).type
|
|
112
|
+
) {
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
lastCommonIndex = i;
|
|
196
116
|
}
|
|
117
|
+
return expandedPaths
|
|
118
|
+
.filter(
|
|
119
|
+
(path) =>
|
|
120
|
+
path.split(TREE_COLUMN_VALUE_SEPARATOR).length <= lastCommonIndex + 1,
|
|
121
|
+
)
|
|
122
|
+
.sort();
|
|
197
123
|
}
|
|
@@ -63,7 +63,7 @@ export abstract class DataCubeQuerySnapshotController
|
|
|
63
63
|
'\nPrevious Snapshot',
|
|
64
64
|
this.latestSnapshot ?? {},
|
|
65
65
|
'\nDiff',
|
|
66
|
-
deepDiff(
|
|
66
|
+
deepDiff(this.latestSnapshot ?? {}, snapshot),
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
this.latestSnapshot = snapshot;
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { action, makeObservable, observable } from 'mobx';
|
|
18
18
|
import type { DataCubeViewState } from '../DataCubeViewState.js';
|
|
19
|
-
import type
|
|
19
|
+
import { type DataCubeQuerySnapshot } from '../core/DataCubeQuerySnapshot.js';
|
|
20
20
|
import type { DataCubeQueryEditorPanelState } from './DataCubeEditorPanelState.js';
|
|
21
21
|
import type { DataCubeEditorState } from './DataCubeEditorState.js';
|
|
22
22
|
import { DataCubeEditorMutableConfiguration } from './DataCubeEditorMutableConfiguration.js';
|
|
@@ -34,14 +34,15 @@ export class DataCubeEditorGeneralPropertiesPanelState
|
|
|
34
34
|
|
|
35
35
|
constructor(editor: DataCubeEditorState) {
|
|
36
36
|
makeObservable(this, {
|
|
37
|
+
configuration: observable,
|
|
38
|
+
|
|
37
39
|
name: observable,
|
|
38
40
|
setName: action,
|
|
39
41
|
|
|
40
42
|
limit: observable,
|
|
41
43
|
setLimit: action,
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
setConfiguration: action,
|
|
45
|
+
applySnaphot: action,
|
|
45
46
|
});
|
|
46
47
|
|
|
47
48
|
this.editor = editor;
|
|
@@ -56,10 +57,6 @@ export class DataCubeEditorGeneralPropertiesPanelState
|
|
|
56
57
|
this.limit = val;
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
setConfiguration(val: DataCubeEditorMutableConfiguration) {
|
|
60
|
-
this.configuration = val;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
60
|
applySnaphot(
|
|
64
61
|
snapshot: DataCubeQuerySnapshot,
|
|
65
62
|
configuration: DataCubeConfiguration,
|
|
@@ -70,8 +67,8 @@ export class DataCubeEditorGeneralPropertiesPanelState
|
|
|
70
67
|
? snapshot.data.limit
|
|
71
68
|
: -1,
|
|
72
69
|
);
|
|
73
|
-
this.
|
|
74
|
-
|
|
70
|
+
this.configuration = DataCubeEditorMutableConfiguration.create(
|
|
71
|
+
snapshot.data.configuration,
|
|
75
72
|
);
|
|
76
73
|
}
|
|
77
74
|
|