Skip to content

Spark 3.1: fill ORC initial defaults on the row reader - #264

Open
cbb330 wants to merge 1 commit into
chbush/oh120-orc-default-fillfrom
chbush/oh120-spark31-default-fill
Open

Spark 3.1: fill ORC initial defaults on the row reader#264
cbb330 wants to merge 1 commit into
chbush/oh120-orc-default-fillfrom
chbush/oh120-spark31-default-fill

Conversation

@cbb330

@cbb330 cbb330 commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Opts the Spark 3.1 row ORC reader into default filling by supplying BaseDataReader's constant converter to the id-binding StructReader, so an absent field declaring an initial-default is materialized in Spark's in-memory representation.

  • Mirrors the Generic reader from ORC: fill initial defaults for missing id-bound fields #263; the resolution logic itself is shared, not duplicated.
  • The visitor call site in SparkOrcReader is unchanged and byte-identical to upstream — the converter is supplied by SparkOrcValueReaders.StructReader in its own constructor.
  • BaseDataReader.convertConstant is made public so the reader package can reference it.
  • BatchDataReader carries a follow-up note: vectorized reads are not wired, so a table whose schema declares defaults must stay on the row reader.

Provenance

Net new, like #263apache/main throws UnsupportedOperationException rather than reading ORC defaults. The design follows upstream's Parquet reader, where each engine supplies its own constant conversion.

Stack

  1. ORC: bind struct fields by Iceberg field id in generic and Spark 3.1 readers #265 — ID-based StructReader backport (base: openhouse-1.2.0)
  2. ORC: fill initial defaults for missing id-bound fields #263 — Generic ORC initial-default fill
  3. This PR — Spark 3.1 ORC initial-default fill

Depends on #263's converter-aware constructor. Review this PR's own delta against its base branch chbush/oh120-orc-default-fill.

Supported scope

Spark 3.1 ORC row reader. Vectorized ORC, other Spark/Flink readers, and predicate pushdown on omitted default columns remain deferred.

Testing Done

  • Spark 3.1 row tests: declared, undeclared, and nested defaults
  • Spark 3.1 ORC suites pass: TestSparkOrcReaderDefaults (3), TestSparkOrcReader (13), TestSparkOrcReadMetadataColumns (6) — 22 tests, 0 failures
  • Full forced rerun across the stack: 481 tests, 0 failures
  • Spotless and checkstyle pass

Tests generated with unit-tests plugin

Made with Cursor

Opt the Spark 3.1 row ORC reader into default filling by supplying Spark's
constant converter to the id-binding StructReader, so an absent field that
declares an initial-default is materialized in Spark's in-memory
representation.

Move convertConstant out of BaseDataReader into SparkValueConverters in the
data package, mirroring Flink's RowDataUtil. The converter is a value
conversion utility rather than reader behavior, and the readers that need it
live in the data package. This keeps BaseDataReader package-private instead
of widening an internal class to public, and leaves the dependency running
source -> data.

Mirrors the Generic reader; the visitor call site is unchanged. Vectorized
reads are not wired yet, so a table whose schema declares defaults must stay
on the row reader.

Co-authored-by: Cursor <cursoragent@cursor.com>
@cbb330
cbb330 force-pushed the chbush/oh120-spark31-default-fill branch from 4f928f2 to 5549db5 Compare July 29, 2026 06:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant