Skip to content

Commit 10dd0a1

Browse files
committed
Avoid flattening dictionaries in Join InLists
1 parent 9771125 commit 10dd0a1

File tree

1 file changed

+13
-26
lines changed

1 file changed

+13
-26
lines changed

datafusion/physical-plan/src/joins/hash_join/inlist_builder.rs

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
use std::sync::Arc;
2121

2222
use arrow::array::{ArrayRef, StructArray};
23-
use arrow::compute::cast;
2423
use arrow::datatypes::{Field, FieldRef, Fields};
2524
use arrow_schema::DataType;
2625
use datafusion_common::Result;
@@ -33,19 +32,6 @@ pub(super) fn build_struct_fields(data_types: &[DataType]) -> Result<Fields> {
3332
.collect()
3433
}
3534

36-
/// Casts dictionary-encoded arrays to their underlying value type, preserving row count.
37-
/// Non-dictionary arrays are returned as-is.
38-
fn flatten_dictionary_array(array: &ArrayRef) -> Result<ArrayRef> {
39-
match array.data_type() {
40-
DataType::Dictionary(_, value_type) => {
41-
let casted = cast(array, value_type)?;
42-
// Recursively flatten in case of nested dictionaries
43-
flatten_dictionary_array(&casted)
44-
}
45-
_ => Ok(Arc::clone(array)),
46-
}
47-
}
48-
4935
/// Builds InList values from join key column arrays.
5036
///
5137
/// If `join_key_arrays` is:
@@ -65,20 +51,14 @@ fn flatten_dictionary_array(array: &ArrayRef) -> Result<ArrayRef> {
6551
pub(super) fn build_struct_inlist_values(
6652
join_key_arrays: &[ArrayRef],
6753
) -> Result<Option<ArrayRef>> {
68-
// Flatten any dictionary-encoded arrays
69-
let flattened_arrays: Vec<ArrayRef> = join_key_arrays
70-
.iter()
71-
.map(flatten_dictionary_array)
72-
.collect::<Result<Vec<_>>>()?;
73-
7454
// Build the source array/struct
75-
let source_array: ArrayRef = if flattened_arrays.len() == 1 {
55+
let source_array: ArrayRef = if join_key_arrays.len() == 1 {
7656
// Single column: use directly
77-
Arc::clone(&flattened_arrays[0])
57+
Arc::clone(&join_key_arrays[0])
7858
} else {
7959
// Multi-column: build StructArray once from all columns
8060
let fields = build_struct_fields(
81-
&flattened_arrays
61+
&join_key_arrays
8262
.iter()
8363
.map(|arr| arr.data_type().clone())
8464
.collect::<Vec<_>>(),
@@ -88,7 +68,7 @@ pub(super) fn build_struct_inlist_values(
8868
let arrays_with_fields: Vec<(FieldRef, ArrayRef)> = fields
8969
.iter()
9070
.cloned()
91-
.zip(flattened_arrays.iter().cloned())
71+
.zip(join_key_arrays.iter().cloned())
9272
.collect();
9373

9474
Arc::new(StructArray::from(arrays_with_fields))
@@ -152,7 +132,14 @@ mod tests {
152132
assert_eq!(
153133
*result.data_type(),
154134
DataType::Struct(
155-
build_struct_fields(&[DataType::Utf8, DataType::Int32]).unwrap()
135+
build_struct_fields(&[
136+
DataType::Dictionary(
137+
Box::new(DataType::Int8),
138+
Box::new(DataType::Utf8)
139+
),
140+
DataType::Int32
141+
])
142+
.unwrap()
156143
)
157144
);
158145
}
@@ -168,6 +155,6 @@ mod tests {
168155
.unwrap();
169156

170157
assert_eq!(result.len(), 3);
171-
assert_eq!(*result.data_type(), DataType::Utf8);
158+
assert_eq!(result.data_type(), dict_array.data_type());
172159
}
173160
}

0 commit comments

Comments
 (0)