[pull] master from cube-js:master - #657
Merged
Merged
Conversation
β¦11514) * fix(tesseract): report multi-stage reads of out-of-grain dimensions A multi-stage member whose SQL reads a dimension that is not part of the grain it is computed at emitted SQL referencing the dimension's own cube alias, which the CTE's FROM never brings into scope. Postgres rejects such a query with "missing FROM-clause entry"; nothing reported it at plan time. Report the member and the dimension where a multi-stage member's deps are decomposed into children, naming the `grain.include` entry that makes the model plan. Reachability mirrors reference resolution: a member the source exposes as a column stops the walk, anything else is reachable only if every member its own SQL reads is, and a dimension that also reads a raw cube column is unreachable regardless of what its member deps resolve to. Only the slots that reach rendered SQL are considered β `drill_filters` are never emitted and a `mask` only for masked members, so neither can put a column requirement on a CTE. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(tesseract): apply the grain check to masks that are actually applied A mask reaches the rendered SQL for the members it is applied to, so a mask reading a dimension outside the stage grain emits the same dangling cube alias β for masked tenants only, which is where it is hardest to notice. Excluding `mask_sql` unconditionally left that case unreported. Thread the masking predicate through the reachability walk so the mask slot counts as rendered exactly when the member is masked. Also pin two behaviours that were decisions rather than accidents: a `grain.include` on a child widens that child's leaf and not the columns its CTE projects, so it does not satisfy a parent reading the dimension; and the CASE-SWITCH path plans branch dependencies as their own CTEs, which is why it skips the check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(tesseract): execute the multi-stage grain plans against postgres The plans the grain check lets through were asserted on substrings only, so nothing established that they run. Execute the six of them and pin the result sets: the declared-grain measure returns the first-half-of-month totals (420 / 650 / 850 against the seed), and the derived-dimension, query-grain, keys-side, drill-filter and mask shapes return their expected rows. The keys-side result carries the whole month against the `completed` row rather than the `completed` total. That follows from `reduce_by` collapsing the measure below the status grain, so the test says so β the number reads like a mistake otherwise. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * test(tesseract): pin the mask render path and make the snapshots total Row order: four of the executed snapshots pinned an order no ORDER BY determines β the queries group by a dimension and the month while ordering by the dimension alone, so the committed rows were hash-aggregate output. Name every grouped dimension in `order:`, as the neighbouring suite does. Mask coverage: nothing established the premise the mask branch rests on β that an applied mask is rendered inside the multi-stage CTE. It is, and the new test pins it against the CTE column. Writing that test turned up a limitation worth recording: an unconditional mask replaces the member's aggregate, so its dimension read sits outside any aggregate and has to be in the stage's own GROUP BY. A declared leaf grain puts the column in the source but not in that GROUP BY, and the database rejects the result. The reachability check asks only whether a column exists, so it does not tell the two apart β noted on the test and on the mask branch. Also compare the masked-dimension measure against a literal the seed matches, so its result set discriminates instead of being twelve zeros. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
β¦s sql (#11517) * feat(tesseract): push a segment named in FILTER_PARAMS into the cube's sql `FILTER_PARAMS.<cube>.<segment>.filter(...)` compiled without error but rendered `1 = 1`, leaving the segment predicate in the outer WHERE after the joins. On a cube wrapping a large union scan that predicate is what makes the scan viable, so the query never completes. A segment is compared to no value, so the `filter()` argument is the whole predicate rather than the left side of one. It is stated there rather than taken from the segment's own `sql`, which prefixes its columns with the cube β not in scope inside the sql that builds that cube, the same reason a dimension binding restates its column. `find_subtree_for_members` now matches a `Segment` node when a target names it, which also activates the binding through the existing activity visitor, and `BaseSegment` renders the binding's column when the filters context carries one. A segment absent from the query still renders `1 = 1`. The name is matched along the reference chain, so a view re-exporting a segment activates the underlying cube's binding. The walk stops at the first symbol that is not a member expression: a segment whose sql is a bare reference resolves on to that dimension, whose binding states a column and not a predicate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(tesseract): degrade a value-taking segment FILTER_PARAMS column to always-true A column that takes filter values cannot render for a segment, which supplies none. Raising a user error there fails a query that a model already serving `1 = 1` used to answer, and it is louder than what the same mismatch gets on the dimension path, which drops only the restatement inside the SQL. An argument the binding cannot resolve at all stays silent too, so the arity is not the place to start reporting. Both callback variants now degrade. A callback declaring no parameters is compiled with none, so the raw-callback variant only ever holds a column that wants values β a rest parameter, or a parameter list that could not be read β and invoking it with none interpolated `undefined` into the cube's sql. The binding is looked up by the path the query asked for before scanning the chain, which is both what the model meant and what the dimension path does. Covers the compiled column in the Postgres suite, which the mock DSL cannot express: the renderer parenthesizes a binding it reached, telling an activated-then-dropped column apart from an unselected segment's bare `1 = 1`. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? π Please sponsor : )