Repository navigation
fix(datafusion): infer singleton distinct counts from exact bounds - #10448
Conversation
Report an exact singleton distinct count for bool, integer, decimal, string, binary, and temporal columns with equal exact min/max and an exact zero null count. Float columns also require an exact zero NaN count because Vortex statistics skip NaNs in extrema. Use the shared inference in both in-memory and persistent file statistics. Preserve explicit IsConstant information, reject unknown statistics, and compare original bounds before schema casts can collapse distinct values. Keep signed zero distinct. Move conversion tests into a tests module and add dtype, null, NaN, missing/inexact-statistic, signed-zero, and lossy timestamp-cast cases. This integration change applies to both V1 and V2 scans. No new latency or throughput claim is made for this branch. Tests, lint, formatting, builds, and benchmarks were not run. Signed-off-by: Joseph Isaacs <[email protected]>
Signed-off-by: Joseph Isaacs <[email protected]>
Merging this PR will degrade performance by 18.02%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | WallTime | filter_neon[8] |
988 ns | 2,140 ns | -53.83% |
| ❌ | Simulation | density_sweep_dense_runs[0.001] |
28.5 µs | 45.9 µs | -37.81% |
| ❌ | WallTime | filter_neon[64] |
3.2 µs | 4.5 µs | -29.47% |
| ❌ | WallTime | threshold_neon[80] |
5.2 µs | 6.4 µs | -17.9% |
| ❌ | WallTime | threshold_neon[8] |
3.6 µs | 4.2 µs | -14.83% |
| ❌ | WallTime | starts_with_avx512[8, VarBin] |
40.7 µs | 46.3 µs | -12.1% |
| ❌ | WallTime | bitpack_blocked_compress_avx2 |
6.8 µs | 7.6 µs | -11.36% |
| ❌ | WallTime | filter_neon[80] |
3.3 µs | 3.7 µs | -11.3% |
| ❌ | WallTime | threshold_neon[64] |
5.2 µs | 5.8 µs | -10.57% |
| ⚡ | WallTime | take_u16_nullable_from_65536_avx512[1048576] |
450.8 µs | 395.2 µs | +14.07% |
| ⚡ |
Simulation | test_scan_filter[int] |
3.5 ms | 3.1 ms | +12.52% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing ji/constant-stats-min-max (519b361) with develop (c128e99)
Polar Signals Profiling ResultsLatest Run
Powered by Polar Signals Cloud |
Benchmarks: PolarSignals Profiling 📖Commits: PR datafusion / vortex-file-compressed / ns (1.003x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: FineWeb NVMe 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.990x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.990x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.998x ➖, 1↑ 2↓)
duckdb / parquet / ns (0.982x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=1 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.995x ➖, 0↑ 0↓)
datafusion / parquet / ns (0.997x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.969x ➖, 2↑ 0↓)
duckdb / parquet / ns (0.997x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-DS SF=1 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.987x ➖, 1↑ 0↓)
datafusion / parquet / ns (1.000x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (0.995x ➖, 3↑ 2↓)
duckdb / parquet / ns (1.004x ➖, 1↑ 4↓)
No file size changes detected. |
Benchmarks: Clickbench on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.001x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.001x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.015x ➖, 0↑ 2↓)
duckdb / parquet / ns (0.994x ➖, 2↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=10 on NVME 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (1.001x ➖, 0↑ 0↓)
datafusion / parquet / ns (1.000x ➖, 0↑ 0↓)
duckdb / vortex-file-compressed / ns (1.004x ➖, 0↑ 1↓)
duckdb / parquet / ns (1.001x ➖, 0↑ 0↓)
No file size changes detected. |
Benchmarks: TPC-H SF=1 on S3 📖Commits: PR How to read Verdict and Engines
datafusion / vortex-file-compressed / ns (0.856x ➖, 2↑ 0↓)
datafusion / parquet / ns (0.964x ➖, 1↑ 0↓)
duckdb / vortex-file-compressed / ns (0.787x ➖, 6↑ 0↓)
duckdb / parquet / ns (0.987x ➖, 0↑ 0↓)
|
The stats tests called `VortexSession::default()` without the trait in scope, which broke every `--all-targets` build. Also apply the pinned nightly rustfmt. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EUqrqh9T3YZqy49vq9Tx4i Signed-off-by: Claude <[email protected]>
`store.s_state` has equal exact min/max bounds in TPC-DS SF=1, so it now reports an exact distinct count of 1. DataFusion uses that to make the smaller rank-filtered subquery the build side of the semi join, which turns the `LeftSemi` join into a `RightSemi` join with swapped inputs. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EUqrqh9T3YZqy49vq9Tx4i Signed-off-by: Claude <[email protected]>
With the new exact singleton distinct counts, DataFusion picks the store_sales aggregate as the build side of the store-channel left join and plans the union as a UnionExec instead of an InterleaveExec. Regenerated with `--complete` against SF=0.1 fixtures; the full SLT suite passes locally. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01EUqrqh9T3YZqy49vq9Tx4i Signed-off-by: Claude <[email protected]>
|
CodSpeed Performance Analysis fails on this PR, but the regressions don't come from it.
No fix to port; this needs acknowledging on CodSpeed. I don't have the means to re-run or acknowledge it from here. Generated by Claude Code |
Summary
Vortex can omit
IsConstantfrom file statistics even when the existing exact min/max bounds prove that a column contains one non-null value. For example, a column withmin = max = 'TN'andnull_count = 0currently reports an unknown distinct count to DataFusion. Inferdistinct_count = Exact(1)from those statistics so DataFusion can use the singleton cardinality when planning.Changes
NaNCount, because Vortex extrema skip NaNs.IsConstantinformation and leave the distinct count unknown when the required statistics are missing or inexact.IsConstantonce file statistics aggregate and persist it.The change applies to both V1 and V2 DataFusion scans.
Validation
The added regression cases have not been run. Tests, lint, formatting, builds, and benchmarks have not been run on this branch; no new latency or throughput improvement is claimed.