@finos/legend-data-cube 0.0.48 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/lib/components/view/grid/DataCubeGrid.d.ts.map +1 -1
  2. package/lib/components/view/grid/DataCubeGrid.js +23 -2
  3. package/lib/components/view/grid/DataCubeGrid.js.map +1 -1
  4. package/lib/index.css +1 -1
  5. package/lib/index.d.ts +3 -2
  6. package/lib/index.d.ts.map +1 -1
  7. package/lib/index.js +5 -2
  8. package/lib/index.js.map +1 -1
  9. package/lib/package.json +3 -3
  10. package/lib/stores/DataCubeAPI.d.ts +6 -0
  11. package/lib/stores/DataCubeAPI.d.ts.map +1 -1
  12. package/lib/stores/DataCubeAPI.js +3 -0
  13. package/lib/stores/DataCubeAPI.js.map +1 -1
  14. package/lib/stores/DataCubeOptions.d.ts +4 -0
  15. package/lib/stores/DataCubeOptions.d.ts.map +1 -1
  16. package/lib/stores/core/DataCubeConfigurationBuilder.js +1 -1
  17. package/lib/stores/core/DataCubeConfigurationBuilder.js.map +1 -1
  18. package/lib/stores/core/DataCubeEngine.d.ts +11 -3
  19. package/lib/stores/core/DataCubeEngine.d.ts.map +1 -1
  20. package/lib/stores/core/DataCubeEngine.js +34 -3
  21. package/lib/stores/core/DataCubeEngine.js.map +1 -1
  22. package/lib/stores/core/DataCubeQueryBuilder.d.ts +3 -4
  23. package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
  24. package/lib/stores/core/DataCubeQueryBuilder.js +19 -13
  25. package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
  26. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts +2 -7
  27. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
  28. package/lib/stores/core/DataCubeQueryBuilderUtils.js +34 -46
  29. package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
  30. package/lib/stores/core/DataCubeQuerySnapshot.d.ts +11 -4
  31. package/lib/stores/core/DataCubeQuerySnapshot.d.ts.map +1 -1
  32. package/lib/stores/core/DataCubeQuerySnapshot.js +10 -0
  33. package/lib/stores/core/DataCubeQuerySnapshot.js.map +1 -1
  34. package/lib/stores/core/DataCubeQuerySnapshotBuilder.d.ts.map +1 -1
  35. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js +1 -2
  36. package/lib/stores/core/DataCubeQuerySnapshotBuilder.js.map +1 -1
  37. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.d.ts.map +1 -1
  38. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js +3 -3
  39. package/lib/stores/core/DataCubeQuerySnapshotBuilderUtils.js.map +1 -1
  40. package/lib/stores/core/model/CachedDataCubeSource.d.ts +27 -0
  41. package/lib/stores/core/model/CachedDataCubeSource.d.ts.map +1 -0
  42. package/lib/stores/core/model/CachedDataCubeSource.js +26 -0
  43. package/lib/stores/core/model/CachedDataCubeSource.js.map +1 -0
  44. package/lib/stores/services/DataCubeQuerySnapshotService.js +1 -1
  45. package/lib/stores/services/DataCubeQuerySnapshotService.js.map +1 -1
  46. package/lib/stores/services/DataCubeTaskService.d.ts.map +1 -1
  47. package/lib/stores/services/DataCubeTaskService.js +2 -0
  48. package/lib/stores/services/DataCubeTaskService.js.map +1 -1
  49. package/lib/stores/view/DataCubeViewState.d.ts +5 -0
  50. package/lib/stores/view/DataCubeViewState.d.ts.map +1 -1
  51. package/lib/stores/view/DataCubeViewState.js +52 -9
  52. package/lib/stores/view/DataCubeViewState.js.map +1 -1
  53. package/lib/stores/view/extend/DataCubeColumnEditorState.d.ts.map +1 -1
  54. package/lib/stores/view/extend/DataCubeColumnEditorState.js +7 -5
  55. package/lib/stores/view/extend/DataCubeColumnEditorState.js.map +1 -1
  56. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts +1 -0
  57. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  58. package/lib/stores/view/grid/DataCubeGridClientEngine.js +9 -5
  59. package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
  60. package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts +3 -4
  61. package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
  62. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +5 -5
  63. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js.map +1 -1
  64. package/lib/stores/view/grid/DataCubeGridState.d.ts +2 -0
  65. package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
  66. package/lib/stores/view/grid/DataCubeGridState.js +28 -2
  67. package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
  68. package/package.json +8 -8
  69. package/src/components/view/grid/DataCubeGrid.tsx +44 -1
  70. package/src/index.tsx +10 -2
  71. package/src/stores/DataCubeAPI.ts +9 -0
  72. package/src/stores/DataCubeOptions.ts +4 -0
  73. package/src/stores/core/DataCubeConfigurationBuilder.ts +1 -1
  74. package/src/stores/core/DataCubeEngine.tsx +51 -11
  75. package/src/stores/core/DataCubeQueryBuilder.ts +38 -30
  76. package/src/stores/core/DataCubeQueryBuilderUtils.ts +42 -67
  77. package/src/stores/core/DataCubeQuerySnapshot.ts +15 -4
  78. package/src/stores/core/DataCubeQuerySnapshotBuilder.ts +2 -6
  79. package/src/stores/core/DataCubeQuerySnapshotBuilderUtils.ts +2 -3
  80. package/src/stores/core/model/CachedDataCubeSource.ts +29 -0
  81. package/src/stores/services/DataCubeQuerySnapshotService.ts +2 -2
  82. package/src/stores/services/DataCubeTaskService.ts +2 -0
  83. package/src/stores/view/DataCubeViewState.ts +54 -17
  84. package/src/stores/view/extend/DataCubeColumnEditorState.tsx +7 -15
  85. package/src/stores/view/grid/DataCubeGridClientEngine.ts +22 -26
  86. package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +19 -32
  87. package/src/stores/view/grid/DataCubeGridState.ts +35 -1
  88. package/tsconfig.json +1 -0
