diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7cdbf4946e251..c9d34b6ea6223 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+### Bug Fixes
+
+- **cubesql:** push down window functions and multi-argument aggregates ([#11684](https://github.com/cube-js/cube/issues/11684)) ([4567c07](https://github.com/cube-js/cube/commit/4567c074fe4a2d13d278c3dd4c6c71217094bc4a))
+- **query-orchestrator:** key refresh key cache entries consistently ([#11607](https://github.com/cube-js/cube/issues/11607)) ([5bc6308](https://github.com/cube-js/cube/commit/5bc6308326500e847feb23eb2ed56f81ad904cab))
+- **tesseract:** fold nested multi-fact join legs into one scan ([#11643](https://github.com/cube-js/cube/issues/11643)) ([92d1595](https://github.com/cube-js/cube/commit/92d159529b6c8282d91d0b0bae92b707c6c2d537))
+- **tesseract:** keep expression measures out of nested group merging ([#11707](https://github.com/cube-js/cube/issues/11707)) ([6046c7c](https://github.com/cube-js/cube/commit/6046c7cdb3cd37a75d2f29db8dbe866500ebd7fa))
+
+### Features
+
+- Support local computeing for interval refresh keys (behind flag) ([#11614](https://github.com/cube-js/cube/issues/11614)) ([d2b43a4](https://github.com/cube-js/cube/commit/d2b43a4accd2c5d116342f9ad5be648920197a7e))
+
+### Performance Improvements
+
+- **cubestore:** turn on the performance toggles by default ([#11600](https://github.com/cube-js/cube/issues/11600)) ([33dc677](https://github.com/cube-js/cube/commit/33dc677fb65cdd34765832920f6ceb68c52370d1))
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
### Bug Fixes
diff --git a/SECURITY.md b/SECURITY.md
index bf28cf61433bc..033fd2dd81c06 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,5 +2,5 @@
## Reporting a Vulnerability
-Please email security reports to info@cube.dev or reach out to maintainers directly in https://slack.cube.dev.
+Please email security reports to security@cube.dev or reach out to maintainers directly in https://slack.cube.dev.
Please do not create issues or public conversations for discovered security issues until patch is shipped.
diff --git a/docs-mintlify/reference/configuration/environment-variables.mdx b/docs-mintlify/reference/configuration/environment-variables.mdx
index ed782d1eb9fc5..a6146ae6efe5a 100644
--- a/docs-mintlify/reference/configuration/environment-variables.mdx
+++ b/docs-mintlify/reference/configuration/environment-variables.mdx
@@ -1417,6 +1417,36 @@ this variable.
| ------------------------- | ---------------------- | --------------------- |
| A valid number in seconds | `600` | `600` |
+## `CUBEJS_REFRESH_KEY_LOCAL_TIME`
+
+To check an `every`-based [`refresh_key`](/reference/data-modeling/cube#refresh_key), Cube
+asks the database what time it is. If `true`, it uses its own clock instead and those
+queries stop entirely, including the ones scheduled refresh issues to warm them.
+
+| Possible Values | Default in Development | Default in Production |
+| --------------- | ---------------------- | --------------------- |
+| `true`, `false` | `false` | `false` |
+
+Cube already caches each result for a fraction of the interval, so this is not one query
+saved per request — it is one per refresh key per renewal window, multiplied by every cube,
+tenant, and timezone in the deployment.
+
+Refresh keys written with `sql` or marked
+[`incremental`](/reference/data-modeling/pre-aggregations#incremental) keep querying the
+database, since their values depend on your data and not just on the time. So do all
+refresh keys if you have set
+[`queryCacheOptions.refreshKeyRenewalThreshold`][ref-config-query-cache-options], which
+works by caching the query result.
+
+
+
+Cube now trusts each machine's clock, so they all have to agree. Set this variable to the
+same value on **every** API instance and refresh worker and keep them synchronized with
+NTP. Instances on opposite sides of an interval boundary compute different refresh keys,
+which can build the same pre-aggregation twice.
+
+
+
## `CUBEJS_REFRESH_WORKER`
If `true`, this instance of Cube will **only** refresh pre-aggregations.
@@ -2307,6 +2337,7 @@ The port for a Cube deployment to listen to API connections on.
https://motherduck.com/docs/authenticating-to-motherduck/#authentication-using-a-service-token
[ref-config-db]: /admin/connect-to-data/data-sources
[ref-config-driver-factory]: /reference/configuration/config#driver_factory
+[ref-config-query-cache-options]: /reference/configuration/config#orchestrator_options
[ref-config-multiple-ds-cloud]: /admin/connect-to-data/multiple-data-sources
[ref-config-multiple-ds-decorating-env]: /admin/connect-to-data/multiple-data-sources#under-the-hood
[ref-preagg-data-source]: /docs/pre-aggregations/refreshing-pre-aggregations#pre-aggregation-data-source
diff --git a/lerna.json b/lerna.json
index 36fe9e0466506..c47c3b5eccfaa 100644
--- a/lerna.json
+++ b/lerna.json
@@ -1,5 +1,5 @@
{
- "version": "1.7.30",
+ "version": "1.7.31",
"npmClient": "yarn",
"command": {
"bootstrap": {
diff --git a/packages/cubejs-api-gateway/CHANGELOG.md b/packages/cubejs-api-gateway/CHANGELOG.md
index 93e18608d8382..2ced4fa35f090 100644
--- a/packages/cubejs-api-gateway/CHANGELOG.md
+++ b/packages/cubejs-api-gateway/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/api-gateway
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/api-gateway
diff --git a/packages/cubejs-api-gateway/package.json b/packages/cubejs-api-gateway/package.json
index 3392d18ceac9a..67e0d0ac3c65d 100644
--- a/packages/cubejs-api-gateway/package.json
+++ b/packages/cubejs-api-gateway/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/api-gateway",
"description": "Cube API Gateway",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,9 +27,9 @@
"dist/src/*"
],
"dependencies": {
- "@cubejs-backend/native": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/native": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@ungap/structured-clone": "^0.3.4",
"assert-never": "^1.4.0",
"body-parser": "^1.19.0",
@@ -53,7 +53,7 @@
"zod": "^4.1.13"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/express": "^4.17.21",
"@types/jest": "^29",
"@types/jsonwebtoken": "^9.0.2",
diff --git a/packages/cubejs-athena-driver/CHANGELOG.md b/packages/cubejs-athena-driver/CHANGELOG.md
index ff87ba1aeb712..33bf14e29dd0b 100644
--- a/packages/cubejs-athena-driver/CHANGELOG.md
+++ b/packages/cubejs-athena-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/athena-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/athena-driver
diff --git a/packages/cubejs-athena-driver/package.json b/packages/cubejs-athena-driver/package.json
index 6574923cc2d5d..9625fed3494c2 100644
--- a/packages/cubejs-athena-driver/package.json
+++ b/packages/cubejs-athena-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/athena-driver",
"description": "Cube.js Athena database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -31,12 +31,12 @@
"dependencies": {
"@aws-sdk/client-athena": "^3.22.0",
"@aws-sdk/credential-providers": "^3.22.0",
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30"
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"@types/ramda": "^0.27.40",
"typescript": "~5.2.2"
},
diff --git a/packages/cubejs-backend-cloud/CHANGELOG.md b/packages/cubejs-backend-cloud/CHANGELOG.md
index 1b426910b60fb..106dfe6c4bedc 100644
--- a/packages/cubejs-backend-cloud/CHANGELOG.md
+++ b/packages/cubejs-backend-cloud/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/cloud
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/cloud
diff --git a/packages/cubejs-backend-cloud/package.json b/packages/cubejs-backend-cloud/package.json
index 81547573cc241..fcff9a30e3a15 100644
--- a/packages/cubejs-backend-cloud/package.json
+++ b/packages/cubejs-backend-cloud/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/cloud",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Cube Cloud package",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
@@ -30,7 +30,7 @@
"devDependencies": {
"@babel/core": "^7.24.5",
"@babel/preset-env": "^7.24.5",
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/fs-extra": "^9.0.8",
"@types/jest": "^29",
"jest": "^29",
@@ -38,7 +38,7 @@
},
"dependencies": {
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/shared": "1.7.31",
"chokidar": "^3.5.1",
"env-var": "^6.3.0",
"form-data": "^4.0.0",
diff --git a/packages/cubejs-backend-maven/CHANGELOG.md b/packages/cubejs-backend-maven/CHANGELOG.md
index d39e8c931c384..8e7599f08b22e 100644
--- a/packages/cubejs-backend-maven/CHANGELOG.md
+++ b/packages/cubejs-backend-maven/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/maven
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/maven
diff --git a/packages/cubejs-backend-maven/package.json b/packages/cubejs-backend-maven/package.json
index dee585526d0e6..73af82480e1fe 100644
--- a/packages/cubejs-backend-maven/package.json
+++ b/packages/cubejs-backend-maven/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/maven",
"description": "Cube.js Maven Wrapper for java dependencies downloading",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -31,12 +31,12 @@
"dist/src/*"
],
"dependencies": {
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/shared": "1.7.31",
"source-map-support": "^0.5.19",
"xmlbuilder2": "^2.4.0"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"jest": "^29",
diff --git a/packages/cubejs-backend-native/CHANGELOG.md b/packages/cubejs-backend-native/CHANGELOG.md
index 9e50cba02ca34..32cc71c63dfb6 100644
--- a/packages/cubejs-backend-native/CHANGELOG.md
+++ b/packages/cubejs-backend-native/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/native
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/native
diff --git a/packages/cubejs-backend-native/package.json b/packages/cubejs-backend-native/package.json
index 8735460e4f095..b35df0ff223b4 100644
--- a/packages/cubejs-backend-native/package.json
+++ b/packages/cubejs-backend-native/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/native",
- "version": "1.7.30",
+ "version": "1.7.31",
"author": "Cube Dev, Inc.",
"description": "Native module for Cube.js (binding to Rust codebase)",
"main": "dist/js/index.js",
@@ -39,7 +39,7 @@
"dist/js"
],
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"cargo-cp-artifact": "^0.1.9",
@@ -50,8 +50,8 @@
"uuid": "^11.1.1"
},
"dependencies": {
- "@cubejs-backend/cubesql": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/cubesql": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@cubejs-infra/post-installer": "^0.1.2"
},
"resources": {
diff --git a/packages/cubejs-backend-shared/CHANGELOG.md b/packages/cubejs-backend-shared/CHANGELOG.md
index efba85976b470..15c8089bc3bf9 100644
--- a/packages/cubejs-backend-shared/CHANGELOG.md
+++ b/packages/cubejs-backend-shared/CHANGELOG.md
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+### Features
+
+- Support local computeing for interval refresh keys (behind flag) ([#11614](https://github.com/cube-js/cube/issues/11614)) ([d2b43a4](https://github.com/cube-js/cube/commit/d2b43a4accd2c5d116342f9ad5be648920197a7e))
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/shared
diff --git a/packages/cubejs-backend-shared/package.json b/packages/cubejs-backend-shared/package.json
index 62473a4584d61..139dc874ca9ae 100644
--- a/packages/cubejs-backend-shared/package.json
+++ b/packages/cubejs-backend-shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/shared",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Shared code for Cube.js backend packages",
"main": "dist/src/index.js",
"typings": "dist/src/index.d.ts",
@@ -27,7 +27,7 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/bytes": "^3.1.5",
"@types/cli-progress": "^3.9.1",
"@types/jest": "^29",
diff --git a/packages/cubejs-backend-shared/src/env.ts b/packages/cubejs-backend-shared/src/env.ts
index 158707e6948d4..abf8a55c96416 100644
--- a/packages/cubejs-backend-shared/src/env.ts
+++ b/packages/cubejs-backend-shared/src/env.ts
@@ -368,6 +368,9 @@ const variables: Record any> = {
preciseDecimalInCubestore: () => get('CUBEJS_DB_PRECISE_DECIMAL_IN_CUBESTORE')
.default('false')
.asBoolStrict(),
+ refreshKeyLocalTime: () => get('CUBEJS_REFRESH_KEY_LOCAL_TIME')
+ .default('false')
+ .asBoolStrict(),
/** ****************************************************************
* Common db options *
diff --git a/packages/cubejs-backend-shared/test/env.test.ts b/packages/cubejs-backend-shared/test/env.test.ts
index 65893dda63b8c..bd4fcb8e3b579 100644
--- a/packages/cubejs-backend-shared/test/env.test.ts
+++ b/packages/cubejs-backend-shared/test/env.test.ts
@@ -107,6 +107,25 @@ describe('getEnv', () => {
).toBe(10);
});
+ test('refreshKeyLocalTime', () => {
+ delete process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME;
+ expect(getEnv('refreshKeyLocalTime')).toBe(false);
+
+ process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME = 'true';
+ expect(getEnv('refreshKeyLocalTime')).toBe(true);
+
+ process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME = 'false';
+ expect(getEnv('refreshKeyLocalTime')).toBe(false);
+ });
+
+ test('refreshKeyLocalTime(exception)', () => {
+ process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME = 'yes';
+
+ expect(() => getEnv('refreshKeyLocalTime')).toThrowError();
+
+ delete process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME;
+ });
+
test('livePreview', () => {
expect(getEnv('livePreview')).toBe(true);
diff --git a/packages/cubejs-base-driver/CHANGELOG.md b/packages/cubejs-base-driver/CHANGELOG.md
index 777983fd4f929..66c2dbbcc3cc8 100644
--- a/packages/cubejs-base-driver/CHANGELOG.md
+++ b/packages/cubejs-base-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/base-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/base-driver
diff --git a/packages/cubejs-base-driver/package.json b/packages/cubejs-base-driver/package.json
index d27f9234e2bc1..ff861a150058b 100644
--- a/packages/cubejs-base-driver/package.json
+++ b/packages/cubejs-base-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/base-driver",
"description": "Cube.js Base Driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -33,11 +33,11 @@
"@aws-sdk/s3-request-presigner": "^3.49.0",
"@azure/identity": "^4.4.1",
"@azure/storage-blob": "^12.9.0",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/shared": "1.7.31",
"@google-cloud/storage": "^7.13.0"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"jest": "^29",
diff --git a/packages/cubejs-bigquery-driver/CHANGELOG.md b/packages/cubejs-bigquery-driver/CHANGELOG.md
index d33cba8b57f1a..139d01837c5a5 100644
--- a/packages/cubejs-bigquery-driver/CHANGELOG.md
+++ b/packages/cubejs-bigquery-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/bigquery-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/bigquery-driver
diff --git a/packages/cubejs-bigquery-driver/package.json b/packages/cubejs-bigquery-driver/package.json
index d6b747c527f4f..91e7e1470eef2 100644
--- a/packages/cubejs-bigquery-driver/package.json
+++ b/packages/cubejs-bigquery-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/bigquery-driver",
"description": "Cube.js BigQuery database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -29,15 +29,15 @@
"main": "index.js",
"types": "dist/src/index.d.ts",
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/shared": "1.7.31",
"@google-cloud/bigquery": "^7.7.0",
"@google-cloud/storage": "^7.13.0",
"ramda": "^0.27.2"
},
"devDependencies": {
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/testing-shared": "1.7.31",
"@types/big.js": "^6.2.2",
"@types/dedent": "^0.7.0",
"@types/jest": "^29",
diff --git a/packages/cubejs-cli/CHANGELOG.md b/packages/cubejs-cli/CHANGELOG.md
index f5f7a3ed8c543..d9b282f6e2354 100644
--- a/packages/cubejs-cli/CHANGELOG.md
+++ b/packages/cubejs-cli/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package cubejs-cli
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package cubejs-cli
diff --git a/packages/cubejs-cli/package.json b/packages/cubejs-cli/package.json
index 16645c5d6a842..d4e5385c41874 100644
--- a/packages/cubejs-cli/package.json
+++ b/packages/cubejs-cli/package.json
@@ -2,7 +2,7 @@
"name": "cubejs-cli",
"description": "Cube.js Command Line Interface",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -30,10 +30,10 @@
"LICENSE"
],
"dependencies": {
- "@cubejs-backend/cloud": "1.7.30",
+ "@cubejs-backend/cloud": "1.7.31",
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"chalk": "^2.4.2",
"cli-progress": "^3.10",
"commander": "^2.19.0",
@@ -50,8 +50,8 @@
"colors": "1.4.0"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/server": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/server": "1.7.31",
"@oclif/command": "^1.8.0",
"@types/cli-progress": "^3.8.0",
"@types/cross-spawn": "^6.0.2",
diff --git a/packages/cubejs-clickhouse-driver/CHANGELOG.md b/packages/cubejs-clickhouse-driver/CHANGELOG.md
index 92ca4bcac5032..925759cf0a0b3 100644
--- a/packages/cubejs-clickhouse-driver/CHANGELOG.md
+++ b/packages/cubejs-clickhouse-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/clickhouse-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/clickhouse-driver
diff --git a/packages/cubejs-clickhouse-driver/package.json b/packages/cubejs-clickhouse-driver/package.json
index 7b66380a7f86b..0dea34959f94f 100644
--- a/packages/cubejs-clickhouse-driver/package.json
+++ b/packages/cubejs-clickhouse-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/clickhouse-driver",
"description": "Cube.js ClickHouse database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -29,16 +29,16 @@
},
"dependencies": {
"@clickhouse/client": "^1.12.0",
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"moment": "^2.24.0",
"sqlstring": "^2.3.1",
"uuid": "^11.1.1"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"typescript": "~5.2.2"
diff --git a/packages/cubejs-client-core/CHANGELOG.md b/packages/cubejs-client-core/CHANGELOG.md
index a860171bb078c..a65cfdace21e7 100644
--- a/packages/cubejs-client-core/CHANGELOG.md
+++ b/packages/cubejs-client-core/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/core
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/core
diff --git a/packages/cubejs-client-core/package.json b/packages/cubejs-client-core/package.json
index f95d24294e261..b463365078b3d 100644
--- a/packages/cubejs-client-core/package.json
+++ b/packages/cubejs-client-core/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/core",
- "version": "1.7.30",
+ "version": "1.7.31",
"engines": {},
"type": "module",
"repository": {
@@ -58,7 +58,7 @@
],
"license": "MIT",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/d3-format": "^3",
"@types/d3-time-format": "^4",
"@types/moment-range": "^4.0.0",
diff --git a/packages/cubejs-client-dx/CHANGELOG.md b/packages/cubejs-client-dx/CHANGELOG.md
index b100292f30d14..9e0c2aa9b541d 100644
--- a/packages/cubejs-client-dx/CHANGELOG.md
+++ b/packages/cubejs-client-dx/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/dx
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/dx
diff --git a/packages/cubejs-client-dx/package.json b/packages/cubejs-client-dx/package.json
index 512779b63ecd2..67f3c4f3e5c29 100644
--- a/packages/cubejs-client-dx/package.json
+++ b/packages/cubejs-client-dx/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/dx",
- "version": "1.7.30",
+ "version": "1.7.31",
"engines": {},
"repository": {
"type": "git",
diff --git a/packages/cubejs-client-ngx/CHANGELOG.md b/packages/cubejs-client-ngx/CHANGELOG.md
index ae5aa6423dc71..e0e880e5ba75e 100644
--- a/packages/cubejs-client-ngx/CHANGELOG.md
+++ b/packages/cubejs-client-ngx/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/ngx
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/ngx
diff --git a/packages/cubejs-client-ngx/package.json b/packages/cubejs-client-ngx/package.json
index a1ddcbccbba2c..9d30fe40451d2 100644
--- a/packages/cubejs-client-ngx/package.json
+++ b/packages/cubejs-client-ngx/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/ngx",
- "version": "1.7.30",
+ "version": "1.7.31",
"author": "Cube Dev, Inc.",
"engines": {},
"repository": {
diff --git a/packages/cubejs-client-react/CHANGELOG.md b/packages/cubejs-client-react/CHANGELOG.md
index 52f76e9974f44..f8ffa5c5a3437 100644
--- a/packages/cubejs-client-react/CHANGELOG.md
+++ b/packages/cubejs-client-react/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/react
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/react
diff --git a/packages/cubejs-client-react/package.json b/packages/cubejs-client-react/package.json
index 3b18f594783a2..b097d34e744d6 100644
--- a/packages/cubejs-client-react/package.json
+++ b/packages/cubejs-client-react/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/react",
- "version": "1.7.30",
+ "version": "1.7.31",
"author": "Cube Dev, Inc.",
"license": "MIT",
"engines": {},
@@ -26,7 +26,7 @@
],
"dependencies": {
"@babel/runtime": "^7.1.2",
- "@cubejs-client/core": "1.7.30",
+ "@cubejs-client/core": "1.7.31",
"core-js": "^3.6.5",
"ramda": "^0.27.2"
},
diff --git a/packages/cubejs-client-vue3/CHANGELOG.md b/packages/cubejs-client-vue3/CHANGELOG.md
index bdbd06a977525..d20041878ee3d 100644
--- a/packages/cubejs-client-vue3/CHANGELOG.md
+++ b/packages/cubejs-client-vue3/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/vue3
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/vue3
diff --git a/packages/cubejs-client-vue3/package.json b/packages/cubejs-client-vue3/package.json
index 4188836a87a02..a56caac886f7b 100644
--- a/packages/cubejs-client-vue3/package.json
+++ b/packages/cubejs-client-vue3/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/vue3",
- "version": "1.7.30",
+ "version": "1.7.31",
"engines": {},
"repository": {
"type": "git",
@@ -27,7 +27,7 @@
"src"
],
"dependencies": {
- "@cubejs-client/core": "1.7.30",
+ "@cubejs-client/core": "1.7.31",
"ramda": "^0.27.0"
},
"devDependencies": {
diff --git a/packages/cubejs-client-ws-transport/CHANGELOG.md b/packages/cubejs-client-ws-transport/CHANGELOG.md
index d822c77c43afb..c6f4ec82d7eed 100644
--- a/packages/cubejs-client-ws-transport/CHANGELOG.md
+++ b/packages/cubejs-client-ws-transport/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/ws-transport
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/ws-transport
diff --git a/packages/cubejs-client-ws-transport/package.json b/packages/cubejs-client-ws-transport/package.json
index c385e4e514659..5ee747f310f36 100644
--- a/packages/cubejs-client-ws-transport/package.json
+++ b/packages/cubejs-client-ws-transport/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-client/ws-transport",
- "version": "1.7.30",
+ "version": "1.7.31",
"engines": {},
"repository": {
"type": "git",
@@ -20,7 +20,7 @@
},
"dependencies": {
"@babel/runtime": "^7.1.2",
- "@cubejs-client/core": "1.7.30",
+ "@cubejs-client/core": "1.7.31",
"core-js": "^3.6.5",
"isomorphic-ws": "^4.0.1",
"ws": "^7.3.1"
@@ -33,7 +33,7 @@
"@babel/core": "^7.3.3",
"@babel/preset-env": "^7.3.1",
"@babel/preset-typescript": "^7.12.1",
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/ws": "^7.2.9",
"typescript": "~5.2.2"
},
diff --git a/packages/cubejs-crate-driver/CHANGELOG.md b/packages/cubejs-crate-driver/CHANGELOG.md
index 0d8d3a9e51781..455ca2ef7d784 100644
--- a/packages/cubejs-crate-driver/CHANGELOG.md
+++ b/packages/cubejs-crate-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/crate-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/crate-driver
diff --git a/packages/cubejs-crate-driver/package.json b/packages/cubejs-crate-driver/package.json
index 9b05e6502a7c8..07f7d8bddf822 100644
--- a/packages/cubejs-crate-driver/package.json
+++ b/packages/cubejs-crate-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/crate-driver",
"description": "Cube.js Crate database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -29,13 +29,13 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/postgres-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30"
+ "@cubejs-backend/postgres-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"testcontainers": "^10.28.0",
"typescript": "~5.2.2"
},
diff --git a/packages/cubejs-cubestore-driver/CHANGELOG.md b/packages/cubejs-cubestore-driver/CHANGELOG.md
index eb0aa363dea77..c912263b784cc 100644
--- a/packages/cubejs-cubestore-driver/CHANGELOG.md
+++ b/packages/cubejs-cubestore-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/cubestore-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/cubestore-driver
diff --git a/packages/cubejs-cubestore-driver/package.json b/packages/cubejs-cubestore-driver/package.json
index 6fba9cd0d4f28..6e4c0e8270a3c 100644
--- a/packages/cubejs-cubestore-driver/package.json
+++ b/packages/cubejs-cubestore-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/cubestore-driver",
"description": "Cube Store driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,10 +27,10 @@
"unit": "jest --coverage"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/cubestore": "1.7.30",
- "@cubejs-backend/native": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/cubestore": "1.7.31",
+ "@cubejs-backend/native": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"csv-write-stream": "^2.0.0",
"flatbuffers": "25.9.23",
"fs-extra": "^9.1.0",
@@ -41,7 +41,7 @@
"ws": "^7.4.3"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/csv-write-stream": "^2.0.0",
"@types/jest": "^29",
"@types/node": "^22",
diff --git a/packages/cubejs-databricks-jdbc-driver/CHANGELOG.md b/packages/cubejs-databricks-jdbc-driver/CHANGELOG.md
index 7470a4e86136e..d017227bb1901 100644
--- a/packages/cubejs-databricks-jdbc-driver/CHANGELOG.md
+++ b/packages/cubejs-databricks-jdbc-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/databricks-jdbc-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/databricks-jdbc-driver
diff --git a/packages/cubejs-databricks-jdbc-driver/package.json b/packages/cubejs-databricks-jdbc-driver/package.json
index 5e347fbe2f19a..43ba30a838826 100644
--- a/packages/cubejs-databricks-jdbc-driver/package.json
+++ b/packages/cubejs-databricks-jdbc-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/databricks-jdbc-driver",
"description": "Cube.js Databricks database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -30,17 +30,17 @@
"bin"
],
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/jdbc-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/jdbc-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"node-fetch": "^2.6.1",
"ramda": "^0.27.2",
"source-map-support": "^0.5.19",
"uuid": "^11.1.1"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"@types/ramda": "^0.27.34",
diff --git a/packages/cubejs-dbt-schema-extension/CHANGELOG.md b/packages/cubejs-dbt-schema-extension/CHANGELOG.md
index d50a7a04a8164..e6ec7c74b61a9 100644
--- a/packages/cubejs-dbt-schema-extension/CHANGELOG.md
+++ b/packages/cubejs-dbt-schema-extension/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/dbt-schema-extension
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/dbt-schema-extension
diff --git a/packages/cubejs-dbt-schema-extension/package.json b/packages/cubejs-dbt-schema-extension/package.json
index 2a7d176e10d76..9b5e08b991ad7 100644
--- a/packages/cubejs-dbt-schema-extension/package.json
+++ b/packages/cubejs-dbt-schema-extension/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/dbt-schema-extension",
"description": "Cube.js dbt Schema Extension",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -25,14 +25,14 @@
"lint:fix": "eslint --fix src/* --ext .ts,.js"
},
"dependencies": {
- "@cubejs-backend/schema-compiler": "1.7.30",
+ "@cubejs-backend/schema-compiler": "1.7.31",
"fs-extra": "^9.1.0",
"inflection": "^1.12.0",
"node-fetch": "^2.6.1"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"stream-to-array": "^2.3.0",
diff --git a/packages/cubejs-docker/CHANGELOG.md b/packages/cubejs-docker/CHANGELOG.md
index 2a561a74be2e3..5432c52af3f24 100644
--- a/packages/cubejs-docker/CHANGELOG.md
+++ b/packages/cubejs-docker/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/docker
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/docker
diff --git a/packages/cubejs-docker/package.json b/packages/cubejs-docker/package.json
index ad5c811852a2a..3c1f447de511b 100644
--- a/packages/cubejs-docker/package.json
+++ b/packages/cubejs-docker/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/docker",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Cube.js In Docker (virtual package)",
"author": "Cube Dev, Inc.",
"license": "Apache-2.0",
@@ -9,34 +9,34 @@
"node": ">=20.0.0"
},
"dependencies": {
- "@cubejs-backend/athena-driver": "1.7.30",
- "@cubejs-backend/bigquery-driver": "1.7.30",
- "@cubejs-backend/clickhouse-driver": "1.7.30",
- "@cubejs-backend/crate-driver": "1.7.30",
- "@cubejs-backend/databricks-jdbc-driver": "1.7.30",
- "@cubejs-backend/dbt-schema-extension": "1.7.30",
- "@cubejs-backend/dremio-driver": "1.7.30",
- "@cubejs-backend/druid-driver": "1.7.30",
- "@cubejs-backend/duckdb-driver": "1.7.30",
- "@cubejs-backend/firebolt-driver": "1.7.30",
- "@cubejs-backend/hive-driver": "1.7.30",
- "@cubejs-backend/ksql-driver": "1.7.30",
- "@cubejs-backend/materialize-driver": "1.7.30",
- "@cubejs-backend/mongobi-driver": "1.7.30",
- "@cubejs-backend/mssql-driver": "1.7.30",
- "@cubejs-backend/mysql-driver": "1.7.30",
- "@cubejs-backend/oracle-driver": "1.7.30",
- "@cubejs-backend/pinot-driver": "1.7.30",
- "@cubejs-backend/postgres-driver": "1.7.30",
- "@cubejs-backend/prestodb-driver": "1.7.30",
- "@cubejs-backend/questdb-driver": "1.7.30",
- "@cubejs-backend/redshift-driver": "1.7.30",
- "@cubejs-backend/server": "1.7.30",
- "@cubejs-backend/snowflake-driver": "1.7.30",
- "@cubejs-backend/sqlite-driver": "1.7.30",
- "@cubejs-backend/trino-driver": "1.7.30",
- "@cubejs-backend/vertica-driver": "1.7.30",
- "cubejs-cli": "1.7.30",
+ "@cubejs-backend/athena-driver": "1.7.31",
+ "@cubejs-backend/bigquery-driver": "1.7.31",
+ "@cubejs-backend/clickhouse-driver": "1.7.31",
+ "@cubejs-backend/crate-driver": "1.7.31",
+ "@cubejs-backend/databricks-jdbc-driver": "1.7.31",
+ "@cubejs-backend/dbt-schema-extension": "1.7.31",
+ "@cubejs-backend/dremio-driver": "1.7.31",
+ "@cubejs-backend/druid-driver": "1.7.31",
+ "@cubejs-backend/duckdb-driver": "1.7.31",
+ "@cubejs-backend/firebolt-driver": "1.7.31",
+ "@cubejs-backend/hive-driver": "1.7.31",
+ "@cubejs-backend/ksql-driver": "1.7.31",
+ "@cubejs-backend/materialize-driver": "1.7.31",
+ "@cubejs-backend/mongobi-driver": "1.7.31",
+ "@cubejs-backend/mssql-driver": "1.7.31",
+ "@cubejs-backend/mysql-driver": "1.7.31",
+ "@cubejs-backend/oracle-driver": "1.7.31",
+ "@cubejs-backend/pinot-driver": "1.7.31",
+ "@cubejs-backend/postgres-driver": "1.7.31",
+ "@cubejs-backend/prestodb-driver": "1.7.31",
+ "@cubejs-backend/questdb-driver": "1.7.31",
+ "@cubejs-backend/redshift-driver": "1.7.31",
+ "@cubejs-backend/server": "1.7.31",
+ "@cubejs-backend/snowflake-driver": "1.7.31",
+ "@cubejs-backend/sqlite-driver": "1.7.31",
+ "@cubejs-backend/trino-driver": "1.7.31",
+ "@cubejs-backend/vertica-driver": "1.7.31",
+ "cubejs-cli": "1.7.31",
"typescript": "~5.2.2"
},
"resolutions": {
diff --git a/packages/cubejs-dremio-driver/CHANGELOG.md b/packages/cubejs-dremio-driver/CHANGELOG.md
index 3588fe407f41f..53130e6163187 100644
--- a/packages/cubejs-dremio-driver/CHANGELOG.md
+++ b/packages/cubejs-dremio-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/dremio-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/dremio-driver
diff --git a/packages/cubejs-dremio-driver/package.json b/packages/cubejs-dremio-driver/package.json
index 153e068ff98f0..deb04aed67b8b 100644
--- a/packages/cubejs-dremio-driver/package.json
+++ b/packages/cubejs-dremio-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/dremio-driver",
"description": "Cube.js Dremio driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -23,14 +23,14 @@
"lint:fix": "eslint driver/*.js"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"axios": "^1.8.3"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"jest": "^29"
},
"license": "Apache-2.0",
diff --git a/packages/cubejs-druid-driver/CHANGELOG.md b/packages/cubejs-druid-driver/CHANGELOG.md
index a6f1e384ef8b5..7d51d93d20972 100644
--- a/packages/cubejs-druid-driver/CHANGELOG.md
+++ b/packages/cubejs-druid-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/druid-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/druid-driver
diff --git a/packages/cubejs-druid-driver/package.json b/packages/cubejs-druid-driver/package.json
index 2a632431328e1..bbbb5102de26a 100644
--- a/packages/cubejs-druid-driver/package.json
+++ b/packages/cubejs-druid-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/druid-driver",
"description": "Cube.js Druid database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"license": "Apache-2.0",
"repository": {
"type": "git",
@@ -28,13 +28,13 @@
"dist/src/*"
],
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"axios": "^1.8.3"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"jest": "^29",
diff --git a/packages/cubejs-duckdb-driver/CHANGELOG.md b/packages/cubejs-duckdb-driver/CHANGELOG.md
index bc2583f43c79e..bcca4273319ca 100644
--- a/packages/cubejs-duckdb-driver/CHANGELOG.md
+++ b/packages/cubejs-duckdb-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/duckdb-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/duckdb-driver
diff --git a/packages/cubejs-duckdb-driver/package.json b/packages/cubejs-duckdb-driver/package.json
index 61b3e01c26fa7..1b4ba37d1805f 100644
--- a/packages/cubejs-duckdb-driver/package.json
+++ b/packages/cubejs-duckdb-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/duckdb-driver",
"description": "Cube DuckDB database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -28,15 +28,15 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"duckdb": "^1.4.1"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"jest": "^29",
diff --git a/packages/cubejs-firebolt-driver/CHANGELOG.md b/packages/cubejs-firebolt-driver/CHANGELOG.md
index 3c4fe1bf1de22..ee8dc7a54c262 100644
--- a/packages/cubejs-firebolt-driver/CHANGELOG.md
+++ b/packages/cubejs-firebolt-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/firebolt-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/firebolt-driver
diff --git a/packages/cubejs-firebolt-driver/package.json b/packages/cubejs-firebolt-driver/package.json
index 473ae8e9320f0..5c951d1773f50 100644
--- a/packages/cubejs-firebolt-driver/package.json
+++ b/packages/cubejs-firebolt-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/firebolt-driver",
"description": "Cube.js Firebolt database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -28,15 +28,15 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"firebolt-sdk": "1.10.0"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"typescript": "~5.2.2"
},
"publishConfig": {
diff --git a/packages/cubejs-hive-driver/CHANGELOG.md b/packages/cubejs-hive-driver/CHANGELOG.md
index 6b48fa8c76975..1307ba987e863 100644
--- a/packages/cubejs-hive-driver/CHANGELOG.md
+++ b/packages/cubejs-hive-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/hive-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/hive-driver
diff --git a/packages/cubejs-hive-driver/package.json b/packages/cubejs-hive-driver/package.json
index 3d12f7708ea0e..3b1427d5009ef 100644
--- a/packages/cubejs-hive-driver/package.json
+++ b/packages/cubejs-hive-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/hive-driver",
"description": "Cube.js Hive database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -17,8 +17,8 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"jshs2": "^0.4.4",
"sasl-plain": "^0.1.0",
"saslmechanisms": "^0.1.1",
@@ -27,7 +27,7 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30"
+ "@cubejs-backend/linter": "1.7.31"
},
"publishConfig": {
"access": "public"
diff --git a/packages/cubejs-jdbc-driver/CHANGELOG.md b/packages/cubejs-jdbc-driver/CHANGELOG.md
index 8e0902c91365c..35632e8b27775 100644
--- a/packages/cubejs-jdbc-driver/CHANGELOG.md
+++ b/packages/cubejs-jdbc-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/jdbc-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/jdbc-driver
diff --git a/packages/cubejs-jdbc-driver/package.json b/packages/cubejs-jdbc-driver/package.json
index dd2463662ea4a..e8215f27f1314 100644
--- a/packages/cubejs-jdbc-driver/package.json
+++ b/packages/cubejs-jdbc-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/jdbc-driver",
"description": "Cube.js JDBC database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -26,9 +26,9 @@
"index.js"
],
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
"@cubejs-backend/node-java-maven": "^0.1.3",
- "@cubejs-backend/shared": "1.7.30"
+ "@cubejs-backend/shared": "1.7.31"
},
"optionalDependencies": {
"@cubejs-backend/jdbc": "^0.9.0",
@@ -42,7 +42,7 @@
"testEnvironment": "node"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/node": "^22",
"typescript": "~5.2.2"
}
diff --git a/packages/cubejs-ksql-driver/CHANGELOG.md b/packages/cubejs-ksql-driver/CHANGELOG.md
index 83dc3211c4509..dfcd969cb1c0c 100644
--- a/packages/cubejs-ksql-driver/CHANGELOG.md
+++ b/packages/cubejs-ksql-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/ksql-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/ksql-driver
diff --git a/packages/cubejs-ksql-driver/package.json b/packages/cubejs-ksql-driver/package.json
index 1611c6d15b7d9..7b1271d0a177c 100644
--- a/packages/cubejs-ksql-driver/package.json
+++ b/packages/cubejs-ksql-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/ksql-driver",
"description": "Cube.js ksql database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -26,9 +26,9 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"async-mutex": "0.3.2",
"axios": "^1.8.3",
"kafkajs": "^2.2.3"
@@ -41,7 +41,7 @@
"extends": "../cubejs-linter"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"typescript": "~5.2.2"
}
}
diff --git a/packages/cubejs-linter/CHANGELOG.md b/packages/cubejs-linter/CHANGELOG.md
index b384465c30793..16ab6611ab9ae 100644
--- a/packages/cubejs-linter/CHANGELOG.md
+++ b/packages/cubejs-linter/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/linter
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/linter
diff --git a/packages/cubejs-linter/package.json b/packages/cubejs-linter/package.json
index 6c781652e9608..179331188571f 100644
--- a/packages/cubejs-linter/package.json
+++ b/packages/cubejs-linter/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/linter",
"description": "Cube.js ESLint (virtual package) for linting code",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
diff --git a/packages/cubejs-materialize-driver/CHANGELOG.md b/packages/cubejs-materialize-driver/CHANGELOG.md
index 61ed9f3665d8d..5e8a70d6685fa 100644
--- a/packages/cubejs-materialize-driver/CHANGELOG.md
+++ b/packages/cubejs-materialize-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/materialize-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/materialize-driver
diff --git a/packages/cubejs-materialize-driver/package.json b/packages/cubejs-materialize-driver/package.json
index 4059012ebf227..ccbcc7024e685 100644
--- a/packages/cubejs-materialize-driver/package.json
+++ b/packages/cubejs-materialize-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/materialize-driver",
"description": "Cube.js Materialize database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,15 +27,15 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/postgres-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/postgres-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"semver": "^7.6.3"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing": "1.7.31",
"typescript": "~5.2.2"
},
"publishConfig": {
diff --git a/packages/cubejs-mongobi-driver/CHANGELOG.md b/packages/cubejs-mongobi-driver/CHANGELOG.md
index 409598ac3ecd4..ac8b5e647e220 100644
--- a/packages/cubejs-mongobi-driver/CHANGELOG.md
+++ b/packages/cubejs-mongobi-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/mongobi-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/mongobi-driver
diff --git a/packages/cubejs-mongobi-driver/package.json b/packages/cubejs-mongobi-driver/package.json
index 2f295eae55ec0..5f40fdf163ba1 100644
--- a/packages/cubejs-mongobi-driver/package.json
+++ b/packages/cubejs-mongobi-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/mongobi-driver",
"description": "Cube.js MongoBI driver",
"author": "krunalsabnis@gmail.com",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,8 +27,8 @@
"integration:mongobi": "jest dist/test"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@types/node": "^22",
"moment": "^2.29.1",
"mysql2": "^3.11.5"
@@ -38,7 +38,7 @@
"access": "public"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"testcontainers": "^10.28.0",
"typescript": "~5.2.2"
},
diff --git a/packages/cubejs-mssql-driver/CHANGELOG.md b/packages/cubejs-mssql-driver/CHANGELOG.md
index 218001409e81a..41304f729ef6d 100644
--- a/packages/cubejs-mssql-driver/CHANGELOG.md
+++ b/packages/cubejs-mssql-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/mssql-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/mssql-driver
diff --git a/packages/cubejs-mssql-driver/package.json b/packages/cubejs-mssql-driver/package.json
index 040c1e93de6bf..89b554c2935ec 100644
--- a/packages/cubejs-mssql-driver/package.json
+++ b/packages/cubejs-mssql-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/mssql-driver",
"description": "Cube.js MS SQL database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -25,8 +25,8 @@
"lint:fix": "eslint --fix src/* --ext .ts,.js"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"mssql": "^11.0.1"
},
"devDependencies": {
diff --git a/packages/cubejs-mysql-aurora-serverless-driver/CHANGELOG.md b/packages/cubejs-mysql-aurora-serverless-driver/CHANGELOG.md
index 23ca15b7665fc..9c74a1df3351d 100644
--- a/packages/cubejs-mysql-aurora-serverless-driver/CHANGELOG.md
+++ b/packages/cubejs-mysql-aurora-serverless-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/mysql-aurora-serverless-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/mysql-aurora-serverless-driver
diff --git a/packages/cubejs-mysql-aurora-serverless-driver/package.json b/packages/cubejs-mysql-aurora-serverless-driver/package.json
index 31fce5b70499f..5432b76bb31d5 100644
--- a/packages/cubejs-mysql-aurora-serverless-driver/package.json
+++ b/packages/cubejs-mysql-aurora-serverless-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/mysql-aurora-serverless-driver",
"description": "Cube.js Aurora Serverless Mysql database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -21,14 +21,14 @@
"lint": "eslint driver/*.js test/*.js"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@types/mysql": "^2.15.15",
"aws-sdk": "^2.787.0",
"data-api-client": "^1.1.0"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/data-api-client": "^1.2.1",
"@types/jest": "^29",
"jest": "^29",
diff --git a/packages/cubejs-mysql-driver/CHANGELOG.md b/packages/cubejs-mysql-driver/CHANGELOG.md
index 3f24d4f91b547..a0eb094bd71db 100644
--- a/packages/cubejs-mysql-driver/CHANGELOG.md
+++ b/packages/cubejs-mysql-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/mysql-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/mysql-driver
diff --git a/packages/cubejs-mysql-driver/package.json b/packages/cubejs-mysql-driver/package.json
index b14c35d744b28..9b5a3d6c6b4af 100644
--- a/packages/cubejs-mysql-driver/package.json
+++ b/packages/cubejs-mysql-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/mysql-driver",
"description": "Cube.js Mysql database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,13 +27,13 @@
"lint:fix": "eslint --fix src/* test/* --ext .ts,.js"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"mysql2": "^3.16.1"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"stream-to-array": "^2.3.0",
diff --git a/packages/cubejs-oracle-driver/CHANGELOG.md b/packages/cubejs-oracle-driver/CHANGELOG.md
index 29078e2e09a9b..3f123d52a9caa 100644
--- a/packages/cubejs-oracle-driver/CHANGELOG.md
+++ b/packages/cubejs-oracle-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/oracle-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/oracle-driver
diff --git a/packages/cubejs-oracle-driver/package.json b/packages/cubejs-oracle-driver/package.json
index 4e2500a625a38..28e17085cc236 100644
--- a/packages/cubejs-oracle-driver/package.json
+++ b/packages/cubejs-oracle-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/oracle-driver",
"description": "Cube.js oracle database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -13,8 +13,8 @@
},
"main": "driver/OracleDriver.js",
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"ramda": "^0.27.0"
},
"devDependencies": {
diff --git a/packages/cubejs-pinot-driver/CHANGELOG.md b/packages/cubejs-pinot-driver/CHANGELOG.md
index d710c67119f76..e6b58888f5a23 100644
--- a/packages/cubejs-pinot-driver/CHANGELOG.md
+++ b/packages/cubejs-pinot-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/pinot-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/pinot-driver
diff --git a/packages/cubejs-pinot-driver/package.json b/packages/cubejs-pinot-driver/package.json
index ab3c747965659..e07bae208368f 100644
--- a/packages/cubejs-pinot-driver/package.json
+++ b/packages/cubejs-pinot-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/pinot-driver",
"description": "Cube.js Pinot database driver",
"author": "Julian Ronsse, InTheMemory, Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -28,9 +28,9 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"node-fetch": "^2.6.1",
"ramda": "^0.27.2"
},
@@ -39,7 +39,7 @@
"access": "public"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"should": "^13.2.3",
diff --git a/packages/cubejs-playground/CHANGELOG.md b/packages/cubejs-playground/CHANGELOG.md
index 1e39ca0aed773..e77044c92eb3c 100644
--- a/packages/cubejs-playground/CHANGELOG.md
+++ b/packages/cubejs-playground/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-client/playground
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-client/playground
diff --git a/packages/cubejs-playground/package.json b/packages/cubejs-playground/package.json
index 7ff9c0a814617..1a07bf5a56b5a 100644
--- a/packages/cubejs-playground/package.json
+++ b/packages/cubejs-playground/package.json
@@ -1,7 +1,7 @@
{
"name": "@cubejs-client/playground",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"engines": {},
"repository": {
"type": "git",
@@ -68,8 +68,8 @@
"@ant-design/compatible": "^1.0.1",
"@ant-design/icons": "^5.3.5",
"@cube-dev/ui-kit": "0.52.3",
- "@cubejs-client/core": "1.7.30",
- "@cubejs-client/react": "1.7.30",
+ "@cubejs-client/core": "1.7.31",
+ "@cubejs-client/react": "1.7.31",
"@types/flexsearch": "^0.7.3",
"@types/node": "^22",
"@types/react": "^18.3.4",
diff --git a/packages/cubejs-postgres-driver/CHANGELOG.md b/packages/cubejs-postgres-driver/CHANGELOG.md
index 5ed8f409e7e98..0c17972f03f3e 100644
--- a/packages/cubejs-postgres-driver/CHANGELOG.md
+++ b/packages/cubejs-postgres-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/postgres-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/postgres-driver
diff --git a/packages/cubejs-postgres-driver/package.json b/packages/cubejs-postgres-driver/package.json
index 13f4fb458edbc..04dca7c34c292 100644
--- a/packages/cubejs-postgres-driver/package.json
+++ b/packages/cubejs-postgres-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/postgres-driver",
"description": "Cube.js Postgres database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,8 +27,8 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@types/pg": "^8.16.0",
"@types/pg-query-stream": "^1.0.3",
"pg": "^8.18.0",
@@ -36,8 +36,8 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"testcontainers": "^10.28.0",
"typescript": "~5.2.2"
},
diff --git a/packages/cubejs-prestodb-driver/CHANGELOG.md b/packages/cubejs-prestodb-driver/CHANGELOG.md
index 9828026498df2..cf00ac153c875 100644
--- a/packages/cubejs-prestodb-driver/CHANGELOG.md
+++ b/packages/cubejs-prestodb-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/prestodb-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/prestodb-driver
diff --git a/packages/cubejs-prestodb-driver/package.json b/packages/cubejs-prestodb-driver/package.json
index 24cdd6c43253b..d65fb71cc1e81 100644
--- a/packages/cubejs-prestodb-driver/package.json
+++ b/packages/cubejs-prestodb-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/prestodb-driver",
"description": "Cube.js Presto database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -28,8 +28,8 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"presto-client": "1.2.0",
"ramda": "^0.27.0"
},
@@ -38,7 +38,7 @@
"access": "public"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"should": "^13.2.3",
diff --git a/packages/cubejs-query-orchestrator/CHANGELOG.md b/packages/cubejs-query-orchestrator/CHANGELOG.md
index 0ce799cd4164b..fd3148d697652 100644
--- a/packages/cubejs-query-orchestrator/CHANGELOG.md
+++ b/packages/cubejs-query-orchestrator/CHANGELOG.md
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+### Bug Fixes
+
+- **query-orchestrator:** key refresh key cache entries consistently ([#11607](https://github.com/cube-js/cube/issues/11607)) ([5bc6308](https://github.com/cube-js/cube/commit/5bc6308326500e847feb23eb2ed56f81ad904cab))
+
+### Features
+
+- Support local computeing for interval refresh keys (behind flag) ([#11614](https://github.com/cube-js/cube/issues/11614)) ([d2b43a4](https://github.com/cube-js/cube/commit/d2b43a4accd2c5d116342f9ad5be648920197a7e))
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
### Bug Fixes
diff --git a/packages/cubejs-query-orchestrator/package.json b/packages/cubejs-query-orchestrator/package.json
index fc1cd9dd5bb9e..801d6ab50fbef 100644
--- a/packages/cubejs-query-orchestrator/package.json
+++ b/packages/cubejs-query-orchestrator/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/query-orchestrator",
"description": "Cube.js Query Orchestrator and Cache",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -30,15 +30,15 @@
"dist/src/*"
],
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/cubestore-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/cubestore-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"csv-write-stream": "^2.0.0",
"lru-cache": "^11.1.0",
"ramda": "^0.27.2"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"@types/node": "^22",
"@types/ramda": "^0.27.32",
diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts b/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts
index d956215fc50d2..c0d4d726e1bc6 100644
--- a/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts
+++ b/packages/cubejs-query-orchestrator/src/orchestrator/QueryCache.ts
@@ -25,7 +25,12 @@ import { ContinueWaitError } from './ContinueWaitError';
import { LocalCacheDriver } from './LocalCacheDriver';
import { DriverFactory, DriverFactoryByDataSource } from './DriverFactory';
import { LoadPreAggregationResult, PreAggregationDescription } from './PreAggregations';
-import { getCacheHash, extractRequestUUID } from './utils';
+import {
+ getCacheHash,
+ extractRequestUUID,
+ evaluateLocalRefreshKey,
+ isValidLocalRefreshKey,
+} from './utils';
import { CacheAndQueryDriverType, MetadataOperationType } from './QueryOrchestrator';
export type CacheQueryResultOptions = {
@@ -52,12 +57,24 @@ export type CacheQueryResultOptions = {
export type RefreshKeyCacheOptions =
Pick;
+/**
+ * Everything needed to evaluate an `every` based refreshKey without touching a
+ * database: `FLOOR((utcOffset + unixTimestamp - dayOffset) / interval)`.
+ */
+export type LocalRefreshKeyDescriptor = {
+ interval: number;
+ utcOffset: number;
+ dayOffset: number;
+ cron?: boolean;
+};
+
type QueryOptions = {
external?: boolean;
renewalThreshold?: number;
updateWindowSeconds?: number;
renewalThresholdOutsideUpdateWindow?: number;
incremental?: boolean;
+ localRefreshKey?: LocalRefreshKeyDescriptor;
};
export type QueryWithParams = [
@@ -154,6 +171,7 @@ type CacheOperationContext = {
export interface QueryCacheOptions {
refreshKeyRenewalThreshold?: number;
+ localRefreshKey?: boolean;
externalQueueOptions?: any;
externalDriverFactory?: DriverFactory;
backgroundRenew?: Boolean;
@@ -182,6 +200,8 @@ export class QueryCache {
protected static readonly IN_MEMORY_CACHE_DISABLE_PERIOD = 5 * 60 * 1000;
+ protected readonly localRefreshKeyEnabled: boolean;
+
public constructor(
protected readonly cachePrefix: string,
protected readonly driverFactory: DriverFactoryByDataSource,
@@ -208,6 +228,33 @@ export class QueryCache {
this.memoryCache = new LRUCache({
max: options.maxInMemoryCacheEntries || 10000
});
+ this.localRefreshKeyEnabled = options.localRefreshKey ?? false;
+ }
+
+ /**
+ * Whether interval based refresh keys are answered from this instance clock instead of being
+ * run as queries and cached.
+ */
+ public isLocalRefreshKeyActive(): boolean {
+ return this.localRefreshKeyEnabled && !this.options.refreshKeyRenewalThreshold;
+ }
+
+ public localRefreshKeyResult(queryOptions?: QueryOptions): [{ refresh_key: string }] | null {
+ if (!this.localRefreshKeyEnabled || !isValidLocalRefreshKey(queryOptions?.localRefreshKey)) {
+ return null;
+ }
+
+ // `refreshKeyRenewalThreshold` throttles how often the SQL result is re-read, and that is
+ // also what bounds how often the key advances: a value cached for a day advances daily,
+ // whatever `every` says. A locally evaluated key has no cache entry to age out, so the only
+ // way to keep honouring the override is to leave these keys on the SQL path.
+ // TODO: support the two together by snapping the local value to the threshold instead of
+ // falling back to a query.
+ if (!this.isLocalRefreshKeyActive()) {
+ return null;
+ }
+
+ return evaluateLocalRefreshKey(queryOptions?.localRefreshKey);
}
public getCacheDriver(): CacheDriverInterface {
@@ -462,6 +509,12 @@ export class QueryCache {
options: RefreshKeyCacheOptions,
) {
const [query, values, queryOptions] = sqlQuery;
+
+ const local = this.localRefreshKeyResult(queryOptions);
+ if (local) {
+ return local;
+ }
+
const cacheKey = QueryCache.refreshKeyIdentity(sqlQuery, options.dataSource);
return this.cacheQueryResult(query, values, cacheKey, expiration, {
diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts b/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts
index 9a32c023e3ab5..709a96f8eac49 100644
--- a/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts
+++ b/packages/cubejs-query-orchestrator/src/orchestrator/utils.ts
@@ -2,7 +2,7 @@ import crypto from 'crypto';
import { getProcessUid } from '@cubejs-backend/shared';
import { QueryKey, QueryKeyHash } from '@cubejs-backend/base-driver';
-import { CacheKey } from './QueryCache';
+import { CacheKey, LocalRefreshKeyDescriptor } from './QueryCache';
/**
* Unique process ID regexp.
@@ -32,6 +32,33 @@ export function getCacheHash(queryKey: QueryKey | CacheKey, processUid?: string)
}
}
+/**
+ * `nowMs` is not floored to whole seconds first: for an integer `interval >= 1` the
+ * fractional part cannot cross a boundary, which is also why the fractional seconds of
+ * `EXTRACT(EPOCH FROM NOW())` never mattered on the SQL path.
+ *
+ * The key is a string because `contentVersion` and the query cache `renewalKey` hash it
+ * through `JSON.stringify`: `2980310` and `"2980310"` are different keys, so a number here
+ * would rebuild every pre-aggregation the first time the flag is switched on. A string is
+ * also what the SQL path yields — an `every` key runs against Cube Store whenever an
+ * external store is configured, and Cube Store carries every column as a string.
+ */
+export function evaluateLocalRefreshKey(
+ descriptor: LocalRefreshKeyDescriptor,
+ nowMs: number = Date.now(),
+): [{ refresh_key: string }] {
+ const { utcOffset, interval, dayOffset } = descriptor;
+
+ return [{ refresh_key: String(Math.floor((utcOffset + nowMs / 1000 - dayOffset) / interval)) }];
+}
+
+export function isValidLocalRefreshKey(descriptor?: LocalRefreshKeyDescriptor): boolean {
+ return !!descriptor &&
+ Number.isFinite(descriptor.interval) && descriptor.interval > 0 &&
+ Number.isFinite(descriptor.utcOffset) &&
+ Number.isFinite(descriptor.dayOffset);
+}
+
/**
* Extracts the UUID prefix from a request ID by stripping the `-span-N` suffix.
*/
diff --git a/packages/cubejs-query-orchestrator/test/unit/PreAggregations.test.ts b/packages/cubejs-query-orchestrator/test/unit/PreAggregations.test.ts
index f1fa0fd82525a..8da233f14d7bf 100644
--- a/packages/cubejs-query-orchestrator/test/unit/PreAggregations.test.ts
+++ b/packages/cubejs-query-orchestrator/test/unit/PreAggregations.test.ts
@@ -467,6 +467,110 @@ describe('PreAggregations', () => {
});
});
+ describe('local refresh key', () => {
+ const REFRESH_KEY_SQL = 'SELECT FLOOR((UNIX_TIMESTAMP()) / 600) as refresh_key';
+ const descriptor = { interval: 600, utcOffset: 0, dayOffset: 0, cron: false };
+
+ const newQueryCache = (localRefreshKey?: boolean) => new QueryCache(
+ 'TEST',
+ mockDriverFactory as any,
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ () => {},
+ {
+ cacheAndQueueDriver: 'memory',
+ localRefreshKey,
+ queueOptions: async () => ({ executionTimeout: 1, concurrency: 2 }),
+ },
+ );
+
+ const newLoadCache = (localRefreshKey?: boolean) => {
+ const cache = newQueryCache(localRefreshKey);
+ (cache.getCacheDriver() as LocalCacheDriver).reset();
+
+ const preAggregations = new PreAggregations(
+ 'TEST',
+ mockDriverFactory as any,
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ () => {},
+ cache,
+ { queueOptions: async () => ({ executionTimeout: 1, concurrency: 2 }) },
+ );
+
+ return new PreAggregationLoadCache(
+ mockDriverFactory as any,
+ cache,
+ preAggregations,
+ { dataSource: 'default' },
+ );
+ };
+
+ test('keyQueryResult evaluates locally without querying the datasource', async () => {
+ const loadCache = newLoadCache(true);
+
+ const result = await loadCache.keyQueryResult(
+ [REFRESH_KEY_SQL, [], { external: true, renewalThreshold: 60, localRefreshKey: descriptor }],
+ false,
+ 10,
+ );
+
+ expect(result).toEqual([{ refresh_key: String(Math.floor(Date.now() / 1000 / descriptor.interval)) }]);
+ expect(mockDriver!.executedQueries).toEqual([]);
+ });
+
+ test('keyQueryResult still queries when the flag is off', async () => {
+ const loadCache = newLoadCache(false);
+
+ await loadCache.keyQueryResult(
+ [REFRESH_KEY_SQL, [], { external: false, renewalThreshold: 60, localRefreshKey: descriptor }],
+ false,
+ 10,
+ );
+
+ expect(mockDriver!.executedQueries).toEqual([REFRESH_KEY_SQL]);
+ });
+
+ test('keyQueryResult still queries an incremental key that carries no descriptor', async () => {
+ const loadCache = newLoadCache(true);
+ const incrementalSql = 'SELECT CASE WHEN NOW() < $1 THEN FLOOR((UNIX_TIMESTAMP()) / 3600) END as refresh_key';
+
+ await loadCache.keyQueryResult(
+ [incrementalSql, [], {
+ external: false,
+ renewalThreshold: 300,
+ incremental: true,
+ renewalThresholdOutsideUpdateWindow: 86400,
+ }],
+ false,
+ 10,
+ );
+
+ expect(mockDriver!.executedQueries).toEqual([incrementalSql]);
+ });
+
+ // A single load reads the invalidation keys several times (contentVersion, the returned
+ // refreshKeyValues, the refresh queue key). If the clock were re-read, a load crossing an
+ // interval boundary would look a table up under one content version and enqueue it under
+ // another.
+ test('keyQueryResult is stable across an interval boundary within one load cache', async () => {
+ const loadCache = newLoadCache(true);
+ const key: [string, any[], Record] =
+ [REFRESH_KEY_SQL, [], { external: true, renewalThreshold: 60, localRefreshKey: descriptor }];
+
+ const nowSpy = jest.spyOn(Date, 'now').mockReturnValue(600_000);
+ try {
+ const first = await loadCache.keyQueryResult(key, false, 10);
+ expect(first).toEqual([{ refresh_key: '1' }]);
+
+ nowSpy.mockReturnValue(1_200_000);
+ const second = await loadCache.keyQueryResult(key, false, 10);
+
+ expect(second).toEqual(first);
+ } finally {
+ nowSpy.mockRestore();
+ }
+ });
+ });
+
describe('loadAllPreAggregationsIfNeeded', () => {
let preAggregations: PreAggregations | null = null;
diff --git a/packages/cubejs-query-orchestrator/test/unit/QueryCache.abstract.ts b/packages/cubejs-query-orchestrator/test/unit/QueryCache.abstract.ts
index 178749756aaac..d68d43a91ac2a 100644
--- a/packages/cubejs-query-orchestrator/test/unit/QueryCache.abstract.ts
+++ b/packages/cubejs-query-orchestrator/test/unit/QueryCache.abstract.ts
@@ -470,6 +470,195 @@ export const QueryCacheTest = (name: string, options: QueryCacheTestOptions) =>
});
});
+ describe('local refresh key', () => {
+ const REFRESH_KEY_SQL = 'SELECT FLOOR((UNIX_TIMESTAMP()) / 600) as refresh_key';
+ const descriptor = { interval: 600, utcOffset: 0, dayOffset: 0, cron: false };
+
+ const newCache = (additionalOptions: Partial = {}) => (
+ new QueryCacheOpened(
+ crypto.randomBytes(16).toString('hex'),
+ () => {
+ throw new Error('driverFactory is not implemented, mock should be used...');
+ },
+ jest.fn(),
+ { ...options, ...additionalOptions },
+ )
+ );
+
+ const loadRefreshKey = async (
+ queryOptions: any,
+ additionalOptions: Partial = {},
+ ) => {
+ const localCache = newCache(additionalOptions);
+ const spy = jest.spyOn(localCache, 'queryWithRetryAndRelease')
+ .mockImplementation(async () => [{ refresh_key: 12345 }]);
+
+ try {
+ const [result] = await Promise.all(
+ localCache.loadRefreshKeys(
+ [[REFRESH_KEY_SQL, [], queryOptions]],
+ 60,
+ { dataSource: 'default' },
+ )
+ );
+
+ return { result, executed: spy.mock.calls.length, logged: localCache.logger.mock.calls };
+ } finally {
+ spy.mockRestore();
+ await localCache.cleanup();
+ }
+ };
+
+ it('evaluates locally without touching the driver', async () => {
+ const { result, executed } = await loadRefreshKey(
+ { external: true, renewalThreshold: 60, localRefreshKey: descriptor },
+ { localRefreshKey: true },
+ );
+
+ expect(executed).toBe(0);
+ expect(result).toEqual([{ refresh_key: String(Math.floor(Date.now() / 1000 / 600)) }]);
+ });
+
+ it('runs the query when the flag is off', async () => {
+ const { result, executed } = await loadRefreshKey(
+ { external: true, renewalThreshold: 60, localRefreshKey: descriptor },
+ { localRefreshKey: false },
+ );
+
+ expect(executed).toBe(1);
+ expect(result).toEqual([{ refresh_key: 12345 }]);
+ });
+
+ it('runs the query when there is no descriptor', async () => {
+ const { executed } = await loadRefreshKey(
+ { external: false, renewalThreshold: 10 },
+ { localRefreshKey: true },
+ );
+
+ expect(executed).toBe(1);
+ });
+
+ it('runs the query when the descriptor is malformed', async () => {
+ const { executed } = await loadRefreshKey(
+ { external: true, renewalThreshold: 60, localRefreshKey: { ...descriptor, interval: 0 } },
+ { localRefreshKey: true },
+ );
+
+ expect(executed).toBe(1);
+ });
+
+ // Local evaluation would advance the key on every interval boundary, ignoring the
+ // throttle a deployment asked for and multiplying pre-aggregation rebuilds.
+ it('runs the query when refreshKeyRenewalThreshold is configured', async () => {
+ const { result, executed } = await loadRefreshKey(
+ { external: true, renewalThreshold: 60, localRefreshKey: descriptor },
+ { localRefreshKey: true, refreshKeyRenewalThreshold: 24 * 60 * 60 },
+ );
+
+ expect(executed).toBe(1);
+ expect(result).toEqual([{ refresh_key: 12345 }]);
+ });
+
+ // The refresh scheduler reads this to decide whether warming a refresh key is pointless,
+ // so it has to agree with the branches above.
+ it('reports whether local evaluation is in effect', async () => {
+ const enabled = newCache({ localRefreshKey: true });
+ const disabled = newCache({ localRefreshKey: false });
+ const throttled = newCache({ localRefreshKey: true, refreshKeyRenewalThreshold: 24 * 60 * 60 });
+
+ try {
+ expect(enabled.isLocalRefreshKeyActive()).toBe(true);
+ expect(disabled.isLocalRefreshKeyActive()).toBe(false);
+ expect(throttled.isLocalRefreshKeyActive()).toBe(false);
+ } finally {
+ await Promise.all([enabled.cleanup(), disabled.cleanup(), throttled.cleanup()]);
+ }
+ });
+
+ it('runs the query when the flag is unset', async () => {
+ const { result, executed } = await loadRefreshKey({
+ external: true,
+ renewalThreshold: 60,
+ localRefreshKey: descriptor,
+ });
+
+ expect(executed).toBe(1);
+ expect(result).toEqual([{ refresh_key: 12345 }]);
+ });
+
+ // Falling back to the SQL path is intended for every declined branch, so nothing reports
+ // it; the ordinary cache messages are still expected.
+ it.each([
+ { name: 'the flag is off', additionalOptions: { localRefreshKey: false } },
+ { name: 'the flag is unset', additionalOptions: {} },
+ {
+ name: 'refreshKeyRenewalThreshold is configured',
+ additionalOptions: { localRefreshKey: true, refreshKeyRenewalThreshold: 24 * 60 * 60 },
+ },
+ ])('does not report the declined local evaluation when $name', async ({ additionalOptions }) => {
+ const { logged } = await loadRefreshKey(
+ { external: true, renewalThreshold: 60, localRefreshKey: descriptor },
+ additionalOptions,
+ );
+
+ expect(logged.map(([message]) => message).filter(m => /local/i.test(m))).toEqual([]);
+ });
+
+ describe('localRefreshKeyResult', () => {
+ const withCache = async (
+ additionalOptions: Partial,
+ fn: (localCache: QueryCacheOpened) => void,
+ ) => {
+ const localCache = newCache(additionalOptions);
+
+ try {
+ fn(localCache);
+ expect(localCache.logger).not.toHaveBeenCalled();
+ } finally {
+ await localCache.cleanup();
+ }
+ };
+
+ const queryOptions = (localRefreshKey?: unknown) => { localRefreshKey };
+
+ it('evaluates a valid descriptor', () => withCache({ localRefreshKey: true }, localCache => {
+ expect(localCache.localRefreshKeyResult(queryOptions(descriptor)))
+ .toEqual([{ refresh_key: String(Math.floor(Date.now() / 1000 / 600)) }]);
+ }));
+
+ // Cube Store returns every column as a string, so a locally evaluated key has to be
+ // a string too or flipping the flag invalidates every pre-aggregation once.
+ it('returns the key as a string', () => withCache({ localRefreshKey: true }, localCache => {
+ const [{ refresh_key: value }] = localCache
+ .localRefreshKeyResult(queryOptions(descriptor))!;
+
+ expect(typeof value).toBe('string');
+ }));
+
+ it('declines when the flag is off', () => withCache({ localRefreshKey: false }, localCache => {
+ expect(localCache.localRefreshKeyResult(queryOptions(descriptor))).toBeNull();
+ }));
+
+ it('declines without a descriptor', () => withCache({ localRefreshKey: true }, localCache => {
+ expect(localCache.localRefreshKeyResult()).toBeNull();
+ expect(localCache.localRefreshKeyResult(queryOptions())).toBeNull();
+ }));
+
+ it('declines a malformed descriptor', () => withCache({ localRefreshKey: true }, localCache => {
+ expect(localCache.localRefreshKeyResult(
+ queryOptions({ ...descriptor, interval: 0 }),
+ )).toBeNull();
+ }));
+
+ it('declines when refreshKeyRenewalThreshold is configured', () => withCache(
+ { localRefreshKey: true, refreshKeyRenewalThreshold: 24 * 60 * 60 },
+ localCache => {
+ expect(localCache.localRefreshKeyResult(queryOptions(descriptor))).toBeNull();
+ },
+ ));
+ });
+ });
+
it('queryCacheKey format', () => {
const key1 = QueryCache.queryCacheKey({
query: 'select data',
diff --git a/packages/cubejs-query-orchestrator/test/unit/utils.test.ts b/packages/cubejs-query-orchestrator/test/unit/utils.test.ts
new file mode 100644
index 0000000000000..c61eda8333190
--- /dev/null
+++ b/packages/cubejs-query-orchestrator/test/unit/utils.test.ts
@@ -0,0 +1,68 @@
+import { evaluateLocalRefreshKey, isValidLocalRefreshKey } from '../../src/orchestrator/utils';
+
+describe('evaluateLocalRefreshKey', () => {
+ const tenMinutes = { interval: 600, utcOffset: 0, dayOffset: 0 };
+
+ test('returns the same row shape as SELECT FLOOR(...) as refresh_key', () => {
+ expect(evaluateLocalRefreshKey(tenMinutes, 600_000)).toEqual([{ refresh_key: '1' }]);
+ expect(evaluateLocalRefreshKey(tenMinutes, 6_000_000)).toEqual([{ refresh_key: '10' }]);
+ });
+
+ test('changes exactly at the interval boundary', () => {
+ expect(evaluateLocalRefreshKey(tenMinutes, 599_999)).toEqual([{ refresh_key: '0' }]);
+ expect(evaluateLocalRefreshKey(tenMinutes, 600_000)).toEqual([{ refresh_key: '1' }]);
+ expect(evaluateLocalRefreshKey(tenMinutes, 1_199_999)).toEqual([{ refresh_key: '1' }]);
+ expect(evaluateLocalRefreshKey(tenMinutes, 1_200_000)).toEqual([{ refresh_key: '2' }]);
+ });
+
+ test('sub-second precision never changes the result', () => {
+ for (const ms of [0, 1, 250, 500, 999]) {
+ expect(evaluateLocalRefreshKey(tenMinutes, 600_000 + ms)).toEqual(
+ evaluateLocalRefreshKey(tenMinutes, 600_000)
+ );
+ }
+ });
+
+ test('applies a negative utcOffset', () => {
+ // America/Los_Angeles in PST: -8 hours
+ expect(evaluateLocalRefreshKey({ interval: 3600, utcOffset: -28800, dayOffset: 0 }, 28_800_000))
+ .toEqual([{ refresh_key: '0' }]);
+ });
+
+ test('applies dayOffset for cron based keys', () => {
+ // every '0 10 * * *' => interval 1 day, dayOffset 10 hours
+ const daily = { interval: 86400, utcOffset: 0, dayOffset: 36000, cron: true };
+
+ // 09:59:59 UTC on the epoch day is still before the first fire time
+ expect(evaluateLocalRefreshKey(daily, 35_999_000)).toEqual([{ refresh_key: '-1' }]);
+ expect(evaluateLocalRefreshKey(daily, 36_000_000)).toEqual([{ refresh_key: '0' }]);
+ expect(evaluateLocalRefreshKey(daily, 36_000_000 + 86_400_000)).toEqual([{ refresh_key: '1' }]);
+ });
+
+ test('defaults to the current clock', () => {
+ const before = Math.floor(Date.now() / 1000 / tenMinutes.interval);
+ const [{ refresh_key: value }] = evaluateLocalRefreshKey(tenMinutes);
+ const after = Math.floor(Date.now() / 1000 / tenMinutes.interval);
+
+ expect(typeof value).toBe('string');
+ expect(Number(value)).toBeGreaterThanOrEqual(before);
+ expect(Number(value)).toBeLessThanOrEqual(after);
+ });
+});
+
+describe('isValidLocalRefreshKey', () => {
+ test('accepts a well formed descriptor', () => {
+ expect(isValidLocalRefreshKey({ interval: 600, utcOffset: 0, dayOffset: 0 })).toBe(true);
+ expect(isValidLocalRefreshKey({ interval: 1, utcOffset: -28800, dayOffset: 36000 })).toBe(true);
+ });
+
+ test('rejects anything that would produce a garbage key', () => {
+ expect(isValidLocalRefreshKey(undefined)).toBe(false);
+ expect(isValidLocalRefreshKey({ interval: 0, utcOffset: 0, dayOffset: 0 })).toBe(false);
+ expect(isValidLocalRefreshKey({ interval: -600, utcOffset: 0, dayOffset: 0 })).toBe(false);
+ expect(isValidLocalRefreshKey({ interval: NaN, utcOffset: 0, dayOffset: 0 })).toBe(false);
+ expect(isValidLocalRefreshKey({ interval: Infinity, utcOffset: 0, dayOffset: 0 })).toBe(false);
+ expect(isValidLocalRefreshKey({ interval: 600, utcOffset: NaN, dayOffset: 0 })).toBe(false);
+ expect(isValidLocalRefreshKey({ interval: 600, utcOffset: 0, dayOffset: NaN })).toBe(false);
+ });
+});
diff --git a/packages/cubejs-questdb-driver/CHANGELOG.md b/packages/cubejs-questdb-driver/CHANGELOG.md
index 2bca67baa0adc..b80ef909d9c8b 100644
--- a/packages/cubejs-questdb-driver/CHANGELOG.md
+++ b/packages/cubejs-questdb-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/questdb-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/questdb-driver
diff --git a/packages/cubejs-questdb-driver/package.json b/packages/cubejs-questdb-driver/package.json
index c73d250476a76..10aa65c14cafa 100644
--- a/packages/cubejs-questdb-driver/package.json
+++ b/packages/cubejs-questdb-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/questdb-driver",
"description": "Cube.js QuestDB database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,9 +27,9 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@types/pg": "^8.6.0",
"moment": "^2.24.0",
"pg": "^8.7.0",
@@ -37,8 +37,8 @@
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"testcontainers": "^10.28.0",
"typescript": "~5.2.2"
},
diff --git a/packages/cubejs-redshift-driver/CHANGELOG.md b/packages/cubejs-redshift-driver/CHANGELOG.md
index effc51e86ffb8..137099af75d9f 100644
--- a/packages/cubejs-redshift-driver/CHANGELOG.md
+++ b/packages/cubejs-redshift-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/redshift-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/redshift-driver
diff --git a/packages/cubejs-redshift-driver/package.json b/packages/cubejs-redshift-driver/package.json
index 50c94f5fbd39f..4af1d9ce2069c 100644
--- a/packages/cubejs-redshift-driver/package.json
+++ b/packages/cubejs-redshift-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/redshift-driver",
"description": "Cube.js Redshift database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -27,13 +27,13 @@
"dependencies": {
"@aws-sdk/client-redshift": "^3.22.0",
"@aws-sdk/credential-providers": "^3.22.0",
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/postgres-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30"
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/postgres-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"typescript": "~5.2.2"
},
"publishConfig": {
diff --git a/packages/cubejs-schema-compiler/CHANGELOG.md b/packages/cubejs-schema-compiler/CHANGELOG.md
index 3c1ae1d0bd966..9184e9c967a2c 100644
--- a/packages/cubejs-schema-compiler/CHANGELOG.md
+++ b/packages/cubejs-schema-compiler/CHANGELOG.md
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+### Bug Fixes
+
+- **cubesql:** push down window functions and multi-argument aggregates ([#11684](https://github.com/cube-js/cube/issues/11684)) ([4567c07](https://github.com/cube-js/cube/commit/4567c074fe4a2d13d278c3dd4c6c71217094bc4a))
+
+### Features
+
+- Support local computeing for interval refresh keys (behind flag) ([#11614](https://github.com/cube-js/cube/issues/11614)) ([d2b43a4](https://github.com/cube-js/cube/commit/d2b43a4accd2c5d116342f9ad5be648920197a7e))
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/schema-compiler
diff --git a/packages/cubejs-schema-compiler/package.json b/packages/cubejs-schema-compiler/package.json
index 8f8de2567083c..9044322bad769 100644
--- a/packages/cubejs-schema-compiler/package.json
+++ b/packages/cubejs-schema-compiler/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/schema-compiler",
"description": "Cube schema compiler",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -40,8 +40,8 @@
"@babel/standalone": "^7.24",
"@babel/traverse": "^7.24",
"@babel/types": "^7.24",
- "@cubejs-backend/native": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/native": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"antlr4": "^4.13.2",
"camelcase": "^6.2.0",
"cron-parser": "^4.9.0",
@@ -60,9 +60,9 @@
},
"devDependencies": {
"@clickhouse/client": "^1.12.0",
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/mssql-driver": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/mssql-driver": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
"@types/babel__code-frame": "^7.0.6",
"@types/babel__generator": "^7.6.8",
"@types/babel__traverse": "^7.20.5",
diff --git a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
index 77a772f98fd57..5f478fbaf9b11 100644
--- a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
+++ b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js
@@ -287,6 +287,7 @@ export class BaseQuery {
memberToAlias: this.options.memberToAlias,
expressionParams: this.options.expressionParams,
convertTzForRawTimeDimension: this.options.convertTzForRawTimeDimension,
+ localRefreshKey: this.options.localRefreshKey,
from: this.options.from,
multiStageQuery: this.options.multiStageQuery,
multiStageDimensions: this.options.multiStageDimensions,
@@ -362,6 +363,9 @@ export class BaseQuery {
// toggled independently. The neverUseSqlPlannerPreaggregation() guard still opts
// specific query types (e.g. CubeStoreQuery) out for correctness.
this.canUseNativeSqlPlannerPreAggregation = this.useNativeSqlPlanner && !this.neverUseSqlPlannerPreaggregation();
+ // Gated at emit time so that with the flag off the refresh key tuples stay
+ // byte-identical and nothing downstream re-hashes to a new cache key.
+ this.localRefreshKey = this.options.localRefreshKey ?? getEnv('refreshKeyLocalTime');
this.queryLevelJoinHints = this.options.joinHints ?? [];
this.prebuildJoin();
@@ -4227,6 +4231,7 @@ export class BaseQuery {
externalQueryClass: this.options.externalQueryClass,
queryFactory: this.options.queryFactory,
useNativeSqlPlanner: this.options.useNativeSqlPlanner,
+ localRefreshKey: this.options.localRefreshKey,
...options,
};
}
@@ -4265,19 +4270,22 @@ export class BaseQuery {
this.refreshKeySelect(sql),
{
external,
- renewalThreshold: this.refreshKeyRenewalThresholdForInterval(cubeFromPath.refreshKey)
+ renewalThreshold: this.refreshKeyRenewalThresholdForInterval(cubeFromPath.refreshKey),
+ ...this.localRefreshKeyOptions(cubeFromPath.refreshKey, query)
},
query
];
}
}
- const [sql, external, query] = this.everyRefreshKeySql(this.defaultEveryRefreshKey());
+ const defaultEveryRefreshKey = this.defaultEveryRefreshKey();
+ const [sql, external, query] = this.everyRefreshKeySql(defaultEveryRefreshKey);
return [
this.refreshKeySelect(sql),
{
external,
- renewalThreshold: this.defaultRefreshKeyRenewalThreshold()
+ renewalThreshold: this.defaultRefreshKeyRenewalThreshold(),
+ ...this.localRefreshKeyOptions(defaultEveryRefreshKey, query)
},
query
];
@@ -4851,21 +4859,49 @@ export class BaseQuery {
};
}
+ /**
+ * Both the rendered SQL and the descriptor handed to the orchestrator for local
+ * evaluation derive from this, so they cannot disagree on the formula.
+ *
+ * @return {{ utcOffset: number, interval: number, dayOffset: number, cron: boolean }}
+ */
+ everyRefreshKeyParts(refreshKey) {
+ const every = refreshKey.every || '1 hour';
+
+ if (/^(\d+) (second|minute|hour|day|week)s?$/.test(every)) {
+ return {
+ utcOffset: this.timezone ? moment.tz(this.timezone).utcOffset() * 60 : 0,
+ interval: this.parseSecondDuration(every),
+ dayOffset: 0,
+ cron: false,
+ };
+ }
+
+ return { ...this.calcIntervalForCronString(refreshKey), cron: true };
+ }
+
+ /**
+ * @protected
+ * @param {BaseQuery} [query] the instance that rendered the SQL, when it differs from `this`
+ */
+ localRefreshKeyOptions(refreshKey, query) {
+ return this.localRefreshKey
+ ? { localRefreshKey: (query || this).everyRefreshKeyParts(refreshKey) }
+ : {};
+ }
+
everyRefreshKeySql(refreshKey, external = false) {
if (this.externalQueryClass) {
return this.externalQuery().everyRefreshKeySql(refreshKey, true);
}
- const every = refreshKey.every || '1 hour';
+ const { utcOffset, interval, dayOffset, cron } = this.everyRefreshKeyParts(refreshKey);
- if (/^(\d+) (second|minute|hour|day|week)s?$/.test(every)) {
- const utcOffset = this.timezone ? moment.tz(this.timezone).utcOffset() * 60 : 0;
+ if (!cron) {
const utcOffsetPrefix = utcOffset ? `${utcOffset} + ` : '';
- return [this.floorSql(`(${utcOffsetPrefix}${this.unixTimestampSql()}) / ${this.parseSecondDuration(every)}`), external, this];
+ return [this.floorSql(`(${utcOffsetPrefix}${this.unixTimestampSql()}) / ${interval}`), external, this];
}
- const { dayOffset, utcOffset, interval } = this.calcIntervalForCronString(refreshKey);
-
/**
* Small explanation how it works for every `0 8 * * *`
* 28800 is a $dayOffset
@@ -5057,6 +5093,13 @@ export class BaseQuery {
}
if (preAggregation.refreshKey.every || preAggregation.refreshKey.incremental) {
+ // An incremental key is wrapped into `CASE WHEN NOW() < `
+ // against an allocated partition range param, so it is not reproducible from
+ // a time interval alone.
+ const localRefreshKeyOptions = preAggregation.refreshKey.incremental
+ ? {}
+ : this.localRefreshKeyOptions(preAggregation.refreshKey, refreshKeyQuery);
+
return [
refreshKeyQuery.paramAllocator.buildSqlAndParams(this.refreshKeySelect(refreshKey)).concat({
external: refreshKeyExternal,
@@ -5065,7 +5108,8 @@ export class BaseQuery {
updateWindowSeconds: preAggregation.refreshKey.updateWindow &&
this.parseSecondDuration(preAggregation.refreshKey.updateWindow),
renewalThresholdOutsideUpdateWindow: preAggregation.refreshKey.incremental &&
- 24 * 60 * 60
+ 24 * 60 * 60,
+ ...localRefreshKeyOptions
})
];
}
@@ -5089,15 +5133,15 @@ export class BaseQuery {
() => preAggregationQueryForSql.cacheKeyQueries(
(refreshKeyCube, [refreshKeySQL, refreshKeyQueryOptions, refreshKeyQuery]) => {
if (!cubeFromPath.refreshKey) {
- const [sql, external, query] = this.everyRefreshKeySql({
- every: '1 hour'
- });
+ const hourlyRefreshKey = { every: '1 hour' };
+ const [sql, external, query] = this.everyRefreshKeySql(hourlyRefreshKey);
return [
this.refreshKeySelect(sql),
{
external,
renewalThreshold: this.defaultRefreshKeyRenewalThreshold(),
+ ...this.localRefreshKeyOptions(hourlyRefreshKey, query)
},
query
];
diff --git a/packages/cubejs-schema-compiler/src/compiler/CubeEvaluator.ts b/packages/cubejs-schema-compiler/src/compiler/CubeEvaluator.ts
index 3beac37469f09..b899e43f7c3a6 100644
--- a/packages/cubejs-schema-compiler/src/compiler/CubeEvaluator.ts
+++ b/packages/cubejs-schema-compiler/src/compiler/CubeEvaluator.ts
@@ -4,6 +4,7 @@ import R from 'ramda';
import {
AccessPolicyDefinition,
CubeDefinitionExtended,
+ CubeRefreshKey,
CubeSymbols,
Folder,
FolderInclude,
@@ -199,6 +200,7 @@ export type EvaluatedCube = {
isView?: boolean;
includedMembers?: ViewIncludedMember[];
defaultFilters?: ViewDefaultValueFilter[];
+ refreshKey?: CubeRefreshKey;
};
export class CubeEvaluator extends CubeSymbols {
diff --git a/packages/cubejs-schema-compiler/test/integration/postgres/multi-stage-grain-rolling-window.test.ts b/packages/cubejs-schema-compiler/test/integration/postgres/multi-stage-grain-rolling-window.test.ts
new file mode 100644
index 0000000000000..cd22421d4c0ba
--- /dev/null
+++ b/packages/cubejs-schema-compiler/test/integration/postgres/multi-stage-grain-rolling-window.test.ts
@@ -0,0 +1,170 @@
+import { getEnv } from '@cubejs-backend/shared';
+import { prepareYamlCompiler } from '../../unit/PrepareCompiler';
+import { dbRunner } from './PostgresDBRunner';
+
+// A multi-stage measure that declares both `grain` and `rolling_window`.
+// The grain says at what grain the value inside a bucket is computed; the
+// window says which rows land in the bucket. Both have to hold at once.
+//
+// Inline data: two equally weighted rows per day, so the weighted daily
+// factor equals the row factor — 1.10, 1.20, 0.50. Linked over the three
+// days that is exactly -0.34, and every window below is wide enough to
+// cover all three, so at any grain coarser than a day the windowed measure
+// has to agree with the plain one.
+//
+// The measures round to six digits so the assertions compare exact strings
+// rather than IEEE noise from EXP/LN.
+describe('Multi-Stage grain with rolling window', () => {
+ jest.setTimeout(200000);
+
+ const { compiler, joinGraph, cubeEvaluator } = prepareYamlCompiler(`
+cubes:
+ - name: returns
+ sql: >
+ SELECT '2024-01-01'::date as DAY, 'A' as SECURITY, 10.0 as IRR, 100.0 as WEIGHT
+ union all
+ SELECT '2024-01-01'::date, 'B', 10.0, 100.0
+ union all
+ SELECT '2024-01-02'::date, 'A', 20.0, 100.0
+ union all
+ SELECT '2024-01-02'::date, 'B', 20.0, 100.0
+ union all
+ SELECT '2024-01-03'::date, 'A', -50.0, 100.0
+ union all
+ SELECT '2024-01-03'::date, 'B', -50.0, 100.0
+
+ dimensions:
+ - name: day
+ sql: DAY
+ type: time
+
+ - name: security
+ sql: SECURITY
+ type: string
+
+ - name: irr
+ sql: IRR
+ type: number
+
+ - name: weight
+ sql: WEIGHT
+ type: number
+
+ measures:
+ - name: weight_sum
+ sql: "{CUBE.weight}"
+ type: sum
+
+ - name: irr_weight_sum
+ sql: "{CUBE.irr} * {CUBE.weight}"
+ type: sum
+
+ - name: daily_irr_weight
+ multi_stage: true
+ sql: "{CUBE.irr_weight_sum}"
+ type: number
+
+ - name: daily_weight
+ multi_stage: true
+ sql: "{CUBE.weight_sum}"
+ type: number
+
+ - name: log_return_sum
+ multi_stage: true
+ sql: "LN(1.0 + ({CUBE.daily_irr_weight} / NULLIF({CUBE.daily_weight}, 0)) / 100.0)"
+ type: sum
+ grain:
+ include:
+ - returns.day
+
+ - name: twr
+ multi_stage: true
+ sql: "ROUND((EXP({CUBE.log_return_sum}) - 1)::numeric, 6)"
+ type: number
+
+ - name: log_return_sum_ytd
+ multi_stage: true
+ sql: "LN(1.0 + ({CUBE.daily_irr_weight} / NULLIF({CUBE.daily_weight}, 0)) / 100.0)"
+ type: sum
+ grain:
+ include:
+ - returns.day
+ rolling_window:
+ type: to_date
+ granularity: year
+
+ - name: twr_ytd
+ multi_stage: true
+ sql: "ROUND((EXP({CUBE.log_return_sum_ytd}) - 1)::numeric, 6)"
+ type: number
+
+ - name: log_return_sum_1y
+ multi_stage: true
+ sql: "LN(1.0 + ({CUBE.daily_irr_weight} / NULLIF({CUBE.daily_weight}, 0)) / 100.0)"
+ type: sum
+ grain:
+ include:
+ - returns.day
+ rolling_window:
+ trailing: 1 year
+ offset: end
+
+ - name: twr_1y
+ multi_stage: true
+ sql: "ROUND((EXP({CUBE.log_return_sum_1y}) - 1)::numeric, 6)"
+ type: number
+ `);
+
+ if (getEnv('nativeSqlPlanner')) {
+ it('day granularity: the window accumulates over the declared grain', async () => dbRunner.runQueryTest({
+ measures: ['returns.twr', 'returns.twr_ytd', 'returns.twr_1y'],
+ timeDimensions: [{
+ dimension: 'returns.day',
+ granularity: 'day',
+ dateRange: ['2024-01-01', '2024-01-03'],
+ }],
+ order: [{ id: 'returns.day' }],
+ timezone: 'UTC',
+ }, [
+ // Per-day factors 1.10 / 1.20 / 0.50; the windows link them up.
+ { returns__day_day: '2024-01-01T00:00:00.000Z', returns__twr: '0.100000', returns__twr_ytd: '0.100000', returns__twr_1y: '0.100000' },
+ { returns__day_day: '2024-01-02T00:00:00.000Z', returns__twr: '0.200000', returns__twr_ytd: '0.320000', returns__twr_1y: '0.320000' },
+ { returns__day_day: '2024-01-03T00:00:00.000Z', returns__twr: '-0.500000', returns__twr_ytd: '-0.340000', returns__twr_1y: '-0.340000' },
+ ], { joinGraph, cubeEvaluator, compiler }));
+
+ it('month granularity: query grain does not replace the declared grain', async () => dbRunner.runQueryTest({
+ measures: ['returns.twr', 'returns.twr_ytd', 'returns.twr_1y'],
+ timeDimensions: [{
+ dimension: 'returns.day',
+ granularity: 'month',
+ dateRange: ['2024-01-01', '2024-01-31'],
+ }],
+ order: [{ id: 'returns.day' }],
+ timezone: 'UTC',
+ }, [
+ { returns__day_month: '2024-01-01T00:00:00.000Z', returns__twr: '-0.340000', returns__twr_ytd: '-0.340000', returns__twr_1y: '-0.340000' },
+ ], { joinGraph, cubeEvaluator, compiler }));
+
+ it('no time dimension: the window is one bucket over the whole range', async () => dbRunner.runQueryTest({
+ measures: ['returns.twr', 'returns.twr_ytd', 'returns.twr_1y'],
+ timezone: 'UTC',
+ }, [
+ { returns__twr: '-0.340000', returns__twr_ytd: '-0.340000', returns__twr_1y: '-0.340000' },
+ ], { joinGraph, cubeEvaluator, compiler }));
+
+ it('non-time dimension: the grain survives a plain group by', async () => dbRunner.runQueryTest({
+ measures: ['returns.twr', 'returns.twr_ytd', 'returns.twr_1y'],
+ dimensions: ['returns.security'],
+ order: [{ id: 'returns.security' }],
+ timezone: 'UTC',
+ }, [
+ { returns__security: 'A', returns__twr: '-0.340000', returns__twr_ytd: '-0.340000', returns__twr_1y: '-0.340000' },
+ { returns__security: 'B', returns__twr: '-0.340000', returns__twr_ytd: '-0.340000', returns__twr_1y: '-0.340000' },
+ ], { joinGraph, cubeEvaluator, compiler }));
+ } else {
+ test.skip('day granularity: the window accumulates over the declared grain', () => { expect(1).toBe(1); });
+ test.skip('month granularity: query grain does not replace the declared grain', () => { expect(1).toBe(1); });
+ test.skip('no time dimension: the window is one bucket over the whole range', () => { expect(1).toBe(1); });
+ test.skip('non-time dimension: the grain survives a plain group by', () => { expect(1).toBe(1); });
+ }
+});
diff --git a/packages/cubejs-schema-compiler/test/unit/base-query.test.ts b/packages/cubejs-schema-compiler/test/unit/base-query.test.ts
index 10ef064f06814..43c4533279337 100644
--- a/packages/cubejs-schema-compiler/test/unit/base-query.test.ts
+++ b/packages/cubejs-schema-compiler/test/unit/base-query.test.ts
@@ -1367,6 +1367,75 @@ describe('SQL Generation', () => {
expect(error).toBeInstanceOf(UserError);
}
});
+
+ it('Test for everyRefreshKeyParts', async () => {
+ await compilers.compiler.compile();
+
+ const timezone = 'America/Los_Angeles';
+ const query = new PostgresQuery(compilers, {
+ measures: ['cards.count'],
+ timeDimensions: [],
+ filters: [],
+ timezone,
+ });
+
+ const utcOffset = moment.tz(timezone).utcOffset() * 60;
+
+ expect(query.everyRefreshKeyParts({ every: '1 hour' }))
+ .toEqual({ utcOffset, interval: 3600, dayOffset: 0, cron: false });
+ expect(query.everyRefreshKeyParts({ every: '10 seconds' }))
+ .toEqual({ utcOffset, interval: 10, dayOffset: 0, cron: false });
+ expect(query.everyRefreshKeyParts({ every: '10 minute' }))
+ .toEqual({ utcOffset, interval: 600, dayOffset: 0, cron: false });
+
+ expect(query.everyRefreshKeyParts({ every: '0 * * * *', timezone }))
+ .toEqual({ utcOffset, interval: 3600, dayOffset: 0, cron: true });
+ expect(query.everyRefreshKeyParts({ every: '0 10 * * *', timezone }))
+ .toEqual({ utcOffset, interval: 86400, dayOffset: 36000, cron: true });
+ expect(query.everyRefreshKeyParts({ every: '30 5 * * 5', timezone }))
+ .toEqual({ utcOffset, interval: 604800, dayOffset: 106200, cron: true });
+ });
+
+ it('everyRefreshKeyParts agrees with the SQL it renders', async () => {
+ await compilers.compiler.compile();
+
+ const timezone = 'America/Los_Angeles';
+ const query = new PostgresQuery(compilers, {
+ measures: ['cards.count'],
+ timeDimensions: [],
+ filters: [],
+ timezone,
+ });
+
+ // Pins the clock to `t` so the emitted SQL can be compared against what the
+ // orchestrator now computes from the descriptor instead.
+ const evalSql = (sql: string, t: number) => {
+ const asJs = sql
+ .split('EXTRACT(EPOCH FROM NOW())').join(String(t))
+ .split('FLOOR').join('Math.floor');
+ // eslint-disable-next-line no-new-func
+ return Function(`"use strict"; return (${asJs});`)();
+ };
+
+ const refreshKeys = [
+ { every: '10 seconds' },
+ { every: '10 minute' },
+ { every: '1 hour' },
+ { every: '7 day' },
+ { every: '0 * * * *', timezone },
+ { every: '0 10 * * *', timezone },
+ { every: '30 5 * * 5', timezone },
+ ];
+
+ for (const refreshKey of refreshKeys) {
+ const [sql] = query.everyRefreshKeySql(refreshKey);
+ const { utcOffset, interval, dayOffset } = query.everyRefreshKeyParts(refreshKey);
+
+ for (const t of [0, 1, 1_500_000_000, 1_767_225_600]) {
+ expect(Math.floor((utcOffset + t - dayOffset) / interval)).toEqual(evalSql(sql, t));
+ }
+ }
+ });
});
describe('refreshKey from schema', () => {
@@ -1592,6 +1661,188 @@ describe('SQL Generation', () => {
});
});
+ describe('refreshKey local time evaluation', () => {
+ const compilers = /** @type Compilers */ prepareJsCompiler(
+ createCubeSchema({
+ name: 'cards',
+ refreshKey: `
+ refreshKey: {
+ every: '10 minute',
+ },
+ `,
+ preAggregations: `
+ countCreatedAt: {
+ type: 'rollup',
+ external: true,
+ measureReferences: [count],
+ timeDimensionReference: createdAt,
+ granularity: \`day\`,
+ partitionGranularity: \`month\`,
+ refreshKey: {
+ every: '1 hour',
+ },
+ scheduledRefresh: true,
+ },
+ maxCreatedAt: {
+ type: 'rollup',
+ external: true,
+ measureReferences: [max],
+ timeDimensionReference: createdAt,
+ granularity: \`day\`,
+ partitionGranularity: \`month\`,
+ refreshKey: {
+ sql: 'SELECT MAX(created_at) FROM cards',
+ },
+ scheduledRefresh: true,
+ },
+ minCreatedAt: {
+ type: 'rollup',
+ external: false,
+ measureReferences: [min],
+ timeDimensionReference: createdAt,
+ granularity: \`day\`,
+ partitionGranularity: \`month\`,
+ refreshKey: {
+ every: '1 hour',
+ incremental: true,
+ },
+ scheduledRefresh: true,
+ },
+ `
+ })
+ );
+
+ const timezone = 'America/Los_Angeles';
+
+ const newQuery = (query: any) => new PostgresQuery(compilers, {
+ timeDimensions: [],
+ filters: [],
+ timezone,
+ localRefreshKey: true,
+ ...query,
+ });
+
+ it('carries the descriptor on a cube refreshKey.every', async () => {
+ await compilers.compiler.compile();
+
+ const utcOffset = moment.tz(timezone).utcOffset() * 60;
+ const query = newQuery({ measures: ['cards.sum'], externalQueryClass: MssqlQuery });
+
+ expect(query.cacheKeyQueries()).toEqual([
+ [
+ `SELECT FLOOR((${utcOffset} + DATEDIFF(SECOND,'1970-01-01', GETUTCDATE())) / 600) as refresh_key`,
+ [],
+ {
+ external: true,
+ renewalThreshold: 60,
+ localRefreshKey: { utcOffset, interval: 600, dayOffset: 0, cron: false },
+ }
+ ]
+ ]);
+ });
+
+ it('carries the descriptor on a pre-aggregation refreshKey.every', async () => {
+ await compilers.compiler.compile();
+
+ const utcOffset = moment.tz(timezone).utcOffset() * 60;
+ const query = newQuery({ measures: ['cards.count'], externalQueryClass: MssqlQuery });
+
+ const preAggregations: any = query.newPreAggregations().preAggregationsDescription();
+ expect(preAggregations.length).toEqual(1);
+ expect(preAggregations[0].invalidateKeyQueries).toEqual([
+ [
+ `SELECT FLOOR((${utcOffset} + DATEDIFF(SECOND,'1970-01-01', GETUTCDATE())) / 3600) as refresh_key`,
+ [],
+ {
+ external: true,
+ renewalThreshold: 300,
+ localRefreshKey: { utcOffset, interval: 3600, dayOffset: 0, cron: false },
+ }
+ ]
+ ]);
+ });
+
+ it('leaves refreshKey.sql on the SQL path', async () => {
+ await compilers.compiler.compile();
+
+ const query = newQuery({ measures: ['cards.max'], externalQueryClass: MssqlQuery });
+
+ const preAggregations: any = query.newPreAggregations().preAggregationsDescription();
+ expect(preAggregations.length).toEqual(1);
+ expect(preAggregations[0].invalidateKeyQueries[0][2]).not.toHaveProperty('localRefreshKey');
+ });
+
+ it('leaves an incremental refreshKey on the SQL path', async () => {
+ await compilers.compiler.compile();
+
+ const query = newQuery({
+ measures: ['cards.min'],
+ timeDimensions: [{
+ dimension: 'cards.createdAt',
+ granularity: 'day',
+ dateRange: ['2016-12-30', '2017-01-05']
+ }],
+ externalQueryClass: MssqlQuery,
+ });
+
+ const preAggregations: any = query.newPreAggregations().preAggregationsDescription();
+ expect(preAggregations.length).toEqual(1);
+ expect(preAggregations[0].invalidateKeyQueries[0][2]).toMatchObject({ incremental: true });
+ expect(preAggregations[0].invalidateKeyQueries[0][2]).not.toHaveProperty('localRefreshKey');
+ });
+ });
+
+ describe('refreshKey local time evaluation (cube without refreshKey)', () => {
+ const compilers = /** @type Compilers */ prepareJsCompiler(
+ createCubeSchema({
+ name: 'cards',
+ preAggregations: `
+ countCreatedAt: {
+ type: 'rollup',
+ external: true,
+ measureReferences: [count],
+ timeDimensionReference: createdAt,
+ granularity: \`day\`,
+ partitionGranularity: \`month\`,
+ scheduledRefresh: true,
+ },
+ `
+ })
+ );
+
+ it('falls back to the hourly default with a descriptor', async () => {
+ await compilers.compiler.compile();
+
+ const query = new PostgresQuery(compilers, {
+ measures: ['cards.count'],
+ timeDimensions: [],
+ filters: [],
+ timezone: 'UTC',
+ localRefreshKey: true,
+ });
+
+ const preAggregations: any = query.newPreAggregations().preAggregationsDescription();
+ expect(preAggregations.length).toEqual(1);
+ expect(preAggregations[0].invalidateKeyQueries[0][2].localRefreshKey)
+ .toEqual({ utcOffset: 0, interval: 3600, dayOffset: 0, cron: false });
+ });
+
+ it('emits no descriptor when the flag is off', async () => {
+ await compilers.compiler.compile();
+
+ const query = new PostgresQuery(compilers, {
+ measures: ['cards.count'],
+ timeDimensions: [],
+ filters: [],
+ timezone: 'UTC',
+ });
+
+ const preAggregations: any = query.newPreAggregations().preAggregationsDescription();
+ expect(preAggregations.length).toEqual(1);
+ expect(preAggregations[0].invalidateKeyQueries[0][2]).not.toHaveProperty('localRefreshKey');
+ });
+ });
+
describe('refreshKey only cube (immutable)', () => {
/** @type Compilers */ prepareJsCompiler(
createCubeSchema({
diff --git a/packages/cubejs-server-core/CHANGELOG.md b/packages/cubejs-server-core/CHANGELOG.md
index 2be949add167a..6e93921974177 100644
--- a/packages/cubejs-server-core/CHANGELOG.md
+++ b/packages/cubejs-server-core/CHANGELOG.md
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+### Features
+
+- Support local computeing for interval refresh keys (behind flag) ([#11614](https://github.com/cube-js/cube/issues/11614)) ([d2b43a4](https://github.com/cube-js/cube/commit/d2b43a4accd2c5d116342f9ad5be648920197a7e))
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/server-core
diff --git a/packages/cubejs-server-core/package.json b/packages/cubejs-server-core/package.json
index 0d394cbf07e52..76fc9a0161ce3 100644
--- a/packages/cubejs-server-core/package.json
+++ b/packages/cubejs-server-core/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/server-core",
"description": "Cube.js base component to wire all backend components together",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -29,16 +29,16 @@
"unit": "jest --runInBand --forceExit --coverage dist/test"
},
"dependencies": {
- "@cubejs-backend/api-gateway": "1.7.30",
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/cloud": "1.7.30",
- "@cubejs-backend/cubestore-driver": "1.7.30",
+ "@cubejs-backend/api-gateway": "1.7.31",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/cloud": "1.7.31",
+ "@cubejs-backend/cubestore-driver": "1.7.31",
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/native": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
- "@cubejs-backend/templates": "1.7.30",
+ "@cubejs-backend/native": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
+ "@cubejs-backend/templates": "1.7.31",
"codesandbox-import-utils": "^2.1.12",
"cross-spawn": "^7.0.1",
"fs-extra": "^8.1.0",
@@ -62,8 +62,8 @@
"ws": "^7.5.3"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-client/playground": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-client/playground": "1.7.31",
"@types/cross-spawn": "^6.0.2",
"@types/express": "^4.17.21",
"@types/fs-extra": "^9.0.8",
diff --git a/packages/cubejs-server-core/src/core/CompilerApi.ts b/packages/cubejs-server-core/src/core/CompilerApi.ts
index c6e1481713747..f82feb816ae58 100644
--- a/packages/cubejs-server-core/src/core/CompilerApi.ts
+++ b/packages/cubejs-server-core/src/core/CompilerApi.ts
@@ -37,6 +37,7 @@ export interface CompilerApiOptions {
preAggregationsSchema?: string | ((context: Context) => string | Promise);
allowUngroupedWithoutPrimaryKey?: boolean;
convertTzForRawTimeDimension?: boolean;
+ localRefreshKey?: boolean;
schemaVersion?: () => string | object | Promise;
contextToGroups?: (context: Context) => string[] | Promise;
compileContext?: any;
@@ -105,6 +106,8 @@ export class CompilerApi {
protected readonly convertTzForRawTimeDimension?: boolean;
+ protected readonly localRefreshKey?: boolean;
+
public schemaVersion?: () => string | object | Promise;
protected readonly contextToGroups?: (context: Context) => string[] | Promise;
@@ -146,6 +149,7 @@ export class CompilerApi {
this.preAggregationsSchema = this.options.preAggregationsSchema;
this.allowUngroupedWithoutPrimaryKey = this.options.allowUngroupedWithoutPrimaryKey;
this.convertTzForRawTimeDimension = this.options.convertTzForRawTimeDimension;
+ this.localRefreshKey = this.options.localRefreshKey;
this.schemaVersion = this.options.schemaVersion;
this.contextToGroups = this.options.contextToGroups;
this.compileContext = options.compileContext;
@@ -967,6 +971,7 @@ export class CompilerApi {
preAggregationsSchema: this.preAggregationsSchema,
allowUngroupedWithoutPrimaryKey: this.allowUngroupedWithoutPrimaryKey,
convertTzForRawTimeDimension: this.convertTzForRawTimeDimension,
+ localRefreshKey: this.localRefreshKey,
queryFactory: this.queryFactory,
}
);
diff --git a/packages/cubejs-server-core/src/core/OptsHandler.ts b/packages/cubejs-server-core/src/core/OptsHandler.ts
index 328f5130055f1..a8cdb25995517 100644
--- a/packages/cubejs-server-core/src/core/OptsHandler.ts
+++ b/packages/cubejs-server-core/src/core/OptsHandler.ts
@@ -602,8 +602,10 @@ export class OptsHandler {
? clone.rollupOnlyMode
: getEnv('rollupOnlyMode');
- // query queue options
clone.queryCacheOptions = clone.queryCacheOptions || {};
+ clone.queryCacheOptions.localRefreshKey = getEnv('refreshKeyLocalTime');
+
+ // query queue options
clone.queryCacheOptions.queueOptions = this.queueOptionsWrapper(
context,
clone.queryCacheOptions.queueOptions,
diff --git a/packages/cubejs-server-core/src/core/RefreshScheduler.ts b/packages/cubejs-server-core/src/core/RefreshScheduler.ts
index 5ab684bbb83f5..6c824bbfea4ef 100644
--- a/packages/cubejs-server-core/src/core/RefreshScheduler.ts
+++ b/packages/cubejs-server-core/src/core/RefreshScheduler.ts
@@ -343,6 +343,12 @@ export class RefreshScheduler {
const compilers = await compilerApi.getCompilers();
const queryForEvaluation = await compilerApi.createQueryByDataSource(compilers, {});
+ const orchestratorApi = await this.serverCore.getOrchestratorApi(context);
+ const localRefreshKey = orchestratorApi
+ .getQueryOrchestrator()
+ .getQueryCache()
+ .isLocalRefreshKeyActive();
+
await Promise.all(queryForEvaluation.cubeEvaluator.cubeNames().map(async cube => {
const cubeFromPath = queryForEvaluation.cubeEvaluator.cubeFromPath(cube);
const measuresCount = Object.keys(cubeFromPath.measures || {}).length;
@@ -350,6 +356,16 @@ export class RefreshScheduler {
if (measuresCount === 0 && dimensionsCount === 0) {
return;
}
+
+ // This method exists only to warm the shared refresh key cache, and a locally evaluated
+ // key has no cache entry to warm — the getSql plus executeQuery per timezone below would
+ // be spent on a result that is thrown away. A `sql` key still hits the data source, and
+ // so do interval keys whenever the cache declines to evaluate them locally.
+ const sqlRefreshKey = !!cubeFromPath.refreshKey && 'sql' in cubeFromPath.refreshKey;
+ if (localRefreshKey && !sqlRefreshKey) {
+ return;
+ }
+
await Promise.all(queryingOptions.timezones.map(async timezone => {
const query = {
...queryingOptions,
@@ -364,7 +380,6 @@ export class RefreshScheduler {
timezone
};
const sqlQuery = await compilerApi.getSql(query);
- const orchestratorApi = await this.serverCore.getOrchestratorApi(context);
await orchestratorApi.executeQuery({
...sqlQuery,
sql: null,
diff --git a/packages/cubejs-server-core/src/core/server.ts b/packages/cubejs-server-core/src/core/server.ts
index 48b146c8abb70..d52b43566cbc1 100644
--- a/packages/cubejs-server-core/src/core/server.ts
+++ b/packages/cubejs-server-core/src/core/server.ts
@@ -738,6 +738,7 @@ export class CubejsServerCore {
this.options.allowUngroupedWithoutPrimaryKey ||
getEnv('allowUngroupedWithoutPrimaryKey'),
convertTzForRawTimeDimension: getEnv('convertTzForRawTimeDimension'),
+ localRefreshKey: getEnv('refreshKeyLocalTime'),
compileContext: options.context,
dialectClass: options.dialectClass,
externalDialectClass: options.externalDialectClass,
diff --git a/packages/cubejs-server-core/src/core/types.ts b/packages/cubejs-server-core/src/core/types.ts
index 3d1cfee7d79ee..2e4084159a551 100644
--- a/packages/cubejs-server-core/src/core/types.ts
+++ b/packages/cubejs-server-core/src/core/types.ts
@@ -60,6 +60,7 @@ export interface QueueInitedOptions {
export interface QueryInitedOptions {
queueOptions: (dataSource: string) => Promise;
+ localRefreshKey: boolean;
refreshKeyRenewalThreshold?: number;
backgroundRenew?: boolean;
externalQueueOptions?: QueueOptions;
diff --git a/packages/cubejs-server-core/test/unit/RefreshScheduler.test.ts b/packages/cubejs-server-core/test/unit/RefreshScheduler.test.ts
index 85ccd19175ced..c2b2abb9c807b 100644
--- a/packages/cubejs-server-core/test/unit/RefreshScheduler.test.ts
+++ b/packages/cubejs-server-core/test/unit/RefreshScheduler.test.ts
@@ -232,6 +232,43 @@ cube('Bar', {
]),
};
+const repositoryWithRefreshKeys: SchemaFileRepository = {
+ localPath: () => __dirname,
+ dataSchemaFiles: () => Promise.resolve([
+ {
+ fileName: 'main.js', content: `
+cube('Interval', {
+ sql: 'select * from interval_cube',
+
+ refreshKey: {
+ every: '1 hour'
+ },
+
+ measures: {
+ count: {
+ type: 'count'
+ }
+ }
+});
+
+cube('Sql', {
+ sql: 'select * from sql_cube',
+
+ refreshKey: {
+ sql: 'SELECT MAX(updated_at) FROM sql_cube_refresh'
+ },
+
+ measures: {
+ count: {
+ type: 'count'
+ }
+ }
+});
+`,
+ },
+ ]),
+};
+
class MockDriver extends BaseDriver {
public tables: any[] = [];
@@ -350,10 +387,11 @@ class MockDriver extends BaseDriver {
let testCounter = 1;
-const setupScheduler = ({ repository, useOriginalSqlPreAggregations, skipAssertSecurityContext }: {
+const setupScheduler = ({ repository, useOriginalSqlPreAggregations, skipAssertSecurityContext, refreshKeyRenewalThreshold }: {
repository: SchemaFileRepository,
useOriginalSqlPreAggregations?: boolean,
- skipAssertSecurityContext?: true
+ skipAssertSecurityContext?: true,
+ refreshKeyRenewalThreshold?: number
}) => {
const mockDriver = new MockDriver();
const externalDriver = new MockDriver();
@@ -390,6 +428,7 @@ const setupScheduler = ({ repository, useOriginalSqlPreAggregations, skipAssertS
queueOptions: () => ({
concurrency: 2,
}),
+ ...(refreshKeyRenewalThreshold && { refreshKeyRenewalThreshold }),
},
preAggregationsOptions: {
queueOptions: () => ({
@@ -427,6 +466,7 @@ describe('Refresh Scheduler', () => {
delete process.env.CUBEJS_DROP_PRE_AGG_WITHOUT_TOUCH;
delete process.env.CUBEJS_TOUCH_PRE_AGG_TIMEOUT;
delete process.env.CUBEJS_DB_QUERY_TIMEOUT;
+ delete process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME;
});
afterAll(async () => {
@@ -1240,4 +1280,52 @@ describe('Refresh Scheduler', () => {
// backoffDataStillActive exists, which means backoff is still in place
// (nextTimestamp may be close to current time due to test execution delays)
});
+
+ describe('Local refresh key', () => {
+ const ctx = { authInfo: { tenantId: 'tenant1' }, securityContext: { tenantId: 'tenant1' }, requestId: 'local refresh key' };
+
+ const runRefresh = async (refreshKeyRenewalThreshold?: number) => {
+ const { refreshScheduler, mockDriver } = setupScheduler({
+ repository: repositoryWithRefreshKeys,
+ refreshKeyRenewalThreshold,
+ });
+
+ await refreshScheduler.runScheduledRefresh(ctx, {
+ concurrency: 1,
+ workerIndices: [0],
+ throwErrors: true,
+ });
+
+ return {
+ // `every` keys render as `SELECT FLOOR(...) as refresh_key`, a `sql` key renders as itself
+ intervalKeyQueries: mockDriver.executedQueries.filter(q => q.match(/refresh_key/)),
+ sqlKeyQueries: mockDriver.executedQueries.filter(q => q.match(/sql_cube_refresh/)),
+ };
+ };
+
+ test('warms both kinds of refresh key with the flag off', async () => {
+ const { intervalKeyQueries, sqlKeyQueries } = await runRefresh();
+
+ expect(intervalKeyQueries.length).toBeGreaterThan(0);
+ expect(sqlKeyQueries.length).toBeGreaterThan(0);
+ });
+
+ test('skips interval keys that are evaluated locally', async () => {
+ process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME = 'true';
+
+ const { intervalKeyQueries, sqlKeyQueries } = await runRefresh();
+
+ expect(intervalKeyQueries).toEqual([]);
+ expect(sqlKeyQueries.length).toBeGreaterThan(0);
+ });
+
+ test('keeps warming interval keys when refreshKeyRenewalThreshold vetoes local evaluation', async () => {
+ process.env.CUBEJS_REFRESH_KEY_LOCAL_TIME = 'true';
+
+ const { intervalKeyQueries, sqlKeyQueries } = await runRefresh(120);
+
+ expect(intervalKeyQueries.length).toBeGreaterThan(0);
+ expect(sqlKeyQueries.length).toBeGreaterThan(0);
+ });
+ });
});
diff --git a/packages/cubejs-server/CHANGELOG.md b/packages/cubejs-server/CHANGELOG.md
index 567809f1892af..b80c84a4c8bc9 100644
--- a/packages/cubejs-server/CHANGELOG.md
+++ b/packages/cubejs-server/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/server
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/server
diff --git a/packages/cubejs-server/package.json b/packages/cubejs-server/package.json
index f974dc38d755c..d643b0edf2754 100644
--- a/packages/cubejs-server/package.json
+++ b/packages/cubejs-server/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/server",
"description": "Cube.js all-in-one server",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"types": "index.d.ts",
"repository": {
"type": "git",
@@ -40,11 +40,11 @@
"jest:shapshot": "jest --updateSnapshot test"
},
"dependencies": {
- "@cubejs-backend/cubestore-driver": "1.7.30",
+ "@cubejs-backend/cubestore-driver": "1.7.31",
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/native": "1.7.30",
- "@cubejs-backend/server-core": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/native": "1.7.31",
+ "@cubejs-backend/server-core": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@oclif/color": "^1.0.0",
"@oclif/command": "^1.8.13",
"@oclif/config": "^1.18.2",
@@ -61,8 +61,8 @@
"ws": "^7.1.2"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
"@oclif/dev-cli": "^1.23.1",
"@types/body-parser": "^1.19.0",
"@types/cors": "^2.8.8",
diff --git a/packages/cubejs-snowflake-driver/CHANGELOG.md b/packages/cubejs-snowflake-driver/CHANGELOG.md
index b7d22560b238c..a967dc36dfcc6 100644
--- a/packages/cubejs-snowflake-driver/CHANGELOG.md
+++ b/packages/cubejs-snowflake-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/snowflake-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/snowflake-driver
diff --git a/packages/cubejs-snowflake-driver/package.json b/packages/cubejs-snowflake-driver/package.json
index 2b44b82aa56f0..676c6695abf63 100644
--- a/packages/cubejs-snowflake-driver/package.json
+++ b/packages/cubejs-snowflake-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/snowflake-driver",
"description": "Cube.js Snowflake database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -29,8 +29,8 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.726.0",
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"snowflake-sdk": "^2.4.0"
},
"license": "Apache-2.0",
@@ -41,7 +41,7 @@
"extends": "../cubejs-linter"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"typescript": "~5.2.2",
"vitest": "^4"
}
diff --git a/packages/cubejs-sqlite-driver/CHANGELOG.md b/packages/cubejs-sqlite-driver/CHANGELOG.md
index 6073e09361abb..bd33db79ae477 100644
--- a/packages/cubejs-sqlite-driver/CHANGELOG.md
+++ b/packages/cubejs-sqlite-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/sqlite-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/sqlite-driver
diff --git a/packages/cubejs-sqlite-driver/package.json b/packages/cubejs-sqlite-driver/package.json
index 783aa6ff043ce..3d536acd9a176 100644
--- a/packages/cubejs-sqlite-driver/package.json
+++ b/packages/cubejs-sqlite-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/sqlite-driver",
"description": "Cube.js Sqlite database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -18,13 +18,13 @@
"unit": "jest"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"sqlite3": "^5.1.7"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"jest": "^29"
},
"publishConfig": {
diff --git a/packages/cubejs-templates/CHANGELOG.md b/packages/cubejs-templates/CHANGELOG.md
index 4a45caa6eeaf7..5473e5f3bec07 100644
--- a/packages/cubejs-templates/CHANGELOG.md
+++ b/packages/cubejs-templates/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/templates
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/templates
diff --git a/packages/cubejs-templates/package.json b/packages/cubejs-templates/package.json
index bafc5445509c8..02a949c3f2466 100644
--- a/packages/cubejs-templates/package.json
+++ b/packages/cubejs-templates/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/templates",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Cube.js Templates helpers",
"author": "Cube Dev, Inc.",
"repository": {
@@ -31,7 +31,7 @@
"extends": "../cubejs-linter"
},
"dependencies": {
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/shared": "1.7.31",
"cross-spawn": "^7.0.3",
"fs-extra": "^9.1.0",
"node-fetch": "^2.6.1",
@@ -40,7 +40,7 @@
"tar": "^7.5.22"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"typescript": "~5.2.2"
}
}
diff --git a/packages/cubejs-testing-drivers/CHANGELOG.md b/packages/cubejs-testing-drivers/CHANGELOG.md
index 0fed12620cd56..afebdfb4b995d 100644
--- a/packages/cubejs-testing-drivers/CHANGELOG.md
+++ b/packages/cubejs-testing-drivers/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/testing-drivers
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/testing-drivers
diff --git a/packages/cubejs-testing-drivers/package.json b/packages/cubejs-testing-drivers/package.json
index fe4f969b9bef3..99d1bb776d5d7 100644
--- a/packages/cubejs-testing-drivers/package.json
+++ b/packages/cubejs-testing-drivers/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/testing-drivers",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Cube.js drivers test suite",
"author": "Cube Dev, Inc.",
"repository": {
@@ -87,29 +87,29 @@
"dist/src"
],
"dependencies": {
- "@cubejs-backend/athena-driver": "1.7.30",
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/bigquery-driver": "1.7.30",
- "@cubejs-backend/clickhouse-driver": "1.7.30",
- "@cubejs-backend/crate-driver": "1.7.30",
- "@cubejs-backend/cubestore-driver": "1.7.30",
- "@cubejs-backend/databricks-jdbc-driver": "1.7.30",
+ "@cubejs-backend/athena-driver": "1.7.31",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/bigquery-driver": "1.7.31",
+ "@cubejs-backend/clickhouse-driver": "1.7.31",
+ "@cubejs-backend/crate-driver": "1.7.31",
+ "@cubejs-backend/cubestore-driver": "1.7.31",
+ "@cubejs-backend/databricks-jdbc-driver": "1.7.31",
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/mssql-driver": "1.7.30",
- "@cubejs-backend/mysql-driver": "1.7.30",
- "@cubejs-backend/oracle-driver": "1.7.30",
- "@cubejs-backend/pinot-driver": "1.7.30",
- "@cubejs-backend/postgres-driver": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
- "@cubejs-backend/questdb-driver": "1.7.30",
- "@cubejs-backend/server-core": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
- "@cubejs-backend/snowflake-driver": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
- "@cubejs-backend/trino-driver": "1.7.30",
- "@cubejs-client/core": "1.7.30",
- "@cubejs-client/ws-transport": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/mssql-driver": "1.7.31",
+ "@cubejs-backend/mysql-driver": "1.7.31",
+ "@cubejs-backend/oracle-driver": "1.7.31",
+ "@cubejs-backend/pinot-driver": "1.7.31",
+ "@cubejs-backend/postgres-driver": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
+ "@cubejs-backend/questdb-driver": "1.7.31",
+ "@cubejs-backend/server-core": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
+ "@cubejs-backend/snowflake-driver": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
+ "@cubejs-backend/trino-driver": "1.7.31",
+ "@cubejs-client/core": "1.7.31",
+ "@cubejs-client/ws-transport": "1.7.31",
"@jest/globals": "^29",
"@types/jest": "^29",
"@types/node": "^22",
diff --git a/packages/cubejs-testing-shared/CHANGELOG.md b/packages/cubejs-testing-shared/CHANGELOG.md
index ee0607123ec84..44c565adf37d8 100644
--- a/packages/cubejs-testing-shared/CHANGELOG.md
+++ b/packages/cubejs-testing-shared/CHANGELOG.md
@@ -3,6 +3,12 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+### Bug Fixes
+
+- **cubesql:** push down window functions and multi-argument aggregates ([#11684](https://github.com/cube-js/cube/issues/11684)) ([4567c07](https://github.com/cube-js/cube/commit/4567c074fe4a2d13d278c3dd4c6c71217094bc4a))
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/testing-shared
diff --git a/packages/cubejs-testing-shared/package.json b/packages/cubejs-testing-shared/package.json
index d4320cc67313f..2ce65227996fa 100644
--- a/packages/cubejs-testing-shared/package.json
+++ b/packages/cubejs-testing-shared/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/testing-shared",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Cube.js Testing Helpers",
"author": "Cube Dev, Inc.",
"repository": {
@@ -26,16 +26,16 @@
],
"dependencies": {
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/query-orchestrator": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"@testcontainers/kafka": "~10.28.0",
"dedent": "^0.7.0",
"node-fetch": "^2.6.7",
"testcontainers": "^10.28.0"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@jest/globals": "^29",
"@types/dedent": "^0.7.0",
"@types/jest": "^29",
diff --git a/packages/cubejs-testing/CHANGELOG.md b/packages/cubejs-testing/CHANGELOG.md
index 4033f82bc0860..bb9d27eb309a2 100644
--- a/packages/cubejs-testing/CHANGELOG.md
+++ b/packages/cubejs-testing/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/testing
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/testing
diff --git a/packages/cubejs-testing/package.json b/packages/cubejs-testing/package.json
index e8d10b68297eb..eb759b5c53074 100644
--- a/packages/cubejs-testing/package.json
+++ b/packages/cubejs-testing/package.json
@@ -1,6 +1,6 @@
{
"name": "@cubejs-backend/testing",
- "version": "1.7.30",
+ "version": "1.7.31",
"description": "Cube.js e2e tests",
"author": "Cube Dev, Inc.",
"repository": {
@@ -92,15 +92,15 @@
"birdbox-fixtures"
],
"dependencies": {
- "@cubejs-backend/cubestore-driver": "1.7.30",
+ "@cubejs-backend/cubestore-driver": "1.7.31",
"@cubejs-backend/dotenv": "^9.0.2",
- "@cubejs-backend/ksql-driver": "1.7.30",
- "@cubejs-backend/postgres-driver": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
- "@cubejs-client/ws-transport": "1.7.30",
+ "@cubejs-backend/ksql-driver": "1.7.31",
+ "@cubejs-backend/postgres-driver": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
+ "@cubejs-client/ws-transport": "1.7.31",
"dedent": "^0.7.0",
"fs-extra": "^8.1.0",
"http-proxy": "^1.18.1",
@@ -111,8 +111,8 @@
},
"devDependencies": {
"@4tw/cypress-drag-drop": "^1.6.0",
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-client/core": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-client/core": "1.7.31",
"@jest/globals": "^29",
"@types/dedent": "^0.7.0",
"@types/http-proxy": "^1.17.5",
diff --git a/packages/cubejs-trino-driver/CHANGELOG.md b/packages/cubejs-trino-driver/CHANGELOG.md
index cf430a87ff383..f04447edc4794 100644
--- a/packages/cubejs-trino-driver/CHANGELOG.md
+++ b/packages/cubejs-trino-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/trino-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/trino-driver
diff --git a/packages/cubejs-trino-driver/package.json b/packages/cubejs-trino-driver/package.json
index 1a88430ea2959..c742f72c1377a 100644
--- a/packages/cubejs-trino-driver/package.json
+++ b/packages/cubejs-trino-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/trino-driver",
"description": "Cube.js Trino database driver",
"author": "Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -28,10 +28,10 @@
"lint:fix": "eslint --fix src/* --ext .ts"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/prestodb-driver": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/prestodb-driver": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"node-fetch": "^2.6.1",
"presto-client": "^1.2.0"
},
@@ -40,7 +40,7 @@
"access": "public"
},
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"testcontainers": "^10.28.0",
diff --git a/packages/cubejs-vertica-driver/CHANGELOG.md b/packages/cubejs-vertica-driver/CHANGELOG.md
index 6a065b2038da8..23da6e1dd563b 100644
--- a/packages/cubejs-vertica-driver/CHANGELOG.md
+++ b/packages/cubejs-vertica-driver/CHANGELOG.md
@@ -3,6 +3,10 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
+## [1.7.31](https://github.com/cube-js/cube/compare/v1.7.30...v1.7.31) (2026-08-31)
+
+**Note:** Version bump only for package @cubejs-backend/vertica-driver
+
## [1.7.30](https://github.com/cube-js/cube/compare/v1.7.29...v1.7.30) (2026-08-28)
**Note:** Version bump only for package @cubejs-backend/vertica-driver
diff --git a/packages/cubejs-vertica-driver/package.json b/packages/cubejs-vertica-driver/package.json
index e9e88a79e204e..e611a3a235699 100644
--- a/packages/cubejs-vertica-driver/package.json
+++ b/packages/cubejs-vertica-driver/package.json
@@ -2,7 +2,7 @@
"name": "@cubejs-backend/vertica-driver",
"description": "Cube.js Vertica database driver",
"author": "Eduard Karacharov, Tim Brown, Cube Dev, Inc.",
- "version": "1.7.30",
+ "version": "1.7.31",
"repository": {
"type": "git",
"url": "https://github.com/cube-js/cube.git",
@@ -19,16 +19,16 @@
"lint:fix": "eslint --fix **/*.js"
},
"dependencies": {
- "@cubejs-backend/base-driver": "1.7.30",
- "@cubejs-backend/query-orchestrator": "1.7.30",
- "@cubejs-backend/schema-compiler": "1.7.30",
- "@cubejs-backend/shared": "1.7.30",
+ "@cubejs-backend/base-driver": "1.7.31",
+ "@cubejs-backend/query-orchestrator": "1.7.31",
+ "@cubejs-backend/schema-compiler": "1.7.31",
+ "@cubejs-backend/shared": "1.7.31",
"vertica-nodejs": "^1.0.3"
},
"license": "Apache-2.0",
"devDependencies": {
- "@cubejs-backend/linter": "1.7.30",
- "@cubejs-backend/testing-shared": "1.7.30",
+ "@cubejs-backend/linter": "1.7.31",
+ "@cubejs-backend/testing-shared": "1.7.31",
"@types/jest": "^29",
"jest": "^29",
"testcontainers": "^10.28.0"
diff --git a/rust/cube/cubesqlplanner/cubesqlplanner/src/planner/collectors/has_expression_or_calculated_members.rs b/rust/cube/cubesqlplanner/cubesqlplanner/src/planner/collectors/has_expression_or_calculated_members.rs
new file mode 100644
index 0000000000000..e32e06662fb32
--- /dev/null
+++ b/rust/cube/cubesqlplanner/cubesqlplanner/src/planner/collectors/has_expression_or_calculated_members.rs
@@ -0,0 +1,59 @@
+use crate::planner::{MemberSymbol, TraversalVisitor};
+use cubenativeutils::CubeError;
+use std::rc::Rc;
+
+struct HasExpressionOrCalculatedMembersCollector {
+ found: bool,
+}
+
+impl HasExpressionOrCalculatedMembersCollector {
+ fn new() -> Self {
+ Self { found: false }
+ }
+
+ fn extract_result(self) -> bool {
+ self.found
+ }
+}
+
+impl TraversalVisitor for HasExpressionOrCalculatedMembersCollector {
+ type State = ();
+ fn on_node_traverse(
+ &mut self,
+ node: &Rc,
+ _: &Self::State,
+ ) -> Result