From c05a70f2d7a5d26ea4f6957401b82c4001abddb1 Mon Sep 17 00:00:00 2001 From: Dmitry Patsura Date: Wed, 26 Aug 2026 15:25:24 +0200 Subject: [PATCH 1/4] refactor(query-orchestrator): Queue - drop getQueryDef lookup on skipped processing (#11654) --- .../src/orchestrator/QueryQueue.ts | 22 +++---------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/packages/cubejs-query-orchestrator/src/orchestrator/QueryQueue.ts b/packages/cubejs-query-orchestrator/src/orchestrator/QueryQueue.ts index 8ad5b2f4f81d1..17b2283015099 100644 --- a/packages/cubejs-query-orchestrator/src/orchestrator/QueryQueue.ts +++ b/packages/cubejs-query-orchestrator/src/orchestrator/QueryQueue.ts @@ -812,30 +812,15 @@ export class QueryQueue { protected async retrieveQueryForProcessing(queryKeyHashed: QueryKeyHash, queueId: QueueId): Promise { const queueConnection = await this.queueDriver.createConnection(); - let query; - try { const retrieved = await queueConnection.retrieveForProcessing(queryKeyHashed, queueId); if (!retrieved) { - query = await queueConnection.getQueryDef(queryKeyHashed, null); - - // TODO Ideally streaming queries should reconcile queue here after waiting on open slot however in practice continue wait timeout reconciles faster CPU-wise - // if (query?.queryHandler === 'stream') { - // const [active] = await queueConnection.getQueryStageState(true); - // if (active && active.length > 0) { - // await Promise.race(active.map(keyHash => queueConnection.getResultBlocking(keyHash))); - // await this.reconcileQueue(); - // } - // } - this.logger('Skip processing', { queueId, - queryKey: query && query.queryKey || queryKeyHashed, - requestId: query && query.requestId, + queryKey: queryKeyHashed, queuePrefix: this.redisQueuePrefix, - query, - queryExists: !!query }); + return null; } @@ -843,8 +828,7 @@ export class QueryQueue { } catch (e: any) { this.logger('Queue storage error', { queueId, - queryKey: query && query.queryKey || queryKeyHashed, - requestId: query && query.requestId, + queryKey: queryKeyHashed, error: (e.stack || e).toString(), queuePrefix: this.redisQueuePrefix }); From 43964f87e48c0bef8fc58e7b30c625e832dea4f0 Mon Sep 17 00:00:00 2001 From: Dmitry Patsura Date: Wed, 26 Aug 2026 15:31:35 +0200 Subject: [PATCH 2/4] v1.7.27 --- CHANGELOG.md | 13 +++++ lerna.json | 2 +- packages/cubejs-api-gateway/CHANGELOG.md | 4 ++ packages/cubejs-api-gateway/package.json | 10 ++-- packages/cubejs-athena-driver/CHANGELOG.md | 4 ++ packages/cubejs-athena-driver/package.json | 10 ++-- packages/cubejs-backend-cloud/CHANGELOG.md | 4 ++ packages/cubejs-backend-cloud/package.json | 6 +- packages/cubejs-backend-maven/CHANGELOG.md | 4 ++ packages/cubejs-backend-maven/package.json | 6 +- packages/cubejs-backend-native/CHANGELOG.md | 6 ++ packages/cubejs-backend-native/package.json | 8 +-- packages/cubejs-backend-shared/CHANGELOG.md | 4 ++ packages/cubejs-backend-shared/package.json | 4 +- packages/cubejs-base-driver/CHANGELOG.md | 4 ++ packages/cubejs-base-driver/package.json | 6 +- packages/cubejs-bigquery-driver/CHANGELOG.md | 4 ++ packages/cubejs-bigquery-driver/package.json | 8 +-- packages/cubejs-cli/CHANGELOG.md | 4 ++ packages/cubejs-cli/package.json | 12 ++-- .../cubejs-clickhouse-driver/CHANGELOG.md | 4 ++ .../cubejs-clickhouse-driver/package.json | 10 ++-- packages/cubejs-client-core/CHANGELOG.md | 4 ++ packages/cubejs-client-core/package.json | 4 +- packages/cubejs-client-dx/CHANGELOG.md | 4 ++ packages/cubejs-client-dx/package.json | 2 +- packages/cubejs-client-ngx/CHANGELOG.md | 4 ++ packages/cubejs-client-ngx/package.json | 2 +- packages/cubejs-client-react/CHANGELOG.md | 4 ++ packages/cubejs-client-react/package.json | 4 +- packages/cubejs-client-vue3/CHANGELOG.md | 4 ++ packages/cubejs-client-vue3/package.json | 4 +- .../cubejs-client-ws-transport/CHANGELOG.md | 4 ++ .../cubejs-client-ws-transport/package.json | 6 +- packages/cubejs-crate-driver/CHANGELOG.md | 4 ++ packages/cubejs-crate-driver/package.json | 10 ++-- packages/cubejs-cubestore-driver/CHANGELOG.md | 4 ++ packages/cubejs-cubestore-driver/package.json | 12 ++-- .../CHANGELOG.md | 4 ++ .../package.json | 12 ++-- .../cubejs-dbt-schema-extension/CHANGELOG.md | 4 ++ .../cubejs-dbt-schema-extension/package.json | 8 +-- packages/cubejs-docker/CHANGELOG.md | 4 ++ packages/cubejs-docker/package.json | 58 +++++++++---------- packages/cubejs-dremio-driver/CHANGELOG.md | 4 ++ packages/cubejs-dremio-driver/package.json | 12 ++-- packages/cubejs-druid-driver/CHANGELOG.md | 4 ++ packages/cubejs-druid-driver/package.json | 10 ++-- packages/cubejs-duckdb-driver/CHANGELOG.md | 4 ++ packages/cubejs-duckdb-driver/package.json | 12 ++-- packages/cubejs-firebolt-driver/CHANGELOG.md | 4 ++ packages/cubejs-firebolt-driver/package.json | 12 ++-- packages/cubejs-hive-driver/CHANGELOG.md | 4 ++ packages/cubejs-hive-driver/package.json | 8 +-- packages/cubejs-jdbc-driver/CHANGELOG.md | 4 ++ packages/cubejs-jdbc-driver/package.json | 8 +-- packages/cubejs-ksql-driver/CHANGELOG.md | 4 ++ packages/cubejs-ksql-driver/package.json | 10 ++-- packages/cubejs-linter/CHANGELOG.md | 4 ++ packages/cubejs-linter/package.json | 2 +- .../cubejs-materialize-driver/CHANGELOG.md | 4 ++ .../cubejs-materialize-driver/package.json | 12 ++-- packages/cubejs-mongobi-driver/CHANGELOG.md | 4 ++ packages/cubejs-mongobi-driver/package.json | 8 +-- packages/cubejs-mssql-driver/CHANGELOG.md | 4 ++ packages/cubejs-mssql-driver/package.json | 6 +- .../CHANGELOG.md | 4 ++ .../package.json | 8 +-- packages/cubejs-mysql-driver/CHANGELOG.md | 4 ++ packages/cubejs-mysql-driver/package.json | 10 ++-- packages/cubejs-oracle-driver/CHANGELOG.md | 4 ++ packages/cubejs-oracle-driver/package.json | 6 +- packages/cubejs-pinot-driver/CHANGELOG.md | 4 ++ packages/cubejs-pinot-driver/package.json | 10 ++-- packages/cubejs-playground/CHANGELOG.md | 4 ++ packages/cubejs-playground/package.json | 6 +- packages/cubejs-postgres-driver/CHANGELOG.md | 4 ++ packages/cubejs-postgres-driver/package.json | 10 ++-- packages/cubejs-prestodb-driver/CHANGELOG.md | 4 ++ packages/cubejs-prestodb-driver/package.json | 8 +-- .../cubejs-query-orchestrator/CHANGELOG.md | 4 ++ .../cubejs-query-orchestrator/package.json | 10 ++-- packages/cubejs-questdb-driver/CHANGELOG.md | 4 ++ packages/cubejs-questdb-driver/package.json | 12 ++-- packages/cubejs-redshift-driver/CHANGELOG.md | 4 ++ packages/cubejs-redshift-driver/package.json | 10 ++-- packages/cubejs-schema-compiler/CHANGELOG.md | 6 ++ packages/cubejs-schema-compiler/package.json | 12 ++-- packages/cubejs-server-core/CHANGELOG.md | 4 ++ packages/cubejs-server-core/package.json | 24 ++++---- packages/cubejs-server/CHANGELOG.md | 4 ++ packages/cubejs-server/package.json | 14 ++--- packages/cubejs-snowflake-driver/CHANGELOG.md | 4 ++ packages/cubejs-snowflake-driver/package.json | 8 +-- packages/cubejs-sqlite-driver/CHANGELOG.md | 4 ++ packages/cubejs-sqlite-driver/package.json | 8 +-- packages/cubejs-templates/CHANGELOG.md | 4 ++ packages/cubejs-templates/package.json | 6 +- packages/cubejs-testing-drivers/CHANGELOG.md | 4 ++ packages/cubejs-testing-drivers/package.json | 46 +++++++-------- packages/cubejs-testing-shared/CHANGELOG.md | 4 ++ packages/cubejs-testing-shared/package.json | 10 ++-- packages/cubejs-testing/CHANGELOG.md | 4 ++ packages/cubejs-testing/package.json | 22 +++---- packages/cubejs-trino-driver/CHANGELOG.md | 4 ++ packages/cubejs-trino-driver/package.json | 12 ++-- packages/cubejs-vertica-driver/CHANGELOG.md | 4 ++ packages/cubejs-vertica-driver/package.json | 14 ++--- rust/cubesql/CHANGELOG.md | 10 ++++ rust/cubesql/package.json | 2 +- rust/cubestore/CHANGELOG.md | 6 ++ rust/cubestore/Cargo.lock | 2 +- rust/cubestore/cubestore/Cargo.toml | 2 +- rust/cubestore/package.json | 6 +- 114 files changed, 536 insertions(+), 291 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dad1e9b9dacfb..847c4ea6d1f8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,19 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [1.7.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +### Bug Fixes + +- **backend-native:** treat a client disconnect on /v1/cubesql as a graceful end ([#11649](https://github.com/cube-js/cube/issues/11649)) ([e803c6c](https://github.com/cube-js/cube/commit/e803c6cb58610c5da1a0710664a99d3047a6b3de)) +- **cubesql:** Prefer SQL pushdown over limitless post-processing ([#11559](https://github.com/cube-js/cube/issues/11559)) ([b022de1](https://github.com/cube-js/cube/commit/b022de166acefa29766c4760f81241e31cf9ac16)) +- **cubestore:** inline aggregate dropped rows past the first partition ([#11631](https://github.com/cube-js/cube/issues/11631)) ([6f3e66d](https://github.com/cube-js/cube/commit/6f3e66d4fcf89733a21d730d3e90fcb493a72dd0)) +- **schema-compiler:** a cube that extends another broke the parent's multi-stage measures ([#11641](https://github.com/cube-js/cube/issues/11641)) ([657f4e1](https://github.com/cube-js/cube/commit/657f4e18ae75c69dd4db4057e14867f8a7d91247)) + +### Features + +- **cubesql:** Support `COPY ... FROM STDIN` ([#11538](https://github.com/cube-js/cube/issues/11538)) ([534f839](https://github.com/cube-js/cube/commit/534f8392830df33b7934129cbcbe068984e42903)) + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Bug Fixes diff --git a/lerna.json b/lerna.json index 720149e2d0b99..ca0c93c498eb0 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.7.26", + "version": "1.7.27", "npmClient": "yarn", "command": { "bootstrap": { diff --git a/packages/cubejs-api-gateway/CHANGELOG.md b/packages/cubejs-api-gateway/CHANGELOG.md index 0aa7e1651b913..eabda1dd058a1 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/api-gateway + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 029c10694fbad..38a1ce078dbff 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.26", + "version": "1.7.27", "repository": { "type": "git", "url": "https://github.com/cube-js/cube.git", @@ -27,9 +27,9 @@ "dist/src/*" ], "dependencies": { - "@cubejs-backend/native": "1.7.26", - "@cubejs-backend/query-orchestrator": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/native": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@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.26", + "@cubejs-backend/linter": "1.7.27", "@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 845db75b18973..dc78153be4acf 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/athena-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 c2bd7fbb850ea..43ee64c2999d7 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26" + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "@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 f2d34bab27dbb..c7c2acc9bd6df 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/cloud + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 4b3111c2ad2aa..fabf31b9f54a8 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.26", + "version": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "@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.26", + "@cubejs-backend/shared": "1.7.27", "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 dd86abf1f6b57..408c7670cc0c7 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/maven + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 aea2e8c2f1a81..fc10cfae81702 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.26", + "version": "1.7.27", "license": "Apache-2.0", "repository": { "type": "git", @@ -31,12 +31,12 @@ "dist/src/*" ], "dependencies": { - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/shared": "1.7.27", "source-map-support": "^0.5.19", "xmlbuilder2": "^2.4.0" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 701861af2a30f..aed3734f9888d 100644 --- a/packages/cubejs-backend-native/CHANGELOG.md +++ b/packages/cubejs-backend-native/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +### Bug Fixes + +- **backend-native:** treat a client disconnect on /v1/cubesql as a graceful end ([#11649](https://github.com/cube-js/cube/issues/11649)) ([e803c6c](https://github.com/cube-js/cube/commit/e803c6cb58610c5da1a0710664a99d3047a6b3de)) + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 0173c85dcba94..6add5c1ec2237 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.26", + "version": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "@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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/cubesql": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@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 ffd5595085c51..1eead5215a522 100644 --- a/packages/cubejs-backend-shared/CHANGELOG.md +++ b/packages/cubejs-backend-shared/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/shared + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Features diff --git a/packages/cubejs-backend-shared/package.json b/packages/cubejs-backend-shared/package.json index b35f9be3be5a6..2e5a5144f9d9e 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.26", + "version": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "@types/bytes": "^3.1.5", "@types/cli-progress": "^3.9.1", "@types/jest": "^29", diff --git a/packages/cubejs-base-driver/CHANGELOG.md b/packages/cubejs-base-driver/CHANGELOG.md index a1960770bf16f..f9c03c4d70d2b 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/base-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Features diff --git a/packages/cubejs-base-driver/package.json b/packages/cubejs-base-driver/package.json index 90aea2c3b8bf7..dda5cc756bcae 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.26", + "version": "1.7.27", "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.26", + "@cubejs-backend/shared": "1.7.27", "@google-cloud/storage": "^7.13.0" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 a2b165c4ee68f..1b323d3e5bc6d 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/bigquery-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 9c5aa6af93aa2..be427c75837de 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.26", + "version": "1.7.27", "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.26", + "@cubejs-backend/base-driver": "1.7.27", "@cubejs-backend/dotenv": "^9.0.2", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/shared": "1.7.27", "@google-cloud/bigquery": "^7.7.0", "@google-cloud/storage": "^7.13.0", "ramda": "^0.27.2" }, "devDependencies": { - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/testing-shared": "1.7.27", "@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 8272183b715d3..96a54fd9078a2 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package cubejs-cli + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package cubejs-cli diff --git a/packages/cubejs-cli/package.json b/packages/cubejs-cli/package.json index 730e9e9d6584c..2cb5bfd135381 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.26", + "version": "1.7.27", "repository": { "type": "git", "url": "https://github.com/cube-js/cube.git", @@ -30,10 +30,10 @@ "LICENSE" ], "dependencies": { - "@cubejs-backend/cloud": "1.7.26", + "@cubejs-backend/cloud": "1.7.27", "@cubejs-backend/dotenv": "^9.0.2", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "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.26", - "@cubejs-backend/server": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/server": "1.7.27", "@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 5d16c298d5fd5..2d7838c010291 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/clickhouse-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 b6d891f939e5f..ccf2498ae8295 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "moment": "^2.24.0", "sqlstring": "^2.3.1", "uuid": "^11.1.1" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "@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 e2cc3e94973ed..44fb3ee8ef4e6 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/core + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 4d96750368678..ba8a45356a865 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.26", + "version": "1.7.27", "engines": {}, "type": "module", "repository": { @@ -58,7 +58,7 @@ ], "license": "MIT", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 21ba9e1849985..30c531fc211ae 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/dx + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 8813e7f7a1019..48f91965efb86 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.26", + "version": "1.7.27", "engines": {}, "repository": { "type": "git", diff --git a/packages/cubejs-client-ngx/CHANGELOG.md b/packages/cubejs-client-ngx/CHANGELOG.md index 597e74a30a6fd..32f829c6b4da6 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/ngx + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 d7729c88aef00..136f9a492a703 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.26", + "version": "1.7.27", "author": "Cube Dev, Inc.", "engines": {}, "repository": { diff --git a/packages/cubejs-client-react/CHANGELOG.md b/packages/cubejs-client-react/CHANGELOG.md index 31d0ddb9e48e3..d27f87eab87d9 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/react + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 4c157e562ce7a..2e04b912c69ab 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.26", + "version": "1.7.27", "author": "Cube Dev, Inc.", "license": "MIT", "engines": {}, @@ -26,7 +26,7 @@ ], "dependencies": { "@babel/runtime": "^7.1.2", - "@cubejs-client/core": "1.7.26", + "@cubejs-client/core": "1.7.27", "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 66f4a3457ad06..8bf7974e71c84 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/vue3 + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 a3a3b7f20bfa4..f5e96384ed8fc 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.26", + "version": "1.7.27", "engines": {}, "repository": { "type": "git", @@ -27,7 +27,7 @@ "src" ], "dependencies": { - "@cubejs-client/core": "1.7.26", + "@cubejs-client/core": "1.7.27", "ramda": "^0.27.0" }, "devDependencies": { diff --git a/packages/cubejs-client-ws-transport/CHANGELOG.md b/packages/cubejs-client-ws-transport/CHANGELOG.md index 905ce5b80ab34..2fe08dcaa30ef 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/ws-transport + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 57129687d2ecf..b01f2d565e935 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.26", + "version": "1.7.27", "engines": {}, "repository": { "type": "git", @@ -20,7 +20,7 @@ }, "dependencies": { "@babel/runtime": "^7.1.2", - "@cubejs-client/core": "1.7.26", + "@cubejs-client/core": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "@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 bb70d8bc736ad..6c95a6785b5fc 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/crate-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 433dd2b1fc476..daed222cc526c 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26" + "@cubejs-backend/postgres-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "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 7b515dd690ecb..62476e9e521ab 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/cubestore-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Features diff --git a/packages/cubejs-cubestore-driver/package.json b/packages/cubejs-cubestore-driver/package.json index 41a5bd59e052e..8cb61a624913d 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.26", + "version": "1.7.27", "repository": { "type": "git", "url": "https://github.com/cube-js/cube.git", @@ -26,10 +26,10 @@ "lint:fix": "eslint --fix src/*.ts" }, "dependencies": { - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/cubestore": "1.7.26", - "@cubejs-backend/native": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/cubestore": "1.7.27", + "@cubejs-backend/native": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "csv-write-stream": "^2.0.0", "flatbuffers": "25.9.23", "fs-extra": "^9.1.0", @@ -40,7 +40,7 @@ "ws": "^7.4.3" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 dc093fed8cc83..053ab6ffbab45 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/databricks-jdbc-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 9aef4a00689ab..43ff6bcbc63f1 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.26", + "version": "1.7.27", "license": "Apache-2.0", "repository": { "type": "git", @@ -30,17 +30,17 @@ "bin" ], "dependencies": { - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/jdbc-driver": "1.7.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/jdbc-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "@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 4479b785e5284..65d77e2bbc650 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/dbt-schema-extension + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 96543bc076689..f4dd77b87abf9 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.26", + "version": "1.7.27", "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.26", + "@cubejs-backend/schema-compiler": "1.7.27", "fs-extra": "^9.1.0", "inflection": "^1.12.0", "node-fetch": "^2.6.1" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing": "1.7.27", "@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 b0e8c478ef8a3..4f71ca392e28f 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/docker + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-backend/docker diff --git a/packages/cubejs-docker/package.json b/packages/cubejs-docker/package.json index 0a94c141bcf8c..72523ff40b5ea 100644 --- a/packages/cubejs-docker/package.json +++ b/packages/cubejs-docker/package.json @@ -1,6 +1,6 @@ { "name": "@cubejs-backend/docker", - "version": "1.7.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/bigquery-driver": "1.7.26", - "@cubejs-backend/clickhouse-driver": "1.7.26", - "@cubejs-backend/crate-driver": "1.7.26", - "@cubejs-backend/databricks-jdbc-driver": "1.7.26", - "@cubejs-backend/dbt-schema-extension": "1.7.26", - "@cubejs-backend/dremio-driver": "1.7.26", - "@cubejs-backend/druid-driver": "1.7.26", - "@cubejs-backend/duckdb-driver": "1.7.26", - "@cubejs-backend/firebolt-driver": "1.7.26", - "@cubejs-backend/hive-driver": "1.7.26", - "@cubejs-backend/ksql-driver": "1.7.26", - "@cubejs-backend/materialize-driver": "1.7.26", - "@cubejs-backend/mongobi-driver": "1.7.26", - "@cubejs-backend/mssql-driver": "1.7.26", - "@cubejs-backend/mysql-driver": "1.7.26", - "@cubejs-backend/oracle-driver": "1.7.26", - "@cubejs-backend/pinot-driver": "1.7.26", - "@cubejs-backend/postgres-driver": "1.7.26", - "@cubejs-backend/prestodb-driver": "1.7.26", - "@cubejs-backend/questdb-driver": "1.7.26", - "@cubejs-backend/redshift-driver": "1.7.26", - "@cubejs-backend/server": "1.7.26", - "@cubejs-backend/snowflake-driver": "1.7.26", - "@cubejs-backend/sqlite-driver": "1.7.26", - "@cubejs-backend/trino-driver": "1.7.26", - "@cubejs-backend/vertica-driver": "1.7.26", - "cubejs-cli": "1.7.26", + "@cubejs-backend/athena-driver": "1.7.27", + "@cubejs-backend/bigquery-driver": "1.7.27", + "@cubejs-backend/clickhouse-driver": "1.7.27", + "@cubejs-backend/crate-driver": "1.7.27", + "@cubejs-backend/databricks-jdbc-driver": "1.7.27", + "@cubejs-backend/dbt-schema-extension": "1.7.27", + "@cubejs-backend/dremio-driver": "1.7.27", + "@cubejs-backend/druid-driver": "1.7.27", + "@cubejs-backend/duckdb-driver": "1.7.27", + "@cubejs-backend/firebolt-driver": "1.7.27", + "@cubejs-backend/hive-driver": "1.7.27", + "@cubejs-backend/ksql-driver": "1.7.27", + "@cubejs-backend/materialize-driver": "1.7.27", + "@cubejs-backend/mongobi-driver": "1.7.27", + "@cubejs-backend/mssql-driver": "1.7.27", + "@cubejs-backend/mysql-driver": "1.7.27", + "@cubejs-backend/oracle-driver": "1.7.27", + "@cubejs-backend/pinot-driver": "1.7.27", + "@cubejs-backend/postgres-driver": "1.7.27", + "@cubejs-backend/prestodb-driver": "1.7.27", + "@cubejs-backend/questdb-driver": "1.7.27", + "@cubejs-backend/redshift-driver": "1.7.27", + "@cubejs-backend/server": "1.7.27", + "@cubejs-backend/snowflake-driver": "1.7.27", + "@cubejs-backend/sqlite-driver": "1.7.27", + "@cubejs-backend/trino-driver": "1.7.27", + "@cubejs-backend/vertica-driver": "1.7.27", + "cubejs-cli": "1.7.27", "typescript": "~5.2.2" }, "resolutions": { diff --git a/packages/cubejs-dremio-driver/CHANGELOG.md b/packages/cubejs-dremio-driver/CHANGELOG.md index f41ce16a93ec8..c48a43e5d42c5 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/dremio-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 562ad55c8df75..531adf3f7cb76 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "axios": "^1.8.3" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "jest": "^29" }, "license": "Apache-2.0", diff --git a/packages/cubejs-druid-driver/CHANGELOG.md b/packages/cubejs-druid-driver/CHANGELOG.md index 91dddd6852bd4..bcd80e2de0def 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/druid-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 93b92cebe9ff2..3026bf2187d91 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.26", + "version": "1.7.27", "license": "Apache-2.0", "repository": { "type": "git", @@ -28,13 +28,13 @@ "dist/src/*" ], "dependencies": { - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "axios": "^1.8.3" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 1569068c897f9..abe2bad845565 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/duckdb-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 1f91f1f8c7685..e4a578538d120 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "duckdb": "^1.4.1" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "@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 71bb906216d6a..0f06bd44d9f04 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/firebolt-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 9bac3b7fc7888..f6be80adc7467 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "firebolt-sdk": "1.10.0" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "typescript": "~5.2.2" }, "publishConfig": { diff --git a/packages/cubejs-hive-driver/CHANGELOG.md b/packages/cubejs-hive-driver/CHANGELOG.md index 44e314a6f8626..db347e65440e9 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/hive-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 8eb308a5234c0..002911ad2f84f 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "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.26" + "@cubejs-backend/linter": "1.7.27" }, "publishConfig": { "access": "public" diff --git a/packages/cubejs-jdbc-driver/CHANGELOG.md b/packages/cubejs-jdbc-driver/CHANGELOG.md index 595c1b79a940d..42fbda5675168 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/jdbc-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 732e01b61aa98..90e1f7eff4769 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.26", + "version": "1.7.27", "repository": { "type": "git", "url": "https://github.com/cube-js/cube.git", @@ -26,9 +26,9 @@ "index.js" ], "dependencies": { - "@cubejs-backend/base-driver": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", "@cubejs-backend/node-java-maven": "^0.1.3", - "@cubejs-backend/shared": "1.7.26" + "@cubejs-backend/shared": "1.7.27" }, "optionalDependencies": { "@cubejs-backend/jdbc": "^0.9.0", @@ -42,7 +42,7 @@ "testEnvironment": "node" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@types/node": "^22", "typescript": "~5.2.2" } diff --git a/packages/cubejs-ksql-driver/CHANGELOG.md b/packages/cubejs-ksql-driver/CHANGELOG.md index 6d44a31b2560c..df0cae67705d3 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/ksql-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 fdbf79ea4ed6f..890bebc780389 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "typescript": "~5.2.2" } } diff --git a/packages/cubejs-linter/CHANGELOG.md b/packages/cubejs-linter/CHANGELOG.md index 94948ab77553f..3282e36658616 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/linter + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-backend/linter diff --git a/packages/cubejs-linter/package.json b/packages/cubejs-linter/package.json index 0ac40a7201ef6..bcf436e7c1a9d 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.26", + "version": "1.7.27", "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 174cd54a021a6..08ba06d695699 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/materialize-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 9b1b2e073d778..f6d8a5a1f6cb6 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/postgres-driver": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/postgres-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "semver": "^7.6.3" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing": "1.7.27", "typescript": "~5.2.2" }, "publishConfig": { diff --git a/packages/cubejs-mongobi-driver/CHANGELOG.md b/packages/cubejs-mongobi-driver/CHANGELOG.md index 33a242b9eac65..1cfb8a0c2905b 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/mongobi-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 c50fc8c9a264e..1531c40ef1a43 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@types/node": "^22", "moment": "^2.29.1", "mysql2": "^3.11.5" @@ -38,7 +38,7 @@ "access": "public" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "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 f444830adaf56..a1ed20066cad3 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/mssql-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 2a16b5b0d948d..bca390144ac1e 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "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 072ee9c551c5b..71d3e0542ebe8 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/mysql-aurora-serverless-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 8327b9ff39db9..751f7984415c4 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@types/mysql": "^2.15.15", "aws-sdk": "^2.787.0", "data-api-client": "^1.1.0" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 28b1f95946ee1..9764335438f1f 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/mysql-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 6de25bd9d92ec..8fc97a6aed142 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "mysql2": "^3.16.1" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "@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 acba2afc9be5e..54ffc9154e3ec 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/oracle-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 7aa76436df20b..ba7b718b2cca4 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "ramda": "^0.27.0" }, "devDependencies": { diff --git a/packages/cubejs-pinot-driver/CHANGELOG.md b/packages/cubejs-pinot-driver/CHANGELOG.md index f095f3a319063..2d632f4e3f1c5 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/pinot-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 56773972473fe..f4b1ccacc9d3c 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "node-fetch": "^2.6.1", "ramda": "^0.27.2" }, @@ -39,7 +39,7 @@ "access": "public" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@types/jest": "^29", "jest": "^29", "should": "^13.2.3", diff --git a/packages/cubejs-playground/CHANGELOG.md b/packages/cubejs-playground/CHANGELOG.md index 113bbe1e85e17..d7d581fec092d 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-client/playground + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-client/playground diff --git a/packages/cubejs-playground/package.json b/packages/cubejs-playground/package.json index 9e298c93f6961..db613bde80caf 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.26", + "version": "1.7.27", "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.26", - "@cubejs-client/react": "1.7.26", + "@cubejs-client/core": "1.7.27", + "@cubejs-client/react": "1.7.27", "@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 751b4c509a9e7..ca607a388629d 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/postgres-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 1b012e469ae3e..9dcc61a593613 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@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.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "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 5d91857bb9ae0..3b90a03a0eaf8 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/prestodb-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 f9f22613adcc3..299d712441a16 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "presto-client": "1.2.0", "ramda": "^0.27.0" }, @@ -38,7 +38,7 @@ "access": "public" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 92391f70bdb53..323fa211865be 100644 --- a/packages/cubejs-query-orchestrator/CHANGELOG.md +++ b/packages/cubejs-query-orchestrator/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/query-orchestrator + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Features diff --git a/packages/cubejs-query-orchestrator/package.json b/packages/cubejs-query-orchestrator/package.json index 35f95486d71ce..8c5dd1d79ef19 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.26", + "version": "1.7.27", "repository": { "type": "git", "url": "https://github.com/cube-js/cube.git", @@ -30,15 +30,15 @@ "dist/src/*" ], "dependencies": { - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/cubestore-driver": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/cubestore-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "csv-write-stream": "^2.0.0", "lru-cache": "^11.1.0", "ramda": "^0.27.2" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@types/jest": "^29", "@types/node": "^22", "@types/ramda": "^0.27.32", diff --git a/packages/cubejs-questdb-driver/CHANGELOG.md b/packages/cubejs-questdb-driver/CHANGELOG.md index fefba38b24638..a9a0a210771ca 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/questdb-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 7cb5367eeb164..803b3e0c1212c 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@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.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "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 a1bc797192e93..b70f383023689 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/redshift-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 a40b7c9b84e75..2d3c3468e3354 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/postgres-driver": "1.7.26", - "@cubejs-backend/shared": "1.7.26" + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/postgres-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "typescript": "~5.2.2" }, "publishConfig": { diff --git a/packages/cubejs-schema-compiler/CHANGELOG.md b/packages/cubejs-schema-compiler/CHANGELOG.md index f4845fd91abe7..71ae6ab9fa685 100644 --- a/packages/cubejs-schema-compiler/CHANGELOG.md +++ b/packages/cubejs-schema-compiler/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +### Bug Fixes + +- **schema-compiler:** a cube that extends another broke the parent's multi-stage measures ([#11641](https://github.com/cube-js/cube/issues/11641)) ([657f4e1](https://github.com/cube-js/cube/commit/657f4e18ae75c69dd4db4057e14867f8a7d91247)) + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Bug Fixes diff --git a/packages/cubejs-schema-compiler/package.json b/packages/cubejs-schema-compiler/package.json index 640969ba19ff3..3f7833bee51fd 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/native": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "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.26", - "@cubejs-backend/mssql-driver": "1.7.26", - "@cubejs-backend/query-orchestrator": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/mssql-driver": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", "@types/babel__code-frame": "^7.0.6", "@types/babel__generator": "^7.6.8", "@types/babel__traverse": "^7.20.5", diff --git a/packages/cubejs-server-core/CHANGELOG.md b/packages/cubejs-server-core/CHANGELOG.md index ee520e86fe188..7429bc10d2e73 100644 --- a/packages/cubejs-server-core/CHANGELOG.md +++ b/packages/cubejs-server-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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/server-core + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Features diff --git a/packages/cubejs-server-core/package.json b/packages/cubejs-server-core/package.json index e3f63cc47141d..ac2cab1603083 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/cloud": "1.7.26", - "@cubejs-backend/cubestore-driver": "1.7.26", + "@cubejs-backend/api-gateway": "1.7.27", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/cloud": "1.7.27", + "@cubejs-backend/cubestore-driver": "1.7.27", "@cubejs-backend/dotenv": "^9.0.2", - "@cubejs-backend/native": "1.7.26", - "@cubejs-backend/query-orchestrator": "1.7.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", - "@cubejs-backend/templates": "1.7.26", + "@cubejs-backend/native": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", + "@cubejs-backend/templates": "1.7.27", "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.26", - "@cubejs-client/playground": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-client/playground": "1.7.27", "@types/cross-spawn": "^6.0.2", "@types/express": "^4.17.21", "@types/fs-extra": "^9.0.8", diff --git a/packages/cubejs-server/CHANGELOG.md b/packages/cubejs-server/CHANGELOG.md index b05544cda3056..3319b8bb6f468 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/server + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-backend/server diff --git a/packages/cubejs-server/package.json b/packages/cubejs-server/package.json index e9b208195a197..24a63fbe17002 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.26", + "version": "1.7.27", "types": "index.d.ts", "repository": { "type": "git", @@ -40,11 +40,11 @@ "jest:shapshot": "jest --updateSnapshot test" }, "dependencies": { - "@cubejs-backend/cubestore-driver": "1.7.26", + "@cubejs-backend/cubestore-driver": "1.7.27", "@cubejs-backend/dotenv": "^9.0.2", - "@cubejs-backend/native": "1.7.26", - "@cubejs-backend/server-core": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/native": "1.7.27", + "@cubejs-backend/server-core": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@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.26", - "@cubejs-backend/query-orchestrator": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", "@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 f8460aab737cd..0e5425ea53886 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/snowflake-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 0c2a10f3a89a9..2565ea174ec9d 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "snowflake-sdk": "^2.4.0" }, "license": "Apache-2.0", @@ -41,7 +41,7 @@ "extends": "../cubejs-linter" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "typescript": "~5.2.2", "vitest": "^4" } diff --git a/packages/cubejs-sqlite-driver/CHANGELOG.md b/packages/cubejs-sqlite-driver/CHANGELOG.md index 5aaabc4af61bf..5f4de4cf71311 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/sqlite-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 ede80338c7057..08d93e90f705e 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.26", + "version": "1.7.27", "repository": { "type": "git", "url": "https://github.com/cube-js/cube.git", @@ -18,13 +18,13 @@ "unit": "jest" }, "dependencies": { - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "sqlite3": "^5.1.7" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "jest": "^29" }, "publishConfig": { diff --git a/packages/cubejs-templates/CHANGELOG.md b/packages/cubejs-templates/CHANGELOG.md index 8046deb546f72..2e30d5698b4b7 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/templates + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-backend/templates diff --git a/packages/cubejs-templates/package.json b/packages/cubejs-templates/package.json index 45f93fd19abfb..3831eb914013f 100644 --- a/packages/cubejs-templates/package.json +++ b/packages/cubejs-templates/package.json @@ -1,6 +1,6 @@ { "name": "@cubejs-backend/templates", - "version": "1.7.26", + "version": "1.7.27", "description": "Cube.js Templates helpers", "author": "Cube Dev, Inc.", "repository": { @@ -31,7 +31,7 @@ "extends": "../cubejs-linter" }, "dependencies": { - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/shared": "1.7.27", "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.26", + "@cubejs-backend/linter": "1.7.27", "typescript": "~5.2.2" } } diff --git a/packages/cubejs-testing-drivers/CHANGELOG.md b/packages/cubejs-testing-drivers/CHANGELOG.md index d2c4e9ca4f048..214e193110e57 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/testing-drivers + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 8aa4a6f49f549..c70c2b3513fe1 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.26", + "version": "1.7.27", "description": "Cube.js drivers test suite", "author": "Cube Dev, Inc.", "repository": { @@ -87,29 +87,29 @@ "dist/src" ], "dependencies": { - "@cubejs-backend/athena-driver": "1.7.26", - "@cubejs-backend/base-driver": "1.7.26", - "@cubejs-backend/bigquery-driver": "1.7.26", - "@cubejs-backend/clickhouse-driver": "1.7.26", - "@cubejs-backend/crate-driver": "1.7.26", - "@cubejs-backend/cubestore-driver": "1.7.26", - "@cubejs-backend/databricks-jdbc-driver": "1.7.26", + "@cubejs-backend/athena-driver": "1.7.27", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/bigquery-driver": "1.7.27", + "@cubejs-backend/clickhouse-driver": "1.7.27", + "@cubejs-backend/crate-driver": "1.7.27", + "@cubejs-backend/cubestore-driver": "1.7.27", + "@cubejs-backend/databricks-jdbc-driver": "1.7.27", "@cubejs-backend/dotenv": "^9.0.2", - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/mssql-driver": "1.7.26", - "@cubejs-backend/mysql-driver": "1.7.26", - "@cubejs-backend/oracle-driver": "1.7.26", - "@cubejs-backend/pinot-driver": "1.7.26", - "@cubejs-backend/postgres-driver": "1.7.26", - "@cubejs-backend/query-orchestrator": "1.7.26", - "@cubejs-backend/questdb-driver": "1.7.26", - "@cubejs-backend/server-core": "1.7.26", - "@cubejs-backend/shared": "1.7.26", - "@cubejs-backend/snowflake-driver": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", - "@cubejs-backend/trino-driver": "1.7.26", - "@cubejs-client/core": "1.7.26", - "@cubejs-client/ws-transport": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/mssql-driver": "1.7.27", + "@cubejs-backend/mysql-driver": "1.7.27", + "@cubejs-backend/oracle-driver": "1.7.27", + "@cubejs-backend/pinot-driver": "1.7.27", + "@cubejs-backend/postgres-driver": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", + "@cubejs-backend/questdb-driver": "1.7.27", + "@cubejs-backend/server-core": "1.7.27", + "@cubejs-backend/shared": "1.7.27", + "@cubejs-backend/snowflake-driver": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", + "@cubejs-backend/trino-driver": "1.7.27", + "@cubejs-client/core": "1.7.27", + "@cubejs-client/ws-transport": "1.7.27", "@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 ac4cce20eb2d3..715c417e56823 100644 --- a/packages/cubejs-testing-shared/CHANGELOG.md +++ b/packages/cubejs-testing-shared/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/testing-shared + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 4f455dd4ac173..3ea08e3f76190 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/query-orchestrator": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "@testcontainers/kafka": "~10.28.0", "dedent": "^0.7.0", "node-fetch": "^2.6.7", "testcontainers": "^10.28.0" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 3cc03efd116a0..7060e51c7eb4f 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/testing + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-backend/testing diff --git a/packages/cubejs-testing/package.json b/packages/cubejs-testing/package.json index 7c757bd73b02e..7ebda6080aaab 100644 --- a/packages/cubejs-testing/package.json +++ b/packages/cubejs-testing/package.json @@ -1,6 +1,6 @@ { "name": "@cubejs-backend/testing", - "version": "1.7.26", + "version": "1.7.27", "description": "Cube.js e2e tests", "author": "Cube Dev, Inc.", "repository": { @@ -91,15 +91,15 @@ "birdbox-fixtures" ], "dependencies": { - "@cubejs-backend/cubestore-driver": "1.7.26", + "@cubejs-backend/cubestore-driver": "1.7.27", "@cubejs-backend/dotenv": "^9.0.2", - "@cubejs-backend/ksql-driver": "1.7.26", - "@cubejs-backend/postgres-driver": "1.7.26", - "@cubejs-backend/query-orchestrator": "1.7.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", - "@cubejs-client/ws-transport": "1.7.26", + "@cubejs-backend/ksql-driver": "1.7.27", + "@cubejs-backend/postgres-driver": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", + "@cubejs-client/ws-transport": "1.7.27", "dedent": "^0.7.0", "fs-extra": "^8.1.0", "http-proxy": "^1.18.1", @@ -110,8 +110,8 @@ }, "devDependencies": { "@4tw/cypress-drag-drop": "^1.6.0", - "@cubejs-backend/linter": "1.7.26", - "@cubejs-client/core": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-client/core": "1.7.27", "@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 d6faace9c2fd3..5825b2f0ef28a 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/trino-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 a5eb6b0c07541..7947a673691dd 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/prestodb-driver": "1.7.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/prestodb-driver": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "node-fetch": "^2.6.1", "presto-client": "^1.2.0" }, @@ -40,7 +40,7 @@ "access": "public" }, "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@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 0504968199e12..85f5b77ffbed2 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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +**Note:** Version bump only for package @cubejs-backend/vertica-driver + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **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 2093092eb870d..e40c95dcf142d 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.26", + "version": "1.7.27", "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.26", - "@cubejs-backend/query-orchestrator": "1.7.26", - "@cubejs-backend/schema-compiler": "1.7.26", - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/base-driver": "1.7.27", + "@cubejs-backend/query-orchestrator": "1.7.27", + "@cubejs-backend/schema-compiler": "1.7.27", + "@cubejs-backend/shared": "1.7.27", "vertica-nodejs": "^1.0.3" }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", - "@cubejs-backend/testing-shared": "1.7.26", + "@cubejs-backend/linter": "1.7.27", + "@cubejs-backend/testing-shared": "1.7.27", "@types/jest": "^29", "jest": "^29", "testcontainers": "^10.28.0" diff --git a/rust/cubesql/CHANGELOG.md b/rust/cubesql/CHANGELOG.md index d7b36c4a01f98..70640821c287e 100644 --- a/rust/cubesql/CHANGELOG.md +++ b/rust/cubesql/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +### Bug Fixes + +- **cubesql:** Prefer SQL pushdown over limitless post-processing ([#11559](https://github.com/cube-js/cube/issues/11559)) ([b022de1](https://github.com/cube-js/cube/commit/b022de166acefa29766c4760f81241e31cf9ac16)) + +### Features + +- **cubesql:** Support `COPY ... FROM STDIN` ([#11538](https://github.com/cube-js/cube/issues/11538)) ([534f839](https://github.com/cube-js/cube/commit/534f8392830df33b7934129cbcbe068984e42903)) + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) **Note:** Version bump only for package @cubejs-backend/cubesql diff --git a/rust/cubesql/package.json b/rust/cubesql/package.json index 859f718826eec..0438d17f69b34 100644 --- a/rust/cubesql/package.json +++ b/rust/cubesql/package.json @@ -1,6 +1,6 @@ { "name": "@cubejs-backend/cubesql", - "version": "1.7.26", + "version": "1.7.27", "description": "SQL API for Cube as proxy over MySQL protocol.", "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" diff --git a/rust/cubestore/CHANGELOG.md b/rust/cubestore/CHANGELOG.md index 7b6c74e5ef027..81ce3ccd43421 100644 --- a/rust/cubestore/CHANGELOG.md +++ b/rust/cubestore/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.27](https://github.com/cube-js/cube/compare/v1.7.26...v1.7.27) (2026-08-26) + +### Bug Fixes + +- **cubestore:** inline aggregate dropped rows past the first partition ([#11631](https://github.com/cube-js/cube/issues/11631)) ([6f3e66d](https://github.com/cube-js/cube/commit/6f3e66d4fcf89733a21d730d3e90fcb493a72dd0)) + ## [1.7.26](https://github.com/cube-js/cube/compare/v1.7.25...v1.7.26) (2026-08-24) ### Bug Fixes diff --git a/rust/cubestore/Cargo.lock b/rust/cubestore/Cargo.lock index bfbfca08c7543..7571451e9c16f 100644 --- a/rust/cubestore/Cargo.lock +++ b/rust/cubestore/Cargo.lock @@ -1445,7 +1445,7 @@ dependencies = [ [[package]] name = "cubestore" -version = "1.7.26" +version = "1.7.27" dependencies = [ "actix-rt", "anyhow", diff --git a/rust/cubestore/cubestore/Cargo.toml b/rust/cubestore/cubestore/Cargo.toml index 84baf085915f5..161d1d17d9e30 100644 --- a/rust/cubestore/cubestore/Cargo.toml +++ b/rust/cubestore/cubestore/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cubestore" -version = "1.7.26" +version = "1.7.27" authors = ["Cube Dev, Inc."] edition = "2021" license = "Apache-2.0" diff --git a/rust/cubestore/package.json b/rust/cubestore/package.json index e76557833fd8e..5d350f17211d9 100644 --- a/rust/cubestore/package.json +++ b/rust/cubestore/package.json @@ -1,6 +1,6 @@ { "name": "@cubejs-backend/cubestore", - "version": "1.7.26", + "version": "1.7.27", "description": "Cube.js pre-aggregation storage layer.", "main": "dist/src/index.js", "typings": "dist/src/index.d.ts", @@ -33,7 +33,7 @@ }, "license": "Apache-2.0", "devDependencies": { - "@cubejs-backend/linter": "1.7.26", + "@cubejs-backend/linter": "1.7.27", "@types/jest": "^29", "@types/node": "^18", "jest": "^29", @@ -43,7 +43,7 @@ "access": "public" }, "dependencies": { - "@cubejs-backend/shared": "1.7.26", + "@cubejs-backend/shared": "1.7.27", "@octokit/core": "^3.2.5", "source-map-support": "^0.5.19" }, From 2aba3ac6d15b3f6885df952f3b0380dbbbd5a31d Mon Sep 17 00:00:00 2001 From: Pavel Tiunov Date: Wed, 26 Aug 2026 12:10:13 -0700 Subject: [PATCH 3/4] feat(cubesql): Push UNION down to the data source (#11651) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test(cubesql): Cover UNION of SELECT DISTINCTs in limitless post processing A UNION of two SELECT DISTINCTs over different cubes cannot be pushed down: the branches read different cubes, so the UNION only runs in DataFusion, and the per-branch DISTINCTs collapse into the one above it, leaving each branch an ungrouped scan of raw rows. Pin that shape - the plan it compiles to by default, that the check rejects it, that grouping each branch does not change the verdict, and that a limit on each branch does. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(cubesql): Pin where an outer limit reaches a union's branches UnionSortLimitPushDown copies a limit above a UNION into each of its inputs, so UNION ALL under a limit ends up with bounded scans. A plain UNION dedups above the branches, the limit cannot move through it, and the branches stay unlimited. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * feat(cubesql): Push UNION down to the data source A UNION of queries that all reach the same data source had no representation in the wrapper, so the set operation always ran in DataFusion on top of Cube queries the row limit had already truncated. `SELECT DISTINCT ... UNION SELECT DISTINCT ...` over two views is the shape this shows up as, and it answers with values silently missing. Add a WrappedUnion node the rewriter can put a union into, a rule that moves the wrappers of every query into one wrapper around them, and a rule that folds the DISTINCT of a plain UNION into it rather than leaving the deduplication above. Anything above the union - a projection, a filter - is then pushed into a select that reads from it, and the row cap bounds the result of the whole operation instead of each query. Queries that reach different data sources are left alone: one data source cannot evaluate a set operation over another's rows. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * fix(cubesql): Pass assert messages as format arguments The crate is on the 2018 edition, where an inline argument in a panic message is not interpolated, and clippy rejects it. Also render the row cap of a pushed down union in the dialects that have no LIMIT: T-SQL reads the set operation through a derived table with TOP, Oracle ends it with FETCH NEXT. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * fix(cubesql): Only push a union down where the data source can render it Gate the rule on the data source having a union template, the way the join and subquery rules gate on theirs. Without it a data source with no template fails at SQL generation, where the plan is already chosen and there is no way back to post processing. Give ClickHouse a template of its own: it rejects a bare UNION unless union_default_mode is set, so the set operation has to name which one it is. Read the e-graph so the rule fails closed: an input list is only read when its e-class holds one list, and an input's data source only when every way of wrapping it agrees on the same one, rather than committing to whichever representation comes first. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(cubesql): Cover joining against a pushed down union Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * fix(cubesql): Give every dialect a union it can parse, or none at all BigQuery reads a bare UNION as a parse error the way ClickHouse does: GoogleSQL wants the set operator to name its mode. Give it the same template. SQLite takes no parenthesised operands in a compound select, Druid has no UNION of distinct rows, and ksqlDB has no set operations at all. Drop the template in those three: the rule only pushes a union down where a template says the data source can render one, so they keep doing what they do today and leave it to post processing. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(cubesql): Pin that the join reads the union as its subquery The assertion held on any SQL that mentioned a union anywhere, so a join that lost its union, or a union that lost its join, would both have passed. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(schema-compiler): Cover the union template of every dialect Seven dialects now decide something about statements/union - four write their own, three drop it - and nothing pinned any of it. Read the templates off the adapter directory rather than a list, so a dialect added later cannot escape the invariants: every query rendered once, the row cap rendered, ALL on the branch that keeps duplicates and no other, and blocks that close. A missing endif and a renamed loop variable both fail it. Druid and ksqlDB drop the template in their own packages and are not covered here. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(schema-compiler): Assert the union template renders what it loops over The per-dialect assertions pinned the loop and the limit guard but neither interpolation, so a template that rendered the operator, the parentheses and a LIMIT while dropping the query body satisfied all of them - under a test named for rendering every query. Pin both, and pin every ALL to the branch that keeps duplicates rather than to its presence anywhere in the string. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(schema-compiler): Share one dialect scan between the tests that need it Two copies of "read the adapter directory so a dialect added later cannot escape this" is one copy too many. Move it to test/unit/allDialects.ts, returning each dialect with its name so a failure says which one, and let positional-params drop the names it does not use. Also name the assumption the union template test rests on: it reads templates off a bare prototype, which holds for a template a dialect writes unconditionally and would not for one gated on instance state. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(schema-compiler): assert the union template names the operator Tightening the `ALL` placement check dropped the only assertion that the word `UNION` appears at all, so a template rendering `(q1)\nALL (q2)` passed every assertion in a file about the union operator. Assert it, and make the loop and tag-balance patterns tolerate a tag written without a space after the opener. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(schema-compiler): name the dialect floor and drop a wrapper alias The floor message interpolated the count it found rather than the one it wanted, so a scan that matched three dialects reported "more dialects than 3" without saying how many were expected. Name the threshold in both the constant and the message. In the positional-params caller, the local one-call wrapper discarded each dialect's name and then recovered it from `QueryClass.name`; filter and map over the pairs instead. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * refactor(cubesql): Read the union input list the way the converter does `list_node_ids` walked `UnionInputs` as cons cells and declined anything else, while `match_list_node_ids!` — which the converter uses to read this same list — recurses and treats any non-list node as an element. The cons shape is only what `add_plan_list_node!` happens to build today, so the rule was coupled to a detail the reader on the other side does not assume. Mirror that traversal, and use `var_list_iter!` rather than an open-coded `filter_map`. The guards stay: an e-class holding more than one `UnionInputs` still fails closed, since picking one would drop or reorder the queries of the union, and a self-containing list still terminates. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * docs(cubesql): Record how rewrite rules must traverse lists Every matcher should match one level, and lists are consumed by dedicated push-down/pull-up rules that peel one cons cell at a time. Write down that rule, the helpers that generate the traversal, and why an imperative reader over an e-class is the wrong shape: an e-class holds many representations, so picking one is arbitrary, and the cons shape is an implementation detail of how the list was built. Also record that `wrapper-subqueries-wrapped-scan-to-pull` re-contexts a pushdown replacer without comparing input data sources, so unification on a shared pattern variable does not by itself guarantee agreement for plan-level list elements. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * refactor(cubesql): Traverse the union input list with rewrite rules The rule read `UnionInputs` by walking it in a transform, which is not how lists are consumed here: every matcher should match one level, and a list is peeled one cons cell at a time by dedicated rules. Split it into a push-down rule that matches the union and the head of its list, a pull-up rule that peels one query per application, and a tail rule for the terminal, and drop `list_node_ids` and `wrapped_input` entirely. The queries of a union arrive already pulled up, so the list carries a pull-up replacer rather than a push-down one. A push-down replacer over a finished wrapper is the subquery path's shape, and reaching it here would have matched `wrapper-subqueries-wrapped-scan-to-pull`, which re-contexts an element without comparing input data sources. Data sources now agree by unification instead of by comparison: the head binds `?input_data_source`, and the pull-up rule shares that variable between each query's own context and the list's, so a query reaching another source leaves the list unconsumed and the post processing plan outprices it. Record the rule in CLAUDE.md. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * docs(cubesql): Record that e-graph lists are flat, not head/tail Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * refactor(cubesql): Make the union input list flat `UnionInputs` was built as cons cells by `add_plan_list_node!`, and the rules walked it one cell at a time. Head/tail lists are legacy here, so build it flat — one node holding every query — and match the whole list in one rule. The union now needs a single rule rather than three. It reads every query out of the list at once and unwraps each into the set operation, with `?input_data_source` as a top level element variable so the queries have to agree on a data source for the rule to match at all. Nothing compares data sources any more, and there is no cons walk left to get wrong. That rule needs a transform for what a pattern cannot spell out: the alias converted from `UnionAlias` to `WrappedUnionAlias`, the cleared context, and the union template check. So add `transforming_list_rewrite_with_lists_and_vars`, and run the transform inside `ListNodeApplier` once the substitution carries the list's own variables — wrapping the applier from outside is too early, as the elements' variables are merged in by the applier itself. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * test(cubesql): Pin that a post-processed union keeps every query `UnionInputs` is flat now, and the converter reads it back with `match_list_node_ids!`. That reader is shape agnostic, but nothing pinned it above two queries — where flat and cons actually differ — and the existing no-template test only asserted the plan is still a `Union`, not how many queries survived. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao * fix(cubesql): Restore the two query minimum and the applier var check Three review findings, all on the flat list rework. A single query is not a union. Moving the list walk into the pattern dropped the `inputs.len() < 2` guard the transform used to carry, and with one query `wrapper-push-down-distinct-to-union` folds the `Distinct` in while the template emits no operator at all — the deduplication would go silently missing, which is the failure this PR exists to fix. Express it where the matching happens: `ListNodeSearcher` now takes a minimum element count, and the union rule asks for two. `ListNodeApplier::vars` returned nothing whenever a transform was set, which switched off egg's check for the list and element patterns too, turning a typo there from a panic at rule construction into one on the first matching plan. Take the transform's own variables alongside it and subtract only those, the way `new_list_var` already is. The round trip test counted three inputs and three scans, but identity and order are what a positional read puts at risk: a reversed list, or one query twice, leaves three of everything. Assert each query's members in order. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Xo5DArPYy2Q7ER7HyMo1Ao --------- Co-authored-by: Claude --- .../cubejs-druid-driver/src/DruidQuery.ts | 4 + packages/cubejs-ksql-driver/src/KsqlQuery.ts | 3 + .../src/adapter/BaseQuery.js | 6 + .../src/adapter/BigqueryQuery.ts | 8 + .../src/adapter/ClickHouseQuery.ts | 9 + .../src/adapter/MssqlQuery.ts | 10 + .../src/adapter/OracleQuery.ts | 7 + .../src/adapter/SqliteQuery.ts | 3 + .../test/unit/allDialects.ts | 37 ++ .../test/unit/positional-params.test.ts | 24 +- .../test/unit/union-template.test.ts | 71 +++ rust/cubesql/CLAUDE.md | 41 ++ .../cubesql/src/compile/engine/df/wrapper.rs | 256 ++++++++++ .../cubesql/src/compile/rewrite/converter.rs | 55 +- .../cubesql/src/compile/rewrite/cost.rs | 4 + .../cubesql/src/compile/rewrite/mod.rs | 105 +++- .../src/compile/rewrite/rules/wrapper/mod.rs | 2 + .../compile/rewrite/rules/wrapper/union.rs | 188 +++++++ rust/cubesql/cubesql/src/compile/test/mod.rs | 50 ++ .../cubesql/src/compile/test/test_wrapper.rs | 482 +++++++++++++++++- rust/cubesql/cubesql/src/transport/service.rs | 14 + 21 files changed, 1341 insertions(+), 38 deletions(-) create mode 100644 packages/cubejs-schema-compiler/test/unit/allDialects.ts create mode 100644 packages/cubejs-schema-compiler/test/unit/union-template.test.ts create mode 100644 rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/union.rs diff --git a/packages/cubejs-druid-driver/src/DruidQuery.ts b/packages/cubejs-druid-driver/src/DruidQuery.ts index c4e2d212b1e61..b1d1705c9fc92 100644 --- a/packages/cubejs-druid-driver/src/DruidQuery.ts +++ b/packages/cubejs-druid-driver/src/DruidQuery.ts @@ -70,6 +70,10 @@ export class DruidQuery extends BaseQuery { templates.functions.UTCTIMESTAMP = 'CURRENT_TIMESTAMP'; delete templates.functions.WIDTH_BUCKET; + // Druid only accepts set operations in narrow forms and has no UNION of distinct rows, + // so the SQL API leaves them to post processing here. + delete templates.statements.union; + return templates; } } diff --git a/packages/cubejs-ksql-driver/src/KsqlQuery.ts b/packages/cubejs-ksql-driver/src/KsqlQuery.ts index 3852e647e1ff4..6dd514deef912 100644 --- a/packages/cubejs-ksql-driver/src/KsqlQuery.ts +++ b/packages/cubejs-ksql-driver/src/KsqlQuery.ts @@ -79,6 +79,9 @@ export class KsqlQuery extends BaseQuery { // expressions instead of column ordinals. templates.statements.group_by_exprs = '{{ group_by | map(attribute=\'expr\') | join(\', \') }}'; delete templates.functions.WIDTH_BUCKET; + // ksqlDB has no set operations, so the SQL API leaves them to post processing here. + delete templates.statements.union; + return templates; } diff --git a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js index b74e4b5279b60..5649c9bc9554a 100644 --- a/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js +++ b/packages/cubejs-schema-compiler/src/adapter/BaseQuery.js @@ -4600,6 +4600,12 @@ export class BaseQuery { '{% if offset is not none %}\nOFFSET {{ offset }}{% endif %}', group_by_exprs: '{{ group_by | map(attribute=\'index\') | join(\', \') }}', join: '{{ join_type }} JOIN {{ source }} ON {{ condition }}', + union: '{% for query in queries %}(\n' + + '{{ query | indent(2, true) }}\n' + + ')' + + '{% if not loop.last %}\nUNION {% if not distinct %}ALL {% endif %}{% endif %}' + + '{% endfor %}' + + '{% if limit is not none %}\nLIMIT {{ limit }}{% endif %}', cte: '{{ alias }} AS ({{ query | indent(2, true) }})', time_series_select: 'SELECT date_from::timestamp AS "date_from",\n' + 'date_to::timestamp AS "date_to" \n' + diff --git a/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts b/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts index eb773b66b7598..a161b955b9a44 100644 --- a/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts +++ b/packages/cubejs-schema-compiler/src/adapter/BigqueryQuery.ts @@ -383,6 +383,14 @@ export class BigqueryQuery extends BaseQuery { 'GENERATE_TIMESTAMP_ARRAY(TIMESTAMP({{ range_source }}.{{ min_name }}), TIMESTAMP({{ range_source }}.{{ max_name }}), INTERVAL {{ granularity }})\n' + '{% endif %}' + ') AS d'; + // GoogleSQL requires a set operator to say which mode it is: a bare UNION does not parse. + templates.statements.union = '{% for query in queries %}(\n' + + '{{ query | indent(2, true) }}\n' + + ')' + + '{% if not loop.last %}\nUNION {% if distinct %}DISTINCT{% else %}ALL{% endif %} {% endif %}' + + '{% endfor %}' + + '{% if limit is not none %}\nLIMIT {{ limit }}{% endif %}'; + return templates; } } diff --git a/packages/cubejs-schema-compiler/src/adapter/ClickHouseQuery.ts b/packages/cubejs-schema-compiler/src/adapter/ClickHouseQuery.ts index 6a988b54e92f8..427b383c1f04b 100644 --- a/packages/cubejs-schema-compiler/src/adapter/ClickHouseQuery.ts +++ b/packages/cubejs-schema-compiler/src/adapter/ClickHouseQuery.ts @@ -295,6 +295,15 @@ export class ClickHouseQuery extends BaseQuery { '{% endfor %}' + ') AS dates'; + // ClickHouse rejects a bare UNION unless `union_default_mode` is set, so a set + // operation has to say which one it is. + templates.statements.union = '{% for query in queries %}(\n' + + '{{ query | indent(2, true) }}\n' + + ')' + + '{% if not loop.last %}\nUNION {% if distinct %}DISTINCT{% else %}ALL{% endif %} {% endif %}' + + '{% endfor %}' + + '{% if limit is not none %}\nLIMIT {{ limit }}{% endif %}'; + return templates; } } diff --git a/packages/cubejs-schema-compiler/src/adapter/MssqlQuery.ts b/packages/cubejs-schema-compiler/src/adapter/MssqlQuery.ts index cfde724a5c916..0eedd8690482d 100644 --- a/packages/cubejs-schema-compiler/src/adapter/MssqlQuery.ts +++ b/packages/cubejs-schema-compiler/src/adapter/MssqlQuery.ts @@ -359,6 +359,16 @@ export class MssqlQuery extends BaseQuery { '{% if order_by %}\nORDER BY {{ order_by | map(attribute=\'expr\') | join(\', \') }}\nOFFSET {% if offset is not none %}{{ offset }}{% else %}0{% endif %} ROWS' + '\nFETCH NEXT {% if limit is not none %}{{ limit }}{% else %}2147483647{% endif %} ROWS ONLY{% endif %}' + '{% if ctes %}\nOPTION (MAXRECURSION 0){% endif %}'; + // T-SQL has no LIMIT, and neither TOP nor OFFSET/FETCH can be attached to a set + // operation directly (OFFSET/FETCH also requires an ORDER BY), so a bounded set + // operation is read through a derived table. + templates.statements.union = '{% if limit is not none %}SELECT TOP {{ limit }} * FROM (\n{% endif %}' + + '{% for query in queries %}(\n' + + '{{ query | indent(2, true) }}\n' + + ')' + + '{% if not loop.last %}\nUNION {% if not distinct %}ALL {% endif %}{% endif %}' + + '{% endfor %}' + + '{% if limit is not none %}\n) AS union_result{% endif %}'; // MSSQL has no boolean type — a segment projected as a dimension must be a BIT. templates.expressions.wrap_segment_select = 'CAST((CASE WHEN {{ expr }} THEN 1 ELSE 0 END) AS BIT)'; // Reading a segment back from a pre-aggregation: it is a stored BIT column, diff --git a/packages/cubejs-schema-compiler/src/adapter/OracleQuery.ts b/packages/cubejs-schema-compiler/src/adapter/OracleQuery.ts index 2546630780add..2f8dd5dde8e97 100644 --- a/packages/cubejs-schema-compiler/src/adapter/OracleQuery.ts +++ b/packages/cubejs-schema-compiler/src/adapter/OracleQuery.ts @@ -245,6 +245,13 @@ export class OracleQuery extends BaseQuery { '{% if order_by %}\nORDER BY {{ order_by | map(attribute=\'expr\') | join(\', \') }}{% endif %}' + '{% if offset is not none %}\nOFFSET {{ offset }} ROWS{% endif %}' + '{% if limit is not none %}\nFETCH NEXT {{ limit }} ROWS ONLY{% endif %}'; + // Oracle row-limiting syntax again: the base template ends a set operation with LIMIT. + templates.statements.union = '{% for query in queries %}(\n' + + '{{ query | indent(2, true) }}\n' + + ')' + + '{% if not loop.last %}\nUNION {% if not distinct %}ALL {% endif %}{% endif %}' + + '{% endfor %}' + + '{% if limit is not none %}\nFETCH NEXT {{ limit }} ROWS ONLY{% endif %}'; // Oracle has no `::` cast and no `VALUES` row-constructor table source. Build the // series with TO_TIMESTAMP + UNION ALL SELECT ... FROM DUAL, and no `AS` before // the derived-table alias (Oracle forbids it). `seria` items are [from, to] pairs. diff --git a/packages/cubejs-schema-compiler/src/adapter/SqliteQuery.ts b/packages/cubejs-schema-compiler/src/adapter/SqliteQuery.ts index e28c488605c57..e16e38c9ca23b 100644 --- a/packages/cubejs-schema-compiler/src/adapter/SqliteQuery.ts +++ b/packages/cubejs-schema-compiler/src/adapter/SqliteQuery.ts @@ -85,6 +85,9 @@ export class SqliteQuery extends BaseQuery { public sqlTemplates() { const templates = super.sqlTemplates(); delete templates.functions.WIDTH_BUCKET; + // A compound select takes no parenthesised operands in SQLite, so the SQL API leaves + // set operations to post processing here rather than pushing them down. + delete templates.statements.union; return templates; } } diff --git a/packages/cubejs-schema-compiler/test/unit/allDialects.ts b/packages/cubejs-schema-compiler/test/unit/allDialects.ts new file mode 100644 index 0000000000000..8b94bdfc6709f --- /dev/null +++ b/packages/cubejs-schema-compiler/test/unit/allDialects.ts @@ -0,0 +1,37 @@ +import fs from 'fs'; +import path from 'path'; + +// Tests run from `dist`, so this resolves to the compiled adapters. +const ADAPTER_DIR = path.join(__dirname, '..', '..', 'src', 'adapter'); + +// The adapter directory holds far more than this; the floor is only here so a scan that +// silently matched nothing fails loudly rather than passing every invariant vacuously. +const MIN_DIALECTS = 10; + +/** + * Every dialect, read off the adapter directory rather than listed by hand, so a dialect + * added later cannot quietly escape an invariant asserted over all of them. + * + * Paired with its name, which is what a caller needs to report which dialect failed. + */ +export function allDialects(): [string, any][] { + const classes = fs.readdirSync(ADAPTER_DIR) + // `.ts` keeps this working if the tests are ever run from source. + .map(file => file.match(/^(\w+Query)\.(?:ts|js)$/)?.[1]) + .filter((name): name is string => !!name && name !== 'BaseQuery') + // eslint-disable-next-line global-require, import/no-dynamic-require + .map(name => [name, require(path.join(ADAPTER_DIR, name))[name]] as [string, any]); + + if (classes.length < MIN_DIALECTS) { + throw new Error( + `Expected the adapter directory to hold at least ${MIN_DIALECTS} dialects, found ${classes.length}` + ); + } + + return classes; +} + +export function dialect(name: string): any { + // eslint-disable-next-line global-require, import/no-dynamic-require + return require(path.join(ADAPTER_DIR, name))[name]; +} diff --git a/packages/cubejs-schema-compiler/test/unit/positional-params.test.ts b/packages/cubejs-schema-compiler/test/unit/positional-params.test.ts index e20ff044ff27d..5410da0af546a 100644 --- a/packages/cubejs-schema-compiler/test/unit/positional-params.test.ts +++ b/packages/cubejs-schema-compiler/test/unit/positional-params.test.ts @@ -1,7 +1,6 @@ -import fs from 'fs'; -import path from 'path'; import { BigqueryQuery } from '../../src/adapter/BigqueryQuery'; import { PostgresQuery } from '../../src/adapter/PostgresQuery'; +import { allDialects } from './allDialects'; import { prepareJsCompiler } from './PrepareCompiler'; // `?` placeholders are positional: a value referenced from two places in the @@ -63,23 +62,6 @@ function placeholdersCount(sql: string) { return (sql.match(/\?/g) || []).length; } -// Read off the directory rather than listed by hand, so a dialect added later -// cannot quietly escape the invariant below. -const ADAPTER_DIR = path.join(__dirname, '..', '..', 'src', 'adapter'); - -function allDialects() { - const classes = fs.readdirSync(ADAPTER_DIR) - // Tests run from `dist`, so the adapter dir holds `.js`; `.ts` keeps this - // working if they are ever run from source. - .map(file => file.match(/^(\w+Query)\.(?:ts|js)$/)?.[1]) - .filter((name): name is string => !!name && name !== 'BaseQuery') - // eslint-disable-next-line global-require, import/no-dynamic-require - .map(name => require(path.join(ADAPTER_DIR, name))[name]); - - expect(classes.length).toBeGreaterThan(10); - return classes; -} - describe('positional params', () => { // Dialects whose placeholder carries the param index are free to share a param // between placeholders; those rendering a bare placeholder are not, since the @@ -88,7 +70,7 @@ describe('positional params', () => { const { compiler, joinGraph, cubeEvaluator } = prepareJsCompiler(model); await compiler.compile(); - const reusingPositionalDialects = allDialects().filter(QueryClass => { + const reusingPositionalDialects = allDialects().filter(([, QueryClass]) => { const query = new QueryClass({ joinGraph, cubeEvaluator, compiler }, { measures: ['orders.count'], timezone: 'UTC', @@ -96,7 +78,7 @@ describe('positional params', () => { const indexedPlaceholder = query.sqlTemplates().params.param.includes('param_index'); return !indexedPlaceholder && query.shouldReuseParams; - }).map(QueryClass => QueryClass.name); + }).map(([name]) => name); expect(reusingPositionalDialects).toEqual([]); }); diff --git a/packages/cubejs-schema-compiler/test/unit/union-template.test.ts b/packages/cubejs-schema-compiler/test/unit/union-template.test.ts new file mode 100644 index 0000000000000..c5916a12a6f9a --- /dev/null +++ b/packages/cubejs-schema-compiler/test/unit/union-template.test.ts @@ -0,0 +1,71 @@ +import { allDialects, dialect } from './allDialects'; + +// `statements/union` is read by the SQL API when it pushes a set operation down to the +// data source, and by nothing else, so these assertions are what stands between an edit +// to one of these templates and a syntax error at a customer's warehouse. +// +// Only the templates are read here, off a bare prototype rather than a query built on a +// compiled model. That reads the templates a dialect writes unconditionally, which every +// `statements.union` is today; a dialect that gated one on instance state would need a +// real query here, since `this` carries nothing. +function unionTemplate(QueryClass: any): string | undefined { + return QueryClass.prototype.sqlTemplates + .call(Object.create(QueryClass.prototype)) + .statements + .union; +} + +describe('statements/union', () => { + it.each(allDialects())('%s renders every query, once, bounded', (_name, QueryClass) => { + const template = unionTemplate(QueryClass); + if (template === undefined) { + // Deliberately opted out: with no template the SQL API leaves the set operation to + // post processing rather than pushing down SQL the data source cannot parse + return; + } + + // The operator itself: without it the rendered SQL is not a set operation at all + expect(template).toMatch(/\bUNION\b/); + // Every query of the operation, rendered rather than merely looped over + expect(template).toMatch(/\{%\s*for query in queries\s*%\}/); + expect(template).toContain('{{ query'); + // The row cap bounds the result of the whole operation, and is interpolated into the + // clause that bounds it rather than only guarding it + expect(template).toMatch(/\{%\s*if limit is not none\s*%\}[^]*\{\{\s*limit\s*\}\}/); + // However the dialect spells the operator, `ALL` is what keeps the duplicates, so + // every `ALL` sits on the branch that keeps them and nowhere else. The dialects write + // that branch two ways: naming only `ALL`, or naming both modes. + const keepsDuplicates = /\{%\s*if not distinct\s*%\}ALL|\{%\s*if distinct\s*%\}DISTINCT\{%\s*else\s*%\}ALL/; + expect(template).toMatch(keepsDuplicates); + expect(template.replace(new RegExp(keepsDuplicates.source, 'g'), '')).not.toContain('ALL'); + // Balanced tags: an unclosed block renders as a template error at query time + expect((template.match(/\{%\s*if\b/g) || []).length) + .toEqual((template.match(/\{%\s*endif\s*%\}/g) || []).length); + expect((template.match(/\{%\s*for\b/g) || []).length) + .toEqual((template.match(/\{%\s*endfor\s*%\}/g) || []).length); + }); + + it('leaves the template undefined where a set operation cannot be expressed', () => { + // A compound select takes no parenthesised operand in SQLite + expect(unionTemplate(dialect('SqliteQuery'))).toBeUndefined(); + }); + + it('names the mode of the operation where the dialect requires it', () => { + // GoogleSQL and ClickHouse both reject a bare UNION + for (const name of ['BigqueryQuery', 'ClickHouseQuery']) { + expect(unionTemplate(dialect(name))).toContain('{% if distinct %}DISTINCT{% else %}ALL{% endif %}'); + } + }); + + it('bounds the operation with the row limiting clause of the dialect', () => { + const clauses: [string, string][] = [ + ['PostgresQuery', 'LIMIT {{ limit }}'], + ['OracleQuery', 'FETCH NEXT {{ limit }} ROWS ONLY'], + // Neither TOP nor OFFSET/FETCH attaches to a compound query in T-SQL + ['MssqlQuery', 'SELECT TOP {{ limit }} * FROM ('], + ]; + for (const [name, clause] of clauses) { + expect(unionTemplate(dialect(name))).toContain(clause); + } + }); +}); diff --git a/rust/cubesql/CLAUDE.md b/rust/cubesql/CLAUDE.md index 9b220d2adfa1f..f023e725d8ebe 100644 --- a/rust/cubesql/CLAUDE.md +++ b/rust/cubesql/CLAUDE.md @@ -113,6 +113,47 @@ cargo bench 3. Add tests with snapshot expectations 4. Update protocol-specific handling if needed +### Rewrite rules: never traverse a list recursively + +Every matcher must match exactly **one** level. A list is consumed by dedicated rules +that match the list node itself — never by a transform that walks it. + +- **Lists are flat, not head/tail.** A list node holds all of its elements as children + (`UnionInputs(a, b, c)`), not nested cons cells (`UnionInputs(a, UnionInputs(b, ...))`). + Cons lists are legacy — do not add new ones, and prefer converting one you touch. + Build them with the flat branch of `add_expr_flat_list_node!` (or an equivalent that + adds a single node with every element), register the node in `ListType`, and traverse + with `flat_list_pushdown_pullup_rules` / `replacer_flat_push_down_node` / + `replacer_flat_pull_up_node`, or `transforming_list_rewrite_with_lists_and_vars` when the + output needs a node no pattern can spell out (a cleared replacer context, an alias + converted to another node type). The flat pull-up matches the whole list in one rule and + takes `top_level_elem_vars`, which is how a fact that must hold across every element — + all queries reaching the same data source — is enforced: name the variable there and + unification does the rest, with no comparison of your own. +- Generate the traversal with the existing helpers rather than by hand: + `WrapperRules::list_pushdown_pullup_rules` / `flat_list_pushdown_pullup_rules` + (or `replacer_push_down_node` / `replacer_pull_up_node` underneath them). They emit + the `-push-down`, `-pull-up` and `-tail` rules that distribute a replacer over the + list's elements and collect it back once they are all done. +- Push-down and pull-up are **separate rules**. Do not fold both directions, or the + list walk, into one rewrite with a big transform. +- Do not write an imperative reader over `egraph[id].nodes` to collect a list's + elements inside a transform. An e-class holds many representations, so picking one is + arbitrary; the cons shape is also an implementation detail of how the list was built + (`add_plan_list_node!`), which a hand-rolled reader silently couples itself to. +- A transform should only decide scalar facts (a flag, an alias, whether a template + exists) about nodes the **pattern** already bound. Relationships between several + matched nodes — "both sides reach the same data source" — belong in the pattern, by + reusing one pattern variable in both places, so unification enforces them. +- A push-down replacer must never end up on top of an already pulled-up subtree. Inputs + that arrive as a finished `cube_scan_wrapper(wrapper_pullup_replacer(..))` — the queries + of a set operation, the sides of a join — have nothing left to push into, so their list + carries a **pull-up** replacer and is consumed by pull-up rules. Putting a push-down + replacer there instead makes `wrapper-subqueries-wrapped-scan-to-pull` + (`rules/wrapper/subquery.rs`) match, which re-contexts the element without comparing + input data sources — see the `TODO` on it. That rule is for the subquery path only; + reaching it from anywhere else means the rules above it are shaped wrong. + ### Debugging Query Compilation ```bash # Enable detailed logging diff --git a/rust/cubesql/cubesql/src/compile/engine/df/wrapper.rs b/rust/cubesql/cubesql/src/compile/engine/df/wrapper.rs index d09de2207999b..643f1f3b560cf 100644 --- a/rust/cubesql/cubesql/src/compile/engine/df/wrapper.rs +++ b/rust/cubesql/cubesql/src/compile/engine/df/wrapper.rs @@ -839,6 +839,12 @@ impl CubeScanWrapperNode { .map(|subq| subq.as_ref()) .any(Self::has_ungrouped_wrapped_node) } + } else if let Some(wrapped_union) = node.as_any().downcast_ref::() + { + wrapped_union + .inputs + .iter() + .any(|input| Self::has_ungrouped_wrapped_node(input)) } else { false } @@ -941,6 +947,18 @@ impl CubeScanWrapperNode { Arc::new(LogicalPlan::Extension(Extension { node: Arc::new(new_node), })) + } else if let Some(node) = extension_node + .as_any() + .downcast_ref::() + .cloned() + { + let mut new_node = node.clone(); + new_node.limit = Some(new_node.limit.map_or(query_limit as usize, |limit| { + min(limit, query_limit as usize) + })); + Arc::new(LogicalPlan::Extension(Extension { + node: Arc::new(new_node), + })) } else { node.clone() } @@ -1192,6 +1210,18 @@ impl CubeScanWrapperNode { parent_data_source, ) .await + } else if let Some(wrapped_union_node) = node_any.downcast_ref::() + { + wrapped_union_node + .generate_sql( + meta, + transport, + load_request_meta, + state, + values, + parent_data_source, + ) + .await } else { return Err(CubeError::internal(format!( "Can't generate SQL for node: {node:?}" @@ -1280,6 +1310,232 @@ impl UserDefinedLogicalNode for CubeScanWrapperNode { } } +/// A set operation whose inputs all push down to the same data source, rendered as a +/// `UNION` in the generated SQL rather than run as post processing in DataFusion. +/// +/// The row limit is not part of the plan the rewriter builds: like [`WrappedSelectNode`], +/// this node is capped by [`CubeScanWrapperNode::set_max_limit_for_node`] when it ends up +/// at the root of a wrapped plan. +#[derive(Debug, Clone)] +pub struct WrappedUnionNode { + pub schema: DFSchemaRef, + pub inputs: Vec>, + /// `UNION` when set, `UNION ALL` when not + pub distinct: bool, + pub alias: Option, + pub limit: Option, +} + +impl WrappedUnionNode { + pub fn new( + schema: DFSchemaRef, + inputs: Vec>, + distinct: bool, + alias: Option, + limit: Option, + ) -> Self { + Self { + schema, + inputs, + distinct, + alias, + limit, + } + } + + /// Renders every input as its own query and joins them into one set operation. + /// + /// Every input has to reach the same data source: a set operation the data source + /// evaluates cannot span two of them. + async fn generate_sql( + &self, + meta: &MetaContext, + transport: Arc, + load_request_meta: Arc, + state: Arc, + values: Vec>, + parent_data_source: Option<&str>, + ) -> result::Result { + let Some((first_input, rest_inputs)) = self.inputs.split_first() else { + return Err(CubeError::internal( + "Can't generate SQL for wrapped union: no inputs".to_string(), + )); + }; + + let SqlGenerationResult { + data_source, + from_alias, + column_remapping, + mut sql, + request, + } = CubeScanWrapperNode::generate_sql_for_node_rec( + meta, + Arc::clone(&transport), + Arc::clone(&load_request_meta), + Arc::clone(&state), + Arc::clone(first_input), + // Every input must keep the column names of the union's schema, which is the + // schema of the first one + false, + values.clone(), + parent_data_source, + ) + .await?; + + let Some(data_source) = data_source else { + return Err(CubeError::internal( + "Can't generate SQL for wrapped union: no data source for the first input" + .to_string(), + )); + }; + + let mut queries = Vec::with_capacity(self.inputs.len()); + queries.push(sql.sql.to_string()); + + for input in rest_inputs { + let input_result = CubeScanWrapperNode::generate_sql_for_node_rec( + meta, + Arc::clone(&transport), + Arc::clone(&load_request_meta), + Arc::clone(&state), + Arc::clone(input), + false, + values.clone(), + Some(&data_source), + ) + .await?; + + if input_result.data_source.as_ref() != Some(&data_source) { + return Err(CubeError::internal(format!( + "Can't generate SQL for wrapped union: inputs use different data sources, {:?} and {:?}", + data_source, input_result.data_source + ))); + } + + // Every input generated its SQL on its own, so its placeholders reference its + // own values and have to be remapped onto the combined ones + let (input_sql, input_values) = input_result.sql.unpack(); + let mapping = sql.add_values(input_values); + queries.push(SqlQuery::remap_placeholders(&input_sql, &mapping)?); + } + + let generator = meta + .data_source_to_sql_generator + .get(&data_source) + .ok_or_else(|| { + CubeError::internal(format!( + "Can't generate SQL for wrapped union: no sql generator for '{data_source}' data source" + )) + })?; + + let resulting_sql = generator + .get_sql_templates() + .union(queries, self.distinct, self.limit) + .map_err(|e| { + CubeError::internal(format!("Can't generate SQL for wrapped union: {e}")) + })?; + sql.replace_sql(resulting_sql); + + // Plans above see the union through a single alias, and read its columns by the + // names the first input gave them + let alias = self.alias.clone().or(from_alias); + let column_remapping = column_remapping + .map(|column_remapping| self.requalify_remapping(column_remapping, alias.as_deref())); + + // The column names of the union are the first input's, so its remapping is the one + // that describes them for the plans above. + // TODO only the first input's request is carried up, so the request that travels + // with this SQL describes one input out of several. `WrappedSelectNode` drops the + // requests of its joins the same way + Ok(SqlGenerationResult { + data_source: Some(data_source), + from_alias: alias, + sql, + column_remapping, + request, + }) + } + + /// The union's own schema drops the qualifiers of the first input, or replaces them with + /// its alias, so a column reference from above can carry a qualifier the first input's + /// remapping has never seen. Add those references, pointing at the same targets. + fn requalify_remapping( + &self, + column_remapping: ColumnRemapping, + alias: Option<&str>, + ) -> ColumnRemapping { + let mut column_remapping = column_remapping; + for field in self.schema.fields() { + let name = field.name(); + let Some(target) = column_remapping + .column_remapping + .get(&Column::from_name(name.clone())) + .cloned() + else { + continue; + }; + for qualifier in alias.map(str::to_string).into_iter().chain( + field + .qualifier() + .filter(|qualifier| Some(qualifier.as_str()) != alias) + .cloned(), + ) { + column_remapping.column_remapping.insert( + Column { + relation: Some(qualifier), + name: name.clone(), + }, + target.clone(), + ); + } + } + column_remapping + } +} + +impl UserDefinedLogicalNode for WrappedUnionNode { + fn as_any(&self) -> &dyn Any { + self + } + + fn inputs(&self) -> Vec<&LogicalPlan> { + self.inputs.iter().map(|input| input.as_ref()).collect() + } + + fn schema(&self) -> &DFSchemaRef { + &self.schema + } + + fn expressions(&self) -> Vec { + vec![] + } + + fn fmt_for_explain(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!( + f, + "WrappedUnion: distinct={:?}, alias={:?}, limit={:?}", + self.distinct, self.alias, self.limit + ) + } + + fn from_template( + &self, + exprs: &[Expr], + inputs: &[LogicalPlan], + ) -> Arc { + assert_eq!(inputs.len(), self.inputs.len(), "input size inconsistent"); + assert_eq!(exprs.len(), 0, "expression size inconsistent"); + + Arc::new(WrappedUnionNode { + schema: self.schema.clone(), + inputs: inputs.iter().cloned().map(Arc::new).collect(), + distinct: self.distinct, + alias: self.alias.clone(), + limit: self.limit, + }) + } +} + #[derive(Debug, Clone)] pub struct WrappedSelectNode { pub schema: DFSchemaRef, diff --git a/rust/cubesql/cubesql/src/compile/rewrite/converter.rs b/rust/cubesql/cubesql/src/compile/rewrite/converter.rs index 1f4fdc809b54c..2d7e53d3e5ac7 100644 --- a/rust/cubesql/cubesql/src/compile/rewrite/converter.rs +++ b/rust/cubesql/cubesql/src/compile/rewrite/converter.rs @@ -3,7 +3,7 @@ use crate::{ compile::{ engine::df::{ scan::{CubeScanNode, CubeScanOptions, MemberField}, - wrapper::{CubeScanWrapperNode, WrappedSelectNode}, + wrapper::{CubeScanWrapperNode, WrappedSelectNode, WrappedUnionNode}, }, rewrite::{ analysis::LogicalPlanAnalysis, @@ -30,7 +30,7 @@ use crate::{ ValuesValues, WindowFunctionExprFun, WindowFunctionExprWindowFrame, WrappedSelectAlias, WrappedSelectDistinct, WrappedSelectJoinJoinType, WrappedSelectLimit, WrappedSelectOffset, WrappedSelectPushToCube, WrappedSelectSelectType, - WrappedSelectType, + WrappedSelectType, WrappedUnionAlias, WrappedUnionDistinct, }, CubeContext, }, @@ -152,6 +152,20 @@ macro_rules! add_binary_expr_list_node { }}; } +/// A flat list node: every element is a child of one node. Lists are flat here, and the +/// cons cells `add_plan_list_node!` builds are legacy. +macro_rules! add_plan_flat_list_node { + ($converter:expr, $value_expr:expr, $query_params:expr, $ctx:expr, $field_variant:ident) => {{ + let list = $value_expr + .iter() + .map(|expr| $converter.add_logical_plan_replace_params(expr, $query_params, $ctx)) + .collect::, _>>()?; + $converter + .graph + .add(LogicalPlanLanguage::$field_variant(list)) + }}; +} + macro_rules! add_plan_list_node { ($converter:expr, $value_expr:expr, $query_params:expr, $ctx:expr, $field_variant:ident) => {{ let list = $value_expr @@ -698,7 +712,8 @@ impl LogicalPlanToLanguageConverter { self.graph.add(LogicalPlanLanguage::Repartition([input])) } LogicalPlan::Union(node) => { - let inputs = add_plan_list_node!(self, node.inputs, query_params, ctx, UnionInputs); + let inputs = + add_plan_flat_list_node!(self, node.inputs, query_params, ctx, UnionInputs); let alias = add_data_node!(self, node.alias, UnionAlias); self.graph.add(LogicalPlanLanguage::Union([inputs, alias])) } @@ -2373,6 +2388,40 @@ impl LanguageToLogicalPlanConverter { )), }) } + LogicalPlanLanguage::WrappedUnion(params) => { + let inputs = match_list_node_ids!(node_by_id, params[0], WrappedUnionInputs) + .into_iter() + .map(|n| self.to_logical_plan(n).map(Arc::new)) + .collect::, _>>()?; + + let distinct: bool = match_data_node!(node_by_id, params[1], WrappedUnionDistinct); + let alias: Option = + match_data_node!(node_by_id, params[2], WrappedUnionAlias); + + let Some(first_input) = inputs.first() else { + return Err(CubeError::internal( + "Can't convert wrapped union with no inputs".to_string(), + )); + }; + + // Same as `Union`: the inputs are union compatible, so the first one's schema + // stands for all of them + let schema = first_input.schema().as_ref().clone(); + let schema = match alias { + Some(ref alias) => schema.replace_qualifier(alias.as_str()), + None => schema.strip_qualifiers(), + }; + + LogicalPlan::Extension(Extension { + node: Arc::new(WrappedUnionNode::new( + Arc::new(schema), + inputs, + distinct, + alias, + None, + )), + }) + } LogicalPlanLanguage::Union(params) => { let inputs = match_list_node_ids!(node_by_id, params[0], UnionInputs) .into_iter() diff --git a/rust/cubesql/cubesql/src/compile/rewrite/cost.rs b/rust/cubesql/cubesql/src/compile/rewrite/cost.rs index 362be5f7699ea..a0d0739e07aef 100644 --- a/rust/cubesql/cubesql/src/compile/rewrite/cost.rs +++ b/rust/cubesql/cubesql/src/compile/rewrite/cost.rs @@ -73,8 +73,12 @@ impl BestCubePlan { _ => 0, }; + // What a wrapper does on its own, as opposed to merely holding a scan: a wrapper + // with none of it is an empty wrapper, and preferring it over the plain scan it + // wraps would be pointless let ast_size_inside_wrapper = match enode { LogicalPlanLanguage::WrappedSelect(_) => 1, + LogicalPlanLanguage::WrappedUnion(_) => 1, _ => 0, }; diff --git a/rust/cubesql/cubesql/src/compile/rewrite/mod.rs b/rust/cubesql/cubesql/src/compile/rewrite/mod.rs index eef32945cece1..e0b50cd040c38 100644 --- a/rust/cubesql/cubesql/src/compile/rewrite/mod.rs +++ b/rust/cubesql/cubesql/src/compile/rewrite/mod.rs @@ -294,6 +294,15 @@ crate::plan_to_language! { join_type: JoinType, }, + // A set operation over inputs that are all pushed down to the same data source. + // Unlike `Union`, which is post processing in DataFusion, this one renders as a + // `UNION` in the generated SQL and is evaluated by the data source itself. + WrappedUnion { + inputs: Vec, + distinct: bool, + alias: Option, + }, + CubeScan { alias_to_cube: Vec<(String, String)>, members: Vec, @@ -927,6 +936,8 @@ pub enum ListType { WrappedSelectAggrExpr, WrappedSelectWindowExpr, CubeScanMembers, + UnionInputs, + WrappedUnionInputs, } impl ListType { @@ -948,6 +959,8 @@ impl ListType { Self::WrappedSelectAggrExpr => wrapped_select_aggr_expr_empty_tail(), Self::WrappedSelectWindowExpr => wrapped_select_window_expr_empty_tail(), Self::CubeScanMembers => cube_scan_members_empty_tail(), + Self::UnionInputs => union_inputs_empty_tail(), + Self::WrappedUnionInputs => wrapped_union_inputs_empty_tail(), } } } @@ -964,6 +977,10 @@ struct ListNodeSearcher { list_pattern: Pattern, elem_pattern: Pattern, top_level_elem_vars: Vec, + /// Lists shorter than this do not match. A set operation needs it: one query is not a + /// union, and folding a `Distinct` into a single-query one would drop the deduplication + /// with no operator to render it on. + min_elements: usize, } impl ListNodeSearcher { @@ -974,9 +991,15 @@ impl ListNodeSearcher { list_pattern: list_pattern.parse().unwrap(), elem_pattern: elem_pattern.parse().unwrap(), top_level_elem_vars: vec![], + min_elements: 1, } } + fn with_min_elements(mut self, min_elements: usize) -> Self { + self.min_elements = min_elements; + self + } + fn with_top_level_elem_vars(mut self, vars: &[&str]) -> Self { self.top_level_elem_vars = vars.iter().map(|s| s.parse().unwrap()).collect(); self @@ -1034,6 +1057,12 @@ impl ListNodeSearcher { ListType::CubeScanMembers => { matches!(node, LogicalPlanLanguage::CubeScanMembers(_)) } + ListType::UnionInputs => { + matches!(node, LogicalPlanLanguage::UnionInputs(_)) + } + ListType::WrappedUnionInputs => { + matches!(node, LogicalPlanLanguage::WrappedUnionInputs(_)) + } } } @@ -1047,7 +1076,7 @@ impl ListNodeSearcher { let list_id = list_subst[self.list_var]; for node in egraph[list_id].iter() { let list_children = node.children(); - if !self.match_node(node) || list_children.is_empty() { + if !self.match_node(node) || list_children.len() < self.min_elements.max(1) { continue; } @@ -1196,6 +1225,8 @@ impl ListNodeApplierList { ListType::WrappedSelectAggrExpr => LogicalPlanLanguage::WrappedSelectAggrExpr(list), ListType::WrappedSelectWindowExpr => LogicalPlanLanguage::WrappedSelectWindowExpr(list), ListType::CubeScanMembers => LogicalPlanLanguage::CubeScanMembers(list), + ListType::UnionInputs => LogicalPlanLanguage::UnionInputs(list), + ListType::WrappedUnionInputs => LogicalPlanLanguage::WrappedUnionInputs(list), } } } @@ -1206,9 +1237,26 @@ pub struct ListApplierListPattern { elem_pattern: String, } +type ListNodeTransform = Box bool + Sync + Send>; + struct ListNodeApplier { list_pattern: PatternAst, lists: Vec, + /// Runs once the substitution carries the list's own variables, so it can build nodes + /// the pattern cannot spell out. Returning false drops this match. + transform: Option, + /// The variables the transform inserts. Only these are exempt from egg's check that the + /// searcher binds every variable the applier uses, so a typo anywhere else in the + /// applier still fails when the rule is built rather than when it first matches. + transform_vars: Vec, +} + +impl ListNodeApplier { + fn with_transform(mut self, transform: ListNodeTransform, transform_vars: &[&str]) -> Self { + self.transform = Some(transform); + self.transform_vars = transform_vars.iter().map(|v| v.parse().unwrap()).collect(); + self + } } impl ListNodeApplier { @@ -1233,6 +1281,8 @@ impl ListNodeApplier { lists: impl IntoIterator, ) -> Self { Self { + transform: None, + transform_vars: vec![], list_pattern: list_pattern.parse().unwrap(), lists: lists .into_iter() @@ -1278,6 +1328,11 @@ impl Applier for ListNodeApplier { } let mut subst = subst.clone(); subst.extend(list_substs[0].iter()); + if let Some(transform) = &self.transform { + if !transform(egraph, &mut subst) { + return; + } + } let new_id = egraph.add_instantiation(&self.list_pattern, &subst); if egraph.union(eclass, new_id) { result_ids.push(new_id); @@ -1294,6 +1349,7 @@ impl Applier for ListNodeApplier { vars.extend(list.elem_pattern.vars()); vars.retain(|v| *v != list.new_list_var); // this is bound by the applier itself } + vars.retain(|v| !self.transform_vars.contains(v)); // and these by the transform vars } } @@ -1650,6 +1706,22 @@ fn wrapped_select_joins_empty_tail() -> String { "WrappedSelectJoins".to_string() } +fn wrapped_union(inputs: impl Display, distinct: impl Display, alias: impl Display) -> String { + format!("(WrappedUnion {inputs} {distinct} {alias})") +} + +fn union(inputs: impl Display, alias: impl Display) -> String { + format!("(Union {inputs} {alias})") +} + +fn union_inputs_empty_tail() -> String { + "(UnionInputs)".to_string() +} + +fn wrapped_union_inputs_empty_tail() -> String { + "(WrappedUnionInputs)".to_string() +} + fn wrapped_select_filter_expr(left: impl Display, right: impl Display) -> String { format!("(WrappedSelectFilterExpr {} {})", left, right) } @@ -2444,6 +2516,37 @@ where } } +/// `list_rewrite_with_lists_and_vars` with a transform. The transform runs once the +/// substitution carries the list's own variables — including the `top_level_elem_vars` +/// every element agreed on — so it can build what a pattern cannot: a cleared replacer +/// context, an alias converted to another node type. +pub fn transforming_list_rewrite_with_lists_and_vars( + name: &str, + list_type: ListType, + searcher: ListPattern, + applier_pattern: &str, + lists: impl IntoIterator, + top_level_elem_vars: &[&str], + min_elements: usize, + transform_vars: &[&str], + transform_fn: T, +) -> CubeRewrite +where + T: Fn(&mut CubeEGraph, &mut Subst) -> bool + Sync + Send + 'static, +{ + let searcher = ListNodeSearcher::new( + list_type, + &searcher.list_var, + &searcher.pattern, + &searcher.elem, + ) + .with_top_level_elem_vars(top_level_elem_vars) + .with_min_elements(min_elements); + let applier = ListNodeApplier::from_lists(applier_pattern, lists) + .with_transform(Box::new(transform_fn), transform_vars); + Rewrite::new(name.to_string(), searcher, applier).unwrap() +} + pub fn transform_original_expr_to_alias( alias_expr_var: &'static str, ) -> impl Fn(&mut CubeEGraph, Id, &mut Subst) -> bool { diff --git a/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/mod.rs b/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/mod.rs index f430427bf83db..6ab72ff470f9c 100644 --- a/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/mod.rs +++ b/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/mod.rs @@ -26,6 +26,7 @@ mod sort_expr; mod subquery; mod udaf_function; mod udf_function; +mod union; mod window; mod window_function; mod wrapper_pull_up; @@ -59,6 +60,7 @@ impl RewriteRules for WrapperRules { self.cube_scan_wrapper_rules(&mut rules); self.join_rules(&mut rules); + self.union_rules(&mut rules); self.wrapper_pull_up_rules(&mut rules); self.aggregate_rules(&mut rules); self.aggregate_rules_subquery(&mut rules); diff --git a/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/union.rs b/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/union.rs new file mode 100644 index 0000000000000..9dda9699405f1 --- /dev/null +++ b/rust/cubesql/cubesql/src/compile/rewrite/rules/wrapper/union.rs @@ -0,0 +1,188 @@ +use crate::{ + compile::rewrite::{ + cube_scan_wrapper, distinct, rewrite, + rewriter::{CubeEGraph, CubeRewrite}, + rules::wrapper::WrapperRules, + transforming_list_rewrite_with_lists_and_vars, union, wrapped_union, + wrapper_pullup_replacer, wrapper_replacer_context, ListApplierListPattern, ListPattern, + ListType, LogicalPlanLanguage, UnionAlias, WrappedUnionAlias, + WrapperReplacerContextAliasToCube, WrapperReplacerContextGroupedSubqueries, + WrapperReplacerContextInputDataSource, + }, + transport::DataSource, + var, var_iter, +}; +use egg::Subst; + +impl WrapperRules { + pub fn union_rules(&self, rules: &mut Vec) { + rules.extend(vec![ + // The queries of a union arrive already pulled up, so there is nothing to push + // into them: the whole list is matched at once and every query is unwrapped into + // the set operation. `?input_data_source` is a top level element variable, so + // every query has to reach the same data source for this to match at all — a + // union spanning two of them is left to post processing without a check of its + // own. + transforming_list_rewrite_with_lists_and_vars( + "wrapper-pull-up-union", + ListType::UnionInputs, + ListPattern { + pattern: union("?list", "?union_alias"), + list_var: "?list".to_string(), + elem: cube_scan_wrapper( + wrapper_pullup_replacer( + "?elem", + wrapper_replacer_context( + "?elem_alias_to_cube", + "?elem_push_to_cube", + "?elem_in_projection", + "?elem_cube_members", + "?elem_grouped_subqueries", + "?elem_ungrouped_scan", + "?input_data_source", + ), + ), + "CubeScanWrapperFinalized:false", + ), + }, + &cube_scan_wrapper( + wrapper_pullup_replacer( + wrapped_union( + "?new_list", + "WrappedUnionDistinct:false", + "?wrapped_union_alias", + ), + wrapper_replacer_context( + "?out_alias_to_cube", + // A set operation is evaluated by the data source, so nothing + // above it reaches a Cube load query anymore + "WrapperReplacerContextPushToCube:false", + "WrapperReplacerContextInProjection:false", + "?out_cube_members", + "?out_grouped_subqueries", + "WrapperReplacerContextUngroupedScan:false", + "?input_data_source", + ), + ), + "CubeScanWrapperFinalized:false", + ), + [ListApplierListPattern { + list_type: ListType::WrappedUnionInputs, + new_list_var: "?new_list".to_string(), + elem_pattern: "?elem".to_string(), + }], + &["?input_data_source"], + // One query is not a union, and folding a `Distinct` into a single query + // one would leave the deduplication with no operator to render it on + 2, + &[ + "?wrapped_union_alias", + "?out_alias_to_cube", + "?out_cube_members", + "?out_grouped_subqueries", + ], + self.transform_union( + "?union_alias", + "?input_data_source", + "?wrapped_union_alias", + "?out_alias_to_cube", + "?out_cube_members", + "?out_grouped_subqueries", + ), + ), + // `UNION` is `UNION ALL` with the duplicates dropped, so the data source can do + // both at once and the deduplication does not have to happen in DataFusion + rewrite( + "wrapper-push-down-distinct-to-union", + distinct(cube_scan_wrapper( + wrapper_pullup_replacer( + wrapped_union("?inputs", "WrappedUnionDistinct:false", "?alias"), + "?context", + ), + "CubeScanWrapperFinalized:false", + )), + cube_scan_wrapper( + wrapper_pullup_replacer( + wrapped_union("?inputs", "WrappedUnionDistinct:true", "?alias"), + "?context", + ), + "CubeScanWrapperFinalized:false", + ), + ), + ]); + } + + fn transform_union( + &self, + union_alias_var: &'static str, + input_data_source_var: &'static str, + wrapped_union_alias_var: &'static str, + alias_to_cube_out_var: &'static str, + cube_members_out_var: &'static str, + grouped_subqueries_out_var: &'static str, + ) -> impl Fn(&mut CubeEGraph, &mut Subst) -> bool { + let union_alias_var = var!(union_alias_var); + let input_data_source_var = var!(input_data_source_var); + let wrapped_union_alias_var = var!(wrapped_union_alias_var); + let alias_to_cube_out_var = var!(alias_to_cube_out_var); + let cube_members_out_var = var!(cube_members_out_var); + let grouped_subqueries_out_var = var!(grouped_subqueries_out_var); + let meta = self.meta_context.clone(); + move |egraph, subst| { + let Some(data_source) = var_iter!( + egraph[subst[input_data_source_var]], + WrapperReplacerContextInputDataSource + ) + .flat_map(|data_source| data_source.clone()) + .next() else { + return false; + }; + + // A data source that has no union template cannot render a set operation, and + // there is no way back to post processing once this plan is chosen + if !Self::can_rewrite_template( + &DataSource::Specific(&data_source), + &meta, + "statements/union", + ) { + return false; + } + + let Some(alias) = var_iter!(egraph[subst[union_alias_var]], UnionAlias) + .cloned() + .next() + else { + return false; + }; + subst.insert( + wrapped_union_alias_var, + egraph.add(LogicalPlanLanguage::WrappedUnionAlias(WrappedUnionAlias( + alias, + ))), + ); + + // The queries are complete by now, so nothing above the union can reach the + // cubes and members they were built from + subst.insert( + alias_to_cube_out_var, + egraph.add(LogicalPlanLanguage::WrapperReplacerContextAliasToCube( + WrapperReplacerContextAliasToCube(vec![]), + )), + ); + subst.insert( + cube_members_out_var, + egraph.add(LogicalPlanLanguage::CubeScanMembers(vec![])), + ); + subst.insert( + grouped_subqueries_out_var, + egraph.add( + LogicalPlanLanguage::WrapperReplacerContextGroupedSubqueries( + WrapperReplacerContextGroupedSubqueries(vec![]), + ), + ), + ); + + true + } + } +} diff --git a/rust/cubesql/cubesql/src/compile/test/mod.rs b/rust/cubesql/cubesql/src/compile/test/mod.rs index ca9956563241e..ecf1f645c10ae 100644 --- a/rust/cubesql/cubesql/src/compile/test/mod.rs +++ b/rust/cubesql/cubesql/src/compile/test/mod.rs @@ -728,6 +728,15 @@ OFFSET {{ offset }}{% endif %}"#.to_string(), "statements/join".to_string(), "{{ join_type }} JOIN {{ source }} ON {{ condition }}".to_string(), ), + ( + "statements/union".to_string(), + r#"{% for query in queries %}( +{{ query | indent(2, true) }} +){% if not loop.last %} +UNION {% if not distinct %}ALL {% endif %}{% endif %}{% endfor %}{% if limit is not none %} +LIMIT {{ limit }}{% endif %}"# + .to_string(), + ), ( "statements/group_by_exprs".to_string(), "{{ group_by | map(attribute='index') | join(', ') }}".to_string(), @@ -830,6 +839,47 @@ pub fn get_test_tenant_ctx_with_meta(meta: Vec) -> Arc { get_test_tenant_ctx_with_meta_and_templates(meta, vec![]) } +/// The standard test meta with its cubes spread across several data sources: every cube +/// named in `cube_data_sources` reaches the data source it is paired with, everything else +/// reaches `default`. +pub fn get_test_tenant_ctx_with_cube_data_sources( + cube_data_sources: Vec<(&str, &str)>, +) -> Arc { + let data_source_for_cube = |cube: &str| { + cube_data_sources + .iter() + .find(|(name, _)| *name == cube) + .map_or("default", |(_, data_source)| *data_source) + .to_string() + }; + + let meta = get_test_meta(); + let member_to_data_source: HashMap<_, _> = meta + .iter() + .flat_map(|cube| { + let data_source = data_source_for_cube(&cube.name); + cube.dimensions + .iter() + .map(|d| &d.name) + .chain(cube.measures.iter().map(|m| &m.name)) + .chain(cube.segments.iter().map(|s| &s.name)) + .map(move |member| (member.clone(), data_source.clone())) + }) + .collect(); + + let data_source_to_sql_generator = member_to_data_source + .values() + .map(|data_source| (data_source.clone(), sql_generator(vec![]))) + .collect(); + + Arc::new(MetaContext::new( + meta, + member_to_data_source, + data_source_to_sql_generator, + Uuid::new_v4(), + )) +} + pub async fn get_test_session( protocol: DatabaseProtocol, meta_context: Arc, diff --git a/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs b/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs index 53df62aea1afc..c03599644a7d6 100644 --- a/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs +++ b/rust/cubesql/cubesql/src/compile/test/test_wrapper.rs @@ -15,8 +15,9 @@ use crate::{ rewrite::rewriter::Rewriter, test::{ convert_select_to_query_plan, convert_select_to_query_plan_customized, - convert_select_to_query_plan_with_config, init_testing_logger, LogicalPlanTestUtils, - TestContext, + convert_select_to_query_plan_with_config, convert_sql_to_cube_query, + get_test_session_with_config, get_test_tenant_ctx_with_cube_data_sources, + init_testing_logger, member_expression_sql, LogicalPlanTestUtils, TestContext, }, DatabaseProtocol, }, @@ -3245,8 +3246,11 @@ async fn test_wrapper_limitless_post_processing_ignored_in_stream_mode() { } /// A limit bounds the rows of the query it sits on, not of a query beside it. Summing -/// limits and limitless scans over the whole plan would let the limited branch here stand -/// in for the unlimited one, and the union would read a truncated half without saying so. +/// limits and limitless scans over the whole plan would let the limited query here stand in +/// for the unlimited one, and the union would read a truncated half without saying so. +/// +/// The two queries read different data sources, so the union cannot be pushed down and is +/// left to post processing, which is what makes the pairing observable at all. #[tokio::test] async fn test_wrapper_limitless_post_processing_sibling_without_limit() { if !Rewriter::sql_push_down_enabled() { @@ -3256,16 +3260,21 @@ async fn test_wrapper_limitless_post_processing_sibling_without_limit() { let mut config = ConfigObjImpl::default(); config.fail_on_limitless_post_processing = true; - let context = TestContext::with_config(DatabaseProtocol::PostgreSQL, Arc::new(config)).await; + let meta = get_test_tenant_ctx_with_cube_data_sources(vec![("Logs", "other")]); + let session = + get_test_session_with_config(DatabaseProtocol::PostgreSQL, Arc::new(config), meta.clone()) + .await; - let error = context - .convert_sql_to_cube_query( - "(SELECT customer_gender AS g FROM KibanaSampleDataEcommerce GROUP BY 1 LIMIT 10) \ - UNION ALL \ - (SELECT customer_gender AS g FROM KibanaSampleDataEcommerce GROUP BY 1)", - ) - .await - .expect_err("union with an unlimited branch should fail"); + let error = convert_sql_to_cube_query( + &"(SELECT customer_gender AS g FROM KibanaSampleDataEcommerce GROUP BY 1 LIMIT 10) \ + UNION ALL \ + (SELECT content AS g FROM Logs GROUP BY 1)" + .to_string(), + meta, + session, + ) + .await + .expect_err("union with an unlimited query should fail"); assert!( error .to_string() @@ -3397,3 +3406,450 @@ async fn test_wrapper_limitless_post_processing_ungrouped_aggregate() { error ); } + +/// A `UNION` of two `SELECT DISTINCT`s over different cubes, the shape a BI user writes to +/// list the values of a dimension across two views. +/// +/// It used to be planned as a `DISTINCT` over a `UNION` of two ungrouped scans, both of them +/// truncated to the row cap before the deduplication ever saw them, so values missing from +/// the answer went missing silently. Both queries reach the same data source, so the whole +/// set operation is pushed down to it instead. +#[tokio::test] +async fn test_wrapper_limitless_post_processing_union_of_distinct_selects() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query = "SELECT DISTINCT 'Medical Claims (MX)' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce \ + UNION \ + SELECT DISTINCT 'Pharmacy Claims (RX)' AS table_type, content AS market \ + FROM Logs"; + + let mut config = ConfigObjImpl::default(); + config.fail_on_limitless_post_processing = true; + let context = TestContext::with_config(DatabaseProtocol::PostgreSQL, Arc::new(config)).await; + + let logical_plan = context + .convert_sql_to_cube_query(query) + .await + .expect("union of two queries to the same data source should compile") + .as_logical_plan(); + + // Nothing is left above the pushed down query + let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql; + assert!(sql.contains("UNION"), "union is pushed down: {}", sql); + assert!( + logical_plan + .find_cube_scans() + .iter() + .all(|scan| { scan.request.ungrouped == Some(true) && scan.request.limit.is_none() }), + "the queries themselves stay unlimited, inside the pushed down SQL: {:?}", + logical_plan + ); +} + +/// The queries of a `UNION` reach the same data source, so the data source can evaluate the +/// whole set operation and nothing is left for DataFusion to do on top of two truncated +/// halves. +#[tokio::test] +async fn test_wrapper_union_all_push_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query_plan = convert_select_to_query_plan( + "SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2" + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await; + + let logical_plan = query_plan.as_logical_plan(); + let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql; + assert!(sql.contains("UNION ALL"), "union is pushed down: {}", sql); + assert!( + sql.contains("KibanaSampleDataEcommerce.customer_gender") && sql.contains("Logs.content"), + "both queries are in the pushed down SQL: {}", + sql + ); + // The row cap lands on the result of the whole set operation, not on either query + assert!( + sql.trim_end().ends_with(&format!( + "LIMIT {}", + ConfigObjImpl::default().non_streaming_query_max_row_limit + )), + "the row cap bounds the union: {}", + sql + ); +} + +/// A plain `UNION` drops duplicates, which the data source does as part of the same set +/// operation: it is `UNION ALL` with `ALL` left off, not a separate deduplication. +#[tokio::test] +async fn test_wrapper_union_distinct_push_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query_plan = convert_select_to_query_plan( + "SELECT DISTINCT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce \ + UNION \ + SELECT DISTINCT 'RX' AS table_type, content AS market FROM Logs" + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await; + + let logical_plan = query_plan.as_logical_plan(); + let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql; + assert!( + sql.contains("UNION") && !sql.contains("UNION ALL"), + "distinct union is pushed down as UNION: {}", + sql + ); +} + +/// The queries of a `UNION` are a list, not a pair +#[tokio::test] +async fn test_wrapper_union_three_queries_push_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query_plan = convert_select_to_query_plan( + "SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'DX' AS table_type, notes AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2" + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await; + + let sql = query_plan + .as_logical_plan() + .find_cube_scan_wrapped_sql() + .wrapped_sql + .sql; + assert_eq!( + sql.matches("UNION ALL").count(), + 2, + "all three queries are pushed down: {}", + sql + ); +} + +/// A pushed down union is a query like any other, so a projection and a filter above it are +/// pushed into a select that reads from it. +#[tokio::test] +async fn test_wrapper_union_filter_push_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query_plan = convert_select_to_query_plan( + "SELECT market FROM ( \ + SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2 \ + ) markets WHERE market = 'female'" + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await; + + let logical_plan = query_plan.as_logical_plan(); + assert!( + logical_plan.find_filter().is_none(), + "no filter is left to post processing: {:?}", + logical_plan + ); + let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql; + assert!(sql.contains("UNION ALL"), "union is pushed down: {}", sql); + assert!( + sql.contains("WHERE"), + "the filter reads from the pushed down union: {}", + sql + ); +} + +/// A set operation is evaluated by one data source, so queries that reach two of them cannot +/// be pushed down and the union stays in DataFusion. +#[tokio::test] +async fn test_wrapper_union_different_data_sources_not_pushed_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let meta = get_test_tenant_ctx_with_cube_data_sources(vec![("Logs", "other")]); + let session = get_test_session_with_config( + DatabaseProtocol::PostgreSQL, + Arc::new(ConfigObjImpl::default()), + meta.clone(), + ) + .await; + + let logical_plan = convert_sql_to_cube_query( + &"SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2" + .to_string(), + meta, + session, + ) + .await + .expect("union of two data sources should compile") + .as_logical_plan(); + + assert_eq!( + logical_plan.find_cube_scans().len(), + 2, + "every query keeps its own scan: {:?}", + logical_plan + ); + assert!( + matches!(logical_plan, LogicalPlan::Union(_)), + "the union is left to post processing: {:?}", + logical_plan + ); +} + +/// A data source with no union template cannot render a set operation. The rule has to +/// know that before the plan is chosen, because SQL generation has no way back to post +/// processing. +#[tokio::test] +async fn test_wrapper_union_without_template_not_pushed_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let logical_plan = convert_select_to_query_plan_customized( + "SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2" + .to_string(), + DatabaseProtocol::PostgreSQL, + // An empty template removes it from this data source + vec![("statements/union".to_string(), "".to_string())], + ) + .await + .as_logical_plan(); + + assert!( + matches!(logical_plan, LogicalPlan::Union(_)), + "the union is left to post processing: {:?}", + logical_plan + ); +} + +/// A union left to post processing keeps every one of its queries. `UnionInputs` is a flat +/// list, so the converter reads it back with `match_list_node_ids!` rather than by walking +/// cons cells — this pins that round trip at more than two queries, where the two shapes +/// differ. +#[tokio::test] +async fn test_wrapper_union_three_queries_not_pushed_down_keeps_every_query() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let logical_plan = convert_select_to_query_plan_customized( + "SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'DX' AS table_type, notes AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2" + .to_string(), + DatabaseProtocol::PostgreSQL, + // An empty template removes it from this data source + vec![("statements/union".to_string(), "".to_string())], + ) + .await + .as_logical_plan(); + + let LogicalPlan::Union(union) = &logical_plan else { + panic!("the union is left to post processing: {:?}", logical_plan); + }; + assert_eq!( + union.inputs.len(), + 3, + "one input per query: {:?}", + logical_plan + ); + // The list is written and read back positionally, so identity and order are what the + // flat conversion put at risk: a reader that reversed it, or yielded one query twice, + // would still leave three of everything. Order is not cosmetic for a union — the output + // column names come from the first query, and `WrappedUnionNode` renders it specially. + assert_eq!( + logical_plan + .find_cube_scans() + .iter() + .map(|scan| member_expression_sql(&scan.request.dimensions)) + .collect::>(), + vec![ + vec!["KibanaSampleDataEcommerce.customer_gender".to_string()], + vec!["Logs.content".to_string()], + vec!["KibanaSampleDataEcommerce.notes".to_string()], + ], + "every query survives the round trip, in order: {:?}", + logical_plan + ); +} + +/// A `Sort` directly above a union is not pushed down yet: the select it would be pushed +/// into projects nothing, and a query without a projection is not SQL. The union itself is +/// still pushed down, and the sort of its truncated result is still post processing that +/// `CUBESQL_FAIL_ON_LIMITLESS_POST_PROCESSING` reports. +#[tokio::test] +async fn test_wrapper_union_sort_left_to_post_processing() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let query = "SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2 \ + ORDER BY 1, 2"; + + let logical_plan = + convert_select_to_query_plan(query.to_string(), DatabaseProtocol::PostgreSQL) + .await + .as_logical_plan(); + assert!( + matches!(logical_plan, LogicalPlan::Sort(_)), + "the sort is left to post processing: {:?}", + logical_plan + ); + let sql = logical_plan + .find_cube_scan_wrapped_sql_deep() + .wrapped_sql + .sql; + assert!(sql.contains("UNION ALL"), "union is pushed down: {}", sql); + + let mut config = ConfigObjImpl::default(); + config.fail_on_limitless_post_processing = true; + let context = TestContext::with_config(DatabaseProtocol::PostgreSQL, Arc::new(config)).await; + let error = context + .convert_sql_to_cube_query(query) + .await + .expect_err("sorting a truncated union should fail"); + assert!( + error + .to_string() + .contains("CUBESQL_FAIL_ON_LIMITLESS_POST_PROCESSING"), + "unexpected error: {}", + error + ); +} + +/// A limit on one query of a union bounds that query, and the row cap bounds the result of +/// the whole set operation. Both end up in the pushed down SQL, so neither query is read +/// through the other's limit. +#[tokio::test] +async fn test_wrapper_union_limited_query_push_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let logical_plan = convert_select_to_query_plan( + "(SELECT customer_gender AS g FROM KibanaSampleDataEcommerce GROUP BY 1 LIMIT 10) \ + UNION ALL \ + (SELECT content AS g FROM Logs GROUP BY 1)" + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await + .as_logical_plan(); + + let limits = logical_plan + .find_cube_scans() + .into_iter() + .map(|scan| scan.request.limit) + .collect::>(); + assert_eq!( + limits, + vec![Some(10), None], + "the limit stays with the query it was written on" + ); + + let sql = logical_plan.find_cube_scan_wrapped_sql().wrapped_sql.sql; + assert!(sql.contains("UNION ALL"), "union is pushed down: {}", sql); + assert!( + sql.trim_end().ends_with(&format!( + "LIMIT {}", + ConfigObjImpl::default().non_streaming_query_max_row_limit + )), + "the row cap bounds the union: {}", + sql + ); +} + +/// A pushed down union is a query the rest of the wrapper can build on: joining against one +/// reads it as a subquery of the Cube query, rather than leaving the union to DataFusion. +#[tokio::test] +async fn test_wrapper_union_in_join_push_down() { + if !Rewriter::sql_push_down_enabled() { + return; + } + init_testing_logger(); + + let sql = convert_select_to_query_plan( + "SELECT k.customer_gender, u.market \ + FROM KibanaSampleDataEcommerce k \ + JOIN ( \ + SELECT 'MX' AS table_type, customer_gender AS market \ + FROM KibanaSampleDataEcommerce GROUP BY 1, 2 \ + UNION ALL \ + SELECT 'RX' AS table_type, content AS market FROM Logs GROUP BY 1, 2 \ + ) u ON k.customer_gender = u.market \ + GROUP BY 1, 2" + .to_string(), + DatabaseProtocol::PostgreSQL, + ) + .await + .as_logical_plan() + .find_cube_scan_wrapped_sql() + .wrapped_sql + .sql; + + // The union has to be in the SQL as the join's subquery, not merely somewhere in it: + // a union that lost its join, or a join that lost its union, would both be wrong + assert!( + sql.contains("UNION ALL"), + "the union is pushed down: {}", + sql + ); + assert!( + sql.contains("subqueryJoins"), + "the union is read as the join's subquery: {}", + sql + ); + assert!( + sql.contains("KibanaSampleDataEcommerce.customer_gender") && sql.contains("Logs.content"), + "both queries of the union are in the pushed down SQL: {}", + sql + ); +} diff --git a/rust/cubesql/cubesql/src/transport/service.rs b/rust/cubesql/cubesql/src/transport/service.rs index 764748ff7f4bc..56a55b959e53c 100644 --- a/rust/cubesql/cubesql/src/transport/service.rs +++ b/rust/cubesql/cubesql/src/transport/service.rs @@ -1090,6 +1090,20 @@ impl SqlTemplates { context! { join_type => join_type, source => source, condition => condition }, ) } + + /// Renders `queries` as a single set operation: `UNION` when `distinct`, `UNION ALL` + /// otherwise. `limit` bounds the result of the whole operation, not of any one query. + pub fn union( + &self, + queries: Vec, + distinct: bool, + limit: Option, + ) -> Result { + self.render_template( + "statements/union", + context! { queries => queries, distinct => distinct, limit => limit }, + ) + } } #[cfg(test)] From 3080bd46970e38bac58578cd238bc29a7f71c1cf Mon Sep 17 00:00:00 2001 From: Dmitry Patsura Date: Wed, 26 Aug 2026 21:11:26 +0200 Subject: [PATCH 4/4] docs: Cube Store message size limits (#11655) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: document Cube Store message size limits as a known limitation Cube talks to the cache and queue store over one WebSocket connection per node, and query results are delivered through it (QUEUE ACK) and written to the cache — so a result set above the transport ceiling cannot be delivered at all. A message over that ceiling is not answered with an error: Cube Store logs `Capacity(MessageTooLong { .. })` and closes the socket, and the driver resends everything in flight on reconnect, including the oversized message, which kills the new connection too. The deployment then reports `ConnectionError: CubeStore connection error: write EPIPE` in a loop, and unrelated queries sharing that connection fail alongside it. Adds a "Message size limits" section to the Cube Store architecture page describing the limits, the known limitation, and how to stay under it, plus the three previously undocumented env vars: | Limit | Env var | Default | Range | | ---------------------- | -------------------------------------- | ------- | -------------- | | Transport message size | `CUBESTORE_TRANSPORT_MAX_MESSAGE_SIZE` | 64 MiB | 16 MiB–256 MiB | | Transport frame size | `CUBESTORE_TRANSPORT_MAX_FRAME_SIZE` | 64 MiB | 4 MiB–256 MiB | | Single cache entry | `CUBESTORE_CACHE_MAX_ENTRY_SIZE` | 63 MiB | ≤ message − 1 MiB | Co-Authored-By: Claude Opus 5 (1M context) * docs: trim the Cube Store message size known limitation callout Drop the resend-loop mechanics and the blast-radius note, keeping just the symptom users search for: `write EPIPE`. Co-Authored-By: Claude Opus 5 (1M context) * docs: drop the per-node connection claim from Cube Store message limits The number of connections between Cube and the cache and queue store is an implementation detail that may change; the size ceiling is what the section is about. Co-Authored-By: Claude Opus 5 (1M context) * Update docs-mintlify/docs/pre-aggregations/cube-store-architecture.mdx Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * Update docs-mintlify/docs/pre-aggregations/cube-store-architecture.mdx Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> * docs: name both transport limits in the Cube Store mitigation advice A message is sent as a single frame, so raising the message size alone still trips `CUBESTORE_TRANSPORT_MAX_FRAME_SIZE`. Also shortens the paragraph. Co-Authored-By: Claude Opus 5 (1M context) --------- Co-authored-by: Claude Opus 5 (1M context) Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> --- .../cube-store-architecture.mdx | 36 +++++++++++++++++++ .../configuration/environment-variables.mdx | 32 +++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/docs-mintlify/docs/pre-aggregations/cube-store-architecture.mdx b/docs-mintlify/docs/pre-aggregations/cube-store-architecture.mdx index dd7913e34e82e..4e7cac725e350 100644 --- a/docs-mintlify/docs/pre-aggregations/cube-store-architecture.mdx +++ b/docs-mintlify/docs/pre-aggregations/cube-store-architecture.mdx @@ -996,6 +996,42 @@ Because detection is timestamp-based and cancellation is idempotent, it does not matter which instance notices first: recovery works even if the failed node never comes back. +### Message size limits + +Cube talks to the cache and queue store over a WebSocket connection, and +every cache entry, queue payload, and query result crosses it as one +message. That transport has a hard ceiling: + +| Limit | Environment variable | Default | Allowed range | +|---|---|---|---| +| Transport message size | `CUBESTORE_TRANSPORT_MAX_MESSAGE_SIZE` | 64 MiB | 16 MiB — 256 MiB | +| Transport frame size | `CUBESTORE_TRANSPORT_MAX_FRAME_SIZE` | 64 MiB | 4 MiB — 256 MiB | +| Single cache entry | `CUBESTORE_CACHE_MAX_ENTRY_SIZE` | 63 MiB | up to transport message size − 1 MiB | + +Query results are the usual reason these limits are reached. A result is +handed to the queue store so that every API instance waiting on that query +can pick it up, and it is written to the cache under its cache key — so a +result set larger than the transport limit cannot be delivered at all, +however fast the query that produced it was. + +A cache entry at or above `CUBESTORE_CACHE_MAX_ENTRY_SIZE` is rejected explicitly, +with `Unable to SET cache with '' key, exceeds maximum allowed size for +payload: , max allowed: `. + + + +**Known limitation.** A message above the *transport* limit is not answered +with an error. The deployment then reports `ConnectionError: CubeStore connection error: +write EPIPE`. + + + +If a query hits this limit, reduce the size of its result set — add filters +or a lower `limit`, drop dimensions, or split it into several queries. +Self-hosted deployments can raise the ceiling instead, but +`CUBESTORE_TRANSPORT_MAX_MESSAGE_SIZE` and `CUBESTORE_TRANSPORT_MAX_FRAME_SIZE` +have to go up together, since a message is sent as a single frame. + ### Why it lives in Cube Store Folding the cache and queue into Cube Store is itself a design decision in diff --git a/docs-mintlify/reference/configuration/environment-variables.mdx b/docs-mintlify/reference/configuration/environment-variables.mdx index 979325bf9ef2f..b5856225db9ec 100644 --- a/docs-mintlify/reference/configuration/environment-variables.mdx +++ b/docs-mintlify/reference/configuration/environment-variables.mdx @@ -1870,6 +1870,18 @@ The address/port pair for Cube Store's MySQL-compatible interface. | ------------------------- | ---------------------- | --------------------- | | A valid address/port pair | `0.0.0.0:3306` | `0.0.0.0:3306` | +## `CUBESTORE_CACHE_MAX_ENTRY_SIZE` + +The maximum size of a single entry in Cube Store's +[cache store](/docs/pre-aggregations/cube-store-architecture#cache-and-queue-store). +Larger entries are rejected. Cannot exceed +[`CUBESTORE_TRANSPORT_MAX_MESSAGE_SIZE`](#cubestore_transport_max_message_size) +minus 1 MiB. + +| Possible Values | Default in Development | Default in Production | +| --------------- | ---------------------- | --------------------- | +| A size, e.g. `63MiB` | `63MiB` | `63MiB` | + ## `CUBESTORE_DATA_DIR` A path on the local filesystem to store a local replica of the data. Must be @@ -2134,6 +2146,26 @@ If `true`, then sends telemetry to Cube. | --------------- | ---------------------- | --------------------- | | `true`, `false` | `true` | `true` | +## `CUBESTORE_TRANSPORT_MAX_MESSAGE_SIZE` + +The maximum size of a single message on the WebSocket connection between Cube +and Cube Store. Messages above this size close the connection; see +[message size limits](/docs/pre-aggregations/cube-store-architecture#message-size-limits). + +| Possible Values | Default in Development | Default in Production | +| --------------- | ---------------------- | --------------------- | +| A size from `16MiB` to `256MiB` | `64MiB` | `64MiB` | + +## `CUBESTORE_TRANSPORT_MAX_FRAME_SIZE` + +The maximum size of a single WebSocket frame on the connection between Cube +and Cube Store. A message is split into frames, so this can be smaller than +[`CUBESTORE_TRANSPORT_MAX_MESSAGE_SIZE`](#cubestore_transport_max_message_size). + +| Possible Values | Default in Development | Default in Production | +| --------------- | ---------------------- | --------------------- | +| A size from `4MiB` to `256MiB` | `64MiB` | `64MiB` | + ## `CUBESTORE_WAL_SPLIT_THRESHOLD` The maximum number of rows to keep in a single chunk of data right after