fix: avoid overflow in join cardinality estimation#23788
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #23788 +/- ##
==========================================
- Coverage 80.71% 80.71% -0.01%
==========================================
Files 1089 1089
Lines 368760 368792 +32
Branches 368760 368792 +32
==========================================
+ Hits 297647 297658 +11
- Misses 53372 53387 +15
- Partials 17741 17747 +6 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
cc @asolimando in case you have a chance to review it. |
zhuqi-lucas
left a comment
There was a problem hiding this comment.
LGTM! Clean, targeted fix.
- u128 widening preserves accuracy across the divide, unlike
saturating_mulwhich would collapse tousize::MAX / ndv. Exact → Inexact(usize::MAX)on final-cap is the right degradation.- Test picks
usize::MAX / 2 + 1× 3 — precisely the "overflow-but-recoverable" boundary. Nice.
Auto-propagates to Left/Right/Full via estimate_join_cardinality.
|
run benchmark sql_planner |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing xudong963/fix-join-multiply-overflow (ae47027) to 5de7f1d (merge-base) diff using: sql_planner File an issue against this benchmark runner |
asolimando
left a comment
There was a problem hiding this comment.
Good catch and, as @zhuqi-lucas is saying, this allows to cover more legal cases than saturating_mul, which is nice.
Thanks for the ping for review, LGTM!
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagesql_planner — base (merge-base)
sql_planner — branch
File an issue against this benchmark runner |
|
@xudong963 It looks regression for many cases from the sqlplanner, removed from the merge queue. |
|
run benchmark sql_planner |
|
I rerun the benchmark again to see if it's noisy, and we can merge it after double check. |
|
🤖 Benchmark running (GKE) | trigger CPU Details (lscpu)Comparing xudong963/fix-join-multiply-overflow (29bf69b) to dfe0f26 (merge-base) diff using: sql_planner File an issue against this benchmark runner |
|
🤖 Benchmark completed (GKE) | trigger Instance: CPU Details (lscpu)Details
Resource Usagesql_planner — base (merge-base)
sql_planner — branch
File an issue against this benchmark runner |
|
The latest benchmark is ok. |
Which issue does this PR close?
Rationale for this change
Join cardinality estimation multiplies two
usizerow counts before applying the join-key NDV divisor. A large Cartesian-product intermediate can therefore overflow and panic even when the normalized cardinality is representable. Saturating the product before division would avoid the panic but produce an inaccurate estimate.What changes are included in this PR?
u128before applying the NDV divisor.usize.usize::MAXand mark it inexact, consistent with existing statistics arithmetic.Are these changes tested?
Yes.
Are there any user-facing changes?
Queries with very large join statistics no longer panic during cardinality estimation. There are no public API changes.