@cubejs-backend/schema-compiler 1.3.83 → 1.3.85
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/BaseQuery.d.ts +12 -4
- package/dist/src/adapter/BaseQuery.d.ts.map +1 -1
- package/dist/src/adapter/BaseQuery.js +61 -18
- package/dist/src/adapter/BaseQuery.js.map +1 -1
- package/dist/src/adapter/OracleQuery.d.ts +10 -0
- package/dist/src/adapter/OracleQuery.d.ts.map +1 -1
- package/dist/src/adapter/OracleQuery.js +76 -1
- package/dist/src/adapter/OracleQuery.js.map +1 -1
- package/dist/src/adapter/PreAggregations.d.ts +15 -2
- package/dist/src/adapter/PreAggregations.d.ts.map +1 -1
- package/dist/src/adapter/PreAggregations.js +100 -49
- package/dist/src/adapter/PreAggregations.js.map +1 -1
- package/dist/src/compiler/CubeEvaluator.d.ts +2 -3
- package/dist/src/compiler/CubeEvaluator.d.ts.map +1 -1
- package/dist/src/compiler/CubeEvaluator.js +10 -3
- package/dist/src/compiler/CubeEvaluator.js.map +1 -1
- package/dist/src/compiler/CubeSymbols.d.ts +14 -3
- package/dist/src/compiler/CubeSymbols.d.ts.map +1 -1
- package/dist/src/compiler/CubeSymbols.js +30 -7
- package/dist/src/compiler/CubeSymbols.js.map +1 -1
- package/dist/src/compiler/JoinGraph.d.ts +1 -1
- package/dist/src/compiler/JoinGraph.d.ts.map +1 -1
- package/dist/src/scaffolding/ScaffoldingSchema.d.ts.map +1 -1
- package/dist/src/scaffolding/ScaffoldingSchema.js +10 -1
- package/dist/src/scaffolding/ScaffoldingSchema.js.map +1 -1
- package/package.json +6 -6
|
@@ -20,6 +20,16 @@ export declare class OracleQuery extends BaseQuery {
|
|
|
20
20
|
timeStampCast(value: any): string;
|
|
21
21
|
timeStampParam(timeDimension: any): string;
|
|
22
22
|
timeGroupedColumn(granularity: any, dimension: any): any;
|
|
23
|
+
/**
|
|
24
|
+
* Oracle uses ADD_MONTHS for year/month/quarter intervals
|
|
25
|
+
* and NUMTODSINTERVAL for day/hour/minute/second intervals
|
|
26
|
+
*/
|
|
27
|
+
addInterval(date: string, interval: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Oracle subtraction uses ADD_MONTHS with negative values
|
|
30
|
+
* and subtracts NUMTODSINTERVAL for time units
|
|
31
|
+
*/
|
|
32
|
+
subtractInterval(date: string, interval: string): string;
|
|
23
33
|
newFilter(filter: any): any;
|
|
24
34
|
unixTimestampSql(): string;
|
|
25
35
|
preAggregationTableName(cube: any, preAggregationName: any, skipSchema: any): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OracleQuery.d.ts","sourceRoot":"","sources":["../../../src/adapter/OracleQuery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"OracleQuery.d.ts","sourceRoot":"","sources":["../../../src/adapter/OracleQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AA8BxC,qBAAa,WAAY,SAAQ,SAAS;IACxC;;;OAGG;IACI,qBAAqB;IAM5B;;OAEG;IACH,IAAW,aAAa,WAEvB;IAED,IAAW,YAAY,WAEtB;IAED;;;OAGG;IACI,aAAa;IAab,SAAS,CAAC,KAAK,KAAA;IAOf,YAAY,CAAC,KAAK,KAAA;IAMlB,aAAa,CAAC,KAAK,KAAA;IAKnB,cAAc,CAAC,aAAa,KAAA;IAI5B,iBAAiB,CAAC,WAAW,KAAA,EAAE,SAAS,KAAA;IAO/C;;;OAGG;IACI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAqC1D;;;OAGG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAqCxD,SAAS,CAAC,MAAM,KAAA;IAIhB,gBAAgB;IAKhB,uBAAuB,CAAC,IAAI,KAAA,EAAE,kBAAkB,KAAA,EAAE,UAAU,KAAA;CAOpE"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.OracleQuery = void 0;
|
|
4
|
+
const shared_1 = require("@cubejs-backend/shared");
|
|
4
5
|
const BaseQuery_1 = require("./BaseQuery");
|
|
5
6
|
const BaseFilter_1 = require("./BaseFilter");
|
|
6
7
|
const UserError_1 = require("../compiler/UserError");
|
|
@@ -50,7 +51,9 @@ class OracleQuery extends BaseQuery_1.BaseQuery {
|
|
|
50
51
|
* using forSelect dimensions for grouping
|
|
51
52
|
*/
|
|
52
53
|
groupByClause() {
|
|
53
|
-
|
|
54
|
+
// Only include dimensions that have select columns
|
|
55
|
+
// Time dimensions without granularity return null from selectColumns()
|
|
56
|
+
const dimensions = this.forSelect().filter((item) => (!!item.dimension && item.selectColumns && item.selectColumns()));
|
|
54
57
|
if (!dimensions.length) {
|
|
55
58
|
return '';
|
|
56
59
|
}
|
|
@@ -80,6 +83,78 @@ class OracleQuery extends BaseQuery_1.BaseQuery {
|
|
|
80
83
|
}
|
|
81
84
|
return `TRUNC(${dimension}, '${GRANULARITY_VALUE[granularity]}')`;
|
|
82
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Oracle uses ADD_MONTHS for year/month/quarter intervals
|
|
88
|
+
* and NUMTODSINTERVAL for day/hour/minute/second intervals
|
|
89
|
+
*/
|
|
90
|
+
addInterval(date, interval) {
|
|
91
|
+
const intervalParsed = (0, shared_1.parseSqlInterval)(interval);
|
|
92
|
+
let res = date;
|
|
93
|
+
// Handle year/month/quarter using ADD_MONTHS
|
|
94
|
+
let totalMonths = 0;
|
|
95
|
+
if (intervalParsed.year) {
|
|
96
|
+
totalMonths += intervalParsed.year * 12;
|
|
97
|
+
}
|
|
98
|
+
if (intervalParsed.quarter) {
|
|
99
|
+
totalMonths += intervalParsed.quarter * 3;
|
|
100
|
+
}
|
|
101
|
+
if (intervalParsed.month) {
|
|
102
|
+
totalMonths += intervalParsed.month;
|
|
103
|
+
}
|
|
104
|
+
if (totalMonths !== 0) {
|
|
105
|
+
res = `ADD_MONTHS(${res}, ${totalMonths})`;
|
|
106
|
+
}
|
|
107
|
+
// Handle day/hour/minute/second using NUMTODSINTERVAL
|
|
108
|
+
if (intervalParsed.day) {
|
|
109
|
+
res = `${res} + NUMTODSINTERVAL(${intervalParsed.day}, 'DAY')`;
|
|
110
|
+
}
|
|
111
|
+
if (intervalParsed.hour) {
|
|
112
|
+
res = `${res} + NUMTODSINTERVAL(${intervalParsed.hour}, 'HOUR')`;
|
|
113
|
+
}
|
|
114
|
+
if (intervalParsed.minute) {
|
|
115
|
+
res = `${res} + NUMTODSINTERVAL(${intervalParsed.minute}, 'MINUTE')`;
|
|
116
|
+
}
|
|
117
|
+
if (intervalParsed.second) {
|
|
118
|
+
res = `${res} + NUMTODSINTERVAL(${intervalParsed.second}, 'SECOND')`;
|
|
119
|
+
}
|
|
120
|
+
return res;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Oracle subtraction uses ADD_MONTHS with negative values
|
|
124
|
+
* and subtracts NUMTODSINTERVAL for time units
|
|
125
|
+
*/
|
|
126
|
+
subtractInterval(date, interval) {
|
|
127
|
+
const intervalParsed = (0, shared_1.parseSqlInterval)(interval);
|
|
128
|
+
let res = date;
|
|
129
|
+
// Handle year/month/quarter using ADD_MONTHS with negative values
|
|
130
|
+
let totalMonths = 0;
|
|
131
|
+
if (intervalParsed.year) {
|
|
132
|
+
totalMonths += intervalParsed.year * 12;
|
|
133
|
+
}
|
|
134
|
+
if (intervalParsed.quarter) {
|
|
135
|
+
totalMonths += intervalParsed.quarter * 3;
|
|
136
|
+
}
|
|
137
|
+
if (intervalParsed.month) {
|
|
138
|
+
totalMonths += intervalParsed.month;
|
|
139
|
+
}
|
|
140
|
+
if (totalMonths !== 0) {
|
|
141
|
+
res = `ADD_MONTHS(${res}, -${totalMonths})`;
|
|
142
|
+
}
|
|
143
|
+
// Handle day/hour/minute/second using NUMTODSINTERVAL with subtraction
|
|
144
|
+
if (intervalParsed.day) {
|
|
145
|
+
res = `${res} - NUMTODSINTERVAL(${intervalParsed.day}, 'DAY')`;
|
|
146
|
+
}
|
|
147
|
+
if (intervalParsed.hour) {
|
|
148
|
+
res = `${res} - NUMTODSINTERVAL(${intervalParsed.hour}, 'HOUR')`;
|
|
149
|
+
}
|
|
150
|
+
if (intervalParsed.minute) {
|
|
151
|
+
res = `${res} - NUMTODSINTERVAL(${intervalParsed.minute}, 'MINUTE')`;
|
|
152
|
+
}
|
|
153
|
+
if (intervalParsed.second) {
|
|
154
|
+
res = `${res} - NUMTODSINTERVAL(${intervalParsed.second}, 'SECOND')`;
|
|
155
|
+
}
|
|
156
|
+
return res;
|
|
157
|
+
}
|
|
83
158
|
newFilter(filter) {
|
|
84
159
|
return new OracleFilter(this, filter);
|
|
85
160
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OracleQuery.js","sourceRoot":"","sources":["../../../src/adapter/OracleQuery.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AACxC,6CAA0C;AAC1C,qDAAkD;AAGlD,MAAM,iBAAiB,GAAG;IACxB,GAAG,EAAE,IAAI;IACT,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE,IAAI;IACZ,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;IACX,IAAI,EAAE,MAAM;CACb,CAAC;AAEF,MAAM,YAAa,SAAQ,uBAAU;IAC5B,aAAa;QAClB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI;QAC5C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,OAAO,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IACnF,CAAC;CACF;AAED,MAAa,WAAY,SAAQ,qBAAS;IACxC;;;OAGG;IACI,qBAAqB;QAC1B,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,KAAK,YAAY,CAAC;QACnI,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACpF,OAAO,GAAG,YAAY,GAAG,WAAW,EAAE,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,IAAW,aAAa;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;OAGG;IACI,aAAa;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,IAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"OracleQuery.js","sourceRoot":"","sources":["../../../src/adapter/OracleQuery.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PreAggregationDefinition } from '../compiler/CubeSymbols';
|
|
2
|
+
import { JoinEdge } from '../compiler/JoinGraph';
|
|
2
3
|
import { BaseQuery } from './BaseQuery';
|
|
3
4
|
import { PreAggregationReferences, PreAggregationTimeDimensionReference } from '../compiler/CubeEvaluator';
|
|
4
5
|
import { BaseTimeDimension } from './BaseTimeDimension';
|
|
@@ -7,7 +8,6 @@ import { BaseFilter } from './BaseFilter';
|
|
|
7
8
|
import { BaseGroupFilter } from './BaseGroupFilter';
|
|
8
9
|
import { BaseDimension } from './BaseDimension';
|
|
9
10
|
import { BaseSegment } from './BaseSegment';
|
|
10
|
-
export type RollupJoin = any;
|
|
11
11
|
export type PartitionTimeDimension = {
|
|
12
12
|
dimension: string;
|
|
13
13
|
dateRange: [string, string];
|
|
@@ -50,6 +50,15 @@ export type EvaluateReferencesContext = {
|
|
|
50
50
|
inPreAggEvaluation?: boolean;
|
|
51
51
|
};
|
|
52
52
|
export type BaseMember = BaseDimension | BaseMeasure | BaseFilter | BaseGroupFilter | BaseSegment;
|
|
53
|
+
export type JoinEdgeWithMembers = JoinEdge & {
|
|
54
|
+
fromMembers: string[];
|
|
55
|
+
toMembers: string[];
|
|
56
|
+
};
|
|
57
|
+
export type RollupJoinItem = JoinEdgeWithMembers & {
|
|
58
|
+
fromPreAggObj: PreAggregationForQuery;
|
|
59
|
+
toPreAggObj: PreAggregationForQuery;
|
|
60
|
+
};
|
|
61
|
+
export type RollupJoin = RollupJoinItem[];
|
|
53
62
|
export type CanUsePreAggregationFn = (references: PreAggregationReferences) => boolean;
|
|
54
63
|
/**
|
|
55
64
|
* TODO: Write a real type.
|
|
@@ -120,10 +129,11 @@ export declare class PreAggregations {
|
|
|
120
129
|
private rollupMatchResults;
|
|
121
130
|
private findRollupPreAggregationsForCube;
|
|
122
131
|
getRollupPreAggregationByName(cube: any, preAggregationName: any): PreAggregationForQueryWithTableName | {};
|
|
132
|
+
private collectJoinHintsFromRollupReferences;
|
|
123
133
|
private buildRollupJoin;
|
|
124
134
|
private preAggObjForJoin;
|
|
125
135
|
private resolveJoinMembers;
|
|
126
|
-
private
|
|
136
|
+
private cubesHintsFromPreAggregation;
|
|
127
137
|
private evaluatedPreAggregationObj;
|
|
128
138
|
static checkPartitionGranularityDefined(cube: string, preAggregationName: string, preAggregation: PreAggregationForQuery): string;
|
|
129
139
|
static memberNameMismatchValidation(preAggA: PreAggregationForQuery, preAggB: PreAggregationForQuery, memberType: 'measures' | 'dimensions' | 'timeDimensions'): void;
|
|
@@ -147,6 +157,9 @@ export declare class PreAggregations {
|
|
|
147
157
|
autoRollupPreAggregationQuery(cube: string, aggregation: PreAggregationDefinitionExtended): BaseQuery;
|
|
148
158
|
private mergePartitionTimeDimensions;
|
|
149
159
|
private autoRollupNameSuffix;
|
|
160
|
+
private enrichMembersCubeJoinPath;
|
|
161
|
+
private buildMembersFullName;
|
|
162
|
+
private buildTimeDimensionsFullName;
|
|
150
163
|
private evaluateAllReferences;
|
|
151
164
|
originalSqlPreAggregationTable(preAggregationDescription: PreAggregationForCube): string;
|
|
152
165
|
private rollupLambdaUnion;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PreAggregations.d.ts","sourceRoot":"","sources":["../../../src/adapter/PreAggregations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"PreAggregations.d.ts","sourceRoot":"","sources":["../../../src/adapter/PreAggregations.ts"],"names":[],"mappings":"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"}
|
|
@@ -63,7 +63,7 @@ class PreAggregations {
|
|
|
63
63
|
if (foundPreAggregation.preAggregation.type === 'rollupJoin') {
|
|
64
64
|
preAggregations = foundPreAggregation.preAggregationsToJoin || [];
|
|
65
65
|
}
|
|
66
|
-
if (foundPreAggregation.preAggregation.type === 'rollupLambda') {
|
|
66
|
+
else if (foundPreAggregation.preAggregation.type === 'rollupLambda') {
|
|
67
67
|
preAggregations = foundPreAggregation.referencedPreAggregations || [];
|
|
68
68
|
}
|
|
69
69
|
return preAggregations.map(preAggregation => {
|
|
@@ -425,10 +425,10 @@ class PreAggregations {
|
|
|
425
425
|
* Determine whether pre-aggregation can be used or not.
|
|
426
426
|
*/
|
|
427
427
|
const canUsePreAggregationNotAdditive = (references) => {
|
|
428
|
-
const refTimeDimensions = backAlias(sortTimeDimensions(references.timeDimensions));
|
|
429
428
|
const qryTimeDimensions = references.allowNonStrictDateRangeMatch
|
|
430
429
|
? transformedQuery.timeDimensions
|
|
431
430
|
: transformedQuery.sortedTimeDimensions;
|
|
431
|
+
const refTimeDimensions = backAlias(sortTimeDimensions(references.timeDimensions));
|
|
432
432
|
const backAliasMeasures = backAlias(references.measures);
|
|
433
433
|
const backAliasDimensions = backAlias(references.dimensions);
|
|
434
434
|
return ((transformedQuery.hasNoTimeDimensionsWithoutGranularity) && (!transformedQuery.hasCumulativeMeasures) && (ramda_1.default.equals(qryTimeDimensions, refTimeDimensions)) && (transformedQuery.isAdditive ||
|
|
@@ -436,9 +436,9 @@ class PreAggregations {
|
|
|
436
436
|
references.dimensions.length === filterDimensionsSingleValueEqual.size &&
|
|
437
437
|
ramda_1.default.all(d => filterDimensionsSingleValueEqual.has(d), backAliasDimensions) ||
|
|
438
438
|
transformedQuery.allFiltersWithinSelectedDimensions &&
|
|
439
|
-
ramda_1.default.equals(backAliasDimensions, transformedQuery.sortedDimensions)) && (ramda_1.default.all(m => backAliasMeasures.
|
|
439
|
+
ramda_1.default.equals(backAliasDimensions, transformedQuery.sortedDimensions)) && (ramda_1.default.all(m => backAliasMeasures.includes(m), transformedQuery.measures) ||
|
|
440
440
|
// TODO do we need backAlias here?
|
|
441
|
-
ramda_1.default.all(m => backAliasMeasures.
|
|
441
|
+
ramda_1.default.all(m => backAliasMeasures.includes(m), transformedQuery.leafMeasures)));
|
|
442
442
|
};
|
|
443
443
|
/**
|
|
444
444
|
* Expand granularity into array of granularity hierarchy.
|
|
@@ -491,15 +491,10 @@ class PreAggregations {
|
|
|
491
491
|
return false;
|
|
492
492
|
}
|
|
493
493
|
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
backAlias(dimsToMatch) :
|
|
499
|
-
(dimsToMatch)).indexOf(d) !== -1, dimensions);
|
|
500
|
-
// In 'rollupJoin' / 'rollupLambda' pre-aggregations fullName members will be empty, because there are
|
|
501
|
-
// no connections in the joinTree between cubes from different datasources
|
|
502
|
-
const timeDimsToMatch = references.rollups.length > 0 ? references.timeDimensions : references.fullNameTimeDimensions;
|
|
494
|
+
const dimensionsMatch = (dimensions, doBackAlias) => {
|
|
495
|
+
const target = doBackAlias ? backAlias(references.dimensions) : references.dimensions;
|
|
496
|
+
return dimensions.every(d => target.includes(d));
|
|
497
|
+
};
|
|
503
498
|
const timeDimensionsMatch = (timeDimensionsList, doBackAlias) => ramda_1.default.allPass(timeDimensionsList.map(tds => ramda_1.default.anyPass(tds.map((td) => {
|
|
504
499
|
if (td[1] === '*') {
|
|
505
500
|
return ramda_1.default.any((tdtc) => tdtc[0] === td[0]); // need to match the dimension at least
|
|
@@ -508,8 +503,8 @@ class PreAggregations {
|
|
|
508
503
|
return ramda_1.default.includes(td);
|
|
509
504
|
}
|
|
510
505
|
}))))(doBackAlias ?
|
|
511
|
-
backAlias(sortTimeDimensions(
|
|
512
|
-
(sortTimeDimensions(
|
|
506
|
+
backAlias(sortTimeDimensions(references.timeDimensions)) :
|
|
507
|
+
(sortTimeDimensions(references.timeDimensions)));
|
|
513
508
|
if (transformedQuery.ungrouped) {
|
|
514
509
|
const allReferenceCubes = ramda_1.default.pipe(ramda_1.default.map((name) => name?.split('.')[0]), ramda_1.default.uniq, ramda_1.default.sortBy(ramda_1.default.identity))([
|
|
515
510
|
...references.measures.map(m => CubeSymbols_1.CubeSymbols.joinHintFromPath(m).path),
|
|
@@ -634,15 +629,30 @@ class PreAggregations {
|
|
|
634
629
|
return {};
|
|
635
630
|
}
|
|
636
631
|
}
|
|
632
|
+
collectJoinHintsFromRollupReferences(refs) {
|
|
633
|
+
if (!refs.joinTree) {
|
|
634
|
+
return [];
|
|
635
|
+
}
|
|
636
|
+
const hints = [refs.joinTree.root];
|
|
637
|
+
for (const j of refs.joinTree.joins) {
|
|
638
|
+
hints.push([j.from, j.to]);
|
|
639
|
+
}
|
|
640
|
+
return hints;
|
|
641
|
+
}
|
|
637
642
|
// TODO check multiplication factor didn't change
|
|
638
643
|
buildRollupJoin(preAggObj, preAggObjsToJoin) {
|
|
639
644
|
return this.query.cacheValue(['buildRollupJoin', JSON.stringify(preAggObj), JSON.stringify(preAggObjsToJoin)], () => {
|
|
640
|
-
|
|
641
|
-
//
|
|
642
|
-
this.query.
|
|
643
|
-
|
|
645
|
+
// It's not enough to call buildJoin() directly on cubesFromPreAggregation()
|
|
646
|
+
// because transitive joins won't be collected in that case.
|
|
647
|
+
const builtJoinTree = this.query.joinTreeForHints(this.cubesHintsFromPreAggregation(preAggObj), true);
|
|
648
|
+
if (!builtJoinTree) {
|
|
649
|
+
throw new UserError_1.UserError(`Can't build join tree for pre-aggregation ${preAggObj.cube}.${preAggObj.preAggregationName}`);
|
|
650
|
+
}
|
|
651
|
+
const targetJoins = this.resolveJoinMembers(builtJoinTree);
|
|
644
652
|
// TODO join hints?
|
|
645
|
-
|
|
653
|
+
const existingJoins = preAggObjsToJoin
|
|
654
|
+
.map(p => this.resolveJoinMembers(this.query.joinTreeForHints(this.cubesHintsFromPreAggregation(p), true)))
|
|
655
|
+
.flat();
|
|
646
656
|
const nonExistingJoins = targetJoins.filter(target => !existingJoins.find(existing => existing.originalFrom === target.originalFrom &&
|
|
647
657
|
existing.originalTo === target.originalTo &&
|
|
648
658
|
ramda_1.default.equals(existing.fromMembers, target.fromMembers) &&
|
|
@@ -651,8 +661,8 @@ class PreAggregations {
|
|
|
651
661
|
throw new UserError_1.UserError(`Nothing to join in rollup join. Target joins ${JSON.stringify(targetJoins)} are included in existing rollup joins ${JSON.stringify(existingJoins)}`);
|
|
652
662
|
}
|
|
653
663
|
return nonExistingJoins.map(join => {
|
|
654
|
-
const fromPreAggObj = this.preAggObjForJoin(preAggObjsToJoin, join.fromMembers, join);
|
|
655
|
-
const toPreAggObj = this.preAggObjForJoin(preAggObjsToJoin, join.toMembers, join);
|
|
664
|
+
const fromPreAggObj = this.preAggObjForJoin(preAggObjsToJoin, join.fromMembers, join, `${preAggObj.cube}.${preAggObj.preAggregationName}`);
|
|
665
|
+
const toPreAggObj = this.preAggObjForJoin(preAggObjsToJoin, join.toMembers, join, `${preAggObj.cube}.${preAggObj.preAggregationName}`);
|
|
656
666
|
return {
|
|
657
667
|
...join,
|
|
658
668
|
fromPreAggObj,
|
|
@@ -661,11 +671,12 @@ class PreAggregations {
|
|
|
661
671
|
});
|
|
662
672
|
});
|
|
663
673
|
}
|
|
664
|
-
preAggObjForJoin(preAggObjsToJoin, joinMembers, join) {
|
|
674
|
+
preAggObjForJoin(preAggObjsToJoin, joinMembers, join, rollupJoinPreAggName) {
|
|
665
675
|
const fromPreAggObj = preAggObjsToJoin
|
|
666
676
|
.filter(p => joinMembers.every(m => !!p.references.dimensions.find(d => m === d)));
|
|
667
677
|
if (!fromPreAggObj.length) {
|
|
668
|
-
|
|
678
|
+
const msg = `No rollups found that can be used for a rollup join from "${join.from}" (fromMembers: ${JSON.stringify(join.fromMembers)}) to "${join.to}" (toMembers: ${JSON.stringify(join.toMembers)}). Check the "${rollupJoinPreAggName}" pre-aggregation definition — you may have forgotten to specify the full dimension paths`;
|
|
679
|
+
throw new UserError_1.UserError(msg);
|
|
669
680
|
}
|
|
670
681
|
if (fromPreAggObj.length > 1) {
|
|
671
682
|
throw new UserError_1.UserError(`Multiple rollups found that can be used for rollup join ${JSON.stringify(join)}: ${fromPreAggObj.map(p => this.preAggregationId(p)).join(', ')}`);
|
|
@@ -673,13 +684,15 @@ class PreAggregations {
|
|
|
673
684
|
return fromPreAggObj[0];
|
|
674
685
|
}
|
|
675
686
|
resolveJoinMembers(join) {
|
|
687
|
+
const joinMap = new Set();
|
|
676
688
|
return join.joins.map(j => {
|
|
689
|
+
joinMap.add(j.originalFrom);
|
|
677
690
|
const memberPaths = this.query.collectMemberNamesFor(() => this.query.evaluateSql(j.originalFrom, j.join.sql)).map(m => m.split('.'));
|
|
678
|
-
const invalidMembers = memberPaths.filter(m => m[0]
|
|
691
|
+
const invalidMembers = memberPaths.filter(m => !joinMap.has(m[0]) && m[0] !== j.originalTo);
|
|
679
692
|
if (invalidMembers.length) {
|
|
680
693
|
throw new UserError_1.UserError(`Members ${invalidMembers.join(', ')} in join from '${j.originalFrom}' to '${j.originalTo}' doesn't reference join cubes`);
|
|
681
694
|
}
|
|
682
|
-
const fromMembers = memberPaths.filter(m => m[0]
|
|
695
|
+
const fromMembers = memberPaths.filter(m => joinMap.has(m[0])).map(m => m.join('.'));
|
|
683
696
|
if (!fromMembers.length) {
|
|
684
697
|
throw new UserError_1.UserError(`From members are not found in [${memberPaths.map(m => m.join('.')).join(', ')}] for join ${JSON.stringify(j)}. Please make sure join fields are referencing dimensions instead of columns.`);
|
|
685
698
|
}
|
|
@@ -687,6 +700,7 @@ class PreAggregations {
|
|
|
687
700
|
if (!toMembers.length) {
|
|
688
701
|
throw new UserError_1.UserError(`To members are not found in [${memberPaths.map(m => m.join('.')).join(', ')}] for join ${JSON.stringify(j)}. Please make sure join fields are referencing dimensions instead of columns.`);
|
|
689
702
|
}
|
|
703
|
+
joinMap.add(j.originalTo);
|
|
690
704
|
return {
|
|
691
705
|
...j,
|
|
692
706
|
fromMembers,
|
|
@@ -694,8 +708,8 @@ class PreAggregations {
|
|
|
694
708
|
};
|
|
695
709
|
});
|
|
696
710
|
}
|
|
697
|
-
|
|
698
|
-
return ramda_1.default.uniq(preAggObj.references.measures.
|
|
711
|
+
cubesHintsFromPreAggregation(preAggObj) {
|
|
712
|
+
return ramda_1.default.uniq(preAggObj.references.measures.concat(preAggObj.references.dimensions).map(p => p.split('.').slice(0, -1)));
|
|
699
713
|
}
|
|
700
714
|
evaluatedPreAggregationObj(cube, preAggregationName, preAggregation, canUsePreAggregation) {
|
|
701
715
|
const references = this.evaluateAllReferences(cube, preAggregation, preAggregationName);
|
|
@@ -703,7 +717,9 @@ class PreAggregations {
|
|
|
703
717
|
preAggregationName,
|
|
704
718
|
preAggregation,
|
|
705
719
|
cube,
|
|
706
|
-
|
|
720
|
+
// For rollupJoin and rollupLambda we need to enrich references with data
|
|
721
|
+
// from the underlying rollups which are collected later;
|
|
722
|
+
canUsePreAggregation: preAggregation.type === 'rollup' ? canUsePreAggregation(references) : false,
|
|
707
723
|
references,
|
|
708
724
|
preAggregationId: `${cube}.${preAggregationName}`
|
|
709
725
|
};
|
|
@@ -713,10 +729,15 @@ class PreAggregations {
|
|
|
713
729
|
const [joinCube, joinPreAggregationName] = this.query.cubeEvaluator.parsePath('preAggregations', name);
|
|
714
730
|
return this.evaluatedPreAggregationObj(joinCube, joinPreAggregationName, this.query.cubeEvaluator.byPath('preAggregations', name), canUsePreAggregation);
|
|
715
731
|
});
|
|
732
|
+
preAggregationsToJoin.forEach(preAgg => {
|
|
733
|
+
references.rollupsReferences.push(preAgg.references);
|
|
734
|
+
});
|
|
735
|
+
const rollupJoin = this.buildRollupJoin(preAggObj, preAggregationsToJoin);
|
|
716
736
|
return {
|
|
717
737
|
...preAggObj,
|
|
738
|
+
canUsePreAggregation: canUsePreAggregation(references),
|
|
718
739
|
preAggregationsToJoin,
|
|
719
|
-
rollupJoin
|
|
740
|
+
rollupJoin,
|
|
720
741
|
};
|
|
721
742
|
}
|
|
722
743
|
else if (preAggregation.type === 'rollupLambda') {
|
|
@@ -755,8 +776,12 @@ class PreAggregations {
|
|
|
755
776
|
PreAggregations.memberNameMismatchValidation(preAggObj, referencedPreAggregation, 'dimensions');
|
|
756
777
|
PreAggregations.memberNameMismatchValidation(preAggObj, referencedPreAggregation, 'timeDimensions');
|
|
757
778
|
});
|
|
779
|
+
referencedPreAggregations.forEach(preAgg => {
|
|
780
|
+
references.rollupsReferences.push(preAgg.references);
|
|
781
|
+
});
|
|
758
782
|
return {
|
|
759
783
|
...preAggObj,
|
|
784
|
+
canUsePreAggregation: canUsePreAggregation(references),
|
|
760
785
|
referencedPreAggregations,
|
|
761
786
|
};
|
|
762
787
|
}
|
|
@@ -783,7 +808,7 @@ class PreAggregations {
|
|
|
783
808
|
return `${member.dimension.split('.')[1]}.${member.granularity}`;
|
|
784
809
|
}
|
|
785
810
|
else {
|
|
786
|
-
return member.split('.')
|
|
811
|
+
return member.split('.').at(-1);
|
|
787
812
|
}
|
|
788
813
|
});
|
|
789
814
|
}
|
|
@@ -841,11 +866,9 @@ class PreAggregations {
|
|
|
841
866
|
preAggregationQuery: true,
|
|
842
867
|
useOriginalSqlPreAggregationsInPreAggregation: aggregation.useOriginalSqlPreAggregations,
|
|
843
868
|
ungrouped: cubeQuery.preAggregationAllowUngroupingWithPrimaryKey(cube, aggregation) &&
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
return this.query.cubeEvaluator.dimensionByPath(trimmedDimension).primaryKey;
|
|
848
|
-
}),
|
|
869
|
+
references.dimensions.some((d) => this.query.cubeEvaluator.dimensionByPath(
|
|
870
|
+
// `d` can contain full join path, so we should trim it
|
|
871
|
+
this.query.cubeEvaluator.memberShortNameFromPath(d)).primaryKey),
|
|
849
872
|
});
|
|
850
873
|
}
|
|
851
874
|
autoRollupPreAggregationQuery(cube, aggregation) {
|
|
@@ -879,6 +902,32 @@ class PreAggregations {
|
|
|
879
902
|
.replace(/[.]/g, '')
|
|
880
903
|
.toLowerCase();
|
|
881
904
|
}
|
|
905
|
+
enrichMembersCubeJoinPath(cubeName, joinsMap) {
|
|
906
|
+
const path = [cubeName];
|
|
907
|
+
const parentMap = joinsMap;
|
|
908
|
+
while (parentMap[cubeName]) {
|
|
909
|
+
cubeName = parentMap[cubeName];
|
|
910
|
+
path.push(cubeName);
|
|
911
|
+
}
|
|
912
|
+
return path.reverse();
|
|
913
|
+
}
|
|
914
|
+
buildMembersFullName(members, joinsMap) {
|
|
915
|
+
return members.map(d => {
|
|
916
|
+
const [cubeName, ...restPath] = d.split('.');
|
|
917
|
+
const path = this.enrichMembersCubeJoinPath(cubeName, joinsMap);
|
|
918
|
+
return `${path.join('.')}.${restPath.join('.')}`;
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
buildTimeDimensionsFullName(members, joinsMap) {
|
|
922
|
+
return members.map(td => {
|
|
923
|
+
const [cubeName, ...restPath] = td.dimension.split('.');
|
|
924
|
+
const path = this.enrichMembersCubeJoinPath(cubeName, joinsMap);
|
|
925
|
+
return {
|
|
926
|
+
...td,
|
|
927
|
+
dimension: `${path.join('.')}.${restPath.join('.')}`,
|
|
928
|
+
};
|
|
929
|
+
});
|
|
930
|
+
}
|
|
882
931
|
evaluateAllReferences(cube, aggregation, preAggregationName = null, context = {}) {
|
|
883
932
|
const evaluateReferences = () => {
|
|
884
933
|
const references = this.query.cubeEvaluator.evaluatePreAggregationReferences(cube, aggregation);
|
|
@@ -889,18 +938,17 @@ class PreAggregations {
|
|
|
889
938
|
if (preAggQuery) {
|
|
890
939
|
// We need to build a join tree for all references, so they would always include full join path
|
|
891
940
|
// even for preaggregation references without join path. It is necessary to be able to match
|
|
892
|
-
// query and preaggregation based on full join tree.
|
|
893
|
-
// references.{dimensions,measures,timeDimensions} directly, because it will break
|
|
894
|
-
// evaluation of references in the query on later stages.
|
|
895
|
-
// So we store full named members separately and use them in canUsePreAggregation functions.
|
|
941
|
+
// query and preaggregation based on full join tree.
|
|
896
942
|
references.joinTree = preAggQuery.join;
|
|
897
|
-
const
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
943
|
+
const joinsMap = {};
|
|
944
|
+
if (references.joinTree) {
|
|
945
|
+
for (const j of references.joinTree.joins) {
|
|
946
|
+
joinsMap[j.to] = j.from;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
references.dimensions = this.buildMembersFullName(references.dimensions, joinsMap);
|
|
950
|
+
references.measures = this.buildMembersFullName(references.measures, joinsMap);
|
|
951
|
+
references.timeDimensions = this.buildTimeDimensionsFullName(references.timeDimensions, joinsMap);
|
|
904
952
|
}
|
|
905
953
|
}
|
|
906
954
|
if (aggregation.type === 'rollupLambda') {
|
|
@@ -923,7 +971,11 @@ class PreAggregations {
|
|
|
923
971
|
if (!preAggregationName) {
|
|
924
972
|
return evaluateReferences();
|
|
925
973
|
}
|
|
926
|
-
|
|
974
|
+
// Using [cube, preAggregationName] alone as cache keys isn’t reliable,
|
|
975
|
+
// as different queries can build distinct join graphs during pre-aggregation matching.
|
|
976
|
+
// Because the matching logic compares join subgraphs — particularly for 'rollupJoin' and 'rollupLambda'
|
|
977
|
+
// pre-aggregations — relying on such keys may cause incorrect results.
|
|
978
|
+
return this.query.cacheValue(['evaluateAllReferences', cube, preAggregationName, JSON.stringify(this.query.join)], evaluateReferences);
|
|
927
979
|
}
|
|
928
980
|
originalSqlPreAggregationTable(preAggregationDescription) {
|
|
929
981
|
// eslint-disable-next-line prefer-const
|
|
@@ -1095,7 +1147,6 @@ class PreAggregations {
|
|
|
1095
1147
|
}
|
|
1096
1148
|
rollupMembers(preAggregationForQuery, type) {
|
|
1097
1149
|
return preAggregationForQuery.preAggregation.type === 'autoRollup' ?
|
|
1098
|
-
// TODO proper types
|
|
1099
1150
|
preAggregationForQuery.preAggregation[type] :
|
|
1100
1151
|
this.evaluateAllReferences(preAggregationForQuery.cube, preAggregationForQuery.preAggregation, preAggregationForQuery.preAggregationName)[type];
|
|
1101
1152
|
}
|