Skip to content

Commit 6b253c0

Browse files
committed
feat: propagateFiltersToSubQuery flag
1 parent 18da706 commit 6b253c0

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed

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

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -635,19 +635,54 @@ class BaseQuery {
635635
ON ${subQueryAlias}.${primaryKey.aliasName()} = ${this.primaryKeySql(this.cubeEvaluator.primaryKeys[cubeName], cubeName)}`;
636636
}
637637

638+
get filtersWithoutSubQueries() {
639+
if (!this.filtersWithoutSubQueriesValue) {
640+
this.filtersWithoutSubQueriesValue = this.allFilters.filter(
641+
f => this.collectFrom([f], this.collectSubQueryDimensionsFor.bind(this)).length === 0
642+
);
643+
}
644+
return this.filtersWithoutSubQueriesValue;
645+
}
646+
638647
subQueryDescription(dimension) {
639648
const symbol = this.cubeEvaluator.dimensionByPath(dimension);
640649
const [cubeName, name] = this.cubeEvaluator.parsePath('dimensions', dimension);
641650
const prefix = this.subQueryName(cubeName, name);
651+
let filters;
652+
let segments;
653+
let timeDimensions;
654+
if (symbol.propagateFiltersToSubQuery) {
655+
filters = this.filtersWithoutSubQueries.filter(
656+
f => f instanceof BaseFilter && !(f instanceof BaseTimeDimension)
657+
).map(f => ({
658+
dimension: f.dimension,
659+
operator: f.operator,
660+
values: f.values
661+
}));
662+
663+
timeDimensions = this.filtersWithoutSubQueries.filter(
664+
f => f instanceof BaseTimeDimension
665+
).map(f => ({
666+
dimension: f.dimension,
667+
dateRange: f.dateRange
668+
}));
669+
670+
segments = this.filtersWithoutSubQueries.filter(
671+
f => f instanceof BaseSegment
672+
).map(f => f.segment);
673+
}
642674
const subQuery = this.newSubQuery({
643675
cubeAliasPrefix: prefix,
644676
rowLimit: null,
645677
measures: [{
646678
expression: symbol.sql,
647-
cubeName: cubeName,
679+
cubeName,
648680
name
649681
}],
650-
dimensions: [this.primaryKeyName(cubeName)]
682+
dimensions: [this.primaryKeyName(cubeName)],
683+
filters,
684+
segments,
685+
timeDimensions
651686
});
652687
return { prefix, subQuery, cubeName };
653688
}

packages/cubejs-schema-compiler/compiler/CubeValidator.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ const BaseDimensionWithoutSubQuery = {
3030
};
3131

3232
const BaseDimension = Object.assign({
33-
subQuery: Joi.boolean()
33+
subQuery: Joi.boolean(),
34+
propagateFiltersToSubQuery: Joi.boolean()
3435
}, BaseDimensionWithoutSubQuery);
3536

3637
const BaseMeasure = {

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,13 @@ describe('SQL Generation', function test() {
129129
subQuery: true
130130
},
131131
132+
checkinsWithPropagation: {
133+
sql: \`\${visitor_checkins.visitor_checkins_count}\`,
134+
type: \`number\`,
135+
subQuery: true,
136+
propagateFiltersToSubQuery: true
137+
},
138+
132139
subQueryFail: {
133140
sql: '2',
134141
type: \`number\`,
@@ -920,6 +927,52 @@ describe('SQL Generation', function test() {
920927
return result;
921928
});
922929

930+
it('subquery with propagated filters', () => compiler.compile().then(() => {
931+
const query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {
932+
measures: [
933+
'visitors.visitor_count'
934+
],
935+
dimensions: [
936+
'visitors.checkinsWithPropagation'
937+
],
938+
timeDimensions: [{
939+
dimension: 'visitors.created_at',
940+
granularity: 'day',
941+
dateRange: ['2017-01-01', '2017-01-30']
942+
}],
943+
timezone: 'America/Los_Angeles',
944+
filters: [],
945+
order: [{
946+
id: 'visitors.checkins'
947+
}]
948+
});
949+
950+
console.log(query.buildSqlAndParams());
951+
952+
return dbRunner.testQuery(query.buildSqlAndParams()).then(res => {
953+
console.log(JSON.stringify(res));
954+
res.should.be.deepEqual(
955+
[{
956+
"visitors__checkins_with_propagation": "0",
957+
"visitors__created_at_day": "2017-01-06T00:00:00.000Z",
958+
"visitors__visitor_count": "2"
959+
}, {
960+
"visitors__checkins_with_propagation": "1",
961+
"visitors__created_at_day": "2017-01-05T00:00:00.000Z",
962+
"visitors__visitor_count": "1"
963+
}, {
964+
"visitors__checkins_with_propagation": "2",
965+
"visitors__created_at_day": "2017-01-04T00:00:00.000Z",
966+
"visitors__visitor_count": "1"
967+
}, {
968+
"visitors__checkins_with_propagation": "3",
969+
"visitors__created_at_day": "2017-01-02T00:00:00.000Z",
970+
"visitors__visitor_count": "1"
971+
}]
972+
);
973+
});
974+
}));
975+
923976
it('average subquery', () => {
924977
const result = compiler.compile().then(() => {
925978
let query = new PostgresQuery({ joinGraph, cubeEvaluator, compiler }, {

0 commit comments

Comments
 (0)