Skip to content

Parquet: Fix incorrect pruning for nested fields in optional structs - #18069

Open
szehon-ho wants to merge 1 commit into
apache:mainfrom
szehon-ho:codex/parquet-nested-double-metrics-test
Open

Parquet: Fix incorrect pruning for nested fields in optional structs#18069
szehon-ho wants to merge 1 commit into
apache:mainfrom
szehon-ho:codex/parquet-nested-double-metrics-test

Conversation

@szehon-ho

@szehon-ho szehon-ho commented Sep 11, 2026

Copy link
Copy Markdown
Member

Broken case

An optional struct may be null even when one of its nested fields is required. In that case, dereferencing the nested field produces null.

For example, Spark writes both of these rows to one Parquet file:

CREATE TABLE t (
  id INT NOT NULL,
  stats STRUCT<measurement: DOUBLE NOT NULL>
) USING iceberg;

INSERT INTO t VALUES
  (0, NULL),
  (1, STRUCT(CAST(34.0 AS DOUBLE)));

This query must return id = 0 because stats.measurement is null when stats is null:

SELECT id FROM t WHERE stats.measurement IS NULL;

Before this fix, Spark returned no rows. The double writer reported value_count = 1 and null_value_count = 0 for stats.measurement, instead of 2 and 1. Iceberg therefore concluded that the file could not contain a null measurement and incorrectly pruned it.

Cause and fix

Float and double maintain writer-side metrics to exclude NaN values from bounds. Geometry and geography also maintain writer-side metrics for average value sizes. These metrics replace the Parquet footer metrics, but null optional parents were not propagated to metrics produced by descendant writers.

This change propagates an optional parent's null count to every descendant custom metric while preserving bounds, NaN counts, original types, and average value sizes. The existing nested string test continues to cover the unaffected footer-metrics path.

Testing

  • :iceberg-parquet:test --tests "org.apache.iceberg.parquet.TestParquetValueWriters" passes, covering float, double, geometry, and geography beneath a null optional parent, plus the existing direct geospatial case.
  • The nested double Spark SQL test passes across all three Spark 4.1 catalog configurations. Before the fix, all 3 cases returned [] instead of [[0]].
  • :iceberg-parquet:spotlessJavaCheck and :iceberg-spark:iceberg-spark-4.1_2.13:spotlessJavaCheck pass.

AI Disclosure

  • Model: GPT-5
  • Platform/Tool: Codex
  • Human Oversight: partially reviewed
  • Prompt Summary: Fix nested Parquet field metrics for float, double, geometry, and geography beneath optional parents, with unit and Spark SQL regression coverage.

@github-actions github-actions Bot added the data label Sep 11, 2026
@szehon-ho
szehon-ho force-pushed the codex/parquet-nested-double-metrics-test branch from 694e48e to f7e9f11 Compare September 11, 2026 22:13
@szehon-ho szehon-ho changed the title Parquet: Add nested double metrics regression test Spark: Add nested double filter regression test Sep 11, 2026
@github-actions github-actions Bot added the spark label Sep 11, 2026
@szehon-ho
szehon-ho force-pushed the codex/parquet-nested-double-metrics-test branch 2 times, most recently from c9205fe to 0506aa4 Compare September 11, 2026 22:24
@szehon-ho szehon-ho changed the title Spark: Add nested double filter regression test Parquet: Include optional parents in nested field metrics Sep 11, 2026
@szehon-ho
szehon-ho force-pushed the codex/parquet-nested-double-metrics-test branch from 0506aa4 to 98e0663 Compare September 11, 2026 23:05
Propagate null counts from optional Parquet writers to custom metrics produced by descendant fields. This prevents incorrect file pruning for nested float, double, geometry, and geography fields beneath a null optional parent.

Add focused writer-metrics coverage for all affected types and Spark SQL coverage for the resulting nested double filter.

Generated-by: Codex
@szehon-ho
szehon-ho force-pushed the codex/parquet-nested-double-metrics-test branch from 98e0663 to 3950b47 Compare September 11, 2026 23:19
@szehon-ho szehon-ho changed the title Parquet: Include optional parents in nested field metrics Parquet: Fix value and null counts for fields in optional structs Sep 11, 2026
@szehon-ho szehon-ho changed the title Parquet: Fix value and null counts for fields in optional structs Parquet: Fix incorrect pruning for nested fields in optional structs Sep 11, 2026
@szehon-ho
szehon-ho marked this pull request as ready for review September 11, 2026 23:27

@huan233usc huan233usc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM thanks

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants