From b3d2505497e55dc45286b40883d94611129580b0 Mon Sep 17 00:00:00 2001 From: Konstantin Burkalev Date: Wed, 2 Jul 2025 11:34:16 +0300 Subject: [PATCH 1/3] fix(schema-compiler): Fix date filter truncation for rolling window queries --- .../src/adapter/BaseQuery.js | 47 ++++++++--- .../postgres/sql-generation.test.ts | 78 +++++++++++++++++++ 2 files changed, 114 insertions(+), 11 deletions(-) diff --git a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js index a725d8dc510e9..3b2ec023ed845 100644 --- a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js +++ b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js @@ -1037,23 +1037,48 @@ export class BaseQuery { } rollingWindowToDateJoinCondition(granularity) { - return this.timeDimensions - .filter(td => td.granularity) - .map( - d => [ - d, - (dateFrom, dateTo, dateField, _dimensionDateFrom, _dimensionDateTo, _isFromStartToEnd) => `${dateField} >= ${this.timeGroupedColumn(granularity, dateFrom)} AND ${dateField} <= ${dateTo}` - ] - ); + return Object.values( + this.timeDimensions.reduce((acc, td) => { + const key = td.dimension; + + if (!acc[key]) { + acc[key] = td; + } + + if (!acc[key].granularity && td.granularity) { + acc[key] = td; + } + + return acc; + }, {}) + ).map( + d => [ + d, + (dateFrom, dateTo, dateField, _dimensionDateFrom, _dimensionDateTo, _isFromStartToEnd) => `${dateField} >= ${this.timeGroupedColumn(granularity, dateFrom)} AND ${dateField} <= ${dateTo}` + ] + ); } rollingWindowDateJoinCondition(trailingInterval, leadingInterval, offset) { offset = offset || 'end'; - return this.timeDimensions - .filter(td => td.granularity) + return Object.values( + this.timeDimensions.reduce((acc, td) => { + const key = td.dimension; + + if (!acc[key]) { + acc[key] = td; + } + + if (!acc[key].granularity && td.granularity) { + acc[key] = td; + } + + return acc; + }, {}) + ) .map( d => [d, (dateFrom, dateTo, dateField, _dimensionDateFrom, _dimensionDateTo, isFromStartToEnd) => { - // dateFrom based window + // dateFrom based window const conditions = []; if (trailingInterval !== 'unbounded') { const startDate = isFromStartToEnd || offset === 'start' ? dateFrom : dateTo; 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 813760db0f71f..c3c43f7e60dd5 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 @@ -1070,6 +1070,84 @@ SELECT 1 AS revenue, cast('2024-01-01' AS timestamp) as time UNION ALL } ])); + it('rolling window with one time dimension with granularity', async () => runQueryTest({ + measures: [ + 'visitors.countRollingWeekToDate' + ], + timeDimensions: [ + { + dimension: 'visitors.created_at', + granularity: 'day', + dateRange: ['2017-01-01', '2017-01-10'] + } + ], + order: [{ + id: 'visitors.created_at' + }], + timezone: 'America/Los_Angeles' + }, [ + { + visitors__count_rolling_week_to_date: null, + visitors__created_at_day: '2017-01-01T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '1', + visitors__created_at_day: '2017-01-02T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '1', + visitors__created_at_day: '2017-01-03T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '2', + visitors__created_at_day: '2017-01-04T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '3', + visitors__created_at_day: '2017-01-05T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '5', + visitors__created_at_day: '2017-01-06T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '5', + visitors__created_at_day: '2017-01-07T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: '5', + visitors__created_at_day: '2017-01-08T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: null, + visitors__created_at_day: '2017-01-09T00:00:00.000Z', + }, + { + visitors__count_rolling_week_to_date: null, + visitors__created_at_day: '2017-01-10T00:00:00.000Z', + }, + ])); + + it('rolling window with one time dimension without granularity', async () => runQueryTest({ + measures: [ + 'visitors.countRollingWeekToDate' + ], + timeDimensions: [ + { + dimension: 'visitors.created_at', + dateRange: ['2017-01-01', '2017-01-10'] + } + ], + order: [{ + id: 'visitors.created_at' + }], + timezone: 'America/Los_Angeles' + }, [ + { + visitors__count_rolling_week_to_date: '5', + } + ])); + it('rolling window with two time dimension granularities', async () => runQueryTest({ measures: [ 'visitors.countRollingWeekToDate' From 979fc1edbca88d1f39b4d8d85d1548420e9bf7d8 Mon Sep 17 00:00:00 2001 From: Konstantin Burkalev Date: Wed, 2 Jul 2025 12:02:11 +0300 Subject: [PATCH 2/3] fix snapshots --- .../__snapshots__/athena-export-bucket-s3-full.test.ts.snap | 2 +- .../__snapshots__/bigquery-export-bucket-gcs-full.test.ts.snap | 2 +- .../__snapshots__/clickhouse-export-bucket-s3-full.test.ts.snap | 2 +- .../clickhouse-export-bucket-s3-prefix-full.test.ts.snap | 2 +- .../test/__snapshots__/clickhouse-full.test.ts.snap | 2 +- .../databricks-jdbc-export-bucket-azure-full.test.ts.snap | 2 +- ...databricks-jdbc-export-bucket-azure-prefix-full.test.ts.snap | 2 +- .../databricks-jdbc-export-bucket-gcs-full.test.ts.snap | 2 +- .../databricks-jdbc-export-bucket-gcs-prefix-full.test.ts.snap | 2 +- .../databricks-jdbc-export-bucket-s3-full.test.ts.snap | 2 +- .../databricks-jdbc-export-bucket-s3-prefix-full.test.ts.snap | 2 +- .../test/__snapshots__/databricks-jdbc-full.test.ts.snap | 2 +- .../test/__snapshots__/mssql-full.test.ts.snap | 2 +- .../test/__snapshots__/mysql-full.test.ts.snap | 2 +- .../test/__snapshots__/postgres-full.test.ts.snap | 2 +- .../__snapshots__/redshift-export-bucket-s3-full.test.ts.snap | 2 +- .../test/__snapshots__/redshift-full.test.ts.snap | 2 +- .../test/__snapshots__/snowflake-encrypted-pk-full.test.ts.snap | 2 +- .../snowflake-export-bucket-azure-full.test.ts.snap | 2 +- .../snowflake-export-bucket-azure-prefix-full.test.ts.snap | 2 +- ...xport-bucket-azure-via-storage-integration-full.test.ts.snap | 2 +- .../__snapshots__/snowflake-export-bucket-gcs-full.test.ts.snap | 2 +- .../snowflake-export-bucket-gcs-prefix-full.test.ts.snap | 2 +- .../__snapshots__/snowflake-export-bucket-s3-full.test.ts.snap | 2 +- .../snowflake-export-bucket-s3-prefix-full.test.ts.snap | 2 +- .../test/__snapshots__/snowflake-full.test.ts.snap | 2 +- .../birdbox-postgresql-pre-aggregations.test.ts.snap | 2 +- .../__snapshots__/cli-postgresql-pre-aggregations.test.ts.snap | 2 +- 28 files changed, 28 insertions(+), 28 deletions(-) diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/athena-export-bucket-s3-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/athena-export-bucket-s3-full.test.ts.snap index e476188d809e5..0386e57ffa1d1 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/athena-export-bucket-s3-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/athena-export-bucket-s3-full.test.ts.snap @@ -4479,7 +4479,7 @@ Array [ exports[`Queries with the @cubejs-backend/athena-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/bigquery-export-bucket-gcs-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/bigquery-export-bucket-gcs-full.test.ts.snap index 6151311383e79..0511af1464010 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/bigquery-export-bucket-gcs-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/bigquery-export-bucket-gcs-full.test.ts.snap @@ -8149,7 +8149,7 @@ Array [ exports[`Queries with the @cubejs-backend/bigquery-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": 44, + "BigECommerce.rollingCountYTD": 3, }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-full.test.ts.snap index 46d25c66d5c8e..fe1568c9aacb4 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-full.test.ts.snap @@ -4680,7 +4680,7 @@ Array [ exports[`Queries with the @cubejs-backend/clickhouse-driver export-bucket-s3 querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-prefix-full.test.ts.snap index f2b47eecd6f42..aea90fc34c1a5 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-export-bucket-s3-prefix-full.test.ts.snap @@ -4680,7 +4680,7 @@ Array [ exports[`Queries with the @cubejs-backend/clickhouse-driver export-bucket-s3-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-full.test.ts.snap index 2134c6b87aff1..42f25946b7529 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/clickhouse-full.test.ts.snap @@ -4680,7 +4680,7 @@ Array [ exports[`Queries with the @cubejs-backend/clickhouse-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-full.test.ts.snap index 67a92ae7070e9..c87bab9dd5e3a 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-full.test.ts.snap @@ -10885,7 +10885,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver export-bucket-azure querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-prefix-full.test.ts.snap index 7628b6dfb85d9..8a3e70cd33e67 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-azure-prefix-full.test.ts.snap @@ -10690,7 +10690,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver export-bucket-azure-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-full.test.ts.snap index c42ce9fef39a3..264579108e8cf 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-full.test.ts.snap @@ -10885,7 +10885,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver export-bucket-gcs querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-prefix-full.test.ts.snap index 932834e2e1c8e..9e76908cf768e 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-gcs-prefix-full.test.ts.snap @@ -10690,7 +10690,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver export-bucket-gcs-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-full.test.ts.snap index b65744d54238e..f2666d3e16522 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-full.test.ts.snap @@ -10885,7 +10885,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver export-bucket-s3 querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-prefix-full.test.ts.snap index 38ac7dbbb35a3..95dd37d541341 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-export-bucket-s3-prefix-full.test.ts.snap @@ -10690,7 +10690,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver export-bucket-s3-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-full.test.ts.snap index fadc20415235f..fce072a38c3cb 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/databricks-jdbc-full.test.ts.snap @@ -10885,7 +10885,7 @@ Array [ exports[`Queries with the @cubejs-backend/databricks-jdbc-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/mssql-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/mssql-full.test.ts.snap index f87b7a0a8cc15..94e743162c16e 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/mssql-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/mssql-full.test.ts.snap @@ -3965,7 +3965,7 @@ Array [ exports[`Queries with the @cubejs-backend/mssql-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "440000", + "BigECommerce.rollingCountYTD": "30000", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/mysql-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/mysql-full.test.ts.snap index 28f6ea2a85719..e392a5a12f5b7 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/mysql-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/mysql-full.test.ts.snap @@ -3978,7 +3978,7 @@ Array [ exports[`Queries with the @cubejs-backend/mysql-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": 44, + "BigECommerce.rollingCountYTD": 3, }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/postgres-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/postgres-full.test.ts.snap index 276193395175c..8aecfb381e798 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/postgres-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/postgres-full.test.ts.snap @@ -13021,7 +13021,7 @@ Array [ exports[`Queries with the @cubejs-backend/postgres-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/redshift-export-bucket-s3-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/redshift-export-bucket-s3-full.test.ts.snap index 5dd1fea974151..1a8c496c95919 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/redshift-export-bucket-s3-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/redshift-export-bucket-s3-full.test.ts.snap @@ -12753,7 +12753,7 @@ Array [ exports[`Queries with the @cubejs-backend/redshift-driver export-bucket-s3 querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/redshift-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/redshift-full.test.ts.snap index e8a90b2954bcd..95d5d9e95ab34 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/redshift-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/redshift-full.test.ts.snap @@ -12753,7 +12753,7 @@ Array [ exports[`Queries with the @cubejs-backend/redshift-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-encrypted-pk-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-encrypted-pk-full.test.ts.snap index 0473c988d1c26..aae59e24272b1 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-encrypted-pk-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-encrypted-pk-full.test.ts.snap @@ -17984,7 +17984,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver encrypted-pk querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-full.test.ts.snap index 19a75e77428ba..dbcf74d07bfd7 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-full.test.ts.snap @@ -12718,7 +12718,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-azure querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-prefix-full.test.ts.snap index 3054d58dde22e..a2ede7ad0de52 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-prefix-full.test.ts.snap @@ -12523,7 +12523,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-azure-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-via-storage-integration-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-via-storage-integration-full.test.ts.snap index 17be8697a05d1..59c7750db36a8 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-via-storage-integration-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-azure-via-storage-integration-full.test.ts.snap @@ -12925,7 +12925,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-azure-via-storage-integration querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-full.test.ts.snap index 92a245a32eb26..d0d7a47cfd1a3 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-full.test.ts.snap @@ -12925,7 +12925,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-gcs querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-prefix-full.test.ts.snap index c8887e275f7ce..59d466c71a05b 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-gcs-prefix-full.test.ts.snap @@ -12730,7 +12730,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-gcs-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-full.test.ts.snap index 92c55f701dfc6..f4f88a94e063f 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-full.test.ts.snap @@ -12925,7 +12925,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-s3 querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-prefix-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-prefix-full.test.ts.snap index 2bdc99a4e7d47..33335261db3dc 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-prefix-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-export-bucket-s3-prefix-full.test.ts.snap @@ -12730,7 +12730,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver export-bucket-s3-prefix querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-full.test.ts.snap b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-full.test.ts.snap index 81e777544c0d7..823c06e7c0ea0 100644 --- a/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-full.test.ts.snap +++ b/packages/cubejs-testing-drivers/test/__snapshots__/snowflake-full.test.ts.snap @@ -12925,7 +12925,7 @@ Array [ exports[`Queries with the @cubejs-backend/snowflake-driver querying BigECommerce: rolling window YTD without granularity 1`] = ` Array [ Object { - "BigECommerce.rollingCountYTD": "44", + "BigECommerce.rollingCountYTD": "3", }, ] `; diff --git a/packages/cubejs-testing/test/__snapshots__/birdbox-postgresql-pre-aggregations.test.ts.snap b/packages/cubejs-testing/test/__snapshots__/birdbox-postgresql-pre-aggregations.test.ts.snap index 2c460f3a54246..aa6dbc4729a9c 100644 --- a/packages/cubejs-testing/test/__snapshots__/birdbox-postgresql-pre-aggregations.test.ts.snap +++ b/packages/cubejs-testing/test/__snapshots__/birdbox-postgresql-pre-aggregations.test.ts.snap @@ -5,7 +5,7 @@ exports[`postgresql-cubestore HTTP Transport Empty partitions: Empty partitions exports[`postgresql-cubestore HTTP Transport Rolling Mixed With Dimension No Granularity: Rolling Mixed With Dimension No Granularity 1`] = ` Array [ Object { - "visitors.checkinsRollingTotal": "5", + "visitors.checkinsRollingTotal": null, "visitors.source": "some", }, ] diff --git a/packages/cubejs-testing/test/__snapshots__/cli-postgresql-pre-aggregations.test.ts.snap b/packages/cubejs-testing/test/__snapshots__/cli-postgresql-pre-aggregations.test.ts.snap index c08bfb0cae46b..3c28478f95231 100644 --- a/packages/cubejs-testing/test/__snapshots__/cli-postgresql-pre-aggregations.test.ts.snap +++ b/packages/cubejs-testing/test/__snapshots__/cli-postgresql-pre-aggregations.test.ts.snap @@ -5,7 +5,7 @@ exports[`postgresql HTTP Transport Empty partitions: Empty partitions 1`] = `Arr exports[`postgresql HTTP Transport Rolling Mixed With Dimension No Granularity: Rolling Mixed With Dimension No Granularity 1`] = ` Array [ Object { - "visitors.checkinsRollingTotal": "5", + "visitors.checkinsRollingTotal": null, "visitors.source": "some", }, ] From 3c23d6551ee8c7364b7d33cec19dc66c55c1ccfb Mon Sep 17 00:00:00 2001 From: Konstantin Burkalev Date: Wed, 2 Jul 2025 13:07:46 +0300 Subject: [PATCH 3/3] fix BigQuery Dialect --- .../src/adapter/BigqueryQuery.ts | 45 ++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts b/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts index 574a8bb7ddc11..bd615ee791ca5 100644 --- a/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts +++ b/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts @@ -216,14 +216,26 @@ export class BigqueryQuery extends BaseQuery { * joining conditions (note timeStampCast) */ public override rollingWindowToDateJoinCondition(granularity) { - return this.timeDimensions - .filter(td => td.granularity) - .map( - d => [ - d, - (dateFrom: string, dateTo: string, dateField: string, _dimensionDateFrom: string, _dimensionDateTo: string, _isFromStartToEnd: boolean) => `${dateField} >= ${this.timeGroupedColumn(granularity, dateFrom)} AND ${dateField} <= ${this.timeStampCast(dateTo)}` - ] - ); + return Object.values( + this.timeDimensions.reduce((acc, td) => { + const key = td.dimension; + + if (!acc[key]) { + acc[key] = td; + } + + if (!acc[key].granularity && td.granularity) { + acc[key] = td; + } + + return acc; + }, {}) + ).map( + d => [ + d, + (dateFrom: string, dateTo: string, dateField: string, _dimensionDateFrom: string, _dimensionDateTo: string, _isFromStartToEnd: boolean) => `${dateField} >= ${this.timeGroupedColumn(granularity, dateFrom)} AND ${dateField} <= ${this.timeStampCast(dateTo)}` + ] + ); } /** @@ -233,8 +245,21 @@ export class BigqueryQuery extends BaseQuery { */ public override rollingWindowDateJoinCondition(trailingInterval, leadingInterval, offset) { offset = offset || 'end'; - return this.timeDimensions - .filter(td => td.granularity) + return Object.values( + this.timeDimensions.reduce((acc, td) => { + const key = td.dimension; + + if (!acc[key]) { + acc[key] = td; + } + + if (!acc[key].granularity && td.granularity) { + acc[key] = td; + } + + return acc; + }, {}) + ) .map( d => [d, (dateFrom: string, dateTo: string, dateField: string, _dimensionDateFrom: string, _dimensionDateTo: string, isFromStartToEnd: boolean) => { // dateFrom based window