DsThakurRawat opened a new pull request, #26588:
URL: https://github.com/apache/datafusion/pull/26588

   ## Which issue does this PR close?
   
   - Closes #26393.
   
   ## Rationale for this change
   
   In `datafusion/datasource-parquet/src/schema_coercion.rs`, `Int96Coercer` 
matches leaf column paths against `int96_fields` by traversing the schema with 
a DFS stack. When encountering a list field (`DataType::List`), the previous 
implementation hard-coded:
   ```rust
   child_path.push(".list.");
   child_path.push(unprocessed_child.name());
   ```
   
   However, Parquet files written by Spark with legacy formatting 
(`spark.sql.parquet.writeLegacyFormat=true`), Hive, or older Parquet writers 
produce alternative list structures:
   - Spark legacy 3-level list: repeated group named `bag`, child element named 
`array` (e.g. `at.bag.array`).
   - Hive legacy 3-level list: repeated group named `bag`, child element named 
`array_element` (e.g. `at.bag.array_element`).
   - 2-level list: repeated primitive or group (e.g. `at.array`).
   - Repeated primitive at root or struct level without a synthetic list group.
   
   Because `child_path` assumed `.list.<child_name>`, these legacy schemas 
resulted in non-matching paths such as `at.list.array` vs `at.bag.array`, 
leaving INT96 timestamps as `Timestamp(Nanosecond, None)` instead of coercing 
them to the target resolution (e.g., `Timestamp(Microsecond, None)`).
   
   In addition, container types like `DataType::LargeList` and 
`DataType::FixedSizeList` were previously ignored by `Int96Coercer`.
   
   ## What changes are included in this PR?
   
   - Pass `Option<&'a ParquetType>` in the `StackContext` tuple during schema 
DFS traversal to inspect the matching Parquet schema group/primitive types.
   - Introduce `get_parquet_list_element_info`:
     - For primitive repeated fields (2-level lists of primitives or repeated 
root fields), uses the actual field name without superfluous `.list.` segments.
     - For 3-level lists, dynamically extracts the repeated group name (`list`, 
`bag`, etc.) and element field name (`element`, `array`, `array_element`, etc.).
     - For 2-level lists of structs with multiple fields, resolves the repeated 
group directly as the struct element.
     - Gracefully falls back to standard conventions if Parquet type info is 
missing or unannotated.
   - Expand list pattern matching to support `DataType::LargeList` and 
`DataType::FixedSizeList`.
   - Check both `int96_fields.contains(path)` and 
`current_parquet_type.is_some_and(|pt| pt.is_primitive() && 
pt.get_physical_type() == Type::INT96)`.
   
   ## What is the testing strategy for this PR?
   
   - Added `coerce_int96_to_resolution_with_legacy_list_layouts` unit test 
covering:
     - `standard` 3-level (`list/element`)
     - `spark_legacy` 3-level (`bag/array`)
     - `hive` 3-level (`bag/array_element`)
     - `two_level` (`array`)
     - `two_level_struct` (`array` with multiple struct fields)
     - `repeated_primitive_root` (`repeated int96 at`)
     - `nested_lists_legacy` (multi-dimensional list of lists with legacy 
layouts)
   - Added `coerce_int96_to_resolution_with_large_and_fixed_lists` unit test 
testing `LargeList` and `FixedSizeList` containers.
   - Verified all 295 unit tests in `datafusion-datasource-parquet` pass 
without regressions.
   - Ran `cargo fmt --check` and `cargo clippy -p datafusion-datasource-parquet 
--all-targets -- -D warnings`.
   
   ## Are there any user-facing changes?
   
   No breaking changes. Queries reading Parquet files with legacy list 
structures containing INT96 timestamps will now correctly coerce to the 
configured timestamp resolution instead of retaining nanosecond precision.
   


-- 
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