@cubejs-backend/schema-compiler 1.3.23 → 1.3.25
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/AWSElasticSearchQuery.d.ts +3 -9
- package/dist/src/adapter/AWSElasticSearchQuery.d.ts.map +1 -1
- package/dist/src/adapter/AWSElasticSearchQuery.js +4 -50
- package/dist/src/adapter/AWSElasticSearchQuery.js.map +1 -1
- package/dist/src/adapter/BaseMeasure.d.ts +1 -1
- package/dist/src/adapter/BaseQuery.d.ts +43 -8
- package/dist/src/adapter/BaseQuery.d.ts.map +1 -1
- package/dist/src/adapter/BaseQuery.js +188 -32
- package/dist/src/adapter/BaseQuery.js.map +1 -1
- package/dist/src/adapter/BigqueryQuery.d.ts +22 -2
- package/dist/src/adapter/BigqueryQuery.d.ts.map +1 -1
- package/dist/src/adapter/BigqueryQuery.js +84 -14
- package/dist/src/adapter/BigqueryQuery.js.map +1 -1
- package/dist/src/adapter/ClickHouseQuery.d.ts +4 -2
- package/dist/src/adapter/ClickHouseQuery.d.ts.map +1 -1
- package/dist/src/adapter/ClickHouseQuery.js +0 -13
- package/dist/src/adapter/ClickHouseQuery.js.map +1 -1
- package/dist/src/adapter/ElasticSearchQuery.d.ts +9 -2
- package/dist/src/adapter/ElasticSearchQuery.d.ts.map +1 -1
- package/dist/src/adapter/ElasticSearchQuery.js +30 -7
- package/dist/src/adapter/ElasticSearchQuery.js.map +1 -1
- package/dist/src/adapter/HiveQuery.d.ts +1 -1
- package/dist/src/adapter/HiveQuery.d.ts.map +1 -1
- package/dist/src/adapter/HiveQuery.js +3 -3
- package/dist/src/adapter/HiveQuery.js.map +1 -1
- package/dist/src/adapter/PostgresQuery.js +4 -4
- package/dist/src/adapter/PostgresQuery.js.map +1 -1
- package/dist/src/adapter/PrestodbQuery.d.ts +1 -2
- package/dist/src/adapter/PrestodbQuery.d.ts.map +1 -1
- package/dist/src/adapter/PrestodbQuery.js +30 -8
- package/dist/src/adapter/PrestodbQuery.js.map +1 -1
- package/dist/src/adapter/QueryBuilder.d.ts +2 -2
- package/dist/src/adapter/QueryBuilder.d.ts.map +1 -1
- package/dist/src/adapter/QueryBuilder.js.map +1 -1
- package/dist/src/adapter/QueryCache.d.ts +3 -4
- package/dist/src/adapter/QueryCache.d.ts.map +1 -1
- package/dist/src/adapter/QueryCache.js +1 -2
- package/dist/src/adapter/QueryCache.js.map +1 -1
- package/dist/src/compiler/CubeSymbols.d.ts.map +1 -1
- package/dist/src/compiler/CubeSymbols.js +4 -1
- package/dist/src/compiler/CubeSymbols.js.map +1 -1
- package/dist/src/compiler/DataSchemaCompiler.d.ts +92 -69
- package/dist/src/compiler/DataSchemaCompiler.d.ts.map +1 -1
- package/dist/src/compiler/DataSchemaCompiler.js +63 -41
- package/dist/src/compiler/DataSchemaCompiler.js.map +1 -1
- package/dist/src/compiler/ErrorReporter.d.ts +1 -1
- package/dist/src/compiler/ErrorReporter.d.ts.map +1 -1
- package/dist/src/compiler/PrepareCompiler.d.ts +5 -10
- package/dist/src/compiler/PrepareCompiler.d.ts.map +1 -1
- package/dist/src/compiler/PrepareCompiler.js.map +1 -1
- package/dist/src/compiler/YamlCompiler.d.ts +1 -1
- package/dist/src/compiler/YamlCompiler.d.ts.map +1 -1
- package/dist/src/compiler/YamlCompiler.js.map +1 -1
- package/package.json +6 -6
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare class AWSElasticSearchQuery extends
|
|
1
|
+
import { ElasticSearchQuery } from './ElasticSearchQuery';
|
|
2
|
+
export declare class AWSElasticSearchQuery extends ElasticSearchQuery {
|
|
3
3
|
newFilter(filter: any): any;
|
|
4
|
-
convertTz(field: any): string;
|
|
5
|
-
timeStampCast(value: any): string;
|
|
6
|
-
dateTimeCast(value: any): string;
|
|
7
4
|
subtractInterval(date: any, interval: any): string;
|
|
8
5
|
addInterval(date: any, interval: any): string;
|
|
9
6
|
timeGroupedColumn(granularity: any, dimension: any): any;
|
|
10
|
-
|
|
11
|
-
orderHashToString(hash: any): string | null;
|
|
12
|
-
getFieldAlias(id: any): any;
|
|
13
|
-
escapeColumnName(name: any): string;
|
|
7
|
+
unixTimestampSql(): string;
|
|
14
8
|
}
|
|
15
9
|
//# sourceMappingURL=AWSElasticSearchQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AWSElasticSearchQuery.d.ts","sourceRoot":"","sources":["../../../src/adapter/AWSElasticSearchQuery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AWSElasticSearchQuery.d.ts","sourceRoot":"","sources":["../../../src/adapter/AWSElasticSearchQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAqB1D,qBAAa,qBAAsB,SAAQ,kBAAkB;IAC3C,SAAS,CAAC,MAAM,KAAA;IAIhB,gBAAgB,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA;IAI/B,WAAW,CAAC,IAAI,KAAA,EAAE,QAAQ,KAAA;IAI1B,iBAAiB,CAAC,WAAW,KAAA,EAAE,SAAS,KAAA;IAIxC,gBAAgB;CAGjC"}
|
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.AWSElasticSearchQuery = void 0;
|
|
7
|
-
const ramda_1 = __importDefault(require("ramda"));
|
|
8
4
|
const BaseFilter_1 = require("./BaseFilter");
|
|
9
|
-
const
|
|
5
|
+
const ElasticSearchQuery_1 = require("./ElasticSearchQuery");
|
|
10
6
|
const GRANULARITY_TO_INTERVAL = {
|
|
11
7
|
day: (date) => `DATE_FORMAT(${date}, 'yyyy-MM-dd 00:00:00.000')`,
|
|
12
8
|
// eslint-disable-next-line no-unused-vars,@typescript-eslint/no-unused-vars
|
|
@@ -24,19 +20,10 @@ class AWSElasticSearchQueryFilter extends BaseFilter_1.BaseFilter {
|
|
|
24
20
|
return `${column}${not ? ' NOT' : ''} LIKE CONCAT('${p}', ${this.allocateParam(param)}, '${s}')`;
|
|
25
21
|
}
|
|
26
22
|
}
|
|
27
|
-
class AWSElasticSearchQuery extends
|
|
23
|
+
class AWSElasticSearchQuery extends ElasticSearchQuery_1.ElasticSearchQuery {
|
|
28
24
|
newFilter(filter) {
|
|
29
25
|
return new AWSElasticSearchQueryFilter(this, filter);
|
|
30
26
|
}
|
|
31
|
-
convertTz(field) {
|
|
32
|
-
return `${field}`; // TODO
|
|
33
|
-
}
|
|
34
|
-
timeStampCast(value) {
|
|
35
|
-
return `${value}`;
|
|
36
|
-
}
|
|
37
|
-
dateTimeCast(value) {
|
|
38
|
-
return `${value}`; // TODO
|
|
39
|
-
}
|
|
40
27
|
subtractInterval(date, interval) {
|
|
41
28
|
return `DATE_SUB(${date}, INTERVAL ${interval})`;
|
|
42
29
|
}
|
|
@@ -46,41 +33,8 @@ class AWSElasticSearchQuery extends BaseQuery_1.BaseQuery {
|
|
|
46
33
|
timeGroupedColumn(granularity, dimension) {
|
|
47
34
|
return GRANULARITY_TO_INTERVAL[granularity](dimension);
|
|
48
35
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return '';
|
|
52
|
-
}
|
|
53
|
-
const dimensionsForSelect = this.dimensionsForSelect();
|
|
54
|
-
const dimensionColumns = ramda_1.default.flatten(dimensionsForSelect.map(s => s.selectColumns() && s.dimensionSql()))
|
|
55
|
-
.filter(s => !!s);
|
|
56
|
-
return dimensionColumns.length ? ` GROUP BY ${dimensionColumns.join(', ')}` : '';
|
|
57
|
-
}
|
|
58
|
-
orderHashToString(hash) {
|
|
59
|
-
if (!hash || !hash.id) {
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
const fieldAlias = this.getFieldAlias(hash.id);
|
|
63
|
-
if (fieldAlias === null) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
const direction = hash.desc ? 'DESC' : 'ASC';
|
|
67
|
-
return `${fieldAlias} ${direction}`;
|
|
68
|
-
}
|
|
69
|
-
getFieldAlias(id) {
|
|
70
|
-
const equalIgnoreCase = (a, b) => (typeof a === 'string' && typeof b === 'string' && a.toUpperCase() === b.toUpperCase());
|
|
71
|
-
let field;
|
|
72
|
-
field = this.dimensionsForSelect().find(d => equalIgnoreCase(d.dimension, id));
|
|
73
|
-
if (field) {
|
|
74
|
-
return field.dimensionSql();
|
|
75
|
-
}
|
|
76
|
-
field = this.measures.find(d => equalIgnoreCase(d.measure, id) || equalIgnoreCase(d.expressionName, id));
|
|
77
|
-
if (field) {
|
|
78
|
-
return field.aliasName(); // TODO isn't supported
|
|
79
|
-
}
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
escapeColumnName(name) {
|
|
83
|
-
return `${name}`; // TODO
|
|
36
|
+
unixTimestampSql() {
|
|
37
|
+
return 'EXTRACT(EPOCH FROM NOW())';
|
|
84
38
|
}
|
|
85
39
|
}
|
|
86
40
|
exports.AWSElasticSearchQuery = AWSElasticSearchQuery;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AWSElasticSearchQuery.js","sourceRoot":"","sources":["../../../src/adapter/AWSElasticSearchQuery.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AWSElasticSearchQuery.js","sourceRoot":"","sources":["../../../src/adapter/AWSElasticSearchQuery.ts"],"names":[],"mappings":";;;AAAA,6CAA0C;AAC1C,6DAA0D;AAE1D,MAAM,uBAAuB,GAAG;IAC9B,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,8BAA8B;IAChE,4EAA4E;IAC5E,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;IAC3D,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,8BAA8B;IACjE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,8BAA8B;IACnE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,8BAA8B;IACnE,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,8BAA8B;IAClE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,IAAI,8BAA8B;CAClE,CAAC;AAEF,MAAM,2BAA4B,SAAQ,uBAAU;IAC3C,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,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,GAAG,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,iBAAiB,CAAC,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC;IACnG,CAAC;CACF;AAED,MAAa,qBAAsB,SAAQ,uCAAkB;IAC3C,SAAS,CAAC,MAAM;QAC9B,OAAO,IAAI,2BAA2B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;IAEe,gBAAgB,CAAC,IAAI,EAAE,QAAQ;QAC7C,OAAO,YAAY,IAAI,cAAc,QAAQ,GAAG,CAAC;IACnD,CAAC;IAEe,WAAW,CAAC,IAAI,EAAE,QAAQ;QACxC,OAAO,YAAY,IAAI,cAAc,QAAQ,GAAG,CAAC;IACnD,CAAC;IAEe,iBAAiB,CAAC,WAAW,EAAE,SAAS;QACtD,OAAO,uBAAuB,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAEe,gBAAgB;QAC9B,OAAO,2BAA2B,CAAC;IACrC,CAAC;CACF;AApBD,sDAoBC"}
|
|
@@ -30,7 +30,7 @@ export declare class BaseMeasure {
|
|
|
30
30
|
isAdditive(): boolean;
|
|
31
31
|
static isCumulative(definition: any): boolean;
|
|
32
32
|
rollingWindowDefinition(): any;
|
|
33
|
-
dateJoinCondition(): (import("./BaseTimeDimension").BaseTimeDimension | ((dateFrom: any, dateTo: any, dateField: any,
|
|
33
|
+
dateJoinCondition(): (import("./BaseTimeDimension").BaseTimeDimension | ((dateFrom: any, dateTo: any, dateField: any, _dimensionDateFrom: any, _dimensionDateTo: any, _isFromStartToEnd: any) => string))[][] | null;
|
|
34
34
|
windowGranularity(): any;
|
|
35
35
|
minGranularity(granularityA: string | undefined, granularityB: string | undefined): any;
|
|
36
36
|
granularityFromInterval(interval: string): "day" | "hour" | "week" | "month" | "year" | undefined;
|
|
@@ -79,7 +79,14 @@ export class BaseQuery {
|
|
|
79
79
|
/** @type {import('../compiler/JoinGraph').JoinGraph} */
|
|
80
80
|
joinGraph: import('../compiler/JoinGraph').JoinGraph;
|
|
81
81
|
options: any;
|
|
82
|
-
|
|
82
|
+
/**
|
|
83
|
+
* @param {{ id: string, desc: boolean }} hash
|
|
84
|
+
* @returns {string|null}
|
|
85
|
+
*/
|
|
86
|
+
orderHashToString(hash: {
|
|
87
|
+
id: string;
|
|
88
|
+
desc: boolean;
|
|
89
|
+
}): string | null;
|
|
83
90
|
defaultOrder(): {
|
|
84
91
|
id: any;
|
|
85
92
|
desc: boolean;
|
|
@@ -237,9 +244,9 @@ export class BaseQuery {
|
|
|
237
244
|
*/
|
|
238
245
|
buildLambdaQuery(): Record<string, Array<string>>;
|
|
239
246
|
externalQuery(): any;
|
|
240
|
-
runningTotalDateJoinCondition(): (BaseTimeDimension | ((
|
|
241
|
-
rollingWindowToDateJoinCondition(granularity: any): (BaseTimeDimension | ((dateFrom: any, dateTo: any, dateField: any,
|
|
242
|
-
rollingWindowDateJoinCondition(trailingInterval: any, leadingInterval: any, offset: any): (BaseTimeDimension | ((dateFrom: any, dateTo: any, dateField: any,
|
|
247
|
+
runningTotalDateJoinCondition(): (BaseTimeDimension | ((_dateFrom: any, dateTo: any, dateField: any, dimensionDateFrom: any, _dimensionDateTo: any) => string))[][];
|
|
248
|
+
rollingWindowToDateJoinCondition(granularity: any): (BaseTimeDimension | ((dateFrom: any, dateTo: any, dateField: any, _dimensionDateFrom: any, _dimensionDateTo: any, _isFromStartToEnd: any) => string))[][];
|
|
249
|
+
rollingWindowDateJoinCondition(trailingInterval: any, leadingInterval: any, offset: any): (BaseTimeDimension | ((dateFrom: any, dateTo: any, dateField: any, _dimensionDateFrom: any, _dimensionDateTo: any, isFromStartToEnd: any) => string))[][];
|
|
243
250
|
/**
|
|
244
251
|
* @param {string} date
|
|
245
252
|
* @param {string} interval
|
|
@@ -252,6 +259,11 @@ export class BaseQuery {
|
|
|
252
259
|
* @returns {string}
|
|
253
260
|
*/
|
|
254
261
|
addInterval(date: string, interval: string): string;
|
|
262
|
+
/**
|
|
263
|
+
* @param {string} interval
|
|
264
|
+
* @returns {string}
|
|
265
|
+
*/
|
|
266
|
+
intervalString(interval: string): string;
|
|
255
267
|
/**
|
|
256
268
|
* @param {string} timestamp
|
|
257
269
|
* @param {string} interval
|
|
@@ -306,7 +318,12 @@ export class BaseQuery {
|
|
|
306
318
|
overTimeSeriesQuery(baseQueryFn: any, cumulativeMeasure: any, fromRollup: any): any;
|
|
307
319
|
overTimeSeriesSelect(cumulativeMeasures: any, dateSeriesSql: any, baseQuery: any, dateJoinConditionSql: any, baseQueryAlias: any, dateSeriesGranularity: any): string;
|
|
308
320
|
overTimeSeriesForSelect(cumulativeMeasures: any, dateSeriesGranularity: any): string;
|
|
309
|
-
|
|
321
|
+
/**
|
|
322
|
+
* BigQuery has strict date type and can not automatically convert between date
|
|
323
|
+
* and timestamp, so we override dateFromStartToEndConditionSql() in BigQuery Dialect
|
|
324
|
+
* @protected
|
|
325
|
+
*/
|
|
326
|
+
protected dateFromStartToEndConditionSql(dateJoinCondition: any, fromRollup: any, isFromStartToEnd: any): any;
|
|
310
327
|
/**
|
|
311
328
|
* @param {import('./BaseTimeDimension').BaseTimeDimension} timeDimension
|
|
312
329
|
* @return {string}
|
|
@@ -410,6 +427,17 @@ export class BaseQuery {
|
|
|
410
427
|
* @returns {Array<Array<string>>}
|
|
411
428
|
*/
|
|
412
429
|
collectJoinHints(excludeTimeDimensions?: boolean | undefined): Array<Array<string>>;
|
|
430
|
+
joinMembersFromCustomSubQuery(): {
|
|
431
|
+
getMembers: () => {
|
|
432
|
+
path: () => null;
|
|
433
|
+
cube: () => any;
|
|
434
|
+
definition: () => {
|
|
435
|
+
sql: Function;
|
|
436
|
+
type: string;
|
|
437
|
+
};
|
|
438
|
+
}[];
|
|
439
|
+
}[];
|
|
440
|
+
joinMembersFromJoin(join: any): any;
|
|
413
441
|
collectJoinHintsFromMembers(members: any): any[];
|
|
414
442
|
collectFromMembers(excludeTimeDimensions: any, fn: any, methodName: any): any[];
|
|
415
443
|
/**
|
|
@@ -433,11 +461,18 @@ export class BaseQuery {
|
|
|
433
461
|
*/
|
|
434
462
|
groupByClause(): string;
|
|
435
463
|
/**
|
|
436
|
-
* XXX: String as return value is added because of HiveQuery.getFieldIndex()
|
|
437
|
-
* @
|
|
464
|
+
* XXX: String as return value is added because of HiveQuery.getFieldIndex() and DatabricksQuery.getFieldIndex()
|
|
465
|
+
* @protected
|
|
466
|
+
* @param {string} id member name in form of "cube.member[.granularity]"
|
|
438
467
|
* @returns {number|string|null}
|
|
439
468
|
*/
|
|
440
|
-
getFieldIndex(id:
|
|
469
|
+
protected getFieldIndex(id: string): number | string | null;
|
|
470
|
+
/**
|
|
471
|
+
* @protected
|
|
472
|
+
* @param {string} id member name in form of "cube.member[.granularity]"
|
|
473
|
+
* @returns {null|string}
|
|
474
|
+
*/
|
|
475
|
+
protected getFieldAlias(id: string): null | string;
|
|
441
476
|
orderBy(): string;
|
|
442
477
|
/**
|
|
443
478
|
* Returns a complete list of the aliased dimensions, including time
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BaseQuery.d.ts","sourceRoot":"","sources":["../../../src/adapter/BaseQuery.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BaseQuery.d.ts","sourceRoot":"","sources":["../../../src/adapter/BaseQuery.js"],"names":[],"mappings":"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"}
|
|
@@ -377,10 +377,67 @@ class BaseQuery {
|
|
|
377
377
|
*/
|
|
378
378
|
get allJoinHints() {
|
|
379
379
|
if (!this.collectedJoinHints) {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
380
|
+
const [rootOfJoin, ...allMembersJoinHints] = this.collectJoinHintsFromMembers(this.allMembersConcat(false));
|
|
381
|
+
const customSubQueryJoinHints = this.collectJoinHintsFromMembers(this.joinMembersFromCustomSubQuery());
|
|
382
|
+
let joinMembersJoinHints = this.collectJoinHintsFromMembers(this.joinMembersFromJoin(this.join));
|
|
383
|
+
// One cube may join the other cube via transitive joined cubes,
|
|
384
|
+
// members from which are referenced in the join `on` clauses.
|
|
385
|
+
// We need to collect such join hints and push them upfront of the joining one
|
|
386
|
+
// but only if they don't exist yet. Cause in other case we might affect what
|
|
387
|
+
// join path will be constructed in join graph.
|
|
388
|
+
// It is important to use queryLevelJoinHints during the calculation if it is set.
|
|
389
|
+
const constructJH = () => {
|
|
390
|
+
const filteredJoinMembersJoinHints = joinMembersJoinHints.filter(m => !allMembersJoinHints.includes(m));
|
|
391
|
+
return [
|
|
392
|
+
...this.queryLevelJoinHints,
|
|
393
|
+
...(rootOfJoin ? [rootOfJoin] : []),
|
|
394
|
+
...filteredJoinMembersJoinHints,
|
|
395
|
+
...allMembersJoinHints,
|
|
396
|
+
...customSubQueryJoinHints,
|
|
397
|
+
];
|
|
398
|
+
};
|
|
399
|
+
let prevJoins = this.join;
|
|
400
|
+
let prevJoinMembersJoinHints = joinMembersJoinHints;
|
|
401
|
+
let newJoin = this.joinGraph.buildJoin(constructJH());
|
|
402
|
+
const isOrderPreserved = (base, updated) => {
|
|
403
|
+
const common = base.filter(value => updated.includes(value));
|
|
404
|
+
const bFiltered = updated.filter(value => common.includes(value));
|
|
405
|
+
return common.every((x, i) => x === bFiltered[i]);
|
|
406
|
+
};
|
|
407
|
+
const isJoinTreesEqual = (a, b) => {
|
|
408
|
+
if (!a || !b || a.root !== b.root || a.joins.length !== b.joins.length) {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
// We don't care about the order of joins on the same level, so
|
|
412
|
+
// we can compare them as sets.
|
|
413
|
+
const aJoinsSet = new Set(a.joins.map(j => `${j.originalFrom}->${j.originalTo}`));
|
|
414
|
+
const bJoinsSet = new Set(b.joins.map(j => `${j.originalFrom}->${j.originalTo}`));
|
|
415
|
+
if (aJoinsSet.size !== bJoinsSet.size) {
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
for (const val of aJoinsSet) {
|
|
419
|
+
if (!bJoinsSet.has(val)) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return true;
|
|
424
|
+
};
|
|
425
|
+
// Safeguard against infinite loop in case of cyclic joins somehow managed to slip through
|
|
426
|
+
let cnt = 0;
|
|
427
|
+
while (newJoin?.joins.length > 0 && !isJoinTreesEqual(prevJoins, newJoin) && cnt < 10000) {
|
|
428
|
+
prevJoins = newJoin;
|
|
429
|
+
joinMembersJoinHints = this.collectJoinHintsFromMembers(this.joinMembersFromJoin(newJoin));
|
|
430
|
+
if (!isOrderPreserved(prevJoinMembersJoinHints, joinMembersJoinHints)) {
|
|
431
|
+
throw new UserError_1.UserError(`Can not construct joins for the query, potential loop detected: ${prevJoinMembersJoinHints.join('->')} vs ${joinMembersJoinHints.join('->')}`);
|
|
432
|
+
}
|
|
433
|
+
newJoin = this.joinGraph.buildJoin(constructJH());
|
|
434
|
+
prevJoinMembersJoinHints = joinMembersJoinHints;
|
|
435
|
+
cnt++;
|
|
436
|
+
}
|
|
437
|
+
if (cnt >= 10000) {
|
|
438
|
+
throw new UserError_1.UserError('Can not construct joins for the query, potential loop detected');
|
|
439
|
+
}
|
|
440
|
+
this.collectedJoinHints = ramda_1.default.uniq(constructJH());
|
|
384
441
|
}
|
|
385
442
|
return this.collectedJoinHints;
|
|
386
443
|
}
|
|
@@ -447,8 +504,9 @@ class BaseQuery {
|
|
|
447
504
|
res.push({ id, desc: true });
|
|
448
505
|
}
|
|
449
506
|
else if (this.dimensions.length > 0) {
|
|
507
|
+
const dim = this.dimensions[0];
|
|
450
508
|
res.push({
|
|
451
|
-
id:
|
|
509
|
+
id: dim.expressionName ?? dim.dimension,
|
|
452
510
|
desc: false,
|
|
453
511
|
});
|
|
454
512
|
}
|
|
@@ -800,8 +858,7 @@ class BaseQuery {
|
|
|
800
858
|
return this.timeDimensions
|
|
801
859
|
.map(d => [
|
|
802
860
|
d,
|
|
803
|
-
|
|
804
|
-
(dateFrom, dateTo, dateField, dimensionDateFrom, dimensionDateTo) => `${dateField} >= ${dimensionDateFrom} AND ${dateField} <= ${dateTo}`
|
|
861
|
+
(_dateFrom, dateTo, dateField, dimensionDateFrom, _dimensionDateTo) => `${dateField} >= ${dimensionDateFrom} AND ${dateField} <= ${dateTo}`
|
|
805
862
|
]);
|
|
806
863
|
}
|
|
807
864
|
rollingWindowToDateJoinCondition(granularity) {
|
|
@@ -809,14 +866,14 @@ class BaseQuery {
|
|
|
809
866
|
.filter(td => td.granularity)
|
|
810
867
|
.map(d => [
|
|
811
868
|
d,
|
|
812
|
-
(dateFrom, dateTo, dateField,
|
|
869
|
+
(dateFrom, dateTo, dateField, _dimensionDateFrom, _dimensionDateTo, _isFromStartToEnd) => `${dateField} >= ${this.timeGroupedColumn(granularity, dateFrom)} AND ${dateField} <= ${dateTo}`
|
|
813
870
|
]);
|
|
814
871
|
}
|
|
815
872
|
rollingWindowDateJoinCondition(trailingInterval, leadingInterval, offset) {
|
|
816
873
|
offset = offset || 'end';
|
|
817
874
|
return this.timeDimensions
|
|
818
875
|
.filter(td => td.granularity)
|
|
819
|
-
.map(d => [d, (dateFrom, dateTo, dateField,
|
|
876
|
+
.map(d => [d, (dateFrom, dateTo, dateField, _dimensionDateFrom, _dimensionDateTo, isFromStartToEnd) => {
|
|
820
877
|
// dateFrom based window
|
|
821
878
|
const conditions = [];
|
|
822
879
|
if (trailingInterval !== 'unbounded') {
|
|
@@ -840,7 +897,8 @@ class BaseQuery {
|
|
|
840
897
|
* @returns {string}
|
|
841
898
|
*/
|
|
842
899
|
subtractInterval(date, interval) {
|
|
843
|
-
|
|
900
|
+
const intervalStr = this.intervalString(interval);
|
|
901
|
+
return `${date} - interval ${intervalStr}`;
|
|
844
902
|
}
|
|
845
903
|
/**
|
|
846
904
|
* @param {string} date
|
|
@@ -848,7 +906,15 @@ class BaseQuery {
|
|
|
848
906
|
* @returns {string}
|
|
849
907
|
*/
|
|
850
908
|
addInterval(date, interval) {
|
|
851
|
-
|
|
909
|
+
const intervalStr = this.intervalString(interval);
|
|
910
|
+
return `${date} + interval ${intervalStr}`;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* @param {string} interval
|
|
914
|
+
* @returns {string}
|
|
915
|
+
*/
|
|
916
|
+
intervalString(interval) {
|
|
917
|
+
return `'${interval}'`;
|
|
852
918
|
}
|
|
853
919
|
/**
|
|
854
920
|
* @param {string} timestamp
|
|
@@ -1409,7 +1475,15 @@ class BaseQuery {
|
|
|
1409
1475
|
.concat(this.dateFromStartToEndConditionSql(uniqDateJoinCondition, fromRollup, true));
|
|
1410
1476
|
const baseQuery = this.groupedUngroupedSelect(() => baseQueryFn(cumulativeMeasures, filters), cumulativeMeasure.shouldUngroupForCumulative(), !cumulativeMeasure.shouldUngroupForCumulative() && this.minGranularity(cumulativeMeasure.windowGranularity(), dateSeriesGranularity) || undefined);
|
|
1411
1477
|
const baseQueryAlias = this.cubeAlias('base');
|
|
1412
|
-
const dateJoinConditionSql = dateJoinCondition.map(([d, f]) => f(
|
|
1478
|
+
const dateJoinConditionSql = dateJoinCondition.map(([d, f]) => f(
|
|
1479
|
+
// Time-series table is generated differently in different dialects,
|
|
1480
|
+
// but some dialects (like BigQuery) require strict date types and can not automatically convert
|
|
1481
|
+
// between date and timestamp for comparisons, at the same time, time dimensions are expected to be
|
|
1482
|
+
// timestamps, so we need to align types for join conditions/comparisons.
|
|
1483
|
+
// But we can't do it here, as it would break interval maths used in some types of
|
|
1484
|
+
// rolling window join conditions in some dialects (like Redshift), so we need to
|
|
1485
|
+
// do casts granularly in rolling window join conditions functions.
|
|
1486
|
+
`${d.dateSeriesAliasName()}.${this.escapeColumnName('date_from')}`, `${d.dateSeriesAliasName()}.${this.escapeColumnName('date_to')}`, `${baseQueryAlias}.${d.aliasName()}`, `'${d.dateFromFormatted()}'`, `'${d.dateToFormatted()}'`)).join(' AND ');
|
|
1413
1487
|
return this.overTimeSeriesSelect(cumulativeMeasures, dateSeriesSql, baseQuery, dateJoinConditionSql, baseQueryAlias, dateSeriesDimension.granularity);
|
|
1414
1488
|
}
|
|
1415
1489
|
overTimeSeriesSelect(cumulativeMeasures, dateSeriesSql, baseQuery, dateJoinConditionSql, baseQueryAlias, dateSeriesGranularity) {
|
|
@@ -1426,9 +1500,13 @@ class BaseQuery {
|
|
|
1426
1500
|
.filter(c => !!c)
|
|
1427
1501
|
.join(', ');
|
|
1428
1502
|
}
|
|
1503
|
+
/**
|
|
1504
|
+
* BigQuery has strict date type and can not automatically convert between date
|
|
1505
|
+
* and timestamp, so we override dateFromStartToEndConditionSql() in BigQuery Dialect
|
|
1506
|
+
* @protected
|
|
1507
|
+
*/
|
|
1429
1508
|
dateFromStartToEndConditionSql(dateJoinCondition, fromRollup, isFromStartToEnd) {
|
|
1430
1509
|
return dateJoinCondition.map(
|
|
1431
|
-
// TODO these weird conversions to be strict typed for big query.
|
|
1432
1510
|
// TODO Consider adding strict definitions of local and UTC time type
|
|
1433
1511
|
([d, f]) => ({
|
|
1434
1512
|
filterToWhere: () => {
|
|
@@ -1855,7 +1933,17 @@ class BaseQuery {
|
|
|
1855
1933
|
return [s.patchedMeasure.patchedFrom.cubeName].concat(this.evaluateSymbolSql(s.patchedMeasure.patchedFrom.cubeName, s.patchedMeasure.patchedFrom.name, s.definition()));
|
|
1856
1934
|
}
|
|
1857
1935
|
else {
|
|
1858
|
-
|
|
1936
|
+
const res = this.evaluateSql(s.cube().name, s.definition().sql);
|
|
1937
|
+
if (s.isJoinCondition) {
|
|
1938
|
+
// In a join between Cube A and Cube B, sql() may reference members from other cubes.
|
|
1939
|
+
// These referenced cubes must be added as join hints before Cube B to ensure correct SQL generation.
|
|
1940
|
+
const targetCube = s.targetCubeName();
|
|
1941
|
+
let { joinHints } = this.safeEvaluateSymbolContext();
|
|
1942
|
+
joinHints = joinHints.filter(e => e !== targetCube);
|
|
1943
|
+
joinHints.push(targetCube);
|
|
1944
|
+
this.safeEvaluateSymbolContext().joinHints = joinHints;
|
|
1945
|
+
}
|
|
1946
|
+
return res;
|
|
1859
1947
|
}
|
|
1860
1948
|
}
|
|
1861
1949
|
/**
|
|
@@ -1871,7 +1959,15 @@ class BaseQuery {
|
|
|
1871
1959
|
* @returns {Array<Array<string>>}
|
|
1872
1960
|
*/
|
|
1873
1961
|
collectJoinHints(excludeTimeDimensions = false) {
|
|
1874
|
-
const
|
|
1962
|
+
const membersToCollectFrom = [
|
|
1963
|
+
...this.allMembersConcat(excludeTimeDimensions),
|
|
1964
|
+
...this.joinMembersFromJoin(this.join),
|
|
1965
|
+
...this.joinMembersFromCustomSubQuery(),
|
|
1966
|
+
];
|
|
1967
|
+
return this.collectJoinHintsFromMembers(membersToCollectFrom);
|
|
1968
|
+
}
|
|
1969
|
+
joinMembersFromCustomSubQuery() {
|
|
1970
|
+
return this.customSubQueryJoins.map(j => {
|
|
1875
1971
|
const res = {
|
|
1876
1972
|
path: () => null,
|
|
1877
1973
|
cube: () => this.cubeEvaluator.cubeFromPath(j.on.cubeName),
|
|
@@ -1885,19 +1981,17 @@ class BaseQuery {
|
|
|
1885
1981
|
getMembers: () => [res],
|
|
1886
1982
|
};
|
|
1887
1983
|
});
|
|
1888
|
-
|
|
1984
|
+
}
|
|
1985
|
+
joinMembersFromJoin(join) {
|
|
1986
|
+
return join ? join.joins.map(j => ({
|
|
1889
1987
|
getMembers: () => [{
|
|
1890
1988
|
path: () => null,
|
|
1891
1989
|
cube: () => this.cubeEvaluator.cubeFromPath(j.originalFrom),
|
|
1892
1990
|
definition: () => j.join,
|
|
1991
|
+
isJoinCondition: true,
|
|
1992
|
+
targetCubeName: () => j.originalTo,
|
|
1893
1993
|
}]
|
|
1894
1994
|
})) : [];
|
|
1895
|
-
const membersToCollectFrom = [
|
|
1896
|
-
...this.allMembersConcat(excludeTimeDimensions),
|
|
1897
|
-
...joinMembers,
|
|
1898
|
-
...customSubQueryJoinMembers,
|
|
1899
|
-
];
|
|
1900
|
-
return this.collectJoinHintsFromMembers(membersToCollectFrom);
|
|
1901
1995
|
}
|
|
1902
1996
|
collectJoinHintsFromMembers(members) {
|
|
1903
1997
|
return [
|
|
@@ -1966,20 +2060,38 @@ class BaseQuery {
|
|
|
1966
2060
|
return this.rollupGroupByClause(dimensionNames);
|
|
1967
2061
|
}
|
|
1968
2062
|
/**
|
|
1969
|
-
* XXX: String as return value is added because of HiveQuery.getFieldIndex()
|
|
1970
|
-
* @
|
|
2063
|
+
* XXX: String as return value is added because of HiveQuery.getFieldIndex() and DatabricksQuery.getFieldIndex()
|
|
2064
|
+
* @protected
|
|
2065
|
+
* @param {string} id member name in form of "cube.member[.granularity]"
|
|
1971
2066
|
* @returns {number|string|null}
|
|
1972
2067
|
*/
|
|
1973
2068
|
getFieldIndex(id) {
|
|
1974
2069
|
const equalIgnoreCase = (a, b) => (typeof a === 'string' && typeof b === 'string' && a.toUpperCase() === b.toUpperCase());
|
|
1975
|
-
let index;
|
|
1976
|
-
|
|
2070
|
+
let index = -1;
|
|
2071
|
+
const path = id.split('.');
|
|
2072
|
+
// Granularity is specified
|
|
2073
|
+
if (path.length === 3) {
|
|
2074
|
+
const memberName = path.slice(0, 2).join('.');
|
|
2075
|
+
const granularity = path[2];
|
|
2076
|
+
index = this.timeDimensions
|
|
2077
|
+
// Not all time dimensions are used in select list, some are just filters,
|
|
2078
|
+
// but they exist in this.timeDimensions, so need to filter them out
|
|
2079
|
+
.filter(d => d.selectColumns())
|
|
2080
|
+
.findIndex(d => ((equalIgnoreCase(d.dimension, memberName) && (d.granularityObj?.granularity === granularity)) ||
|
|
2081
|
+
equalIgnoreCase(d.expressionName, memberName)));
|
|
2082
|
+
if (index > -1) {
|
|
2083
|
+
return index + 1;
|
|
2084
|
+
}
|
|
2085
|
+
// TODO IT would be nice to log a warning that requested member wasn't found, but we don't have a logger here
|
|
2086
|
+
return null;
|
|
2087
|
+
}
|
|
2088
|
+
const dimensionsForSelect = this.dimensionsForSelect()
|
|
1977
2089
|
// Not all time dimensions are used in select list, some are just filters,
|
|
1978
2090
|
// but they exist in this.timeDimensions, so need to filter them out
|
|
1979
|
-
.filter(d => d.selectColumns())
|
|
1980
|
-
|
|
1981
|
-
if (index > -1) {
|
|
1982
|
-
return index + 1;
|
|
2091
|
+
.filter(d => d.selectColumns());
|
|
2092
|
+
const found = (0, shared_1.findMinGranularityDimension)(id, dimensionsForSelect);
|
|
2093
|
+
if (found?.index > -1) {
|
|
2094
|
+
return found.index + 1;
|
|
1983
2095
|
}
|
|
1984
2096
|
index = this.measures.findIndex(d => equalIgnoreCase(d.measure, id) || equalIgnoreCase(d.expressionName, id));
|
|
1985
2097
|
if (index > -1) {
|
|
@@ -1988,6 +2100,48 @@ class BaseQuery {
|
|
|
1988
2100
|
}
|
|
1989
2101
|
return null;
|
|
1990
2102
|
}
|
|
2103
|
+
/**
|
|
2104
|
+
* @protected
|
|
2105
|
+
* @param {string} id member name in form of "cube.member[.granularity]"
|
|
2106
|
+
* @returns {null|string}
|
|
2107
|
+
*/
|
|
2108
|
+
getFieldAlias(id) {
|
|
2109
|
+
const equalIgnoreCase = (a, b) => (typeof a === 'string' && typeof b === 'string' && a.toUpperCase() === b.toUpperCase());
|
|
2110
|
+
let field;
|
|
2111
|
+
const path = id.split('.');
|
|
2112
|
+
// Granularity is specified
|
|
2113
|
+
if (path.length === 3) {
|
|
2114
|
+
const memberName = path.slice(0, 2).join('.');
|
|
2115
|
+
const granularity = path[2];
|
|
2116
|
+
field = this.timeDimensions
|
|
2117
|
+
// Not all time dimensions are used in select list, some are just filters,
|
|
2118
|
+
// but they exist in this.timeDimensions, so need to filter them out
|
|
2119
|
+
.filter(d => d.selectColumns())
|
|
2120
|
+
.find(d => ((equalIgnoreCase(d.dimension, memberName) && (d.granularityObj?.granularity === granularity)) ||
|
|
2121
|
+
equalIgnoreCase(d.expressionName, memberName)));
|
|
2122
|
+
if (field) {
|
|
2123
|
+
return field.aliasName();
|
|
2124
|
+
}
|
|
2125
|
+
return null;
|
|
2126
|
+
}
|
|
2127
|
+
const dimensionsForSelect = this.dimensionsForSelect()
|
|
2128
|
+
// Not all time dimensions are used in select list, some are just filters,
|
|
2129
|
+
// but they exist in this.timeDimensions, so need to filter them out
|
|
2130
|
+
.filter(d => d.selectColumns());
|
|
2131
|
+
const found = (0, shared_1.findMinGranularityDimension)(id, dimensionsForSelect);
|
|
2132
|
+
if (found?.dimension) {
|
|
2133
|
+
return found.dimension.aliasName();
|
|
2134
|
+
}
|
|
2135
|
+
field = this.measures.find((d) => equalIgnoreCase(d.measure, id) || equalIgnoreCase(d.expressionName, id));
|
|
2136
|
+
if (field) {
|
|
2137
|
+
return field.aliasName();
|
|
2138
|
+
}
|
|
2139
|
+
return null;
|
|
2140
|
+
}
|
|
2141
|
+
/**
|
|
2142
|
+
* @param {{ id: string, desc: boolean }} hash
|
|
2143
|
+
* @returns {string|null}
|
|
2144
|
+
*/
|
|
1991
2145
|
orderHashToString(hash) {
|
|
1992
2146
|
if (!hash || !hash.id) {
|
|
1993
2147
|
return null;
|
|
@@ -2137,7 +2291,7 @@ class BaseQuery {
|
|
|
2137
2291
|
}
|
|
2138
2292
|
pushJoinHints(joinHints) {
|
|
2139
2293
|
if (this.safeEvaluateSymbolContext().joinHints && joinHints) {
|
|
2140
|
-
if (joinHints.length === 1) {
|
|
2294
|
+
if (Array.isArray(joinHints) && joinHints.length === 1) {
|
|
2141
2295
|
[joinHints] = joinHints;
|
|
2142
2296
|
}
|
|
2143
2297
|
this.safeEvaluateSymbolContext().joinHints.push(joinHints);
|
|
@@ -3105,9 +3259,11 @@ class BaseQuery {
|
|
|
3105
3259
|
like_escape: '{{ like_expr }} ESCAPE {{ escape_char }}',
|
|
3106
3260
|
within_group: '{{ fun_sql }} WITHIN GROUP (ORDER BY {{ within_group_concat }})',
|
|
3107
3261
|
concat_strings: '{{ strings | join(\' || \' ) }}',
|
|
3262
|
+
rolling_window_expr_timestamp_cast: '{{ value }}'
|
|
3108
3263
|
},
|
|
3109
3264
|
tesseract: {
|
|
3110
|
-
ilike: '{{ expr }} {% if negated %}NOT {% endif %}ILIKE {{ pattern }}',
|
|
3265
|
+
ilike: '{{ expr }} {% if negated %}NOT {% endif %}ILIKE {{ pattern }}',
|
|
3266
|
+
series_bounds_cast: '{{ expr }}'
|
|
3111
3267
|
},
|
|
3112
3268
|
filters: {
|
|
3113
3269
|
equals: '{{ column }} = {{ value }}{{ is_null_check }}',
|