@cubejs-backend/schema-compiler 1.3.11 → 1.3.13
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/dist/src/adapter/BaseDimension.d.ts +3 -3
- package/dist/src/adapter/BaseDimension.d.ts.map +1 -1
- package/dist/src/adapter/BaseDimension.js.map +1 -1
- package/dist/src/adapter/BaseFilter.d.ts +5 -1
- package/dist/src/adapter/BaseFilter.d.ts.map +1 -1
- package/dist/src/adapter/BaseFilter.js +13 -3
- package/dist/src/adapter/BaseFilter.js.map +1 -1
- package/dist/src/adapter/BaseGroupFilter.d.ts +2 -2
- package/dist/src/adapter/BaseGroupFilter.d.ts.map +1 -1
- package/dist/src/adapter/BaseGroupFilter.js.map +1 -1
- package/dist/src/adapter/BaseMeasure.d.ts +4 -4
- package/dist/src/adapter/BaseMeasure.js.map +1 -1
- package/dist/src/adapter/BaseQuery.d.ts +119 -35
- package/dist/src/adapter/BaseQuery.d.ts.map +1 -1
- package/dist/src/adapter/BaseQuery.js +226 -43
- package/dist/src/adapter/BaseQuery.js.map +1 -1
- package/dist/src/adapter/BaseSegment.d.ts +2 -2
- package/dist/src/adapter/BaseSegment.js.map +1 -1
- package/dist/src/adapter/BaseTimeDimension.d.ts +1 -1
- package/dist/src/adapter/CubeStoreQuery.d.ts +6 -6
- package/dist/src/adapter/CubeStoreQuery.d.ts.map +1 -1
- package/dist/src/adapter/CubeStoreQuery.js +3 -4
- package/dist/src/adapter/CubeStoreQuery.js.map +1 -1
- package/dist/src/adapter/HiveQuery.d.ts +7 -2
- package/dist/src/adapter/HiveQuery.d.ts.map +1 -1
- package/dist/src/adapter/HiveQuery.js +2 -2
- package/dist/src/adapter/HiveQuery.js.map +1 -1
- package/dist/src/adapter/PreAggregations.d.ts +130 -209
- package/dist/src/adapter/PreAggregations.d.ts.map +1 -1
- package/dist/src/adapter/PreAggregations.js +205 -148
- package/dist/src/adapter/PreAggregations.js.map +1 -1
- package/dist/src/compiler/CubeEvaluator.d.ts +37 -9
- package/dist/src/compiler/CubeEvaluator.d.ts.map +1 -1
- package/dist/src/compiler/CubeEvaluator.js +13 -2
- package/dist/src/compiler/CubeEvaluator.js.map +1 -1
- package/dist/src/compiler/CubeSymbols.d.ts +1 -1
- package/dist/src/compiler/CubeSymbols.d.ts.map +1 -1
- package/dist/src/compiler/CubeSymbols.js.map +1 -1
- package/dist/src/compiler/CubeValidator.d.ts.map +1 -1
- package/dist/src/compiler/CubeValidator.js +16 -7
- package/dist/src/compiler/CubeValidator.js.map +1 -1
- package/package.json +6 -6
|
@@ -85,6 +85,24 @@ const SecondsDurations = {
|
|
|
85
85
|
* and {@code CompilerApi} configuration.
|
|
86
86
|
*/
|
|
87
87
|
class BaseQuery {
|
|
88
|
+
/** @type {import('./PreAggregations').PreAggregations} */
|
|
89
|
+
preAggregations;
|
|
90
|
+
/** @type {import('./BaseMeasure').BaseMeasure[]} */
|
|
91
|
+
measures;
|
|
92
|
+
/** @type {import('./BaseDimension').BaseDimension[]} */
|
|
93
|
+
dimensions;
|
|
94
|
+
/** @type {import('./BaseDimension').BaseDimension[]} */
|
|
95
|
+
multiStageDimensions;
|
|
96
|
+
/** @type {import('./BaseTimeDimension').BaseTimeDimension[]} */
|
|
97
|
+
multiStageTimeDimensions;
|
|
98
|
+
/** @type {import('./BaseSegment').BaseSegment[]} */
|
|
99
|
+
segments;
|
|
100
|
+
/** @type {(BaseFilter|BaseGroupFilter)[]} */
|
|
101
|
+
filters;
|
|
102
|
+
/** @type {(BaseFilter|BaseGroupFilter)[]} */
|
|
103
|
+
measureFilters;
|
|
104
|
+
/** @type {import('./BaseTimeDimension').BaseTimeDimension[]} */
|
|
105
|
+
timeDimensions;
|
|
88
106
|
/**
|
|
89
107
|
* BaseQuery class constructor.
|
|
90
108
|
* @param {Compilers|*} compilers
|
|
@@ -218,7 +236,7 @@ class BaseQuery {
|
|
|
218
236
|
rowLimit: this.options.rowLimit,
|
|
219
237
|
preAggregationsSchema: this.options.preAggregationsSchema,
|
|
220
238
|
className: this.constructor.name,
|
|
221
|
-
externalClassName: this.options.externalQueryClass
|
|
239
|
+
externalClassName: this.options.externalQueryClass?.name,
|
|
222
240
|
preAggregationQuery: this.options.preAggregationQuery,
|
|
223
241
|
disableExternalPreAggregations: this.options.disableExternalPreAggregations,
|
|
224
242
|
useOriginalSqlPreAggregationsInPreAggregation: this.options.useOriginalSqlPreAggregationsInPreAggregation,
|
|
@@ -239,18 +257,26 @@ class BaseQuery {
|
|
|
239
257
|
this.timezone = this.options.timezone;
|
|
240
258
|
this.rowLimit = this.options.rowLimit;
|
|
241
259
|
this.offset = this.options.offset;
|
|
260
|
+
/** @type {import('./PreAggregations').PreAggregations} */
|
|
242
261
|
this.preAggregations = this.newPreAggregations();
|
|
262
|
+
/** @type {import('./BaseMeasure').BaseMeasure[]} */
|
|
243
263
|
this.measures = (this.options.measures || []).map(this.newMeasure.bind(this));
|
|
264
|
+
/** @type {import('./BaseDimension').BaseDimension[]} */
|
|
244
265
|
this.dimensions = (this.options.dimensions || []).map(this.newDimension.bind(this));
|
|
266
|
+
/** @type {import('./BaseDimension').BaseDimension[]} */
|
|
245
267
|
this.multiStageDimensions = (this.options.multiStageDimensions || []).map(this.newDimension.bind(this));
|
|
268
|
+
/** @type {import('./BaseTimeDimension').BaseTimeDimension[]} */
|
|
246
269
|
this.multiStageTimeDimensions = (this.options.multiStageTimeDimensions || []).map(this.newTimeDimension.bind(this));
|
|
270
|
+
/** @type {import('./BaseSegment').BaseSegment[]} */
|
|
247
271
|
this.segments = (this.options.segments || []).map(this.newSegment.bind(this));
|
|
248
272
|
const filters = this.extractFiltersAsTree(this.options.filters || []);
|
|
249
273
|
// measure_filter (the one extracted from filters parameter on measure and
|
|
250
|
-
// used in drill
|
|
274
|
+
// used in drill-downs) should go to WHERE instead of HAVING
|
|
251
275
|
/** @type {(BaseFilter|BaseGroupFilter)[]} */
|
|
252
276
|
this.filters = filters.filter(f => f.dimensionGroup || f.dimension || f.operator === 'measure_filter' || f.operator === 'measureFilter').map(this.initFilter.bind(this));
|
|
277
|
+
/** @type {(BaseFilter|BaseGroupFilter)[]} */
|
|
253
278
|
this.measureFilters = filters.filter(f => (f.measureGroup || f.measure) && f.operator !== 'measure_filter' && f.operator !== 'measureFilter').map(this.initFilter.bind(this));
|
|
279
|
+
/** @type {import('./BaseTimeDimension').BaseTimeDimension[]} */
|
|
254
280
|
this.timeDimensions = (this.options.timeDimensions || []).map(dimension => {
|
|
255
281
|
if (!dimension.dimension) {
|
|
256
282
|
const join = this.joinGraph.buildJoin(this.collectJoinHints(true));
|
|
@@ -267,6 +293,11 @@ class BaseQuery {
|
|
|
267
293
|
}).filter(ramda_1.default.identity).map(this.newTimeDimension.bind(this));
|
|
268
294
|
this.allFilters = this.timeDimensions.concat(this.segments).concat(this.filters);
|
|
269
295
|
this.useNativeSqlPlanner = this.options.useNativeSqlPlanner ?? (0, shared_1.getEnv)('nativeSqlPlanner');
|
|
296
|
+
this.canUseNativeSqlPlannerPreAggregation = false;
|
|
297
|
+
if (this.useNativeSqlPlanner) {
|
|
298
|
+
const hasMultiStageMeasures = this.fullKeyQueryAggregateMeasures({ hasMultipliedForPreAggregation: true }).multiStageMembers.length > 0;
|
|
299
|
+
this.canUseNativeSqlPlannerPreAggregation = hasMultiStageMeasures;
|
|
300
|
+
}
|
|
270
301
|
this.prebuildJoin();
|
|
271
302
|
this.cubeAliasPrefix = this.options.cubeAliasPrefix;
|
|
272
303
|
this.preAggregationsSchemaOption = this.options.preAggregationsSchema ?? DEFAULT_PREAGGREGATIONS_SCHEMA;
|
|
@@ -414,12 +445,38 @@ class BaseQuery {
|
|
|
414
445
|
}
|
|
415
446
|
return res;
|
|
416
447
|
}
|
|
448
|
+
/**
|
|
449
|
+
*
|
|
450
|
+
* @param measurePath
|
|
451
|
+
* @returns {BaseMeasure}
|
|
452
|
+
*/
|
|
417
453
|
newMeasure(measurePath) {
|
|
418
454
|
return new BaseMeasure_1.BaseMeasure(this, measurePath);
|
|
419
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
*
|
|
458
|
+
* @param dimensionPath
|
|
459
|
+
* @returns {BaseDimension}
|
|
460
|
+
*/
|
|
420
461
|
newDimension(dimensionPath) {
|
|
462
|
+
if (typeof dimensionPath === 'string') {
|
|
463
|
+
const memberArr = dimensionPath.split('.');
|
|
464
|
+
if (memberArr.length > 3 &&
|
|
465
|
+
memberArr[memberArr.length - 2] === 'granularities' &&
|
|
466
|
+
this.cubeEvaluator.isDimension(memberArr.slice(0, -2))) {
|
|
467
|
+
return this.newTimeDimension({
|
|
468
|
+
dimension: this.cubeEvaluator.pathFromArray(memberArr.slice(0, -2)),
|
|
469
|
+
granularity: memberArr[memberArr.length - 1]
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
421
473
|
return new BaseDimension_1.BaseDimension(this, dimensionPath);
|
|
422
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
*
|
|
477
|
+
* @param segmentPath
|
|
478
|
+
* @returns {BaseSegment}
|
|
479
|
+
*/
|
|
423
480
|
newSegment(segmentPath) {
|
|
424
481
|
return new BaseSegment_1.BaseSegment(this, segmentPath);
|
|
425
482
|
}
|
|
@@ -439,6 +496,11 @@ class BaseQuery {
|
|
|
439
496
|
newFilter(filter) {
|
|
440
497
|
return new BaseFilter_1.BaseFilter(this, filter);
|
|
441
498
|
}
|
|
499
|
+
/**
|
|
500
|
+
*
|
|
501
|
+
* @param filter
|
|
502
|
+
* @returns {BaseGroupFilter}
|
|
503
|
+
*/
|
|
442
504
|
newGroupFilter(filter) {
|
|
443
505
|
return new BaseGroupFilter_1.BaseGroupFilter(filter);
|
|
444
506
|
}
|
|
@@ -449,9 +511,18 @@ class BaseQuery {
|
|
|
449
511
|
newTimeDimension(timeDimension) {
|
|
450
512
|
return new BaseTimeDimension_1.BaseTimeDimension(this, timeDimension);
|
|
451
513
|
}
|
|
514
|
+
/**
|
|
515
|
+
*
|
|
516
|
+
* @param expressionParams
|
|
517
|
+
* @returns {ParamAllocator}
|
|
518
|
+
*/
|
|
452
519
|
newParamAllocator(expressionParams) {
|
|
453
520
|
return new ParamAllocator_1.ParamAllocator(expressionParams);
|
|
454
521
|
}
|
|
522
|
+
/**
|
|
523
|
+
*
|
|
524
|
+
* @returns {PreAggregations}
|
|
525
|
+
*/
|
|
455
526
|
newPreAggregations() {
|
|
456
527
|
return new PreAggregations_1.PreAggregations(this, this.options.historyQueries || [], this.options.cubeLatticeCache);
|
|
457
528
|
}
|
|
@@ -477,7 +548,7 @@ class BaseQuery {
|
|
|
477
548
|
if (!this.options.preAggregationQuery) {
|
|
478
549
|
preAggForQuery =
|
|
479
550
|
this.preAggregations.findPreAggregationForQuery();
|
|
480
|
-
if (this.options.disableExternalPreAggregations && preAggForQuery
|
|
551
|
+
if (this.options.disableExternalPreAggregations && preAggForQuery?.preAggregation.external) {
|
|
481
552
|
preAggForQuery = undefined;
|
|
482
553
|
}
|
|
483
554
|
}
|
|
@@ -536,35 +607,35 @@ class BaseQuery {
|
|
|
536
607
|
* @returns {[string, Array<unknown>]}
|
|
537
608
|
*/
|
|
538
609
|
buildSqlAndParams(exportAnnotatedSql) {
|
|
539
|
-
if (!this.options.preAggregationQuery && !this.options.disableExternalPreAggregations && this.externalQueryClass) {
|
|
540
|
-
if (this.externalPreAggregationQuery()) { // TODO performance
|
|
541
|
-
return this.externalQuery().buildSqlAndParams(exportAnnotatedSql);
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
610
|
if (this.useNativeSqlPlanner) {
|
|
545
611
|
let isRelatedToPreAggregation = false;
|
|
546
|
-
if (this.
|
|
547
|
-
|
|
548
|
-
}
|
|
549
|
-
else if (!this.options.disableExternalPreAggregations && this.externalQueryClass) {
|
|
550
|
-
if (this.externalPreAggregationQuery()) {
|
|
612
|
+
if (!this.canUseNativeSqlPlannerPreAggregation) {
|
|
613
|
+
if (this.options.preAggregationQuery) {
|
|
551
614
|
isRelatedToPreAggregation = true;
|
|
552
615
|
}
|
|
553
|
-
|
|
554
|
-
else {
|
|
555
|
-
let preAggForQuery = this.preAggregations.findPreAggregationForQuery();
|
|
556
|
-
if (this.options.disableExternalPreAggregations && preAggForQuery && preAggForQuery.preAggregation.external) {
|
|
557
|
-
preAggForQuery = undefined;
|
|
558
|
-
}
|
|
559
|
-
if (preAggForQuery) {
|
|
616
|
+
else if (!this.options.disableExternalPreAggregations && this.externalQueryClass && this.externalPreAggregationQuery()) {
|
|
560
617
|
isRelatedToPreAggregation = true;
|
|
561
618
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
619
|
+
else {
|
|
620
|
+
let preAggForQuery = this.preAggregations.findPreAggregationForQuery();
|
|
621
|
+
if (this.options.disableExternalPreAggregations && preAggForQuery && preAggForQuery.preAggregation.external) {
|
|
622
|
+
preAggForQuery = undefined;
|
|
623
|
+
}
|
|
624
|
+
if (preAggForQuery) {
|
|
625
|
+
isRelatedToPreAggregation = true;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
if (isRelatedToPreAggregation) {
|
|
629
|
+
return this.newQueryWithoutNative().buildSqlAndParams(exportAnnotatedSql);
|
|
630
|
+
}
|
|
565
631
|
}
|
|
566
632
|
return this.buildSqlAndParamsRust(exportAnnotatedSql);
|
|
567
633
|
}
|
|
634
|
+
if (!this.options.preAggregationQuery && !this.options.disableExternalPreAggregations && this.externalQueryClass) {
|
|
635
|
+
if (this.externalPreAggregationQuery()) { // TODO performance
|
|
636
|
+
return this.externalQuery().buildSqlAndParams(exportAnnotatedSql);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
568
639
|
return this.compilers.compiler.withQuery(this, () => this.cacheValue(['buildSqlAndParams', exportAnnotatedSql], () => this.paramAllocator.buildSqlAndParams(this.buildParamAnnotatedSql(), exportAnnotatedSql, this.shouldReuseParams), { cache: this.queryCache }));
|
|
569
640
|
}
|
|
570
641
|
buildSqlAndParamsRust(exportAnnotatedSql) {
|
|
@@ -584,7 +655,8 @@ class BaseQuery {
|
|
|
584
655
|
offset: this.options.offset ? this.options.offset.toString() : null,
|
|
585
656
|
baseTools: this,
|
|
586
657
|
ungrouped: this.options.ungrouped,
|
|
587
|
-
exportAnnotatedSql: exportAnnotatedSql === true
|
|
658
|
+
exportAnnotatedSql: exportAnnotatedSql === true,
|
|
659
|
+
preAggregationQuery: this.options.preAggregationQuery
|
|
588
660
|
};
|
|
589
661
|
const buildResult = (0, native_1.buildSqlAndParams)(queryParams);
|
|
590
662
|
if (buildResult.error) {
|
|
@@ -596,9 +668,50 @@ class BaseQuery {
|
|
|
596
668
|
}
|
|
597
669
|
}
|
|
598
670
|
const res = buildResult.result;
|
|
671
|
+
const [query, params, preAggregation] = res;
|
|
599
672
|
// FIXME
|
|
600
|
-
|
|
601
|
-
|
|
673
|
+
const paramsArray = [...params];
|
|
674
|
+
if (preAggregation) {
|
|
675
|
+
this.preAggregations.preAggregationForQuery = preAggregation;
|
|
676
|
+
}
|
|
677
|
+
return [query, paramsArray];
|
|
678
|
+
}
|
|
679
|
+
// FIXME Temporary solution
|
|
680
|
+
findPreAggregationForQueryRust() {
|
|
681
|
+
let optionsOrder = this.options.order;
|
|
682
|
+
if (optionsOrder && !Array.isArray(optionsOrder)) {
|
|
683
|
+
optionsOrder = [optionsOrder];
|
|
684
|
+
}
|
|
685
|
+
const order = optionsOrder ? ramda_1.default.pipe(ramda_1.default.map((hash) => ((!hash || !hash.id) ? null : hash)), ramda_1.default.reject(ramda_1.default.isNil))(optionsOrder) : undefined;
|
|
686
|
+
const queryParams = {
|
|
687
|
+
measures: this.options.measures,
|
|
688
|
+
dimensions: this.options.dimensions,
|
|
689
|
+
segments: this.options.segments,
|
|
690
|
+
timeDimensions: this.options.timeDimensions,
|
|
691
|
+
timezone: this.options.timezone,
|
|
692
|
+
joinGraph: this.joinGraph,
|
|
693
|
+
cubeEvaluator: this.cubeEvaluator,
|
|
694
|
+
order,
|
|
695
|
+
filters: this.options.filters,
|
|
696
|
+
limit: this.options.limit ? this.options.limit.toString() : null,
|
|
697
|
+
rowLimit: this.options.rowLimit ? this.options.rowLimit.toString() : null,
|
|
698
|
+
offset: this.options.offset ? this.options.offset.toString() : null,
|
|
699
|
+
baseTools: this,
|
|
700
|
+
ungrouped: this.options.ungrouped,
|
|
701
|
+
exportAnnotatedSql: false,
|
|
702
|
+
preAggregationQuery: this.options.preAggregationQuery
|
|
703
|
+
};
|
|
704
|
+
const buildResult = (0, native_1.buildSqlAndParams)(queryParams);
|
|
705
|
+
if (buildResult.error) {
|
|
706
|
+
if (buildResult.error.cause === 'User') {
|
|
707
|
+
throw new UserError_1.UserError(buildResult.error.message);
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
throw new Error(buildResult.error.message);
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
const [, , preAggregation] = buildResult.result;
|
|
714
|
+
return preAggregation;
|
|
602
715
|
}
|
|
603
716
|
allCubeMembers(path) {
|
|
604
717
|
const fromPath = this.cubeEvaluator.cubeFromPath(path);
|
|
@@ -615,6 +728,9 @@ class BaseQuery {
|
|
|
615
728
|
generateCustomTimeSeries(granularityInterval, dateRange, origin) {
|
|
616
729
|
return (0, shared_1.timeSeriesFromCustomInterval)(granularityInterval, dateRange, (0, moment_timezone_1.default)(origin), { timestampPrecision: 3 });
|
|
617
730
|
}
|
|
731
|
+
getPreAggregationByName(cube, preAggregationName) {
|
|
732
|
+
return this.preAggregations.getRollupPreAggregationByName(cube, preAggregationName);
|
|
733
|
+
}
|
|
618
734
|
get shouldReuseParams() {
|
|
619
735
|
return false;
|
|
620
736
|
}
|
|
@@ -860,7 +976,7 @@ class BaseQuery {
|
|
|
860
976
|
return `WITH\n${withQueries.map(q => `${q.alias} AS (${q.query})`).join(',\n')}\n${select}`;
|
|
861
977
|
}
|
|
862
978
|
fullKeyQueryAggregateMeasures(context) {
|
|
863
|
-
const measureToHierarchy = this.
|
|
979
|
+
const measureToHierarchy = this.collectRootMeasureToHierarchy(context);
|
|
864
980
|
const allMemberChildren = this.collectAllMemberChildren(context);
|
|
865
981
|
const memberToIsMultiStage = this.collectAllMultiStageMembers(allMemberChildren);
|
|
866
982
|
const hasMultiStageMembers = (m) => {
|
|
@@ -936,12 +1052,12 @@ class BaseQuery {
|
|
|
936
1052
|
// TODO calculate based on remove_filter in future
|
|
937
1053
|
const wouldNodeApplyFilters = !memberChildren[member];
|
|
938
1054
|
let memberFrom = memberChildren[member]
|
|
939
|
-
?.map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, queryContext
|
|
1055
|
+
?.map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, queryContext), memberChildren, withQueries));
|
|
940
1056
|
const unionFromDimensions = memberFrom ? ramda_1.default.uniq(ramda_1.default.flatten(memberFrom.map(f => f.dimensions))) : queryContext.dimensions;
|
|
941
1057
|
const unionDimensionsContext = { ...queryContext, dimensions: unionFromDimensions.filter(d => !this.newDimension(d).isMultiStage()) };
|
|
942
1058
|
// TODO is calling multiStageWithQueries twice optimal?
|
|
943
1059
|
memberFrom = memberChildren[member] &&
|
|
944
|
-
ramda_1.default.uniqBy(f => f.alias, memberChildren[member].map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, unionDimensionsContext
|
|
1060
|
+
ramda_1.default.uniqBy(f => f.alias, memberChildren[member].map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, unionDimensionsContext), memberChildren, withQueries)));
|
|
945
1061
|
const selfContext = this.selfMultiStageContext(member, queryContext, wouldNodeApplyFilters);
|
|
946
1062
|
const subQuery = {
|
|
947
1063
|
...selfContext,
|
|
@@ -960,7 +1076,7 @@ class BaseQuery {
|
|
|
960
1076
|
usedQueries[member.alias] = true;
|
|
961
1077
|
member.memberFrom?.forEach(m => this.collectUsedWithQueries(usedQueries, m));
|
|
962
1078
|
}
|
|
963
|
-
childrenMultiStageContext(memberPath, queryContext
|
|
1079
|
+
childrenMultiStageContext(memberPath, queryContext) {
|
|
964
1080
|
let member;
|
|
965
1081
|
if (this.cubeEvaluator.isMeasure(memberPath)) {
|
|
966
1082
|
member = this.newMeasure(memberPath);
|
|
@@ -973,13 +1089,29 @@ class BaseQuery {
|
|
|
973
1089
|
if (memberDef.addGroupByReferences) {
|
|
974
1090
|
queryContext = { ...queryContext, dimensions: ramda_1.default.uniq(queryContext.dimensions.concat(memberDef.addGroupByReferences)) };
|
|
975
1091
|
}
|
|
976
|
-
if (memberDef.timeShiftReferences) {
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
1092
|
+
if (memberDef.timeShiftReferences?.length) {
|
|
1093
|
+
let mapFn;
|
|
1094
|
+
if (memberDef.timeShiftReferences.length === 1 && !memberDef.timeShiftReferences[0].timeDimension) {
|
|
1095
|
+
const timeShift = memberDef.timeShiftReferences[0];
|
|
1096
|
+
mapFn = (td) => {
|
|
1097
|
+
if (td.shiftInterval) {
|
|
1098
|
+
throw new UserError_1.UserError(`Hierarchical time shift is not supported but was provided for '${td.dimension}'. Parent time shift is '${td.shiftInterval}' and current is '${timeShift.interval}'`);
|
|
1099
|
+
}
|
|
1100
|
+
return {
|
|
1101
|
+
...td,
|
|
1102
|
+
shiftInterval: timeShift.type === 'next' ? this.negateInterval(timeShift.interval) : timeShift.interval
|
|
1103
|
+
};
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
const allBackAliasMembers = this.allBackAliasTimeDimensions();
|
|
1108
|
+
mapFn = (td) => {
|
|
1109
|
+
const timeShift = memberDef.timeShiftReferences.find(r => r.timeDimension === td.dimension || td.dimension === allBackAliasMembers[r.timeDimension]);
|
|
981
1110
|
if (timeShift) {
|
|
982
|
-
|
|
1111
|
+
// We need to ignore aliased td, because it will match and insert shiftInterval on first
|
|
1112
|
+
// occurrence, but later during recursion it will hit the original td but shiftInterval will be
|
|
1113
|
+
// present and simple check for td.shiftInterval will always result in error.
|
|
1114
|
+
if (td.shiftInterval && !td.dimension === allBackAliasMembers[timeShift.timeDimension]) {
|
|
983
1115
|
throw new UserError_1.UserError(`Hierarchical time shift is not supported but was provided for '${td.dimension}'. Parent time shift is '${td.shiftInterval}' and current is '${timeShift.interval}'`);
|
|
984
1116
|
}
|
|
985
1117
|
return {
|
|
@@ -988,7 +1120,11 @@ class BaseQuery {
|
|
|
988
1120
|
};
|
|
989
1121
|
}
|
|
990
1122
|
return td;
|
|
991
|
-
}
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
queryContext = {
|
|
1126
|
+
...queryContext,
|
|
1127
|
+
timeDimensions: queryContext.timeDimensions.map(mapFn)
|
|
992
1128
|
};
|
|
993
1129
|
}
|
|
994
1130
|
queryContext = {
|
|
@@ -1340,7 +1476,7 @@ class BaseQuery {
|
|
|
1340
1476
|
measure: attachedMeasure,
|
|
1341
1477
|
}]];
|
|
1342
1478
|
}
|
|
1343
|
-
|
|
1479
|
+
collectRootMeasureToHierarchy(context) {
|
|
1344
1480
|
const notAddedMeasureFilters = ramda_1.default.flatten(this.measureFilters.map(f => f.getMembers()))
|
|
1345
1481
|
.filter(f => ramda_1.default.none(m => m.measure === f.measure, this.measures));
|
|
1346
1482
|
return ramda_1.default.fromPairs(this.measures.concat(notAddedMeasureFilters).map(m => {
|
|
@@ -1659,8 +1795,12 @@ class BaseQuery {
|
|
|
1659
1795
|
return this.evaluateSql(s.cube().name, s.definition().sql);
|
|
1660
1796
|
}
|
|
1661
1797
|
}
|
|
1662
|
-
|
|
1663
|
-
|
|
1798
|
+
/**
|
|
1799
|
+
*
|
|
1800
|
+
* @returns {Array<string>}
|
|
1801
|
+
*/
|
|
1802
|
+
collectCubeNames() {
|
|
1803
|
+
return this.collectFromMembers([], this.collectCubeNamesFor.bind(this), 'collectCubeNamesFor');
|
|
1664
1804
|
}
|
|
1665
1805
|
/**
|
|
1666
1806
|
*
|
|
@@ -1744,6 +1884,11 @@ class BaseQuery {
|
|
|
1744
1884
|
const dimensionNames = dimensionColumns.map((c, i) => `${i + 1}`);
|
|
1745
1885
|
return this.rollupGroupByClause(dimensionNames);
|
|
1746
1886
|
}
|
|
1887
|
+
/**
|
|
1888
|
+
* XXX: String as return value is added because of HiveQuery.getFieldIndex()
|
|
1889
|
+
* @param id
|
|
1890
|
+
* @returns {number|string|null}
|
|
1891
|
+
*/
|
|
1747
1892
|
getFieldIndex(id) {
|
|
1748
1893
|
const equalIgnoreCase = (a, b) => (typeof a === 'string' && typeof b === 'string' && a.toUpperCase() === b.toUpperCase());
|
|
1749
1894
|
let index;
|
|
@@ -2131,6 +2276,11 @@ class BaseQuery {
|
|
|
2131
2276
|
? prefix + '__' + this.aliasName(cubeName)
|
|
2132
2277
|
: cubeName}`));
|
|
2133
2278
|
}
|
|
2279
|
+
/**
|
|
2280
|
+
*
|
|
2281
|
+
* @param fn
|
|
2282
|
+
* @returns {Array<string>}
|
|
2283
|
+
*/
|
|
2134
2284
|
collectCubeNamesFor(fn) {
|
|
2135
2285
|
const context = { cubeNames: [] };
|
|
2136
2286
|
this.evaluateSymbolSqlWithContext(fn, context);
|
|
@@ -2141,6 +2291,11 @@ class BaseQuery {
|
|
|
2141
2291
|
this.evaluateSymbolSqlWithContext(fn, context);
|
|
2142
2292
|
return context.joinHints;
|
|
2143
2293
|
}
|
|
2294
|
+
/**
|
|
2295
|
+
*
|
|
2296
|
+
* @param fn
|
|
2297
|
+
* @returns {Array<string>}
|
|
2298
|
+
*/
|
|
2144
2299
|
collectMemberNamesFor(fn) {
|
|
2145
2300
|
const context = { memberNames: [] };
|
|
2146
2301
|
this.evaluateSymbolSqlWithContext(fn, context);
|
|
@@ -2367,6 +2522,10 @@ class BaseQuery {
|
|
|
2367
2522
|
const primaryKeyDimension = this.cubeEvaluator.dimensionByPath([cubeName, primaryKeyName]);
|
|
2368
2523
|
return this.evaluateSymbolSql(cubeName, primaryKeyName, primaryKeyDimension);
|
|
2369
2524
|
}
|
|
2525
|
+
/**
|
|
2526
|
+
* @param cubeName
|
|
2527
|
+
* @returns Boolean
|
|
2528
|
+
*/
|
|
2370
2529
|
multipliedJoinRowResult(cubeName) {
|
|
2371
2530
|
// this.join not initialized on collectCubeNamesForSql
|
|
2372
2531
|
return this.join && this.join.multiplicationFactor[cubeName];
|
|
@@ -2490,12 +2649,17 @@ class BaseQuery {
|
|
|
2490
2649
|
// use single underscore for pre-aggregations to avoid fail of pre-aggregation name replace
|
|
2491
2650
|
return inflection_1.default.underscore(name).replace(/\./g, isPreAggregationName ? '_' : '__');
|
|
2492
2651
|
}
|
|
2652
|
+
/**
|
|
2653
|
+
*
|
|
2654
|
+
* @param options
|
|
2655
|
+
* @returns {BaseQuery}
|
|
2656
|
+
*/
|
|
2493
2657
|
newSubQuery(options) {
|
|
2494
2658
|
const QueryClass = this.constructor;
|
|
2495
2659
|
return new QueryClass(this.compilers, this.subQueryOptions(options));
|
|
2496
2660
|
}
|
|
2497
2661
|
newSubQueryForCube(cube, options) {
|
|
2498
|
-
options = { ...options
|
|
2662
|
+
options = { ...options };
|
|
2499
2663
|
if (this.options.queryFactory) {
|
|
2500
2664
|
// When dealing with rollup joins, it's crucial to use the correct parameter allocator for the specific cube in use.
|
|
2501
2665
|
// By default, we'll use BaseQuery, but it's important to note that different databases (Oracle, PostgreSQL, MySQL, Druid, etc.)
|
|
@@ -2903,13 +3067,19 @@ class BaseQuery {
|
|
|
2903
3067
|
},
|
|
2904
3068
|
};
|
|
2905
3069
|
}
|
|
3070
|
+
/**
|
|
3071
|
+
*
|
|
3072
|
+
* @param cube
|
|
3073
|
+
* @param preAggregation
|
|
3074
|
+
* @returns {BaseQuery}
|
|
3075
|
+
*/
|
|
2906
3076
|
// eslint-disable-next-line consistent-return
|
|
2907
|
-
preAggregationQueryForSqlEvaluation(cube, preAggregation) {
|
|
3077
|
+
preAggregationQueryForSqlEvaluation(cube, preAggregation, context = {}) {
|
|
2908
3078
|
if (preAggregation.type === 'autoRollup') {
|
|
2909
3079
|
return this.preAggregations.autoRollupPreAggregationQuery(cube, preAggregation);
|
|
2910
3080
|
}
|
|
2911
3081
|
else if (preAggregation.type === 'rollup') {
|
|
2912
|
-
return this.preAggregations.rollupPreAggregationQuery(cube, preAggregation);
|
|
3082
|
+
return this.preAggregations.rollupPreAggregationQuery(cube, preAggregation, context);
|
|
2913
3083
|
}
|
|
2914
3084
|
else if (preAggregation.type === 'originalSql') {
|
|
2915
3085
|
return this;
|
|
@@ -3395,9 +3565,22 @@ class BaseQuery {
|
|
|
3395
3565
|
.concat(this.timeDimensions)
|
|
3396
3566
|
.map(m => m.getMembers()));
|
|
3397
3567
|
}
|
|
3568
|
+
/**
|
|
3569
|
+
* @returns {Record<string, string>}
|
|
3570
|
+
*/
|
|
3571
|
+
allBackAliasTimeDimensions() {
|
|
3572
|
+
const members = ramda_1.default.flatten(this.timeDimensions.map(m => m.getMembers()));
|
|
3573
|
+
return this.backAliasMembers(members);
|
|
3574
|
+
}
|
|
3575
|
+
/**
|
|
3576
|
+
* @returns {Record<string, string>}
|
|
3577
|
+
*/
|
|
3398
3578
|
allBackAliasMembersExceptSegments() {
|
|
3399
3579
|
return this.backAliasMembers(this.flattenAllMembers(true));
|
|
3400
3580
|
}
|
|
3581
|
+
/**
|
|
3582
|
+
* @returns {Record<string, string>}
|
|
3583
|
+
*/
|
|
3401
3584
|
allBackAliasMembers() {
|
|
3402
3585
|
return this.backAliasMembers(this.flattenAllMembers());
|
|
3403
3586
|
}
|