Skip to content

Add TPC-DS SLT plan tests - #9861

Merged
joseph-isaacs merged 3 commits into
developfrom
ji/tpcds-slt-plans
Sep 16, 2026
Merged

joseph-isaacs merged 3 commits into
developfrom
ji/tpcds-slt-plans

Conversation

@joseph-isaacs

@joseph-isaacs joseph-isaacs commented Sep 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

First of two stacked PRs bringing TPC-DS into the SLT suite, following the same layout as TPC-H (#9794 did the equivalent for ClickBench). This one adds the fixtures and the EXPLAIN plans; result records and the Parquet comparison follow in the PR stacked on top.

It also carries a DuckDB correctness fix that has to land with or before the plans, because without it the recorded plans would contain shared CTEs that the fix removes.

Changes

TPC-DS fixtures and plans

  • slt/tpcds/generate_data.sh generates the 24 tables with DuckDB's tpcds extension through uvx, exports them to Parquet, converts each to Vortex with vx convert, and then runs duckdb/parity.slt, which reads every table in both formats through DuckDB and fails if any row differs. slt/generate_data.sh accepts tpcds like the other datasets; CI already calls the wrapper.
  • Per engine: create.slt.no, drop.slt.no and plans/q1.slt.no to plans/q99.slt.no, from the upstream queries in vortex-bench/sql/tpcds, run unchanged. tpcds.slt asserts the plans against Vortex (EXPLAIN (FORMAT json) with explain_output = 'all' on DuckDB). All 99 queries plan on both engines.
  • The runner registers TPC-DS as a generated-data suite, so its tests report as ignored until both fixture formats exist, rather than failing. README updated.

Most of the diff is the 198 generated plan files; the hand-written part is the generator, the two tpcds.slt drivers, parity.slt, and a four-line runner change.

DuckDB: stop merging Vortex scans that have different pushdown

DuckDB's common-subplan optimizer keys a scan on its serialized form. The Vortex table function keeps pushed-down filters, projections and aggregates in its FFI bind data, which has no serializer, so two scans of the same file with different pushed-down filters serialized identically and were merged into one shared CTE, handing one branch the other's rows. Parquet is unaffected because its filters live in table_filters, which are serialized. Setting verify_serialization = false is how DuckDB expects a function with opaque bind data to opt out of plan serialization, and therefore of subplan merging.

TPC-DS q28 is what surfaced this: its six quantity buckets all returned the fifth bucket's average. Those queries are covered by the result records in the stacked PR.

The TPC-H q11 DuckDB plan is regenerated as a consequence: its scalar subquery is no longer folded into a shared CTE, so the plan gains the scans it previously read back through CTE_SCAN. The CTE and CTE_SCAN nodes disappear, no cardinality estimate changes value, and q11's results are unchanged.

API Changes

verify_serialization = false on the Vortex DuckDB table function opts its plans out of serialization. The visible effect is that DuckDB no longer merges two Vortex scans of the same file into one shared subplan, which changes recorded EXPLAIN output for queries that scan a file more than once. Query results only change where they were previously wrong.

Testing

The TPC-DS plan files are the new tests. I could not run them in this environment — the container has no flatc, so vortex-sqllogictest does not build here at all (failed to run flatc: No such file or directory); this is unrelated to the change. Verification is left to CI.

Earlier in this work, on the combined branch, the full TPC-DS suite passed on both engines, and the verify_serialization change was confirmed to be what fixes q28.

🤖 Generated with Claude Code

https://claude.ai/code/session_01L57FHoJ15heJVNaqgRq7xB

@joseph-isaacs joseph-isaacs added changelog/fix A bug fix ext/duckdb Relates to the DuckDB integration ext/datafusion Relates to the DataFusion integration labels Sep 14, 2026 — with Claude
@codspeed

codspeed Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Merging this PR will improve performance by 12.08%

⚠️ Unknown Walltime execution environment detected

Using the Walltime instrument on standard Hosted Runners will lead to inconsistent data.

For the most accurate results, we recommend using CodSpeed Macro Runners: bare-metal machines fine-tuned for performance measurement consistency.

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 2 improved benchmarks
✅ 2196 untouched benchmarks
🆕 4 new benchmarks
⏩ 218 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
⚡ Simulation allocate_drop_arrow[0] 456.9 ns 402.7 ns +13.45%
⚡ WallTime mul_u32_nonnull_avx512 6.2 µs 5.6 µs +10.72%
🆕 Simulation scalar_access[(1, false, false)] N/A 208.9 µs N/A
🆕 Simulation scalar_access[(1024, false, false)] N/A 132.3 ms N/A
🆕 Simulation scalar_access[(1024, false, true)] N/A 133.3 ms N/A
🆕 Simulation scalar_access[(1024, true, false)] N/A 100.8 ms N/A

Tip

Curious why performance improved? Comment @codspeedbot explain why performance improved on this PR, or directly use the CodSpeed MCP with your agent.


Comparing ji/tpcds-slt-plans (05cb89f) with develop (d69291f)2

Open in CodSpeed

Footnotes

  1. 218 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

  2. No successful run was found on develop (5c8cac4) during the generation of this report, so d69291f was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@joseph-isaacs
joseph-isaacs added this pull request to stack #9864 September 14, 2026 13:01
joseph-isaacs and others added 2 commits September 14, 2026 15:17
DuckDB's common-subplan optimizer keys a scan on its serialized form. The
Vortex table function keeps pushed-down filters, projections and aggregates
in its FFI bind data, which has no serializer, so two scans of the same file
with different pushed-down filters serialized identically and were merged
into one shared CTE, handing one branch the other's rows. Parquet is
unaffected because its filters live in `table_filters`, which are
serialized.

Setting `verify_serialization = false` is how DuckDB expects a function with
opaque bind data to opt out of plan serialization, and therefore of subplan
merging.

TPC-DS q28 is what surfaced this: its six quantity buckets all returned the
fifth bucket's average.

The TPC-H q11 DuckDB plan is regenerated: its scalar subquery is no longer
folded into a shared CTE, so the plan gains the scans it used to read back
through `CTE_SCAN`. Results are unchanged.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L57FHoJ15heJVNaqgRq7xB
Mirror the TPC-H and ClickBench SLT layout for TPC-DS at scale factor 0.1.
`slt/tpcds/generate_data.sh` generates the 24 tables with DuckDB's tpcds
extension, exports them to Parquet, converts each to Vortex, and runs
`duckdb/parity.slt`, which reads every table in both formats through DuckDB
and fails if any row differs. The wrapper `slt/generate_data.sh` accepts
`tpcds` like the other datasets.

Each engine gets `plans/q1` to `plans/q99` from the upstream queries in
`vortex-bench/sql/tpcds`, run unchanged, and `tpcds.slt` asserts the EXPLAIN
plans against Vortex. All 99 queries plan on both engines.

Result records and the Parquet comparison follow separately, so this change
is only the plans.

The runner treats TPC-DS like the other generated-data suites: its tests are
ignored until both fixture formats exist.

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L57FHoJ15heJVNaqgRq7xB
Bring the branch up to date with develop and re-run CI, whose previous run
hit a cluster of network failures in job setup (DuckDB source download,
flatc download, CodSpeed CLI install).

Signed-off-by: Joe Isaacs <joe.isaacs@live.co.uk>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A4nMxew6miuF54SW4HYA1G
@joseph-isaacs
joseph-isaacs merged commit 4af09a9 into develop Sep 16, 2026
81 checks passed
@joseph-isaacs
joseph-isaacs deleted the ji/tpcds-slt-plans branch September 16, 2026 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/fix A bug fix ext/datafusion Relates to the DataFusion integration ext/duckdb Relates to the DuckDB integration

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants