Skip to content

Commit 4276f1b

Browse files
committed
fix(schema-compiler): Handle measures with dimension-only member expressions in fullKeyQueryAggregateMeasures
1 parent eaa34f3 commit 4276f1b

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

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

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1127,9 +1127,22 @@ export class BaseQuery {
11271127
return allMemberChildren[m]?.some(c => hasMultiStageMembers(c)) || false;
11281128
};
11291129

1130+
// This is a bit of a hack
1131+
// For now object can only come from dimension-only measure branch inside collectRootMeasureToHieararchy
1132+
// So just filters those out, and treat them as regular measures
1133+
// TODO teach rest of code here to work with member expressions
1134+
const dimensionOnlyMeasures = Object.values(measureToHierarchy)
1135+
.flat()
1136+
.map((m) => m.measure)
1137+
.filter((m) => typeof m === 'object');
1138+
11301139
const measuresToRender = (multiplied, cumulative) => R.pipe(
11311140
R.values,
11321141
R.flatten,
1142+
R.filter(
1143+
// To filter out member expressions
1144+
m => typeof m.measure === 'string'
1145+
),
11331146
R.filter(
11341147
m => m.multiplied === multiplied && this.newMeasure(m.measure).isCumulative() === cumulative && !hasMultiStageMembers(m.measure)
11351148
),
@@ -1139,7 +1152,8 @@ export class BaseQuery {
11391152
);
11401153

11411154
const multipliedMeasures = measuresToRender(true, false)(measureToHierarchy);
1142-
const regularMeasures = measuresToRender(false, false)(measureToHierarchy);
1155+
const regularMeasures = measuresToRender(false, false)(measureToHierarchy)
1156+
.concat(dimensionOnlyMeasures);
11431157

11441158
const cumulativeMeasures =
11451159
R.pipe(
@@ -1716,6 +1730,19 @@ export class BaseQuery {
17161730
const cubeName = m.expressionCubeName ? `\`${m.expressionCubeName}\` ` : '';
17171731
throw new UserError(`The query contains \`COUNT(*)\` expression but cube/view ${cubeName}is missing \`count\` measure`);
17181732
}
1733+
if (collectedMeasures.length === 0 && m.isMemberExpression) {
1734+
// `m` is member expression measure, but does not reference any other measure
1735+
// Consider this dimensions-only measure. This can happen at least in 2 cases:
1736+
// 1. Ad-hoc aggregation over dimension: SELECT MAX(dim) FROM cube
1737+
// 2. Ungrouped query with SQL pushdown will render every column as measure: SELECT dim1 FROM cube WHERE LOWER(dim2) = 'foo';
1738+
// Measures like this considered regular: they depend only on dimensions and join tree
1739+
// This would return measure object in `measure`, not path
1740+
// TODO return measure object for every measure
1741+
return [`${m.measure.cubeName}.${m.measure.name}`, [{
1742+
multiplied: false,
1743+
measure: m,
1744+
}]];
1745+
}
17191746
return [typeof m.measure === 'string' ? m.measure : `${m.measure.cubeName}.${m.measure.name}`, collectedMeasures];
17201747
}));
17211748
}

0 commit comments

Comments
 (0)