@finos/legend-data-cube 0.1.32 → 0.2.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 (89) hide show
  1. package/lib/components/DataCubeStatusBar.d.ts.map +1 -1
  2. package/lib/components/DataCubeStatusBar.js +4 -2
  3. package/lib/components/DataCubeStatusBar.js.map +1 -1
  4. package/lib/components/view/editor/DataCubeEditor.d.ts.map +1 -1
  5. package/lib/components/view/editor/DataCubeEditor.js +12 -1
  6. package/lib/components/view/editor/DataCubeEditor.js.map +1 -1
  7. package/lib/components/view/grid/DataCubeMultidimensionalGrid.d.ts.map +1 -1
  8. package/lib/components/view/grid/DataCubeMultidimensionalGrid.js +40 -2
  9. package/lib/components/view/grid/DataCubeMultidimensionalGrid.js.map +1 -1
  10. package/lib/index.css +1 -1
  11. package/lib/package.json +1 -1
  12. package/lib/stores/core/DataCubeQueryBuilder.d.ts +12 -0
  13. package/lib/stores/core/DataCubeQueryBuilder.d.ts.map +1 -1
  14. package/lib/stores/core/DataCubeQueryBuilder.js +141 -4
  15. package/lib/stores/core/DataCubeQueryBuilder.js.map +1 -1
  16. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts +2 -0
  17. package/lib/stores/core/DataCubeQueryBuilderUtils.d.ts.map +1 -1
  18. package/lib/stores/core/DataCubeQueryBuilderUtils.js +18 -1
  19. package/lib/stores/core/DataCubeQueryBuilderUtils.js.map +1 -1
  20. package/lib/stores/core/DataCubeQueryEngine.d.ts +6 -0
  21. package/lib/stores/core/DataCubeQueryEngine.d.ts.map +1 -1
  22. package/lib/stores/core/DataCubeQueryEngine.js +9 -0
  23. package/lib/stores/core/DataCubeQueryEngine.js.map +1 -1
  24. package/lib/stores/core/DataCubeSnapshot.d.ts +2 -0
  25. package/lib/stores/core/DataCubeSnapshot.d.ts.map +1 -1
  26. package/lib/stores/core/DataCubeSnapshot.js.map +1 -1
  27. package/lib/stores/core/DataCubeSnapshotBuilder.js +1 -0
  28. package/lib/stores/core/DataCubeSnapshotBuilder.js.map +1 -1
  29. package/lib/stores/core/model/DataCubeSpecification.d.ts +2 -0
  30. package/lib/stores/core/model/DataCubeSpecification.d.ts.map +1 -1
  31. package/lib/stores/core/model/DataCubeSpecification.js +3 -0
  32. package/lib/stores/core/model/DataCubeSpecification.js.map +1 -1
  33. package/lib/stores/view/DataCubeViewState.d.ts.map +1 -1
  34. package/lib/stores/view/DataCubeViewState.js +1 -0
  35. package/lib/stores/view/DataCubeViewState.js.map +1 -1
  36. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.d.ts.map +1 -1
  37. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.js +8 -4
  38. package/lib/stores/view/editor/DataCubeEditorDimensionsPanelState.js.map +1 -1
  39. package/lib/stores/view/editor/DataCubeEditorState.d.ts.map +1 -1
  40. package/lib/stores/view/editor/DataCubeEditorState.js +1 -0
  41. package/lib/stores/view/editor/DataCubeEditorState.js.map +1 -1
  42. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts +163 -1
  43. package/lib/stores/view/grid/DataCubeGridClientEngine.d.ts.map +1 -1
  44. package/lib/stores/view/grid/DataCubeGridClientEngine.js +142 -3
  45. package/lib/stores/view/grid/DataCubeGridClientEngine.js.map +1 -1
  46. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts +155 -1
  47. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.d.ts.map +1 -1
  48. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js +170 -2
  49. package/lib/stores/view/grid/DataCubeGridConfigurationBuilder.js.map +1 -1
  50. package/lib/stores/view/grid/DataCubeGridControllerState.d.ts.map +1 -1
  51. package/lib/stores/view/grid/DataCubeGridControllerState.js +5 -3
  52. package/lib/stores/view/grid/DataCubeGridControllerState.js.map +1 -1
  53. package/lib/stores/view/grid/DataCubeGridDimensionalTree.d.ts +54 -0
  54. package/lib/stores/view/grid/DataCubeGridDimensionalTree.d.ts.map +1 -0
  55. package/lib/stores/view/grid/DataCubeGridDimensionalTree.js +264 -0
  56. package/lib/stores/view/grid/DataCubeGridDimensionalTree.js.map +1 -0
  57. package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts +1 -0
  58. package/lib/stores/view/grid/DataCubeGridMenuBuilder.d.ts.map +1 -1
  59. package/lib/stores/view/grid/DataCubeGridMenuBuilder.js +207 -1
  60. package/lib/stores/view/grid/DataCubeGridMenuBuilder.js.map +1 -1
  61. package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts +2 -0
  62. package/lib/stores/view/grid/DataCubeGridQueryBuilder.d.ts.map +1 -1
  63. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js +7 -1
  64. package/lib/stores/view/grid/DataCubeGridQueryBuilder.js.map +1 -1
  65. package/lib/stores/view/grid/DataCubeGridState.d.ts +6 -1
  66. package/lib/stores/view/grid/DataCubeGridState.d.ts.map +1 -1
  67. package/lib/stores/view/grid/DataCubeGridState.js +38 -2
  68. package/lib/stores/view/grid/DataCubeGridState.js.map +1 -1
  69. package/package.json +2 -2
  70. package/src/components/DataCubeStatusBar.tsx +9 -2
  71. package/src/components/view/editor/DataCubeEditor.tsx +16 -1
  72. package/src/components/view/grid/DataCubeMultidimensionalGrid.tsx +63 -1
  73. package/src/stores/core/DataCubeQueryBuilder.ts +256 -2
  74. package/src/stores/core/DataCubeQueryBuilderUtils.ts +22 -0
  75. package/src/stores/core/DataCubeQueryEngine.ts +10 -0
  76. package/src/stores/core/DataCubeSnapshot.ts +2 -0
  77. package/src/stores/core/DataCubeSnapshotBuilder.ts +1 -1
  78. package/src/stores/core/model/DataCubeSpecification.ts +5 -0
  79. package/src/stores/view/DataCubeViewState.ts +1 -0
  80. package/src/stores/view/editor/DataCubeEditorDimensionsPanelState.ts +9 -7
  81. package/src/stores/view/editor/DataCubeEditorState.tsx +1 -0
  82. package/src/stores/view/grid/DataCubeGridClientEngine.ts +268 -6
  83. package/src/stores/view/grid/DataCubeGridConfigurationBuilder.tsx +244 -3
  84. package/src/stores/view/grid/DataCubeGridControllerState.ts +10 -2
  85. package/src/stores/view/grid/DataCubeGridDimensionalTree.ts +438 -0
  86. package/src/stores/view/grid/DataCubeGridMenuBuilder.tsx +257 -0
  87. package/src/stores/view/grid/DataCubeGridQueryBuilder.ts +22 -1
  88. package/src/stores/view/grid/DataCubeGridState.ts +92 -2
  89. package/tsconfig.json +1 -0
