diff --git a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js index b7fc25e842a63..c7617ddf8e9b2 100644 --- a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js +++ b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js @@ -1428,10 +1428,15 @@ export class BaseQuery { if (memberDef.timeShiftReferences?.length) { let mapFn; + const allBackAliasMembers = this.allBackAliasTimeDimensions(); + if (memberDef.timeShiftReferences.length === 1 && !memberDef.timeShiftReferences[0].timeDimension) { const timeShift = memberDef.timeShiftReferences[0]; mapFn = (td) => { - 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]) { 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 { @@ -1440,7 +1445,6 @@ export class BaseQuery { }; }; } else { - const allBackAliasMembers = this.allBackAliasTimeDimensions(); mapFn = (td) => { const timeShift = memberDef.timeShiftReferences.find(r => r.timeDimension === td.dimension || td.dimension === allBackAliasMembers[r.timeDimension]); if (timeShift) { diff --git a/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts b/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts index f3cde5a46fbde..9ce2f24a7ae1c 100644 --- a/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts +++ b/packages/cubejs-schema-compiler/test/integration/postgres/sql-generation.test.ts @@ -1444,6 +1444,33 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL { 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('CAGR (no td in time_shift via view)', async () => runQueryTest({ + measures: [ + 'visitors_multi_stage.revenue', + 'visitors_multi_stage.revenue_day_ago_no_td', + ], + 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_no_td: '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_no_td: '300', + } + ])); + it('sql utils', async () => runQueryTest({ measures: [ 'visitors.visitor_count'