Skip to content

Commit e4f80c7

Browse files
committed
functions: Use AnyDictionaryArray
1 parent 5f88209 commit e4f80c7

1 file changed

Lines changed: 16 additions & 48 deletions

File tree

datafusion/functions/src/core/getfield.rs

Lines changed: 16 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,20 +18,16 @@
1818
use std::sync::Arc;
1919

2020
use arrow::array::{
21-
Array, BooleanArray, Capacities, DictionaryArray, MutableArrayData, Scalar,
22-
make_array, make_comparator,
21+
Array, BooleanArray, Capacities, MutableArrayData, Scalar, cast::AsArray, make_array,
22+
make_comparator,
2323
};
2424
use arrow::compute::SortOptions;
25-
use arrow::datatypes::{
26-
DataType, Field, FieldRef, Int8Type, Int16Type, Int32Type, Int64Type, UInt8Type,
27-
UInt16Type, UInt32Type, UInt64Type,
28-
};
25+
use arrow::datatypes::{DataType, Field, FieldRef};
2926
use arrow_buffer::NullBuffer;
3027

3128
use datafusion_common::cast::{as_map_array, as_struct_array};
3229
use datafusion_common::{
33-
Result, ScalarValue, exec_datafusion_err, exec_err, internal_datafusion_err,
34-
internal_err, plan_datafusion_err,
30+
Result, ScalarValue, exec_datafusion_err, exec_err, internal_err, plan_datafusion_err,
3531
};
3632
use datafusion_expr::expr::ScalarFunction;
3733
use datafusion_expr::simplify::ExprSimplifyResult;
@@ -205,48 +201,20 @@ fn extract_single_field(base: ColumnarValue, name: ScalarValue) -> Result<Column
205201
// Dictionary-encoded struct: extract the field from the dictionary's
206202
// values (the deduplicated struct array) and rebuild a dictionary with
207203
// the same keys. This preserves dictionary encoding without expanding.
208-
(DataType::Dictionary(key_type, value_type), _, Some(field_name))
204+
(DataType::Dictionary(_, value_type), _, Some(field_name))
209205
if matches!(value_type.as_ref(), DataType::Struct(_)) =>
210206
{
211-
// Downcast to DictionaryArray to access keys and values without
212-
// materializing the dictionary.
213-
macro_rules! extract_dict_field {
214-
($key_ty:ty) => {{
215-
let dict = array
216-
.as_any()
217-
.downcast_ref::<DictionaryArray<$key_ty>>()
218-
.ok_or_else(|| {
219-
internal_datafusion_err!(
220-
"Failed to downcast dictionary with key type {key_type}"
221-
)
222-
})?;
223-
let values_struct = as_struct_array(dict.values())?;
224-
let field_col =
225-
values_struct.column_by_name(&field_name).ok_or_else(|| {
226-
exec_datafusion_err!(
227-
"Field {field_name} not found in dictionary struct"
228-
)
229-
})?;
230-
// Rebuild dictionary: same keys, extracted field as values.
231-
let new_dict = DictionaryArray::<$key_ty>::try_new(
232-
dict.keys().clone(),
233-
Arc::clone(field_col),
234-
)?;
235-
Ok(ColumnarValue::Array(Arc::new(new_dict)))
236-
}};
237-
}
238-
239-
match key_type.as_ref() {
240-
DataType::Int8 => extract_dict_field!(Int8Type),
241-
DataType::Int16 => extract_dict_field!(Int16Type),
242-
DataType::Int32 => extract_dict_field!(Int32Type),
243-
DataType::Int64 => extract_dict_field!(Int64Type),
244-
DataType::UInt8 => extract_dict_field!(UInt8Type),
245-
DataType::UInt16 => extract_dict_field!(UInt16Type),
246-
DataType::UInt32 => extract_dict_field!(UInt32Type),
247-
DataType::UInt64 => extract_dict_field!(UInt64Type),
248-
other => exec_err!("Unsupported dictionary key type: {other}"),
249-
}
207+
let dict = array.as_any_dictionary();
208+
let values_struct = dict.values().as_struct();
209+
let field_col =
210+
values_struct.column_by_name(&field_name).ok_or_else(|| {
211+
exec_datafusion_err!(
212+
"Field {field_name} not found in dictionary struct"
213+
)
214+
})?;
215+
Ok(ColumnarValue::Array(
216+
dict.with_values(Arc::clone(field_col)),
217+
))
250218
}
251219
(DataType::Map(_, _), ScalarValue::List(arr), _) => {
252220
let key_array: Arc<dyn Array> = arr;

0 commit comments

Comments
 (0)