Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -1310,14 +1310,14 @@
// TODO calculate based on remove_filter in future
const wouldNodeApplyFilters = !memberChildren[member];
let memberFrom = memberChildren[member]
?.map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, queryContext, wouldNodeApplyFilters), memberChildren, withQueries));
?.map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, queryContext), memberChildren, withQueries));

Check warning on line 1313 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

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

Added line #L1313 was not covered by tests
const unionFromDimensions = memberFrom ? R.uniq(R.flatten(memberFrom.map(f => f.dimensions))) : queryContext.dimensions;
const unionDimensionsContext = { ...queryContext, dimensions: unionFromDimensions.filter(d => !this.newDimension(d).isMultiStage()) };
// TODO is calling multiStageWithQueries twice optimal?
memberFrom = memberChildren[member] &&
R.uniqBy(
f => f.alias,
memberChildren[member].map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, unionDimensionsContext, wouldNodeApplyFilters), memberChildren, withQueries))
memberChildren[member].map(child => this.multiStageWithQueries(child, this.childrenMultiStageContext(member, unionDimensionsContext), memberChildren, withQueries))

Check warning on line 1320 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

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

Added line #L1320 was not covered by tests
);
const selfContext = this.selfMultiStageContext(member, queryContext, wouldNodeApplyFilters);
const subQuery = {
Expand All @@ -1344,7 +1344,7 @@
member.memberFrom?.forEach(m => this.collectUsedWithQueries(usedQueries, m));
}

