andygrove opened a new issue, #6192:
URL: https://github.com/apache/datafusion-comet/issues/6192

   ### Describe the bug
   
   With `spark.sql.parquet.fieldId.read.enabled=true`, the native scan reads a 
nested struct by position whenever the requested struct has the same field 
names, in the same order and with the same types, as the file's struct but 
different field ids. Spark resolves those fields by id. Schema evolution that 
drops a nested column and adds it back under the same name produces exactly 
this, since the new column gets a new id, and Comet then returns the dropped 
column's old values where Spark returns null.
   
   ### Steps to reproduce
   
   On `main` at 67803a7a4 with the default Spark 4.1 profile and Comet enabled:
   
   ```scala
   import org.apache.spark.sql.Row
   import org.apache.spark.sql.types._
   
   spark.conf.set("spark.sql.parquet.fieldId.read.enabled", "true")
   def withId(id: Int) = new MetadataBuilder().putLong("parquet.field.id", 
id).build()
   def xy(xId: Int, yId: Int) = new StructType()
     .add("x", LongType, true, withId(xId))
     .add("y", LongType, true, withId(yId))
   
   spark.createDataFrame(
       spark.sparkContext.parallelize(Seq(Row(Row(1L, 2L))), 1),
       new StructType().add("s", xy(1, 2), true, withId(10)))
     .write.mode("overwrite").parquet("/tmp/relabel")
   
   // x was dropped and added back, so it now carries id 3
   spark.read
     .schema(new StructType().add("s", xy(3, 2), true, withId(10)))
     .parquet("/tmp/relabel")
     .show()
   ```
   
   | File → requested | Spark | Comet |
   | --- | --- | --- |
   | `s<x (id 1), y (id 2)>` → `s<x (id 3), y (id 2)>` | `{null, 2}` | `{1, 2}` 
|
   | `s<x (id 1), y (id 2)>` → `s<x (id 2), y (id 1)>` | `{2, 1}` | `{1, 2}` |
   | The same two shapes inside `array<struct>` or a map value | read by id | 
read by position |
   | Root `x (id 1), y (id 2)` → `x (id 2), y (id 1)` | `{2, 1}` | `{2, 1}` |
   
   `CometNativeScanExec` is in the plan for every row, checked against Spark 
4.1.3.
   
   ### Expected behavior
   
   The same answers as Spark. Nested fields that carry a field id are matched 
by id, so a requested id the file does not have reads as null.
   
   ### Additional context
   
   `is_pure_structural_narrowing` declines any target that carries field ids 
([schema_adapter.rs#L122-L126](https://github.com/apache/datafusion-comet/blob/67803a7a422c44de07af1e5d25c1dbeae8df68d4/native/core/src/parquet/schema_adapter.rs#L122-L126)),
 so these columns always get a `CometCastColumnExpr`. Its `evaluate` then takes 
the relabel shortcut 
([cast_column.rs#L278](https://github.com/apache/datafusion-comet/blob/67803a7a422c44de07af1e5d25c1dbeae8df68d4/native/core/src/parquet/cast_column.rs#L278))
 because `types_differ_only_in_field_names` 
([cast_column.rs#L41](https://github.com/apache/datafusion-comet/blob/67803a7a422c44de07af1e5d25c1dbeae8df68d4/native/core/src/parquet/cast_column.rs#L41))
 compares names, types and nullability but not `PARQUET:field_id`. The file's 
array comes back relabelled in place.
   
   The shortcut dates to #3536, and 1.0.0 already sent field ids to the native 
scan, so 1.0.0 is probably affected too. I haven't run it. The native Iceberg 
scan is not affected, because it runs the same adapter with `use_field_id` off 
([iceberg_scan.rs#L233](https://github.com/apache/datafusion-comet/blob/67803a7a422c44de07af1e5d25c1dbeae8df68d4/native/core/src/execution/operators/iceberg_scan.rs#L233)).
   
   #5654 fixes it. Its once-per-file `FieldMapping` only allows the relabel 
shortcut when the mapping is positional, and every shape above matches Spark on 
that branch.
   


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