@@ -81,6 +81,7 @@ import {
81
81
  isPivotResultColumnName,
82
82
  getPivotResultColumnBaseColumnName,
83
83
  DEFAULT_ROOT_AGGREGATION_COLUMN_VALUE,
84
+ DataCubeQueryFilterOperator,
84
85
  } from './DataCubeQueryEngine.js';
85
86
  import type { DataCubeQueryFilterOperation } from './filter/DataCubeQueryFilterOperation.js';
86
87
  import type { DataCubeQueryAggregateOperation } from './aggregation/DataCubeQueryAggregateOperation.js';
@@ -88,6 +89,7 @@ import {
88
89
  DataCubeColumnConfiguration,
89
90
  type DataCubeConfiguration,
90
91
  } from './model/DataCubeConfiguration.js';
92
+ import type { DataCubeDimensionalGroupByNode } from '../view/grid/DataCubeGridDimensionalTree.js';
91
93
 
92
94
  // --------------------------------- UTILITIES ---------------------------------
93
95
 
@@ -645,3 +647,23 @@ export function _filter(
645
647
  return filterCondition.not ? _not(condition) : condition;
646
648
  }
647
649
  }
650
+
651
+ export function _flattenFilterSnapshot(
652
+ groupByNodes: DataCubeDimensionalGroupByNode[],
653
+ ): DataCubeSnapshotFilter {
654
+ const filterConditions = groupByNodes.map((node) => {
655
+ return {
656
+ name: node.column,
657
+ type: 'String', // Assuming all filters are strings — update if needed
658
+ operator: DataCubeQueryFilterOperator.EQUAL,
659
+ value: {
660
+ type: 'String',
661
+ value: node.filter,
662
+ } satisfies DataCubeOperationValue,
663
+ } satisfies DataCubeSnapshotFilterCondition;
664
+ });
665
+ return {
666
+ groupOperator: DataCubeQueryFilterGroupOperator.AND,
667
+ conditions: filterConditions,
668
+ } satisfies DataCubeSnapshotFilter;
669
+ }
@@ -273,6 +273,12 @@ export enum DataCubeGridMode {
273
273
  MULTIDIMENSIONAL = 'Multidimensional',
274
274
  }