@@ -43,7 +43,6 @@ import {
43
43
  V1_PackageableElementPtr,
44
44
  type V1_PrimitiveValueSpecification,
45
45
  V1_Variable,
46
- V1_deserializeValueSpecification,
47
46
  extractElementNameFromPath,
48
47
  type V1_ValueSpecification,
49
48
  extractPackagePathFromPath,
@@ -53,7 +52,6 @@ import {
53
52
  V1_createGenericTypeWithRawType,
54
53
  V1_createRelationType,
55
54
  V1_createRelationTypeColumn,
56
- V1_serializeValueSpecification,
57
55
  } from '@finos/legend-graph';
58
56
  import {
59
57
  type DataCubeQuerySnapshotFilterCondition,
@@ -67,8 +65,6 @@ import {
67
65
  guaranteeIsBoolean,
68
66
  guaranteeIsNumber,
69
67
  UnsupportedOperationError,
70
- guaranteeType,
71
- type PlainObject,
72
68
  } from '@finos/legend-shared';
73
69
  import {
74
70
  DataCubeFunction,
@@ -91,69 +87,6 @@ import {
91
87
 
92
88
  // --------------------------------- UTILITIES ---------------------------------
93
89
 
94
- export function _functionCompositionProcessor(
95
- sequence: V1_AppliedFunction[],
96
- funcMap: DataCubeQueryFunctionMap,
97
- ) {
98
- return (
99
- key: keyof DataCubeQueryFunctionMap,
100
- data: V1_AppliedFunction | V1_AppliedFunction[],
101
- ) => {
102
- switch (key) {
103
- case 'leafExtend':
104
- case 'groupExtend': {
105
- if (Array.isArray(data)) {
106
- data.forEach((func) => sequence.push(func));
107
- funcMap[key] = data;
108
- }
109
- break;
110
- }
111
- default: {
112
- funcMap[key] = data as V1_AppliedFunction;
113
- sequence.push(data as V1_AppliedFunction);
114
- }
115
- }
116
- };
117
- }
118
-
119
- export function _functionCompositionUnProcessor(
120
- sequence: V1_AppliedFunction[],
121
- funcMap: DataCubeQueryFunctionMap,
122
- ) {
123
- return (key: keyof DataCubeQueryFunctionMap) => {
124
- const data = funcMap[key];
125
- if (data) {
126
- if (Array.isArray(data)) {
127
- data.forEach((func) => sequence.splice(sequence.indexOf(func), 1));
128
- } else {
129
- sequence.splice(sequence.indexOf(data), 1);
130
- }
131
- funcMap[key] = undefined;
132
- }
133
- };
134
- }
135
-
136
- export function _deserializeLambda(json: PlainObject<V1_Lambda>) {
137
- return guaranteeType(V1_deserializeValueSpecification(json, []), V1_Lambda);
138
- }
139
-
140
- export function _deserializeValueSpecification(
141
- json: PlainObject<V1_ValueSpecification>,
142
- ) {
143
- return V1_deserializeValueSpecification(json, []);
144
- }
145
-
146
- export function _serializeValueSpecification(protocol: V1_ValueSpecification) {
147
- return V1_serializeValueSpecification(protocol, []);
148
- }
149
-
150
- export function _deserializeFunction(json: PlainObject<V1_Lambda>) {
151
- return guaranteeType(
152
- V1_deserializeValueSpecification(json, []),
153
- V1_AppliedFunction,
154
- );
155
- }
156
-
157
90
  export function _var() {
158
91
  const variable = new V1_Variable();
159
92
  // NOTE: we simplify processing logic by forcing all variable names to default value, i.e. x
@@ -356,6 +289,48 @@ export function _cols(colSpecs: V1_ColSpec[]) {
356
289
 
357
290
  // --------------------------------- BUILDING BLOCKS ---------------------------------
358
291
 
292
+ export function _functionCompositionProcessor(
293
+ sequence: V1_AppliedFunction[],
294
+ funcMap: DataCubeQueryFunctionMap,
295
+ ) {
296
+ return (
297
+ key: keyof DataCubeQueryFunctionMap,
298
+ data: V1_AppliedFunction | V1_AppliedFunction[],
299
+ ) => {
300
+ switch (key) {
301
+ case 'leafExtend':
302
+ case 'groupExtend': {
303
+ if (Array.isArray(data)) {
304
+ data.forEach((func) => sequence.push(func));
305
+ funcMap[key] = data;
306
+ }
307
+ break;
308
+ }
309
+ default: {
310
+ funcMap[key] = data as V1_AppliedFunction;
311
+ sequence.push(data as V1_AppliedFunction);
312
+ }
313
+ }
314
+ };
315
+ }
316
+
317
+ export function _functionCompositionUnProcessor(
318
+ sequence: V1_AppliedFunction[],
319
+ funcMap: DataCubeQueryFunctionMap,
320
+ ) {
321
+ return (key: keyof DataCubeQueryFunctionMap) => {
322
+ const data = funcMap[key];
323
+ if (data) {
324
+ if (Array.isArray(data)) {
325
+ data.forEach((func) => sequence.splice(sequence.indexOf(func), 1));
326
+ } else {
327
+ sequence.splice(sequence.indexOf(data), 1);
328
+ }
329
+ funcMap[key] = undefined;
330
+ }
331
+ };
332
+ }
333
+
359
334
  export function _selectFunction(columns: DataCubeColumn[]) {
360
335
  return _function(DataCubeFunction.SELECT, [
361
336
  _cols(columns.map((col) => _colSpec(col.name))),
@@ -71,10 +71,10 @@ export type DataCubeQuerySnapshotPivot = {
71
71
 
72
72
  export type DataCubeQuerySnapshotProcessingContext = {
73
73
  snapshot: DataCubeQuerySnapshot;
74
- pivotAggColumns: DataCubeQuerySnapshotAggregateColumn[];
75
- pivotSortColumns: DataCubeQuerySnapshotSortColumn[];
76
- groupByAggColumns: DataCubeQuerySnapshotAggregateColumn[];
77
- groupBySortColumns: DataCubeQuerySnapshotSortColumn[];
74
+ pivotAggColumns?: DataCubeQuerySnapshotAggregateColumn[] | undefined;
75
+ pivotSortColumns?: DataCubeQuerySnapshotSortColumn[] | undefined;
76
+ groupByAggColumns?: DataCubeQuerySnapshotAggregateColumn[] | undefined;
77
+ groupBySortColumns?: DataCubeQuerySnapshotSortColumn[] | undefined;
78
78
  };
79
79
 
80
80
  export type DataCubeQuerySnapshotData = {
@@ -185,4 +185,15 @@ export class DataCubeQuerySnapshot {
185
185
  clone._hashCode = this._hashCode;
186
186
  return clone;
187
187
  }
188
+
189
+ serialize() {
190
+ const clone = this.clone();
191
+ return {
192
+ uuid: clone.uuid,
193
+ data: clone.data,
194
+ _isPatchChange: clone._isPatchChange,
195
+ _finalized: clone._finalized,
196
+ _hashCode: clone._hashCode,
197
+ };
198
+ }
188
199
  }
@@ -73,10 +73,6 @@ import {
73
73
  } from './DataCubeQuerySnapshotBuilderUtils.js';
74
74
  import type { DataCubeSource } from './model/DataCubeSource.js';
75
75
  import type { DataCubeEngine } from './DataCubeEngine.js';
76
- import {
77
- _deserializeValueSpecification,
78
- _serializeValueSpecification,
79
- } from './DataCubeQueryBuilderUtils.js';
80
76
 
81
77
  // --------------------------------- BUILDING BLOCKS ---------------------------------
82
78
 
@@ -365,8 +361,8 @@ export async function validateAndBuildQuerySnapshot(
365
361
  // analysis more ergonomic
366
362
 
367
363
  // Clone the query since we will mutate it during the process
368
- const query = _deserializeValueSpecification(
369
- _serializeValueSpecification(partialQuery),
364
+ const query = engine.deserializeValueSpecification(
365
+ engine.serializeValueSpecification(partialQuery),
370
366
  );
371
367
  const funcMap = extractFunctionMap(query);
372
368
  const snapshot = DataCubeQuerySnapshot.create({});
@@ -79,7 +79,6 @@ import {
79
79
  _colSpec,
80
80
  _function,
81
81
  _lambda,
82
- _serializeValueSpecification,
83
82
  _synthesizeMinimalSourceQuery,
84
83
  } from './DataCubeQueryBuilderUtils.js';
85
84
  import { INTERNAL__DataCubeSource } from './model/DataCubeSource.js';
@@ -360,14 +359,14 @@ export async function _extractExtendedColumns(
360
359
  _findCol(columns, colSpec.name),
361
360
  `Can't process extend() expression: failed to retrieve type information for column '${colSpec.name}'`,
362
361
  ).type,
363
- mapFn: _serializeValueSpecification(
362
+ mapFn: engine.serializeValueSpecification(
364
363
  guaranteeNonNullable(
365
364
  colSpec.function1,
366
365
  `Can't process extend() expression: expected a transformation function expression for column '${colSpec.name}'`,
367
366
  ),
368
367
  ),
369
368
  reduceFn: colSpec.function2
370
- ? _serializeValueSpecification(colSpec.function2)
369
+ ? engine.serializeValueSpecification(colSpec.function2)
371
370
  : undefined,
372
371
  }));
373
372
  }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type { V1_PureModelContextData } from '@finos/legend-graph';
18
+ import { DataCubeSource } from './DataCubeSource.js';
19
+
20
+ export const CACHED_DATA_CUBE_SOURCE_TYPE = 'cached';
21
+
22
+ export class CachedDataCubeSource extends DataCubeSource {
23
+ model!: V1_PureModelContextData;
24
+ runtime!: string;
25
+ db!: string;
26
+ schema!: string;
27
+ table!: string;
28
+ count!: number;
29
+ }
@@ -88,8 +88,8 @@ export abstract class DataCubeQuerySnapshotController
88
88
  this._engine.debugProcess(
89
89
  `New Snapshot`,
90
90
  ['Publisher', this.getSnapshotSubscriberName()],
91
- ['Snapshot', snapshot],
92
- ['Previous Snapshot', previousSnapshot],
91
+ ['Snapshot', snapshot.serialize()],
92
+ ['Previous Snapshot', previousSnapshot?.serialize()],
93
93
  ['Diff', deepDiff(previousSnapshot ?? {}, snapshot)],
94
94
  );
95
95
  }
@@ -20,6 +20,8 @@ import { action, computed, makeObservable, observable } from 'mobx';
20
20
  export class Task {
21
21
  readonly uuid = uuid();
22
22
  readonly name: string;
23
+ // use Date.now() vs. performance.now() because need to record the moment
24
+ // the task starts/ends for logging purposes.
23
25
  readonly startTime = Date.now();
24
26
  readonly ownerId?: string | undefined;
25
27
 
@@ -24,13 +24,6 @@ import {
24
24
  import { DataCubeQuerySnapshotService } from '../services/DataCubeQuerySnapshotService.js';
25
25
  import { DataCubeInfoState } from './DataCubeInfoState.js';
26
26
  import { validateAndBuildQuerySnapshot } from '../core/DataCubeQuerySnapshotBuilder.js';
27
- import {
28
- action,
29
- computed,
30
- makeObservable,
31
- observable,
32
- runInAction,
33
- } from 'mobx';
34
27
  import { DataCubeFilterEditorState } from './filter/DataCubeFilterEditorState.js';
35
28
  import { DataCubeExtendManagerState } from './extend/DataCubeExtendManagerState.js';
36
29
  import type { DataCubeState } from '../DataCubeState.js';
@@ -43,6 +36,7 @@ import { DataCubeConfiguration } from '../core/model/DataCubeConfiguration.js';
43
36
  import type { DataCubeLayoutService } from '../services/DataCubeLayoutService.js';
44
37
  import type { DataCubeAlertService } from '../services/DataCubeAlertService.js';
45
38
  import type { DataCubeSettingService } from '../services/DataCubeSettingService.js';
39
+ import { CachedDataCubeSource } from '../core/model/CachedDataCubeSource.js';
46
40
 
47
41
  export class DataCubeViewState {
48
42
  readonly dataCube: DataCubeState;
@@ -61,17 +55,12 @@ export class DataCubeViewState {
61
55
  readonly extend: DataCubeExtendManagerState;
62
56
 
63
57
  readonly initializeState = ActionState.create();
58
+ readonly processCacheState = ActionState.create();
64
59
 
65
60
  private _source?: DataCubeSource | undefined;
61
+ private _originalSource?: DataCubeSource | undefined;
66
62
 
67
63
  constructor(dataCube: DataCubeState) {
68
- makeObservable<DataCubeViewState, '_source'>(this, {
69
- _source: observable,
70
- source: computed,
71
-
72
- initialize: action,
73
- });
74
-
75
64
  this.dataCube = dataCube;
76
65
  this.engine = dataCube.engine;
77
66
  this.logService = dataCube.logService;
@@ -92,6 +81,10 @@ export class DataCubeViewState {
92
81
  this.extend = new DataCubeExtendManagerState(this);
93
82
  }
94
83
 
84
+ getOriginalSource() {
85
+ return this._originalSource;
86
+ }
87
+
95
88
  async generateDataCubeQuery() {
96
89
  const snapshot = this.snapshotService.currentSnapshot;
97
90
  const query = new DataCubeQuery();
@@ -110,6 +103,51 @@ export class DataCubeViewState {
110
103
  return this._source;
111
104
  }
112
105
 
106
+ async initializeCache() {
107
+ this.processCacheState.inProgress();
108
+ const task = this.taskService.newTask('Initializing Cache');
109
+
110
+ try {
111
+ const cachedSource = await this.engine.initializeCache(this.source);
112
+ if (cachedSource) {
113
+ this._source = cachedSource;
114
+ }
115
+ this.processCacheState.pass();
116
+ } catch (error) {
117
+ assertErrorThrown(error);
118
+ this.alertService.alertError(error, {
119
+ message: `Cache Processing Failure: ${error.message}`,
120
+ });
121
+ this._source = this._originalSource;
122
+ this.processCacheState.fail();
123
+ } finally {
124
+ this.taskService.endTask(task);
125
+ }
126
+ }
127
+
128
+ async disposeCache() {
129
+ if (!(this._source instanceof CachedDataCubeSource)) {
130
+ return;
131
+ }
132
+ const cachedSource = this._source;
133
+ this._source = this._originalSource;
134
+
135
+ this.processCacheState.inProgress();
136
+ const task = this.taskService.newTask('Disposing Cache');
137
+
138
+ try {
139
+ await this.engine.disposeCache(cachedSource);
140
+ } catch (error) {
141
+ assertErrorThrown(error);
142
+ this.alertService.alertError(error, {
143
+ message: `Cache Processing Failure: ${error.message}`,
144
+ });
145
+ } finally {
146
+ this.processCacheState.complete();
147
+ this.taskService.endTask(task);
148
+ }
149
+ }
150
+
113
151
  async initialize(query: DataCubeQuery) {
114
152
  this.initializeState.inProgress();
115
153
  const task = this.taskService.newTask('Initializing');
@@ -128,9 +166,8 @@ export class DataCubeViewState {
128
166
  }),
129
167
  );
130
168
  const source = await this.engine.processQuerySource(query.source);
131
- runInAction(() => {
132
- this._source = source;
133
- });
169
+ this._source = source;
170
+ this._originalSource = source;
134
171
  const partialQuery = await this.engine.parseValueSpecification(
135
172
  query.query,
136
173
  );
@@ -47,11 +47,7 @@ import {
47
47
  } from '@finos/legend-graph';
48
48
  import type { DataCubeColumnConfiguration } from '../../core/model/DataCubeConfiguration.js';
49
49
  import type { DataCubeQuerySnapshotExtendedColumn } from '../../core/DataCubeQuerySnapshot.js';
50
- import {
51
- _lambda,
52
- _serializeValueSpecification,
53
- _deserializeValueSpecification,
54
- } from '../../core/DataCubeQueryBuilderUtils.js';
50
+ import { _lambda } from '../../core/DataCubeQueryBuilderUtils.js';
55
51
  import { _findCol } from '../../core/model/DataCubeColumn.js';
56
52
 
57
53
  export abstract class DataCubeColumnBaseEditorState {
@@ -220,13 +216,9 @@ export abstract class DataCubeColumnBaseEditorState {
220
216
  return _lambda(
221
217
  [],
222
218
  [
223
- buildExecutableQuery(
224
- snapshot,
225
- this.view.source,
226
- () => undefined,
227
- this.view.engine.filterOperations,
228
- this.view.engine.aggregateOperations,
229
- ),
219
+ buildExecutableQuery(snapshot, this.view.source, this.view.engine, {
220
+ skipExecutionContext: true,
221
+ }),
230
222
  ],
231
223
  );
232
224
  }
@@ -390,7 +382,7 @@ export class DataCubeNewColumnState extends DataCubeColumnBaseEditorState {
390
382
  {
391
383
  name: this.name,
392
384
  type: returnType,
393
- mapFn: _serializeValueSpecification(query),
385
+ mapFn: this.view.engine.serializeValueSpecification(query),
394
386
  },
395
387
  this.isGroupLevel,
396
388
  this.columnKind,
@@ -440,7 +432,7 @@ export class DataCubeExistingColumnEditorState extends DataCubeColumnBaseEditorS
440
432
 
441
433
  override async getInitialCode(): Promise<string> {
442
434
  return this.view.engine.getValueSpecificationCode(
443
- _deserializeValueSpecification(this.initialData.mapFn),
435
+ this.view.engine.deserializeValueSpecification(this.initialData.mapFn),
444
436
  true,
445
437
  );
446
438
  }
@@ -516,7 +508,7 @@ export class DataCubeExistingColumnEditorState extends DataCubeColumnBaseEditorS
516
508
  {
517
509
  name: this.name,
518
510
  type: returnType,
519
- mapFn: _serializeValueSpecification(query),
511
+ mapFn: this.view.engine.serializeValueSpecification(query),
520
512
  },
521
513
  this.isGroupLevel,
522
514
  this.columnKind,
@@ -121,6 +121,7 @@ export const generateBackgroundColorUtilityClassName = (
121
121
  // See https://www.ag-grid.com/react-data-grid/server-side-model-configuration/#server-side-cache
122
122
  export const INTERNAL__GRID_CLIENT_DEFAULT_CACHE_BLOCK_SIZE = 500;
123
123
  export const INTERNAL__GRID_CLIENT_DEFAULT_ENABLE_PAGINATION = true;
124
+ export const INTERNAL__GRID_CLIENT_DEFAULT_ENABLE_CACHING = false;
124
125
  // NOTE: The cache block size is used by ag-grid to pre-allocate memory for the grid
125
126
  // so the value set must be reasonable, or else it can crash the engine!
126
127
  export const INTERNAL__GRID_CLIENT_MAX_CACHE_BLOCK_SIZE = 1e3;
@@ -264,29 +265,15 @@ async function getCastColumns(
264
265
  snapshot.data.groupExtendedColumns = [];
265
266
  snapshot.data.sortColumns = [];
266
267
  snapshot.data.limit = 0;
267
- const query = buildExecutableQuery(
268
- snapshot,
269
- view.source,
270
- (source) => view.engine.buildExecutionContext(source),
271
- view.engine.filterOperations,
272
- view.engine.aggregateOperations,
273
- {
274
- postProcessor: (
275
- _snapshot,
276
- sequence,
277
- funcMap,
278
- configuration,
279
- filterOperations,
280
- aggregateOperations,
281
- ) => {
282
- // when both pivot and groupBy present, we need to account for the count column
283
- // in the cast expression
284
- if (funcMap.pivot && currentSnapshot.data.groupBy) {
285
- _colSpecArrayParam(funcMap.pivot, 1).colSpecs.push(_aggCountCol());
286
- }
287
- },
268
+ const query = buildExecutableQuery(snapshot, view.source, view.engine, {
269
+ postProcessor: (_snapshot, sequence, funcMap, configuration, engine) => {
270
+ // when both pivot and groupBy present, we need to account for the count column
271
+ // in the cast expression
272
+ if (funcMap.pivot && currentSnapshot.data.groupBy) {
273
+ _colSpecArrayParam(funcMap.pivot, 1).colSpecs.push(_aggCountCol());
274
+ }
288
275
  },
289
- );
276
+ });
290
277
 
291
278
  const lambda = new V1_Lambda();
292
279
  lambda.body.push(query);
@@ -412,13 +399,22 @@ export class DataCubeGridClientServerSideDataSource
412
399
  request,
413
400
  newSnapshot,
414
401
  this._view.source,
415
- (source) => this._view.engine.buildExecutionContext(source),
416
- this._view.engine.filterOperations,
417
- this._view.engine.aggregateOperations,
402
+ this._view.engine,
418
403
  this._grid.isPaginationEnabled,
419
404
  );
420
405
  const lambda = new V1_Lambda();
421
406
  lambda.body.push(executableQuery);
407
+ if (
408
+ this._view.settingService.getBooleanValue(
409
+ DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
410
+ )
411
+ ) {
412
+ this._view.engine.debugProcess(
413
+ `Execution Plan`,
414
+ ['Query', lambda],
415
+ ['Config', `pagination=${this._grid.isPaginationEnabled}`],
416
+ );
417
+ }
422
418
  const result = await this._view.engine.executeQuery(
423
419
  lambda,
424
420
  this._view.source,
@@ -442,12 +438,12 @@ export class DataCubeGridClientServerSideDataSource
442
438
  this._view.engine.debugProcess(
443
439
  `Execution`,
444
440
  ['Query', result.executedQuery],
445
- ['Config', `pagination=${this._grid.isPaginationEnabled}`],
446
441
  [
447
442
  'Stats',
448
443
  `${rowData.length} rows, ${result.result.result.columns.length} columns`,
449
444
  ],
450
445
  ['SQL', result.executedSQL],
446
+ ['SQL Execution Time', result.executionTime],
451
447
  );
452
448
  }
453
449
 
@@ -60,11 +60,10 @@ import {
60
60
  type DataCubeGridClientDataFetchRequest,
61
61
  } from './DataCubeGridClientEngine.js';
62
62
  import { DataCubeConfiguration } from '../../core/model/DataCubeConfiguration.js';
63
- import type { DataCubeQueryFilterOperation } from '../../core/filter/DataCubeQueryFilterOperation.js';
64
- import type { DataCubeQueryAggregateOperation } from '../../core/aggregation/DataCubeQueryAggregateOperation.js';
65
63
  import { _colSpecArrayParam } from '../../core/DataCubeQuerySnapshotBuilderUtils.js';
66
64
  import { buildExecutableQuery } from '../../core/DataCubeQueryBuilder.js';
67
65
  import type { DataCubeSource } from '../../core/model/DataCubeSource.js';
66
+ import type { DataCubeEngine } from '../../core/DataCubeEngine.js';
68
67
 
69
68
  /*****************************************************************************
70
69
  * [GRID]
@@ -148,11 +147,7 @@ export function buildGridDataFetchExecutableQuery(
148
147
  request: DataCubeGridClientDataFetchRequest,
149
148
  snapshot: DataCubeQuerySnapshot,
150
149
  source: DataCubeSource,
151
- executionContextBuilder: (
152
- source: DataCubeSource,
153
- ) => V1_AppliedFunction | undefined,
154
- filterOperations: DataCubeQueryFilterOperation[],
155
- aggregateOperations: DataCubeQueryAggregateOperation[],
150
+ engine: DataCubeEngine,
156
151
  enablePagination: boolean,
157
152
  ) {
158
153
  const processedSnapshot = snapshot.clone();
@@ -170,28 +165,21 @@ export function buildGridDataFetchExecutableQuery(
170
165
  ],
171
166
  };
172
167
  }
173
- return buildExecutableQuery(
174
- processedSnapshot,
175
- source,
176
- executionContextBuilder,
177
- filterOperations,
178
- aggregateOperations,
179
- {
180
- postProcessor: generateGridDataFetchExecutableQueryPostProcessor(request),
181
- rootAggregation: {
182
- columnName: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
183
- },
184
- pagination:
185
- enablePagination &&
186
- request.startRow !== undefined &&
187
- request.endRow !== undefined
188
- ? {
189
- start: request.startRow,
190
- end: request.endRow,
191
- }
192
- : undefined,
168
+ return buildExecutableQuery(processedSnapshot, source, engine, {
169
+ postProcessor: generateGridDataFetchExecutableQueryPostProcessor(request),
170
+ rootAggregation: {
171
+ columnName: INTERNAL__GRID_CLIENT_ROOT_AGGREGATION_COLUMN_ID,
193
172
  },
194
- );
173
+ pagination:
174
+ enablePagination &&
175
+ request.startRow !== undefined &&
176
+ request.endRow !== undefined
177
+ ? {
178
+ start: request.startRow,
179
+ end: request.endRow,
180
+ }
181
+ : undefined,
182
+ });
195
183
  }
196
184
 
197
185
  function generateGridDataFetchExecutableQueryPostProcessor(
@@ -202,8 +190,7 @@ function generateGridDataFetchExecutableQueryPostProcessor(
202
190
  sequence: V1_AppliedFunction[],
203
191
  funcMap: DataCubeQueryFunctionMap,
204
192
  configuration: DataCubeConfiguration,
205
- filterOperations: DataCubeQueryFilterOperation[],
206
- aggregateOperations: DataCubeQueryAggregateOperation[],
193
+ engine: DataCubeEngine,
207
194
  ) => {
208
195
  const _unprocess = _functionCompositionUnProcessor(sequence, funcMap);
209
196
  const data = snapshot.data;
@@ -285,7 +272,7 @@ function generateGridDataFetchExecutableQueryPostProcessor(
285
272
  }),
286
273
  groupOperator: DataCubeQueryFilterGroupOperator.AND,
287
274
  },
288
- filterOperations,
275
+ engine.filterOperations,
289
276
  ),
290
277
  ],
291
278
  ),
@@ -312,7 +299,7 @@ function generateGridDataFetchExecutableQueryPostProcessor(
312
299
  groupByColumns,
313
300
  snapshot,
314
301
  configuration,
315
- aggregateOperations,
302
+ engine.aggregateOperations,
316
303
  ),
317
304
 
318
305
  // if pivot is present, add sum aggregation columns for each