Skip to content

fix(tesseract): widen pre-aggregation range for time_shift reads through a view - #11554

Draft
hamid025 wants to merge 1 commit into
cube-js:masterfrom
hamid025:fix/tesseract-time-shift-view-preagg-range
Draft

fix(tesseract): widen pre-aggregation range for time_shift reads through a view#11554
hamid025 wants to merge 1 commit into
cube-js:masterfrom
hamid025:fix/tesseract-time-shift-view-preagg-range

Conversation

@hamid025

Copy link
Copy Markdown

Fixes #11536.

Problem

A multi_stage measure with a time_shift returns NULL when queried through a view, if the query's date range does not itself already contain the shifted period. The identical query against the cube returns correct values.

extract_date_range widens the matched partition range backwards by the shift interval so the shifted leaf can reach its rows. That widening is skipped for view-qualified queries, so the leaf scans a partition set that cannot contain its rows and yields NULL — silently, with no error.

The pre-aggregation description shows it directly — same query, only the namespace differs:

queried via matchedTimeDimensionDateRange
view 2026-08-03 … 2026-08-09 — not widened
cube 2026-07-27 … 2026-08-09 — widened by exactly the 7-day shift

Root cause

The interval lookup uses BaseFilter::member_name(), which is member_evaluator().full_name(). member_evaluator() calls only resolve_base_symbol — it peels the TimeDimension wrapper but never walks the reference chain.

dimensions_shifts is keyed by reference-chain-resolved names: all_time_members calls resolve_reference_chain() on every symbol before it becomes a key (planner/query_properties.rs).

A view member is a reference to the underlying cube member, so its unresolved name never equals the resolved key, the lookup misses, and no shift is applied.

Fix

Resolve the chain and retry — an exact second lookup, using the identity mechanism already used elsewhere. A member resolving to a different cube's dimension still does not match, so this cannot apply a shift that would not otherwise apply.

Fixing at the insert site instead looks worse: dimensions_shifts is also consumed by extract_time_shifts for render-time SQL, so re-keying there would change rendering as well.

Test

pre-aggregations-multi-stage-time-shift-view.test.ts covers both the direct signal and the end-to-end result:

  • the view query's matchedTimeDimensionDateRange must equal the cube query's
  • the view query must return the same prior-week value the cube query returns (it came back null before the fix)

Gated on getEnv('nativeSqlPlanner'), consistent with the other Tesseract pre-aggregation tests.

Impact

Views are the recommended query interface for BI tools, so in practice most consumer queries take the broken path. The failure is silent: a week-over-week column renders blank and is indistinguishable from genuinely absent data. Shorter windows are affected worst — for an interval I and a range of N days, only the last N − I days get values, so a "last 7 days" dashboard with a 7-day shift is entirely blank.

Notes

Opened as a draft: the change is verified against the source (all three APIs it relies on are present with the expected signatures) but I have no local Rust/Postgres toolchain, so neither the build nor the new test has been run on my side. Marking ready once CI confirms. Happy to adjust the test's fixture dates if the rollup does not match as written.

…ugh a view

`extract_date_range` widens the matched partition range backwards by the
shift interval so a shifted leaf can reach its rows. The lookup that finds
the interval used `BaseFilter::member_name()`, which is
`member_evaluator().full_name()` and only peels the `TimeDimension`
wrapper — it never walks the reference chain.

`dimensions_shifts`, however, is keyed by reference-chain-resolved names:
`all_time_members` calls `resolve_reference_chain()` on every symbol before
it becomes a key. A view member is a reference to the underlying cube
member, so its unresolved name never equals the key, the lookup missed, and
the range was left unwidened for view-qualified queries.

The shifted leaf then scanned a partition set that could not contain its
rows and yielded NULL — silently, with no error — while the identical
cube-qualified query returned correct values. Views are the recommended
query interface for BI tools, so most consumer queries take the broken
path, and shorter windows are affected worst: for an interval I over a
range of N days, only the last N-I days get values.

Retry the lookup with the resolved name. A member resolving to a different
cube's dimension still does not match, so this cannot apply a shift that
would not otherwise apply.

Fixes cube-js#11536

Signed-off-by: Abdulkhamid Ibragimov <abdulkhamid.ibragimov@careem.com>
@github-actions github-actions Bot added rust Pull requests that update Rust code javascript Pull requests that update Javascript code pr:community Contribution from Cube.js community members. labels Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

javascript Pull requests that update Javascript code pr:community Contribution from Cube.js community members. rust Pull requests that update Rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tesseract: multi_stage time_shift returns NULL when queried through a view (pre-agg partition range not widened)

1 participant