275
275
 
276
+ export enum DataCubeClientModelOption {
277
+ ROW_DATA = 'rowData',
278
+ COLUMN_DEFS = 'columnDefs',
279
+ LOADING = 'loading',
280
+ }
281
+
276
282
  export enum DataCubeTitleBarMenuItems {
277
283
  VIEW_SOURCE = 'View Source',
278
284
  RESET_TO_LATEST_SAVE = 'Reset to Latest Save',
@@ -409,6 +415,10 @@ export function ofDataType(
409
415
  return dataTypes.includes(getDataType(type));
410
416
  }
411
417
 
418
+ export function isDimensionalGridMode(gridMode: DataCubeGridMode) {
419
+ return gridMode === DataCubeGridMode.MULTIDIMENSIONAL;
420
+ }
421
+
412
422
  export function isPrimitiveType(type: string) {
413
423
  return (
414
424
  [
@@ -29,6 +29,7 @@ import type {
29
29
  DataCubeQuerySortDirection,
30
30
  } from './DataCubeQueryEngine.js';
31
31
  import type { DataCubeColumn } from './model/DataCubeColumn.js';
32
+ import type { DataCubeDimensionalTree } from '../view/grid/DataCubeGridDimensionalTree.js';
32
33
 
33
34
  export type DataCubeSnapshotFilterCondition = DataCubeColumn & {
34
35
  value: DataCubeOperationValue;
@@ -85,6 +86,7 @@ export type DataCubeSnapshotData = {
85
86
  groupExtendedColumns: DataCubeSnapshotExtendedColumn[];
86
87
  sortColumns: DataCubeSnapshotSortColumn[];
87
88
  limit: number | undefined;
89
+ dimensionalTree?: DataCubeDimensionalTree | undefined;
88
90
  };
89
91
 
90
92
  export class DataCubeSnapshot {
@@ -611,7 +611,7 @@ export async function validateAndBuildSnapshot(
611
611
  engine,
612
612
  );
613
613
  data.configuration = configuration.serialize();
614
-
614
+ data.dimensionalTree = specification.dimensionalTree;
615
615
  return snapshot.finalize();
616
616
  }
617
617
 
@@ -21,6 +21,7 @@ import {
21
21
  } from '@finos/legend-shared';
22
22
  import { createModelSchema, optional, primitive, raw } from 'serializr';
23
23
  import { DataCubeConfiguration } from './DataCubeConfiguration.js';
24
+ import { DataCubeDimensionalTree } from '../../view/grid/DataCubeGridDimensionalTree.js';
24
25
 
25
26
  export class DataCubeSpecificationOptions {
26
27
  autoEnableCache?: boolean | undefined;
@@ -37,6 +38,7 @@ export class DataCubeSpecification {
37
38
  configuration?: DataCubeConfiguration | undefined;
38
39
  source!: PlainObject;
39
40
  options?: DataCubeSpecificationOptions | undefined;
41
+ dimensionalTree?: DataCubeDimensionalTree | undefined;
40
42
 
41
43
  static readonly serialization = new SerializationFactory(
42
44
  createModelSchema(DataCubeSpecification, {
@@ -48,6 +50,9 @@ export class DataCubeSpecification {
48
50
  ),
49
51
  query: primitive(),
50
52
  source: raw(),
53
+ dimensionalTree: optional(
54
+ usingModelSchema(DataCubeDimensionalTree.serialization.schema),
55
+ ),
51
56
  }),
52
57
  );
53
58
  }
@@ -104,6 +104,7 @@ export class DataCubeViewState {
104
104
  snapshot.data.configuration,
105
105
  );
106
106
  query.query = await this.engine.getPartialQueryCode(snapshot);
107
+ query.dimensionalTree = snapshot.data.dimensionalTree;
107
108
  return query;
108
109
  }
109
110
 
@@ -213,6 +213,7 @@ export class DataCubeEditorDimensionsPanelState
213
213
  return _dimension;
214
214
  }),
215
215
  );
216
+ this.refreshDimensionsTreeData();
216
217
  }
217
218
 
218
219
  buildSnapshot(newSnapshot: DataCubeSnapshot, baseSnapshot: DataCubeSnapshot) {
@@ -226,13 +227,14 @@ export class DataCubeEditorDimensionsPanelState
226
227
  name: dimension.name,
227
228
  columns: dimension.columns.map((column) => column.name),
228
229
  }));
