Skip to content

Commit c897dec

Browse files
committed
fix: Multiplied measures rollup select case and leaf measure additive exact match
1 parent b91f408 commit c897dec

File tree

3 files changed

+42
-51
lines changed

3 files changed

+42
-51
lines changed

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

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -330,26 +330,7 @@ class BaseQuery {
330330
}
331331

332332
fullKeyQueryAggregate() {
333-
const measureToHierarchy = this.collectRootMeasureToHieararchy();
334-
335-
const measuresToRender = (multiplied, cumulative) => R.pipe(
336-
R.values,
337-
R.flatten,
338-
R.filter(
339-
m => m.multiplied === multiplied && this.newMeasure(m.measure).isCumulative() === cumulative
340-
),
341-
R.map(m => m.measure),
342-
R.uniq,
343-
R.map(m => this.newMeasure(m))
344-
);
345-
346-
const multipliedMeasures = measuresToRender(true, false)(measureToHierarchy);
347-
const regularMeasures = measuresToRender(false, false)(measureToHierarchy);
348-
const cumulativeMeasures =
349-
R.pipe(
350-
R.map(multiplied => R.xprod([multiplied], measuresToRender(multiplied, true)(measureToHierarchy))),
351-
R.unnest
352-
)([false, true]);
333+
const { multipliedMeasures, regularMeasures, cumulativeMeasures } = this.fullKeyQueryAggregateMeasures();
353334

354335
if (!multipliedMeasures.length && !cumulativeMeasures.length) {
355336
return this.simpleQuery();
@@ -410,6 +391,30 @@ class BaseQuery {
410391
return `SELECT ${this.topLimit()}${columnsToSelect} FROM (${toJoin[0]}) as q_0 ${join}${havingFilters}${this.orderBy()}${this.groupByDimensionLimit()}`;
411392
}
412393

394+
fullKeyQueryAggregateMeasures() {
395+
const measureToHierarchy = this.collectRootMeasureToHieararchy();
396+
397+
const measuresToRender = (multiplied, cumulative) => R.pipe(
398+
R.values,
399+
R.flatten,
400+
R.filter(
401+
m => m.multiplied === multiplied && this.newMeasure(m.measure).isCumulative() === cumulative
402+
),
403+
R.map(m => m.measure),
404+
R.uniq,
405+
R.map(m => this.newMeasure(m))
406+
);
407+
408+
const multipliedMeasures = measuresToRender(true, false)(measureToHierarchy);
409+
const regularMeasures = measuresToRender(false, false)(measureToHierarchy);
410+
const cumulativeMeasures =
411+
R.pipe(
412+
R.map(multiplied => R.xprod([multiplied], measuresToRender(multiplied, true)(measureToHierarchy))),
413+
R.unnest
414+
)([false, true]);
415+
return { multipliedMeasures, regularMeasures, cumulativeMeasures };
416+
}
417+
413418
dimensionsJoinCondition(leftAlias, rightAlias) {
414419
const dimensionAliases = this.dimensionAliasNames();
415420
if (!dimensionAliases.length) {

packages/cubejs-schema-compiler/adapter/PreAggregations.js

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ class PreAggregations {
165165
const isAdditive = R.all(m => m.isAdditive(), query.measures);
166166
const leafMeasureAdditive = R.all(path => query.newMeasure(path).isAdditive(), leafMeasurePaths);
167167
const granularityHierarchies = query.granularityHierarchies();
168+
const hasMultipliedMeasures = query.fullKeyQueryAggregateMeasures().multipliedMeasures.length > 0;
168169

169170
return {
170171
sortedDimensions,
@@ -175,7 +176,8 @@ class PreAggregations {
175176
hasNoTimeDimensionsWithoutGranularity,
176177
allFiltersWithinSelectedDimensions,
177178
isAdditive,
178-
granularityHierarchies
179+
granularityHierarchies,
180+
hasMultipliedMeasures
179181
};
180182
}
181183

@@ -232,8 +234,7 @@ class PreAggregations {
232234
// [[TimeDimension]]
233235
const queryTimeDimensionsList = transformedQuery.sortedTimeDimensions.map(expandTimeDimension);
234236

235-
const canUsePreAggregationNotAdditive = (references) =>
236-
transformedQuery.hasNoTimeDimensionsWithoutGranularity &&
237+
const canUsePreAggregationNotAdditive = (references) => transformedQuery.hasNoTimeDimensionsWithoutGranularity &&
237238
transformedQuery.allFiltersWithinSelectedDimensions &&
238239
R.equals(references.sortedDimensions || references.dimensions, transformedQuery.sortedDimensions) &&
239240
(
@@ -245,35 +246,18 @@ class PreAggregations {
245246
references.sortedTimeDimensions || sortTimeDimensions(references.timeDimensions)
246247
);
247248

248-
const canUsePreAggregationLeafMeasureAdditive = (references) =>
249-
R.all(
250-
d => (references.sortedDimensions || references.dimensions).indexOf(d) !== -1,
251-
transformedQuery.sortedDimensions
252-
) &&
249+
const canUsePreAggregationLeafMeasureAdditive = (references) => R.all(
250+
d => (references.sortedDimensions || references.dimensions).indexOf(d) !== -1,
251+
transformedQuery.sortedDimensions
252+
) &&
253253
R.all(m => references.measures.indexOf(m) !== -1, transformedQuery.leafMeasures) &&
254254
R.allPass(
255255
queryTimeDimensionsList.map(tds => R.anyPass(tds.map(td => R.contains(td))))
256256
)(references.sortedTimeDimensions || sortTimeDimensions(references.timeDimensions));
257257

258-
const canUsePreAggregationAdditive = (references) =>
259-
R.all(
260-
d => (references.sortedDimensions || references.dimensions).indexOf(d) !== -1,
261-
transformedQuery.sortedDimensions
262-
) &&
263-
(
264-
R.all(m => references.measures.indexOf(m) !== -1, transformedQuery.measures) ||
265-
R.all(m => references.measures.indexOf(m) !== -1, transformedQuery.leafMeasures)
266-
) &&
267-
R.allPass(
268-
queryTimeDimensionsList.map(tds => R.anyPass(tds.map(td => R.contains(td))))
269-
)(references.sortedTimeDimensions || sortTimeDimensions(references.timeDimensions));
270-
271-
272258
let canUseFn;
273-
if (transformedQuery.isAdditive) {
274-
canUseFn = canUsePreAggregationAdditive;
275-
} else if (transformedQuery.leafMeasureAdditive) {
276-
canUseFn = canUsePreAggregationLeafMeasureAdditive;
259+
if (transformedQuery.leafMeasureAdditive && !transformedQuery.hasMultipliedMeasures) {
260+
canUseFn = (r) => canUsePreAggregationLeafMeasureAdditive(r) || canUsePreAggregationNotAdditive(r);
277261
} else {
278262
canUseFn = canUsePreAggregationNotAdditive;
279263
}

packages/cubejs-schema-compiler/test/SQLGenerationTest.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,8 +1138,10 @@ describe('SQL Generation', function test() {
11381138
],
11391139
timeDimensions: [{
11401140
dimension: 'visitors.created_at',
1141+
granularity: 'day',
11411142
dateRange: ['2017-01-01', '2017-01-30']
11421143
}],
1144+
dimensions: ['visitor_checkins.source'],
11431145
timezone: 'America/Los_Angeles',
11441146
order: [],
11451147
filters: [{
@@ -1164,11 +1166,11 @@ describe('SQL Generation', function test() {
11641166
])).then(res => {
11651167
console.log(JSON.stringify(res));
11661168
res.should.be.deepEqual(
1167-
[
1168-
{
1169-
"visitors__visitor_revenue": "100"
1170-
}
1171-
]
1169+
[{
1170+
"visitor_checkins__source": "google",
1171+
"visitors__created_at_day": "2017-01-02T00:00:00.000Z",
1172+
"visitors__visitor_revenue": "100"
1173+
}]
11721174
);
11731175
});
11741176
});

0 commit comments

Comments
 (0)