Skip to content

fix(spark): return the requested field when Spark prunes nested fields - #10724

Merged
robert3005 merged 5 commits into
vortex-data:developfrom
gitRasheed:spark-nested-schema-pruning-fix
Oct 23, 2026
Merged

robert3005 merged 5 commits into
vortex-data:developfrom
gitRasheed:spark-nested-schema-pruning-fix

Conversation

@gitRasheed

@gitRasheed gitRasheed commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #10723

Reading one field of a nested column returned a different field, because readSchema() described pruned structs while the native scan returns each top-level column whole.

Changes

pruneColumns now keeps each required column with its full table type, in table order, so readSchema() matches what the reader returns. A query that uses one field of a nested column still reads the whole column.

VortexNestedSchemaPruningTest selects a non-first field from a struct, an array of structs, a map of structs and a struct inside a struct. All four fail without the fix. VortexScanBuilderTest.pruneColumnsKeepsTableTypes checks the read schema directly.

I used AI tools to help write and review this change.

…t fields

With spark.sql.optimizer.nestedSchemaPruning.enabled (the Spark default),
pruneColumns receives struct columns with unused fields removed. The native
scan only projects top-level columns and returns the full struct, but
readSchema() reported the pruned type, so Spark bound nested fields by the
pruned ordinals and silently returned the wrong field: selecting s.c from
s{a,b,c} returned s.a.

Keep each required column's full table type, so readSchema() matches the
data the reader returns. Nested pruning in the native scan can follow.

Signed-off-by: gitRasheed <99349713+gitRasheed@users.noreply.github.com>
Keep the table's columns that Spark requires instead of rebuilding them from
the required schema, so a pruned type can't slip back in. Test struct, array,
map and struct-in-struct fields, and document that pruning is top-level only.

Signed-off-by: gitRasheed <99349713+gitRasheed@users.noreply.github.com>
The Java CI job runs `gradlew check`, which includes spotlessCheck.

Signed-off-by: gitRasheed <99349713+gitRasheed@users.noreply.github.com>
Pin the pruneColumns contract without going through Spark's optimizer: a
nested-pruned required schema yields the table's full column types, in
table order, and unrequired columns are dropped.

Signed-off-by: gitRasheed <99349713+gitRasheed@users.noreply.github.com>
… note

Signed-off-by: gitRasheed <99349713+gitRasheed@users.noreply.github.com>
@gitRasheed
gitRasheed force-pushed the spark-nested-schema-pruning-fix branch from aa17508 to a7744f2 Compare October 23, 2026 13:11
@robert3005 robert3005 added the changelog/fix A bug fix label Oct 23, 2026
@robert3005
robert3005 merged commit ff79104 into vortex-data:develop Oct 23, 2026
115 of 118 checks passed
@codspeed

codspeed Bot commented Oct 23, 2026

Copy link
Copy Markdown

Merging this PR will degrade performance by 17.8%

3 warnings, 1 note

⚠️ Walltime results may be unreliable

Some benchmarks used the Walltime instrument outside CodSpeed Macro Runners, which can make the results inconsistent.

Learn more about Macro Runners

See affected benchmarks

⚠️ Unable to measure the execution of 2 benchmarks

These benchmarks measured no execution time, so their results are not comparable and count as unchanged. This usually happens when the compiler removes the code under test.

Prevent compiler optimizations

See affected benchmarks

⚠️ 17 benchmarks are dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

ℹ️ 40 benchmarks have no flamegraph

The flamegraph wasn't generated: the symbols of the profiling trace could not be resolved, because no information about the language frames was collected.

See affected benchmarks

⚡ 1 improved benchmark
❌ 7 regressed benchmarks
✅ 2400 untouched benchmarks
⏩ 12 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
❌ Walltime threshold_neon[8] 1.3 µs 2.4 µs -45.42%
❌ Walltime threshold_neon[64] 2.6 µs 3.6 µs -28.8%
❌ Walltime filter_neon[8] 880 ns 1,142 ns -22.94%
❌ Walltime threshold_neon[80] 3.9 µs 4.6 µs -14.76%
❌ Walltime filter_neon[64] 1.7 µs 1.9 µs -10.18%
❌ Walltime filter_neon[80] 2.5 µs 2.8 µs -10.18%
❌ Walltime words_gather_dispatch_neon[65536] 1.8 µs 2 µs -10.02%
⚡ Walltime bitpack_blocked_compress_avx2 7.5 µs 6.7 µs +12.51%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing gitRasheed:spark-nested-schema-pruning-fix (a7744f2) with develop (2f2dfce)2

Open in CodSpeed

Footnotes

  1. 12 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 (756f1eb) during the generation of this report, so 2f2dfce was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/fix A bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Spark returns the wrong nested field when nested schema pruning is on

2 participants