mattfaltyn opened a new issue, #17301:
URL: https://github.com/apache/iceberg/issues/17301

   ### Apache Iceberg version
   
   1.11.0 (latest release)
   
   ### Query engine
   
   Other
   
   ### Please describe the bug 🐞
   
   ## Summary
   
   A Parquet read using a `notNaN` filter crashes when the referenced float or 
double column exists in the projected Iceberg schema but is absent from an 
older Parquet file.
   
   This is a normal schema-evolution scenario:
   
   1. Write a Parquet file with schema `{ required long id }`.
   2. Add an optional float column such as `added_float`.
   3. Read the old file using the evolved schema and filter with 
`notNaN("added_float")`.
   
   The added column should read as null for old rows. Iceberg defines null as 
not NaN, so the row group must remain readable. Instead, reader initialization 
throws a `NullPointerException`.
   
   I reproduced this on `main` at commit:
   
   ```text
   1ec15051dc09ef6a0d61fa332eb8f2503f3170f8
   ```
   
   The same faulty code is present in the `apache-iceberg-1.11.0` tag.
   
   ## Minimal reproduction
   
   In `TestDictionaryRowGroupFilter#testColumnNotInFile`, add 
`notNaN("not_in_file")` to the existing `exprs` array:
   
   ```java
   Expression[] exprs =
       new Expression[] {
         lessThan("not_in_file", 1.0f),
         lessThanOrEqual("not_in_file", 1.0f),
         equal("not_in_file", 1.0f),
         greaterThan("not_in_file", 1.0f),
         greaterThanOrEqual("not_in_file", 1.0f),
         notNull("not_in_file"),
         isNull("not_in_file"),
         notEqual("not_in_file", 1.0f),
         notNaN("not_in_file")
       };
   ```
   
   Then run:
   
   ```shell
   ./gradlew --no-build-cache \
     :iceberg-parquet:test \
     --tests org.apache.iceberg.parquet.TestDictionaryRowGroupFilter \
     --no-daemon
   ```
   
   I also reproduced the failure twice through the production 
`Parquet.read(...)` path by writing an old-schema file and reading it with the 
evolved schema.
   
   ## Expected behavior
   
   The reader should retain the row group. Because the column is absent from 
the file, its values are null, and null values satisfy Iceberg's `notNaN` 
expression semantics.
   
   ## Actual behavior
   
   The read fails with:
   
   ```text
   Cannot invoke "java.lang.Boolean.booleanValue()" because
   the return value of "java.util.Map.get(Object)" is null
   ```
   
   The exception originates from `ParquetDictionaryRowGroupFilter.java:178` and 
is reached through `ReadConf.java:109`.
   
   ## Root cause
   
   `ParquetDictionaryRowGroupFilter.EvalVisitor#notNaN` evaluates:
   
   ```java
   if (mayContainNulls.get(id)) {
     return ROWS_MIGHT_MATCH;
   }
   ```
   
   before checking whether the field ID exists in the file metadata:
   
   ```java
   Boolean hasNonDictPage = isFallback.get(id);
   if (hasNonDictPage == null || hasNonDictPage) {
     return ROWS_MIGHT_MATCH;
   }
   ```
   
   For a column absent from the file, neither map has an entry for the field 
ID. The first lookup returns null and is unboxed as a boolean, causing the 
exception.
   
   Moving the existing absent/fallback-column guard before the nullability 
lookup should preserve behavior for present columns while conservatively 
retaining row groups for absent columns.
   
   ## Related history
   
   - #6431 added the nullability check for physically present columns 
containing nulls, but did not cover columns absent from the file.
   - #16692 addresses an initial-default problem in 
`ParquetMetricsRowGroupFilter` and does not change this dictionary-filter path.
   
   I searched existing open and closed issues and pull requests using 
combinations of `notNaN`, `ParquetDictionaryRowGroupFilter`, `missing column`, 
`column not in file`, and `schema evolution`, and did not find an active fix 
for this crash.
   
   ### Willingness to contribute
   
   - [x] I can contribute a fix for this bug independently
   - [ ] I would be willing to contribute a fix for this bug with guidance from 
the Iceberg community
   - [ ] I cannot contribute a fix for this bug at this time


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to