HippoBaro commented on code in PR #11278:
URL: https://github.com/apache/arrow-rs/pull/11278#discussion_r4174734316


##########
parquet/src/arrow/arrow_writer/mod.rs:
##########
@@ -2513,6 +2517,186 @@ mod tests {
         roundtrip(batch_fixed_len_byte_array_decimal, Some(SMALL_SIZE / 2));
     }
 
+    fn read_column(file: Vec<u8>) -> ArrayRef {
+        let reader = ParquetRecordBatchReader::try_new(Bytes::from(file), 
4096).unwrap();
+        let batches: Vec<RecordBatch> = reader.map(|b| b.unwrap()).collect();
+        let arrays: Vec<&dyn Array> = batches.iter().map(|b| 
b.column(0).as_ref()).collect();
+        arrow_select::concat::concat(&arrays).unwrap()
+    }
+
+    fn roundtrip_compatible_column(field: Field, col: ArrayRef) -> ArrayRef {
+        let writer_schema = Arc::new(Schema::new(vec![field]));
+        let batch_schema = Arc::new(Schema::new(vec![Field::new(
+            "c",
+            col.data_type().clone(),
+            col.logical_null_count() != 0,
+        )]));
+        let batch = RecordBatch::try_new(batch_schema, vec![col]).unwrap();
+        let options = ArrowWriterOptions::new().with_skip_arrow_metadata(true);
+        let mut file = vec![];
+        let mut writer =
+            ArrowWriter::try_new_with_options(&mut file, writer_schema, 
options).unwrap();
+        writer.write(&batch).unwrap();
+        writer.close().unwrap();
+        read_column(file)
+    }
+
+    #[test]
+    fn arrow_writer_dense_batches_under_nested_wrapper_schemas() {
+        let run_ends = || Arc::new(Field::new("run_ends", DataType::Int32, 
false));
+        let ree = |value: DataType, nullable| {
+            DataType::RunEndEncoded(run_ends(), Arc::new(Field::new("values", 
value, nullable)))
+        };
+        let assert_unified = |field: Field, actual: ArrayRef, expected: 
&ArrayRef| {
+            assert!(!compute_leaves(&field, &actual).unwrap().is_empty());
+            assert_eq!(
+                roundtrip_compatible_column(field, actual).as_ref(),
+                expected.as_ref()
+            );
+        };
+
+        let item = Arc::new(Field::new_list_field(DataType::Int32, true));
+        let list: ArrayRef = Arc::new(ListArray::new(
+            item.clone(),
+            OffsetBuffer::new(vec![0_i32, 2, 3].into()),
+            Arc::new(Int32Array::from(vec![Some(1), None, Some(3)])),
+            None,
+        ));
+
+        // A dense list under an REE<List> schema uses range traversal; the
+        // schema wrapper is physical, not a second logical list node.
+        let ree_list_field = Field::new("c", ree(list.data_type().clone(), 
false), false);
+        assert_unified(ree_list_field, list.clone(), &list);
+
+        // Dictionary<List> has the same dense logical shape and follows the
+        // same list traversal after schema normalization.
+        let dictionary_list = Field::new(
+            "c",
+            DataType::Dictionary(Box::new(DataType::Int8), 
Box::new(list.data_type().clone())),
+            false,
+        );
+        assert_unified(dictionary_list, list.clone(), &list);
+
+        let dense: ArrayRef = Arc::new(Int32Array::from(vec![Some(7), None, 
Some(9)]));
+        let nested_ree = Field::new("c", ree(ree(DataType::Int32, true), 
false), false);
+        assert_unified(nested_ree, dense.clone(), &dense);
+
+        let dictionary_ree = Field::new(
+            "c",
+            DataType::Dictionary(
+                Box::new(DataType::Int8),
+                Box::new(ree(DataType::Int32, true)),
+            ),
+            false,
+        );
+        assert_unified(dictionary_ree, dense.clone(), &dense);
+
+        // The inverse wrapper order must hoist REE value nullability before
+        // peeling the dictionary; the dense batch contains an actual null.

Review Comment:
   Agreed. `Dictionary<REE<T>>` and `REE<Dictionary<T>>` now have separate 
named tests.



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

Reply via email to