Skip to content

Commit 0918040

Browse files
committed
add ut
1 parent 72d04a7 commit 0918040

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

crates/iceberg/src/arrow/value.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,6 +908,89 @@ mod test {
908908
assert_eq!(result, vec![None; 0]);
909909
}
910910

911+
#[test]
912+
fn test_field_name_fallback_when_id_unavailable() {
913+
// Create an Arrow struct array with fields that don't have field IDs in metadata
914+
let int32_array = Int32Array::from(vec![Some(1), Some(2), None]);
915+
let string_array = StringArray::from(vec![Some("hello"), Some("world"), None]);
916+
917+
let struct_array =
918+
Arc::new(StructArray::from(vec![
919+
(
920+
// Field without field ID metadata - should fallback to name matching
921+
Arc::new(Field::new("field_a", DataType::Int32, true)),
922+
Arc::new(int32_array) as ArrayRef,
923+
),
924+
(
925+
// Field with wrong field ID metadata - should fallback to name matching
926+
Arc::new(Field::new("field_b", DataType::Utf8, true).with_metadata(
927+
HashMap::from([(PARQUET_FIELD_ID_META_KEY.to_string(), "999".to_string())]),
928+
)),
929+
Arc::new(string_array) as ArrayRef,
930+
),
931+
])) as ArrayRef;
932+
933+
// Create Iceberg struct type with field IDs that don't match the Arrow metadata
934+
let iceberg_struct_type = StructType::new(vec![
935+
Arc::new(NestedField::optional(
936+
1, // Different ID than what's in Arrow metadata (or no metadata)
937+
"field_a", // Same name as Arrow field
938+
Type::Primitive(PrimitiveType::Int),
939+
)),
940+
Arc::new(NestedField::optional(
941+
2, // Different ID than what's in Arrow metadata (999)
942+
"field_b", // Same name as Arrow field
943+
Type::Primitive(PrimitiveType::String),
944+
)),
945+
]);
946+
947+
// This should succeed by falling back to field name matching
948+
let result = arrow_struct_to_literal(&struct_array, &iceberg_struct_type).unwrap();
949+
950+
assert_eq!(result, vec![
951+
Some(Literal::Struct(Struct::from_iter(vec![
952+
Some(Literal::int(1)),
953+
Some(Literal::string("hello".to_string())),
954+
]))),
955+
Some(Literal::Struct(Struct::from_iter(vec![
956+
Some(Literal::int(2)),
957+
Some(Literal::string("world".to_string())),
958+
]))),
959+
Some(Literal::Struct(Struct::from_iter(vec![None, None,]))),
960+
]);
961+
}
962+
963+
#[test]
964+
fn test_field_not_found_error() {
965+
// Test that we get an appropriate error when neither field ID nor name matches
966+
967+
let int32_array = Int32Array::from(vec![Some(1), Some(2)]);
968+
969+
let struct_array = Arc::new(StructArray::from(vec![(
970+
Arc::new(Field::new("arrow_field_name", DataType::Int32, true)),
971+
Arc::new(int32_array) as ArrayRef,
972+
)])) as ArrayRef;
973+
974+
// Create Iceberg struct type with field that doesn't match by ID or name
975+
let iceberg_struct_type = StructType::new(vec![Arc::new(NestedField::optional(
976+
10,
977+
"different_field_name", // Different name than Arrow field
978+
Type::Primitive(PrimitiveType::Int),
979+
))]);
980+
981+
// This should fail with an appropriate error message
982+
let result = arrow_struct_to_literal(&struct_array, &iceberg_struct_type);
983+
984+
assert!(result.is_err());
985+
let error = result.unwrap_err();
986+
assert_eq!(error.kind(), ErrorKind::DataInvalid);
987+
assert!(
988+
error.message().contains(
989+
"Field with id=10 or name=different_field_name not found in struct array"
990+
)
991+
);
992+
}
993+
911994
#[test]
912995
fn test_complex_nested() {
913996
// complex nested type for test

0 commit comments

Comments
 (0)