Skip to content

fix(arrow): error on required field absent from data file with no default#2797

Open
mbutrovich wants to merge 2 commits into
apache:mainfrom
mbutrovich:missing_required_default_value
Open

fix(arrow): error on required field absent from data file with no default#2797
mbutrovich wants to merge 2 commits into
apache:mainfrom
mbutrovich:missing_required_default_value

Conversation

@mbutrovich

@mbutrovich mbutrovich commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

Which issue does this PR close?

What changes are included in this PR?

When a projected field is not present in a data file, RecordBatchTransformer resolves it using the spec's Column Projection fallback rules. For a field with no initial-default it produced a null column (rule #4) unconditionally. That is correct only for optional fields.

Per the spec's Default values section, null is a valid default only for an optional field:

If either default is not set for an optional field, then the default value is null for compatibility with older spec versions.

So a required field that is absent from a data file with no initial-default has no valid value, and producing a null column for it violates the field's required (non-nullable) constraint. Previously this surfaced later as a confusing Arrow error (Column '<name>' is declared as non-nullable but contains null values) instead of a clear one.

This PR adds the required-field case to the "not present" fallback in record_batch_transformer.rs: if a field is absent from the data file, has no initial-default, and is required, return Missing required field: <name>. The resolution order now mirrors Iceberg-Java's Parquet readers (BaseParquetReaders / SparkParquetReaders.defaultReader): file value, then initial-default, then null if optional, otherwise error.

Are these changes tested?

Yes, a unit test in record_batch_transformer.rs. Together with the existing test_all_four_spec_rules and schema_evolution_adds_date_column_with_nulls, all combinations of a field absent from the data file are covered:

…ault

RecordBatchTransformer resolved a projected field missing from a data file
by always producing a null column when it had no initial-default. That is
correct only for optional fields. Per the spec's Default values section,
null is a valid default only for optional fields, so a required field that
is absent with no initial-default has no valid value and must error rather
than producing a null column that violates its non-nullable constraint.

Mirror Iceberg-Java's Parquet readers (BaseParquetReaders /
SparkParquetReaders): resolve to the file value, then initial-default, then
null if optional, otherwise raise "Missing required field: <name>".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ArrowReader returns null for a required field absent from a data file, instead of erroring

1 participant