Skip to content

Commit d8d980b

Browse files
authored
fix(arrow-array): disallow creating MapArray with nullable key field (#10272)
# Which issue does this PR close? - Closes #10268 # Rationale for this change we should be unable to create invalid MapArray according to the spec # What changes are included in this PR? added validation that key field is not nullable # Are these changes tested? yes # Are there any user-facing changes? yes, it will now fail for nullable key field
1 parent 8205c54 commit d8d980b

4 files changed

Lines changed: 392 additions & 33 deletions

File tree

arrow-array/src/array/map_array.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ impl MapArray {
6161
/// * `entries.null_count() != 0`
6262
/// * `entries.columns().len() != 2`
6363
/// * `field.data_type() != entries.data_type()`
64+
/// * the keys field is nullable
6465
pub fn try_new(
6566
field: FieldRef,
6667
offsets: OffsetBuffer<i32>,
@@ -109,6 +110,16 @@ impl MapArray {
109110
)));
110111
}
111112

113+
// The Arrow spec requires the "key" field to be non-nullable
114+
// <https://github.com/apache/arrow/blob/98347d233f03bcf4d116d77f1769d498902b1fc8/format/Schema.fbs#L138>
115+
if entries.fields()[0].is_nullable() {
116+
return Err(ArrowError::InvalidArgumentError(
117+
"MapArray keys field cannot be nullable".to_string(),
118+
));
119+
}
120+
// No need to verify if key contain nulls since `StructArray`
121+
// already disallow nulls for non nullable fields
122+
112123
Ok(Self {
113124
data_type: DataType::Map(field, ordered),
114125
nulls,
@@ -931,6 +942,27 @@ mod tests {
931942
);
932943
}
933944

945+
#[test]
946+
fn test_try_new_nullable_keys_field() {
947+
// https://github.com/apache/arrow-rs/issues/10268
948+
let keys = Int32Array::from(vec![Some(1), None]);
949+
let values = Int32Array::from(vec![None, Some(2)]);
950+
let fields = Fields::from(vec![
951+
Field::new("keys", DataType::Int32, true),
952+
Field::new("values", DataType::Int32, true),
953+
]);
954+
let entries =
955+
StructArray::new(fields.clone(), vec![Arc::new(keys), Arc::new(values)], None);
956+
let field = Arc::new(Field::new("entries", DataType::Struct(fields), false));
957+
958+
let err = MapArray::try_new(field, OffsetBuffer::from_lengths([2]), entries, None, false)
959+
.unwrap_err();
960+
assert_eq!(
961+
err.to_string(),
962+
"Invalid argument error: MapArray keys field cannot be nullable"
963+
);
964+
}
965+
934966
#[test]
935967
fn test_from_vec_of_maps() {
936968
for ordered in [true, false] {

0 commit comments

Comments
 (0)