fix(tesseract): Resolve join for hint-less member expressions on views - #11501
Conversation
|
Claude finished @MazterQyou's task in 4m 5s —— View job Review: approach is sound — 2 medium, 3 low (5 inline comments)Full review
VerdictThe diagnosis is right and the fix is in the right place. The old I also checked the Verified the new snapshot against the seed data: Findings
Security / performanceNo security surface here — no user input reaches SQL text through this path; the change only reorders which cube hints seed join resolution. Performance impact is confined to finding 1 (avoidable DocsNothing user-facing changed, so no What I could not verifyI did not compile or run the tests: this is a fresh checkout with no Cargo build cache for the |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #11501 +/- ##
==========================================
+ Coverage 79.47% 79.49% +0.01%
==========================================
Files 480 480
Lines 98861 98928 +67
Branches 3636 3636
==========================================
+ Hits 78568 78638 +70
+ Misses 19773 19771 -2
+ Partials 520 519 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
cbc785f to
55a179d
Compare
|
Claude finished @MazterQyou's task in 5m 2s —— View job Re-review: all 5 prior findings addressed — 1 medium, 3 low (4 new inline comments)Full review
Prior findings — all addressed, threads resolved
Snapshot arithmetic — checked against
|
| # | Sev | Where | Issue |
|---|---|---|---|
| 1 | Medium | multi_fact_join_groups.rs:307-316 |
The join-map last resort only fires for multi-hop views (joinMap is filtered to len > 1), so COUNT(*) alone still hard-errors on a single-cube view like orders_view — the commonest view shape, and precisely the BI-profiling case the PR body cites |
| 2 | Low | multi_fact_join_groups.rs:309-313 |
Root taken from the first joinMap path → depends on view cube ordering; and COUNT(*) on customer_overview means 4 alone vs 13 alongside other measures. Parity with legacy, but should be documented |
| 3 | Low | mock_schema.rs:648-661 |
Populating join_map changes hint collection for every existing view fixture (Single(x) → Vector([x]), a distinct join_tree_cache key). Only 3 assertions needed updating, which is plausible — please confirm the full suite is green |
| 4 | Low | multi_fact_join_groups.rs:112-120 |
JoinHints::push dedups only adjacent Singles, so identical Vectors still repeat in pooled_hints — pre-existing, but pooled_hints is now a cache key of its own |
Finding 1 is the only one I'd want a decision on before merge, and "out of scope, follow-up filed" is a perfectly good answer — the current state is strictly better than the invalid type: unit value, expected struct JoinDefinitionStatic failure either way. The rest are comment/robustness polish.
Code quality
The from_base_hints rewrite is a genuine improvement over the previous filter-then-map: one pass, and the "multi-stage measures get no entry but do count towards the pool" rule is now stated where it happens rather than implied by a filtered_measures vector two blocks up. The inherited flag reads slightly better than a is_some() re-check would, though match inherited_pooled_hints { Some(p) => …, None => … } would make the two modes structurally exclusive rather than coupled through a bool.
The error message is specific and actionable. It interpolates cube_name twice (as the referenced cube and as the join-map owner) which reads a little repetitively for the common case where they're the same string, but it is correct.
Security / performance
No security surface: nothing user-controlled reaches SQL text through this path, and the change only reorders which cube hints seed join resolution. Performance is a wash — collect_join_hints is now also called for multi-stage measures (one extra traversal each, previously skipped), offset by no longer cloning base_hints into the pool per measure. pooled_hints adds one JoinHints clone per MeasuresJoinHints.
Testing
Four new tests covering the three fallback branches plus the terminal error, which is the right decomposition. Two gaps: the positive assertions only fire when a Postgres is reachable (try_execute_pg_from_options returns Option), so in environments without one those three tests degrade to "the planner didn't panic"; and there's no case for a hint-less view ME alongside only multi-stage measures, which is the path the reworked pooling in from_base_hints specifically enables.
Docs
Nothing user-facing changed, so no /docs-mintlify update is needed. The doc comments carry real weight here — they explain the legacy-parity reasoning rather than restating the code, and the per-test comments state the expected numbers and why, which is what makes the 13 in the multi-fact snapshot reviewable at all.
What I could not verify
I could not build or run the tests — cargo check on the cubesqlplanner crate isn't permitted in this job's sandbox, and this is a cold checkout with no build cache. Every finding above is from static reading of the diff, the fixtures, the seed SQL and the JS schema compiler; the snapshot arithmetic is hand-computed. Finding 3 in particular is a request for confirmation, not a claimed regression.
55a179d to
8796a72
Compare
|
Claude finished @MazterQyou's task in 4m 36s —— View job Re-review: 3 of 4 prior findings addressed — 0 medium, 2 low (2 new inline comments)Full review
Prior findings
What I re-verified
New findings
Neither blocks. Finding 1 is about a doc claim over-promising an invariant one constructor can break; finding 2 is a coverage gap plus a mechanical reorder. Code qualityThe The ambiguous-root rejection is the right call over picking a root: the alternative is a silent result change on a YAML reordering with no diagnostic. The error text names the actual cause. The doc block on TestingFive tests now, covering all three fallback branches plus both terminal errors, which is the right decomposition. Remaining gaps: the multi-stage-only pooling path (finding 2), and the three positive assertions only fire when a Postgres is reachable ( Security / performanceNo security surface — nothing user-controlled reaches SQL text through this path; the change only decides which cube hints seed join resolution. Performance is roughly neutral: DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything: there is no Cargo target dir in this checkout and a cold build of the Rust workspace exceeds this job's budget; · branch |
8796a72 to
95ce606
Compare
|
Claude finished @MazterQyou's task in 4m 26s —— View job Re-review: both prior code findings addressed — 1 medium, 1 low (2 new inline comments), 1 prior thread still awaiting confirmationFull review
Prior findings
What I verifiedSnapshot arithmetic, hand-checked against
Also checked: the test is genuinely load-bearing for the pooling branch — New findings
Finding 1 is the only one I'd want a decision on. "Out of scope, single-view assumption documented" is a fine answer — but the doc block's "the members it borrowed from" currently implies a same-view constraint the code doesn't enforce, so either the check or the wording should move. Code qualityThe The new fixture comment on The error messages are specific and name the member. The first still interpolates TestingSix tests now, covering all three fallback branches plus both terminal errors plus the multi-stage pooling path. The remaining gap is unchanged and structural: the four positive assertions only fire when a Postgres is reachable ( No test covers finding 1's shape (hint-less view ME + a measure from a cube outside that view), which is what let it through. Security / performanceNo security surface — nothing user-controlled reaches SQL text through this path; the change only decides which cube hints seed join resolution. Performance is now slightly better than before the reorder: the inherited path skips a full symbol traversal per multi-stage measure, and DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything — |
95ce606 to
88b3882
Compare
|
Claude finished @MazterQyou's task in 4m 52s —— View job Re-review: prior medium finding fixed structurally — 0 medium, 3 low (3 inline comments), 1 prior thread still awaiting confirmationFull review
Prior findings
What I verifiedThe same-view restriction is not a behaviour narrowing: before this PR, a hint-less view ME always got Re-checked the snapshots survive the switch from whole-query pooling to per-cube grouping:
Root rule against the new fixtures: Also checked New findings
None block. All three are polish. Code qualityReplacing the The three-way The TestingEight new tests now, covering all three fallback branches, the cross-view rejection, the nested root, and both terminal errors. Two notes:
One residual, outside this diff
Security / performanceNo security surface — nothing user-controlled reaches SQL text through this path; the change only decides which cube hints seed join resolution. Performance: one DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything — |
88b3882 to
1e92272
Compare
|
Claude finished @MazterQyou's task in 2m 22s —— View job Re-review: both prior code findings fixed — 1 medium, 1 low (2 inline comments), 2 prior threads still openFull review
Prior findings
What I verifiedThe root rule, hand-run against every join map the fixtures produce (mock keeps only
Also re-checked the earlier snapshot arithmetic survives the New findings
Neither blocks. Finding 1 is legacy parity and narrowing it properly means moving the check to where a hint-less view measure consumes Code qualitySplitting the no-single-root case into "several roots" and "cyclic paths", with a shared Dropping the dimension/filter seeding in favour of a plain The TestingNine tests now: three fallback branches, the cross-view rejection, the nested root, and three terminal errors (single-cube view, ambiguous roots, cyclic). The five error tests are sync Security / performanceNo security surface — nothing user-controlled reaches SQL text through this path; the change only decides which cube hints seed join resolution. Performance is slightly better than the previous round: the per-dimension/per-filter DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything — |
1e92272 to
b0b1d9b
Compare
|
Claude finished @MazterQyou's task in 3m 55s —— View job Re-review: both prior code findings addressed — 0 medium, 1 low (1 inline comment), 2 prior threads still openFull review
Prior findings
What I verifiedThe known-hole documentation matches the control flow exactly. Re-ran the root rule against every fixture join map (the mock keeps only
The Snapshot arithmetic is unaffected by this round — the grouping and the fallback chain are untouched — so New finding
Doesn't block. Anchoring on the join shape (a Code qualityThe known-hole paragraph is the best kind of comment for this: it states the hazard, names the mechanism that causes it, points at the test that pins it, and explains why closing it is a larger change than the fix at hand — including the non-obvious consequence that resolving from the view bucket whenever the measure's own hints are empty would make the ordinary case (a view dimension next to The new test's comment carries the same weight, and "if it is ever closed, this test flips to expecting the same rejection as the one below" is exactly the instruction that keeps a behaviour-pinning test from being mistaken for a behaviour-asserting one. Everything else from the last round holds: the TestingTen tests now: three fallback branches, the cross-view measure rejection, the cross-view dimension hole, the nested root, and three terminal errors. Six of them are sync Security / performanceNo security surface — nothing user-controlled reaches SQL text through this path; the change only decides which cube hints seed join resolution. Performance is unchanged from the last round (this round is documentation and a test); the per-cube map is one DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything — |
b0b1d9b to
1376821
Compare
|
Claude finished @MazterQyou's task in 1m 54s —— View job Re-review: documentation-only round — 0 new findings, 2 prior threads still open (1 partially fixed)Full review
What changed this roundThis push is comments and doc text only — Prior findings
On the fidelity correctionChecked Terminology: one line leftTwo of the three call-outs landed. The one still standing is the line the thread is anchored on, # Not multi-stage itself, but depends on a multi-stage measure, so it
# is skipped when building per-measure hints while still contributing
# to the pooled ones."the pooled ones" is the removed whole-query Code qualityThe expanded The block is long (~40 lines) for one function, but each paragraph answers a question a reader will otherwise have: why a view can't seed itself, why other views aren't borrowed from, why the join map is the last resort and which views it misses, why the meaning is query-dependent, and where the dimension-shaped hole is. Splitting it wouldn't make it shorter, only harder to find. TestingTen tests, unchanged from the last round: three fallback branches, the cross-view measure rejection, the cross-view dimension hole, the nested root, and three terminal errors. Six are sync Security / performanceNo change this round — the diff is comments. No security surface (nothing user-controlled reaches SQL text through this path), and the per-cube DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything — |
Signed-off-by: Alex Qyoun-ae <4062971+MazterQyou@users.noreply.github.com>
1376821 to
4b2f485
Compare
|
Claude finished @MazterQyou's task in 1m 51s —— View job Re-review: both prior threads addressed — 0 new findings, nothing outstandingFull review
Prior findings
What I re-verifiedBoth of these tests are sync Nothing else moved this round. The fallback chain in New findingsNone. Both open threads are closed, and I found nothing new in a fresh read of Code qualityThe final state reads well. The three things that carry the most weight for a future reader are all comments that explain a decision rather than restate code: the "Known hole, kept for legacy parity" paragraph on The one nit left over from several rounds ago still stands and still doesn't matter: the terminal error in TestingEleven tests: three fallback branches, the cross-view measure rejection, the cross-view dimension hole, the nested root, the plain no-hints case, and three terminal errors. Seven always assert; the error cases assert on message content, not just failure. Security / performanceNo change this round. No security surface — nothing user-controlled reaches SQL text through this path; the change only decides which cube hints seed join resolution. The per-cube DocsNothing user-facing changed, so no What I could not verifyI could not build or run anything — LGTM from my side — no blocking issues remain. |
Check List
Description of Changes Made
This PR fixes the
invalid type: unit value, expected struct JoinDefinitionStaticerror for queries whose member expressions on a view carry no join hints of their own, such ascount(*)alongsidecount(distinct <view dimension>). Related tests are included.