childrenMultiStageContext(memberPath, queryContext, wouldNodeApplyFilters) {
childrenMultiStageContext(memberPath, queryContext) {
let member;
if (this.cubeEvaluator.isMeasure(memberPath)) {
member = this.newMeasure(memberPath);
Expand All @@ -1371,10 +1371,14 @@
};
};
} else {
const allBackAliasMembers = this.allBackAliasTimeDimensions();

Check warning on line 1374 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

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

Added line #L1374 was not covered by tests
mapFn = (td) => {
const timeShift = memberDef.timeShiftReferences.find(r => r.timeDimension === td.dimension);
const timeShift = memberDef.timeShiftReferences.find(r => r.timeDimension === td.dimension || td.dimension === allBackAliasMembers[r.timeDimension]);

Check warning on line 1376 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

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

Added line #L1376 was not covered by tests
if (timeShift) {
if (td.shiftInterval) {
// We need to ignore aliased td, because it will match and insert shiftInterval on first
// occurrence, but later during recursion it will hit the original td but shiftInterval will be
// present and simple check for td.shiftInterval will always result in error.
if (td.shiftInterval && !td.dimension === allBackAliasMembers[timeShift.timeDimension]) {

Check warning on line 1381 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

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

Added line #L1381 was not covered by tests
throw new UserError(`Hierarchical time shift is not supported but was provided for '${td.dimension}'. Parent time shift is '${td.shiftInterval}' and current is '${timeShift.interval}'`);
}
return {
Expand Down Expand Up @@ -4409,10 +4413,24 @@
);
}

/**
* @returns {Record<string, string>}
*/
allBackAliasTimeDimensions() {
const members = R.flatten(this.timeDimensions.map(m => m.getMembers()));
return this.backAliasMembers(members);

Check warning on line 4421 in packages/cubejs-schema-compiler/src/adapter/BaseQuery.js

View check run for this annotation

Codecov / codecov/patch

packages/cubejs-schema-compiler/src/adapter/BaseQuery.js#L4420-L4421

Added lines #L4420 - L4421 were not covered by tests
}

/**
* @returns {Record<string, string>}
*/
allBackAliasMembersExceptSegments() {
return this.backAliasMembers(this.flattenAllMembers(true));
}

/**
* @returns {Record<string, string>}
*/
allBackAliasMembers() {
return this.backAliasMembers(this.flattenAllMembers());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,34 @@ describe('SQL Generation', () => {
sql: new Function('visitor_revenue', 'visitor_count', 'return visitor_revenue + "/" + visitor_count')
}

cube(\`visitors_create_dates\`, {
sql: \`
select id AS create_date_id, created_at from visitors WHERE \${SECURITY_CONTEXT.source.filter('source')} AND
\${SECURITY_CONTEXT.sourceArray.filter(sourceArray => \`source in (\${sourceArray.join(',')})\`)}
\`,

rewriteQueries: true,

dimensions: {
create_date_id: {
type: 'number',
sql: 'id',
primaryKey: true
},
create_date_created_at: {
type: 'time',
sql: 'created_at',
granularities: {
three_days: {
interval: '3 days',
title: '3 days',
origin: '2017-01-01'
}
}
}
}
})

cube(\`visitors\`, {
sql: \`
select * from visitors WHERE \${SECURITY_CONTEXT.source.filter('source')} AND
Expand All @@ -33,6 +61,10 @@ describe('SQL Generation', () => {
visitor_checkins: {
relationship: 'hasMany',
sql: \`\${CUBE}.id = \${visitor_checkins}.visitor_id\`
},
visitors_create_dates: {
relationship: 'one_to_one',
sql: \`\${CUBE}.id = \${visitors_create_dates}.create_date_id\`
}
},

Expand Down Expand Up @@ -138,6 +170,16 @@ describe('SQL Generation', () => {
type: 'prior',
}]
},
revenue_day_ago_via_join: {
multi_stage: true,
type: 'sum',
sql: \`\${revenue}\`,
time_shift: [{
time_dimension: visitors_create_dates.create_date_created_at,
interval: '1 day',
type: 'prior',
}]
},
cagr_day: {
multi_stage: true,
sql: \`ROUND(100 * \${revenue} / NULLIF(\${revenue_day_ago}, 0))\`,
Expand Down Expand Up @@ -339,6 +381,10 @@ describe('SQL Generation', () => {
cubes: [{
join_path: 'visitors',
includes: '*'
},
{
join_path: 'visitors.visitors_create_dates',
includes: '*'
}]
})

Expand Down Expand Up @@ -1380,6 +1426,45 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL
{ visitors__created_at_day: '2017-01-06T00:00:00.000Z', visitors__cagr_day: '300', visitors__revenue: '900', visitors__revenue_day_ago_no_td: '300' }
]));

it('CAGR via view (td from main cube)', async () => runQueryTest({
measures: [
'visitors_multi_stage.revenue',
'visitors_multi_stage.revenue_day_ago',
'visitors_multi_stage.cagr_day'
],
timeDimensions: [{
dimension: 'visitors_multi_stage.created_at',
granularity: 'day',
dateRange: ['2016-12-01', '2017-01-31']
}],
order: [{
id: 'visitors_multi_stage.created_at'
}],
timezone: 'America/Los_Angeles'
}, [
{ visitors_multi_stage__created_at_day: '2017-01-05T00:00:00.000Z', visitors_multi_stage__cagr_day: '150', visitors_multi_stage__revenue: '300', visitors_multi_stage__revenue_day_ago: '200' },
{ visitors_multi_stage__created_at_day: '2017-01-06T00:00:00.000Z', visitors_multi_stage__cagr_day: '300', visitors_multi_stage__revenue: '900', visitors_multi_stage__revenue_day_ago: '300' }
]));

it('CAGR via view (td from joined cube)', async () => runQueryTest({
measures: [
'visitors_multi_stage.revenue',
'visitors_multi_stage.revenue_day_ago_via_join',
],
timeDimensions: [{
dimension: 'visitors_multi_stage.create_date_created_at',
granularity: 'day',
dateRange: ['2016-12-01', '2017-01-31']
}],
order: [{
id: 'visitors_multi_stage.create_date_created_at'
}],
timezone: 'America/Los_Angeles'
}, [
{ visitors_multi_stage__create_date_created_at_day: '2017-01-05T00:00:00.000Z', visitors_multi_stage__revenue: '300', visitors_multi_stage__revenue_day_ago_via_join: '200' },
{ visitors_multi_stage__create_date_created_at_day: '2017-01-06T00:00:00.000Z', visitors_multi_stage__revenue: '900', visitors_multi_stage__revenue_day_ago_via_join: '300' }
]));

it('sql utils', async () => runQueryTest({
measures: [
'visitors.visitor_count'
Expand Down
Loading