diff --git a/packages/cubejs-schema-compiler/src/adapter/Granularity.ts b/packages/cubejs-schema-compiler/src/adapter/Granularity.ts index d635bd3c6be40..856382e30bf23 100644 --- a/packages/cubejs-schema-compiler/src/adapter/Granularity.ts +++ b/packages/cubejs-schema-compiler/src/adapter/Granularity.ts @@ -21,7 +21,7 @@ export class Granularity { public readonly granularityOffset: string | undefined; - public readonly origin: moment.Moment; + public origin: moment.Moment; private readonly predefinedGranularity: boolean; @@ -52,12 +52,23 @@ export class Granularity { if (customGranularity.origin) { this.origin = moment.tz(customGranularity.origin, query.timezone); } else if (customGranularity.offset) { + // Needed because if interval is week-based, offset is expected to be relative to the start of a week + this.fixOriginForWeeksIfNeeded(); this.granularityOffset = customGranularity.offset; this.origin = addInterval(this.origin, parseSqlInterval(customGranularity.offset)); + } else { + this.fixOriginForWeeksIfNeeded(); } } } + private fixOriginForWeeksIfNeeded() { + const parsedInterval = parseSqlInterval(this.granularityInterval); + if (Object.keys(parsedInterval).length === 1 && parsedInterval.week) { + this.origin = this.origin.isoWeekday(1); + } + } + public isPredefined(): boolean { return this.predefinedGranularity; } diff --git a/packages/cubejs-schema-compiler/test/integration/postgres/custom-granularities.test.ts b/packages/cubejs-schema-compiler/test/integration/postgres/custom-granularities.test.ts index 4be8f26f744b7..000d8482df0d2 100644 --- a/packages/cubejs-schema-compiler/test/integration/postgres/custom-granularities.test.ts +++ b/packages/cubejs-schema-compiler/test/integration/postgres/custom-granularities.test.ts @@ -47,6 +47,9 @@ describe('Custom Granularities', () => { - name: two_weeks_by_friday interval: 2 weeks origin: '2024-08-23' + - name: one_week_by_friday_by_offset + interval: 1 week + offset: 4 days - name: one_hour_by_5min_offset interval: 1 hour offset: 5 minutes @@ -123,6 +126,43 @@ describe('Custom Granularities', () => { { joinGraph, cubeEvaluator, compiler } )); + it('works with one_week_by_friday_by_offset custom granularity w/o dimensions query', async () => dbRunner.runQueryTest( + { + measures: ['orders.count'], + timeDimensions: [{ + dimension: 'orders.createdAt', + granularity: 'one_week_by_friday_by_offset', + dateRange: ['2024-01-01', '2024-03-01'] + }], + dimensions: [], + filters: [], + timezone: 'Europe/London' + }, + [ + { + orders__count: '1', + orders__created_at_one_week_by_friday_by_offset: '2023-12-29T00:00:00.000Z', + }, + { + orders__count: '1', + orders__created_at_one_week_by_friday_by_offset: '2024-01-12T00:00:00.000Z', + }, + { + orders__count: '1', + orders__created_at_one_week_by_friday_by_offset: '2024-01-26T00:00:00.000Z', + }, + { + orders__count: '1', + orders__created_at_one_week_by_friday_by_offset: '2024-02-09T00:00:00.000Z', + }, + { + orders__count: '1', + orders__created_at_one_week_by_friday_by_offset: '2024-02-23T00:00:00.000Z', + }, + ], + { joinGraph, cubeEvaluator, compiler } + )); + it('works with proxied createdAtHalfYear custom granularity as dimension query', async () => dbRunner.runQueryTest( { measures: ['orders.count'],