230
+ newSnapshot.data.configuration = {
231
+ ...newSnapshot.data.configuration,
232
+ dimensions: DataCubeDimensionsConfiguration.serialization.toJson(
233
+ dimensionsConfiguration,
234
+ ),
235
+ };
236
+ } else {
237
+ newSnapshot = baseSnapshot;
229
238
  }
230
-
231
- newSnapshot.data.configuration = {
232
- ...newSnapshot.data.configuration,
233
- dimensions: DataCubeDimensionsConfiguration.serialization.toJson(
234
- dimensionsConfiguration,
235
- ),
236
- };
237
239
  }
238
240
  }
@@ -147,6 +147,7 @@ export class DataCubeEditorState extends DataCubeSnapshotController {
147
147
  return 'editor';
148
148
  }
149
149
 
150
+ //TODO: for dimensional grid, we need to reload the grid when we apply changes
150
151
  async applyChanges(options?: { closeAfterApply?: boolean | undefined }) {
151
152
  this.finalizationState.inProgress();
152
153
 
@@ -25,6 +25,7 @@ import {
25
25
  IllegalStateError,
26
26
  assertErrorThrown,
27
27
  guaranteeNonNullable,
28
+ guaranteeType,
28
29
  hashObject,
29
30
  isBoolean,
30
31
  isNonNullable,
@@ -35,19 +36,27 @@ import {
35
36
  PRIMITIVE_TYPE,
36
37
  PureClientVersion,
37
38
  type TabularDataSet,
39
+ type TDSRow,
38
40
  } from '@finos/legend-graph';
39
41
  import { makeObservable, observable, runInAction } from 'mobx';
40
- import type {
42
+ import {
41
43
  DataCubeConfiguration,
42
- DataCubeConfigurationColorKey,
44
+ type DataCubeConfigurationColorKey,
45
+ type DataCubeDimensionConfiguration,
43
46
  } from '../../core/model/DataCubeConfiguration.js';
44
47
  import { type DataCubeSnapshot } from '../../core/DataCubeSnapshot.js';
45
48
  import { _findCol, _sortByColName } from '../../core/model/DataCubeColumn.js';
46
- import { isPivotResultColumnName } from '../../core/DataCubeQueryEngine.js';
49
+ import {
50
+ DataCubeClientModelOption,
51
+ isPivotResultColumnName,
52
+ } from '../../core/DataCubeQueryEngine.js';
47
53
  import { buildSnapshotFromGridState } from './DataCubeGridSnapshotBuilder.js';
48
54
  import { AlertType } from '../../services/DataCubeAlertService.js';
49
55
  import type { DataCubeViewState } from '../DataCubeViewState.js';
50
- import { buildGridDataFetchExecutableQuery } from './DataCubeGridQueryBuilder.js';
56
+ import {
57
+ buildDimensionalGridDataFetchExecutableQuery,
58
+ buildGridDataFetchExecutableQuery,
59
+ } from './DataCubeGridQueryBuilder.js';
51
60
  import { DataCubeSettingKey } from '../../../__lib__/DataCubeSetting.js';
52
61
  import { DEFAULT_ALERT_WINDOW_CONFIG } from '../../services/DataCubeLayoutService.js';
53
62
  import {
@@ -57,8 +66,24 @@ import {
57
66
  import { _lambda } from '../../core/DataCubeQueryBuilderUtils.js';
58
67
  import { sum } from 'mathjs';
59
68
  import { DataCubeEvent } from '../../../__lib__/DataCubeEvent.js';
60
-
61
- type DataCubeGridClientCellValue = string | number | boolean | null | undefined;
69
+ import { generateColumnDefsForDimensions } from './DataCubeGridConfigurationBuilder.js';
70
+ import {
71
+ DataCubeDimensionalMetadata,
72
+ generateDimensionalPaths,
73
+ type DataCubeDimensionalNode,
74
+ type DataCubeDimensionalGroupByNode,
75
+ type DataCubeDimensionalTree,
76
+ DIMENSIONAL_L0_COLUMN,
77
+ findExtraPaths,
78
+ } from './DataCubeGridDimensionalTree.js';
79
+
80
+ type DataCubeGridClientCellValue =
81
+ | string
82
+ | number
83
+ | boolean
84
+ | Map<string, DataCubeDimensionalMetadata>
85
+ | null
86
+ | undefined;
62
87
  type DataCubeGridClientRowData = {
63
88
  [key: string]: DataCubeGridClientCellValue;
64
89
  };
@@ -259,6 +284,136 @@ function buildRowData(
259
284
  });
260
285
  }
261
286
 
287
+ function buildDimensionalRowData(
288
+ result: TabularDataSet,
289
+ snapshot: DataCubeSnapshot,
290
+ dimensionalNodes: DataCubeDimensionalNode[],
291
+ rowData: DataCubeGridClientRowData[],
292
+ dimensions: DataCubeDimensionConfiguration[],
293
+ ): DataCubeGridClientRowData[] {
294
+ const newRows = result.rows.map((rawRow) =>
295
+ _createClientRow(rawRow, result.columns, dimensionalNodes, dimensions),
296
+ );
297
+
298
+ const updated = [...rowData];
299
+ for (const newRow of newRows) {
300
+ const insertIndex = _findInsertIndex(newRow, updated, dimensionalNodes);
301
+ updated.splice(insertIndex, 0, newRow);
302
+ }
303
+
304
+ return updated;
305
+ }
306
+
307
+ function _createClientRow(
308
+ rawRow: TDSRow,
309
+ columns: string[],
310
+ nodes: DataCubeDimensionalNode[],
311
+ configs: DataCubeDimensionConfiguration[],
312
+ ): DataCubeGridClientRowData {
313
+ const row: DataCubeGridClientRowData = {};
314
+ rawRow.values.forEach((value, i) => {
315
+ row[guaranteeNonNullable(columns[i])] = isBoolean(value)
316
+ ? String(value)
317
+ : isNonNullable(value)
318
+ ? value
319
+ : INTERNAL__GRID_CLIENT_MISSING_VALUE;
320
+ });
321
+
322
+ const metadata = new Map<string, DataCubeDimensionalMetadata>();
323
+ for (const node of nodes) {
324
+ const config = guaranteeNonNullable(
325
+ configs.find((d) => d.name === node.dimension),
326
+ );
327
+ metadata.set(
328
+ node.dimension,
329
+ new DataCubeDimensionalMetadata(
330
+ node.column,
331
+ config.columns.indexOf(node.column),
332
+ node.groupByNodes,
333
+ ),
334
+ );
335
+ }
336
+ row.metadata = metadata;
337
+ return row;
338
+ }
339
+
340
+ function _findInsertIndex(
341
+ newRow: DataCubeGridClientRowData,
342
+ existing: DataCubeGridClientRowData[],
343
+ dimensionalNodes: DataCubeDimensionalNode[],
344
+ ): number {
345
+ const metadata = guaranteeType(
346
+ newRow.metadata,
347
+ Map<string, DataCubeDimensionalMetadata>,
348
+ );
349
+ const groupByNodes = [...metadata.values()].flatMap((m) => m.groupByNodes);
350
+ const dimensions = dimensionalNodes.map((d) => d.dimension);
351
+ const latest = _latestGroupByFilters(groupByNodes);
352
+
353
+ for (let i = existing.length - 1; i >= 0; i--) {
354
+ const existingRow = guaranteeNonNullable(existing[i]);
355
+ if (
356
+ _isParentRow(existingRow, groupByNodes.length, newRow, latest, dimensions)
357
+ ) {
358
+ return i + 1;
359
+ }
360
+ }
361
+
362
+ return existing.length;
363
+ }
364
+
365
+ function _isParentRow(
366
+ existing: DataCubeGridClientRowData,
367
+ groupByCount: number,
368
+ newRow: DataCubeGridClientRowData,
369
+ filters: DataCubeDimensionalGroupByNode[],
370
+ dimensions: string[],
371
+ ): boolean {
372
+ if (groupByCount === 0) {
373
+ let allCount = 0;
374
+ const match = dimensions.every((d) => {
375
+ const e = existing[d],
376
+ n = newRow[d];
377
+ if (e === null || n === null) {
378
+ return false;
379
+ }
380
+ if (String(e) === DIMENSIONAL_L0_COLUMN) {
381
+ allCount++;
382
+ return true;
383
+ }
384
+ return String(e) === String(n);
385
+ });
386
+ return match && allCount >= 1 && allCount <= dimensions.length;
387
+ }
388
+
389
+ return dimensions.every((d) => {
390
+ const filter = filters.find((f) => f.dimension === d);
391
+ const e = existing[d],
392
+ n = newRow[d];
393
+ if (e === null || n === null) {
394
+ return false;
395
+ }
396
+ if (filter) {
397
+ return (
398
+ String(e) === String(filter.filter) ||
399
+ String(e) === String(n) ||
400
+ String(e) === DIMENSIONAL_L0_COLUMN
401
+ );
402
+ }
403
+ return String(e) === String(n);
404
+ });
405
+ }
406
+
407
+ function _latestGroupByFilters(
408
+ nodes: DataCubeDimensionalGroupByNode[],
409
+ ): DataCubeDimensionalGroupByNode[] {
410
+ const map = new Map<string, DataCubeDimensionalGroupByNode>();
411
+ for (const node of nodes) {
412
+ map.set(node.dimension, node);
413
+ }
414
+ return [...map.values()];
415
+ }
416
+
262
417
  async function getCastColumns(
263
418
  currentSnapshot: DataCubeSnapshot,
264
419
  view: DataCubeViewState,
@@ -302,6 +457,113 @@ async function getCastColumns(
302
457
  });
303
458
  }
304
459
 
460
+ export async function fetchDimensionalQueryRows(
461
+ snapshot: DataCubeSnapshot,
462
+ view: DataCubeViewState,
463
+ previousTree?: DataCubeDimensionalTree,
464
+ ) {
465
+ const task = view.taskService.newTask('Fetching data...');
466
+
467
+ let rowData: DataCubeGridClientRowData[] = [];
468
+
469
+ const configuration = DataCubeConfiguration.serialization.fromJson(
470
+ snapshot.data.configuration,
471
+ );
472
+
473
+ // upgrade here by not shooting extra sqls
474
+ let paths = generateDimensionalPaths(
475
+ guaranteeNonNullable(snapshot.data.dimensionalTree),
476
+ );
477
+
478
+ if (previousTree) {
479
+ const oldPaths = generateDimensionalPaths(previousTree);
480
+ if (oldPaths.length <= paths.length) {
481
+ rowData = view.grid.client.getGridOption(
482
+ DataCubeClientModelOption.ROW_DATA,
483
+ ) as DataCubeGridClientRowData[];
484
+ paths = findExtraPaths(oldPaths, paths);
485
+ }
486
+ }
487
+
488
+ for (const path of paths) {
489
+ const executableQuery = buildDimensionalGridDataFetchExecutableQuery(
490
+ snapshot,
491
+ view.source,
492
+ view.engine,
493
+ path,
494
+ );
495
+ let result: DataCubeExecutionResult;
496
+
497
+ try {
498
+ result = await view.engine.executeQuery(
499
+ _lambda([], [executableQuery]),
500
+ view.source,
501
+ {
502
+ debug: view.settingService.getBooleanValue(
503
+ DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
504
+ ),
505
+ clientVersion: view.settingService.getBooleanValue(
506
+ DataCubeSettingKey.DEBUGGER__USE_DEV_CLIENT_PROTOCOL_VERSION,
507
+ )
508
+ ? PureClientVersion.VX_X_X
509
+ : undefined,
510
+ },
511
+ );
512
+
513
+ rowData = buildDimensionalRowData(
514
+ result.result.result,
515
+ snapshot,
516
+ path,
517
+ rowData,
518
+ configuration.dimensions.dimensions,
519
+ );
520
+ } catch (error) {
521
+ assertErrorThrown(error);
522
+ if (error instanceof DataCubeExecutionError) {
523
+ view.alertService.alertExecutionError(error, {
524
+ message: `Data Fetch Failure: Can't execute query.`,
525
+ text: `Error: ${error.message}`,
526
+ });
527
+ } else {
528
+ view.alertService.alertError(error, {
529
+ message: `Data Fetch Failure: ${error.message}`,
530
+ });
531
+ }
532
+ view.taskService.endTask(task);
533
+ return {
534
+ rowData: [],
535
+ columnDefs: [],
536
+ };
537
+ }
538
+
539
+ if (
540
+ view.settingService.getBooleanValue(
541
+ DataCubeSettingKey.DEBUGGER__ENABLE_DEBUG_MODE,
542
+ )
543
+ ) {
544
+ view.engine.debugProcess(
545
+ `Execution`,
546
+ ['Query', result.executedQuery],
547
+ [
548
+ 'Stats',
549
+ `${rowData.length} rows, ${result.result.result.columns.length} columns`,
550
+ ],
551
+ [
552
+ 'SQL',
553
+ result.executedSQL ?? `-- Error: failed to extract executed SQL`,
554
+ ],
555
+ ['SQL Execution Time', result.executionTime],
556
+ );
557
+ }
558
+ }
559
+
560
+ view.taskService.endTask(task);
561
+ return {
562
+ rowData: rowData,
563
+ columnDefs: generateColumnDefsForDimensions(snapshot, configuration),
564
+ };
565
+ }
566
+
305
567
  export type DataCubeGridClientDataFetchRequest = {
306
568
  startRow: number | undefined;
307
569
  endRow: number | undefined;