dwsmith1983 commented on code in PR #5654:
URL: https://github.com/apache/datafusion-comet/pull/5654#discussion_r4095801248


##########
native/core/src/parquet/schema_adapter.rs:
##########
@@ -4170,4 +4686,88 @@ mod test {
         let target = struct_type(vec![("id", DataType::Int64)]);
         assert!(!is_pure_structural_narrowing(&physical, &target, 
&opts).unwrap());
     }
+
+    /// A requested column named like the shield's placeholder must still 
receive its
+    /// configured default. File: `k` (id 2). Required: `k` (id 1) and an 
id-less
+    /// `__COMET_UNMATCHED_FIELD_ID_1` with default 7, case-insensitive, 
field-id reading on.
+    /// The file's `k` is not the id match for requested `k`, so it is hidden 
behind a
+    /// placeholder name; that placeholder must not fold onto the requested 
column, or the
+    /// missing-column check treats it as present and the default is lost.
+    #[tokio::test]
+    async fn parquet_shield_placeholder_never_folds_onto_requested_column() {
+        let file_schema = Arc::new(Schema::new(vec![field_with_id("k", 2)]));
+        let col = Arc::new(Int64Array::from(vec![1])) as Arc<dyn 
arrow::array::Array>;
+        let required_schema = Arc::new(Schema::new(vec![
+            field_with_id("k", 1),
+            Field::new("__COMET_UNMATCHED_FIELD_ID_1", DataType::Int64, true),
+        ]));
+        let defaults = HashMap::from([(
+            Column::new("__COMET_UNMATCHED_FIELD_ID_1", 1),
+            ScalarValue::Int64(Some(7)),
+        )]);
+
+        let mut opts = SparkParquetOptions::new(EvalMode::Legacy, "UTC", 
false);
+        opts.case_sensitive = false;
+        opts.use_field_id = true;
+
+        let batch = scan_with_defaults(
+            file_schema,
+            vec![col],
+            required_schema,
+            opts,
+            Some(defaults),
+        )
+        .await
+        .unwrap();
+        assert_eq!(batch.num_rows(), 1);
+        let k = batch
+            .column(0)
+            .as_any()
+            .downcast_ref::<Int64Array>()
+            .unwrap();
+        assert!(
+            k.is_null(0),
+            "requested k (id 1) has no id match in the file"
+        );
+        let defaulted = batch
+            .column(1)
+            .as_any()
+            .downcast_ref::<Int64Array>()
+            .unwrap();
+        assert!(!defaulted.is_null(0), "configured default must apply");
+        assert_eq!(defaulted.value(0), 7);
+    }
+
+    /// File and requested schema are identical: `s` holding `x` and `y` that 
both carry
+    /// field id 1. No column needs conversion, so no cast is ever emitted, 
yet Spark's
+    /// `clipParquetSchema` rejects the read because requested id 1 resolves 
to two file
+    /// fields. The validation must therefore run when the file schema is 
mapped, not
+    /// only inside a cast.
+    #[tokio::test]
+    async fn parquet_duplicate_struct_field_id_rejected_without_cast() {

Review Comment:
   > Could this one use that shape instead?
   
   Yes. The test is now 
`parquet_duplicate_file_field_id_rejected_when_requested` and uses the shape 
from the first round: the file holds `s<x (id 1), y (id 1), z (id 2)>` and the 
read asks for `s<x (id 1), y (id 3), z (id 2)>`, so the duplicate sits only in 
the file and a planner that declines repeated ids in the requested schema still 
hands this read to the native scan. The scan raises the duplicate id error for 
requested id 1 matching `x` and `y`, where a positional read would hand back 
all three values. The doc comment says why the identical-schema shape is no 
longer reachable and what this one proves instead.
   



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