Skip to content

feat(cubejs): enforce partition pruning in queryRewrite for cubes over partitioned event tables - #84

Merged
acmeguy merged 2 commits into
mainfrom
fix/partition-pruning-rewrite
Sep 3, 2026
Merged

acmeguy merged 2 commits into
mainfrom
fix/partition-pruning-rewrite

Conversation

@acmeguy

@acmeguy acmeguy commented Sep 3, 2026

Copy link
Copy Markdown

Owner rule (cxs2 spec 107 follow-up, 2026-09-03): a cube over cst.semantic_events must never reach ClickHouse without a predicate on the partition time column.

Why. simple_stays.started is properties.started_at (a JSON payload path). Every dashboard query filtered on it read the JSON column across all monthly partitions: 10.15 GiB / 18.6M rows / 6.2 s for a one-week POI ranking (ClickHouse system.query_log), and the server memory guard killed one of any two running together — the "Cube query error: 400" panels in Tychi's dashboards.

What. queryRewrite derives a window from the query's explicit date ranges (timeDimensions.dateRange, inDateRange filters) and adds an inDateRange filter on the cube's partition dimension, widened by a margin on both sides. Policy per source table (default semantic_events → timestamp, 31 days), overridable with CUBEJS_PARTITION_PRUNING and per cube with meta.partition_dimension. Reuses the existing cube-to-table map; runs for every role; no-op when the query already constrains the partition column or states no explicit range (relative ranges are left to Cube).

Measured (same rows, Cube's generated shape): with the window 3.92 GiB / 1.77 s; with the window and the model also projecting only typed columns (separate model change) 29.9 MiB / 71 ms.

Tests: src/__tests__/partitionPruning.test.js (5) — the suite's 6 pre-existing failures at main are unchanged.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nv1ngm1j8mV8rWsumTbpx2

acmeguy and others added 2 commits September 3, 2026 05:39
…r partitioned event tables

Owner rule (cxs2 spec 107 follow-up, 2026-09-03): a cube over
cst.semantic_events must never reach ClickHouse without a predicate on
the partition time column. A row-type cube whose time dimension is a
payload path (simple_stays.started = properties.started_at) made every
dashboard query read the JSON column across all monthly partitions:
10 GiB / 18.6M rows for a one-week POI query, killed by the server
memory guard whenever two ran together.

queryRewrite now derives a window from the query's explicit date ranges
(timeDimensions.dateRange, inDateRange filters) and adds an inDateRange
filter on the cube's partition dimension, widened by a margin on both
sides. Policy per source table (default: semantic_events -> timestamp,
31 days), overridable with CUBEJS_PARTITION_PRUNING and per cube with
meta.partition_dimension. It reuses the existing cube-to-table map, runs
for every role, and stays out of the way when the query already
constrains the partition column or states no explicit range.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nv1ngm1j8mV8rWsumTbpx2
…re default

Local dev on Apple silicon runs cubestore under amd64 emulation, where the
cache driver's WebSocket dies at startup and every query fails with
'Cube Store connection is closed'. Honouring the standard Cube env var
(default unchanged: cubestore) lets the dev stack run with the in-memory
driver; production configs set nothing and keep cubestore.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nv1ngm1j8mV8rWsumTbpx2
@acmeguy
acmeguy merged commit 15688d8 into main Sep 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant