Skip to content

Commit 96799c6

Browse files
committed
Add custom granularities support to time dimension and base query
1 parent f67034e commit 96799c6

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
@@ -2116,6 +2116,10 @@ export class BaseQuery {
21162116
return this.evaluateSymbolSql(dimension.path()[0], dimension.path()[1], dimension.dimensionDefinition());
21172117
}
21182118

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

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

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)