Skip to content

Commit 88de386

Browse files
committed
Add custom granularities support to time dimension and base query
1 parent b26e3b9 commit 88de386

File tree

2 files changed

+45
-10
lines changed

2 files changed

+45
-10
lines changed

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2115,6 +2115,10 @@ export class BaseQuery {
21152115
return this.evaluateSymbolSql(dimension.path()[0], dimension.path()[1], dimension.dimensionDefinition());
21162116
}
21172117

2118+
dimensionGranularitySql(dimension) {
2119+
return this.evaluateSymbolSql(dimension.path()[0], dimension.path()[1], dimension.dimensionDefinition(), null, ['granularities', dimension.granularity]);
2120+
}
2121+
21182122
segmentSql(segment) {
21192123
return this.evaluateSymbolSql(segment.path()[0], segment.path()[1], segment.segmentDefinition());
21202124
}
@@ -2171,12 +2175,12 @@ export class BaseQuery {
21712175
return this.evaluateSymbolContext || {};
21722176
}
21732177

2174-
evaluateSymbolSql(cubeName, name, symbol, memberExpressionType) {
2178+
evaluateSymbolSql(cubeName, name, symbol, memberExpressionType, childPropPathArray) {
21752179
const isMemberExpr = !!memberExpressionType;
21762180
if (!memberExpressionType) {
21772181
this.pushMemberNameForCollectionIfNecessary(cubeName, name);
21782182
}
2179-
const memberPathArray = [cubeName, name];
2183+
const memberPathArray = [cubeName, name].concat(childPropPathArray ?? []);
21802184
const memberPath = this.cubeEvaluator.pathFromArray(memberPathArray);
21812185
let type = memberExpressionType;
21822186
if (!type && this.cubeEvaluator.isMeasure(memberPathArray)) {
@@ -2281,7 +2285,17 @@ export class BaseQuery {
22812285
this.autoPrefixAndEvaluateSql(cubeName, symbol.longitude.sql, isMemberExpr)
22822286
]);
22832287
} else {
2284-
let res = this.autoPrefixAndEvaluateSql(cubeName, symbol.sql, isMemberExpr);
2288+
let res;
2289+
2290+
// TODO Temporarily placed it here, but maybe this should be moved level up and processed in
2291+
// more generalized way to support nested properties not only on dimension level
2292+
if (childPropPathArray && childPropPathArray.length > 0) {
2293+
const childProperty = this.cubeEvaluator.byPath('dimensions', memberPathArray);
2294+
res = this.autoPrefixAndEvaluateSql(cubeName, childProperty.sql, isMemberExpr);
2295+
} else {
2296+
res = this.autoPrefixAndEvaluateSql(cubeName, symbol.sql, isMemberExpr);
2297+
}
2298+
22852299
if (symbol.shiftInterval) {
22862300
res = `(${this.addTimestampInterval(res, symbol.shiftInterval)})`;
22872301
}

packages/cubejs-schema-compiler/src/adapter/BaseTimeDimension.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ export class BaseTimeDimension extends BaseFilter {
1313

1414
public readonly isPredefined: boolean;
1515

16-
public readonly baseGranularity: string;
16+
public readonly baseGranularity: string | undefined;
17+
18+
public readonly granularitySql: Function | undefined;
1719

1820
public readonly boundaryDateRange: any;
1921

@@ -31,9 +33,14 @@ export class BaseTimeDimension extends BaseFilter {
3133
this.dateRange = timeDimension.dateRange;
3234
this.granularity = timeDimension.granularity;
3335
this.isPredefined = isPredefinedGranularity(this.granularity);
34-
this.baseGranularity = this.query.cubeEvaluator
35-
.byPath('dimensions', timeDimension.dimension)
36-
.granularities?.[this.granularity]?.baseGranularity;
36+
if (!this.isPredefined) {
37+
const customGranularity = this.query.cubeEvaluator
38+
.byPath('dimensions', timeDimension.dimension)
39+
.granularities?.[this.granularity];
40+
41+
this.baseGranularity = customGranularity?.baseGranularity;
42+
this.granularitySql = customGranularity?.sql;
43+
}
3744
this.boundaryDateRange = timeDimension.boundaryDateRange;
3845
this.shiftInterval = timeDimension.shiftInterval;
3946
}
@@ -95,12 +102,22 @@ export class BaseTimeDimension extends BaseFilter {
95102
if (context.rollupGranularity === this.granularity) {
96103
return super.dimensionSql();
97104
}
98-
return this.query.timeGroupedColumn(granularity, this.query.dimensionSql(this));
105+
if (this.isPredefined || !this.granularity) {
106+
return this.query.timeGroupedColumn(granularity, this.query.dimensionSql(this));
107+
} else {
108+
return this.query.dimensionGranularitySql(this);
109+
}
99110
}
111+
100112
if (context.ungrouped) {
101113
return this.convertedToTz();
102114
}
103-
return this.query.timeGroupedColumn(granularity, this.convertedToTz());
115+
116+
if (this.isPredefined) {
117+
return this.query.timeGroupedColumn(granularity, this.convertedToTz());
118+
} else {
119+
return this.granularityConvertedToTz();
120+
}
104121
}
105122

106123
public dimensionDefinition(): DimensionDefinition | SegmentDefinition {
@@ -115,7 +132,11 @@ export class BaseTimeDimension extends BaseFilter {
115132
}
116133

117134
public convertedToTz() {
118-
return this.query.convertTz(this.query.dimensionSql(this));
135+
return this.query.convertTz(`${this.query.dimensionSql(this)}`);
136+
}
137+
138+
public granularityConvertedToTz() {
139+
return this.query.convertTz(`(${this.query.dimensionGranularitySql(this)})`);
119140
}
120141

121142
public filterToWhere() {

0 commit comments

Comments
 (0)