(
keys: &ArrayRef,
values: &ArrayRef,
can_evaluate_to_const: bool,
data_type: &DataType,
)
| 240 | } |
| 241 | |
| 242 | fn make_map_batch_internal( |
| 243 | keys: &ArrayRef, |
| 244 | values: &ArrayRef, |
| 245 | can_evaluate_to_const: bool, |
| 246 | data_type: &DataType, |
| 247 | ) -> Result<ColumnarValue> { |
| 248 | if keys.len() != values.len() { |
| 249 | return exec_err!("map requires key and value lists to have the same length"); |
| 250 | } |
| 251 | |
| 252 | // Use the array path (make_map_array_internal) in these cases: |
| 253 | // 1. Not const evaluation (!can_evaluate_to_const) - allows scalar elimination optimization |
| 254 | // 2. NULL maps present (keys.null_count() > 0) - fast path doesn't handle NULL list elements |
| 255 | if !can_evaluate_to_const || keys.null_count() > 0 { |
| 256 | return match data_type { |
| 257 | DataType::LargeList(..) => make_map_array_internal::<i64>(keys, values), |
| 258 | DataType::List(..) => make_map_array_internal::<i32>(keys, values), |
| 259 | DataType::FixedSizeList(..) => { |
| 260 | // FixedSizeList doesn't use OffsetSizeTrait, so handle it separately |
| 261 | make_map_array_from_fixed_size_list(keys, values) |
| 262 | } |
| 263 | _ => exec_err!( |
| 264 | "Expected List, LargeList, or FixedSizeList, got {:?}", |
| 265 | data_type |
| 266 | ), |
| 267 | }; |
| 268 | } |
| 269 | |
| 270 | let key_field = Arc::new(Field::new("key", keys.data_type().clone(), false)); |
| 271 | let value_field = Arc::new(Field::new("value", values.data_type().clone(), true)); |
| 272 | let mut entry_struct_buffer: VecDeque<(Arc<Field>, ArrayRef)> = VecDeque::new(); |
| 273 | let mut entry_offsets_buffer = VecDeque::new(); |
| 274 | entry_offsets_buffer.push_back(0); |
| 275 | |
| 276 | entry_struct_buffer.push_back((Arc::clone(&key_field), Arc::clone(keys))); |
| 277 | entry_struct_buffer.push_back((Arc::clone(&value_field), Arc::clone(values))); |
| 278 | entry_offsets_buffer.push_back(keys.len() as u32); |
| 279 | |
| 280 | let entry_struct: Vec<(Arc<Field>, ArrayRef)> = entry_struct_buffer.into(); |
| 281 | let entry_struct = StructArray::from(entry_struct); |
| 282 | |
| 283 | let map_data_type = DataType::Map( |
| 284 | Arc::new(Field::new( |
| 285 | "entries", |
| 286 | entry_struct.data_type().clone(), |
| 287 | false, |
| 288 | )), |
| 289 | false, |
| 290 | ); |
| 291 | |
| 292 | let entry_offsets: Vec<u32> = entry_offsets_buffer.into(); |
| 293 | let entry_offsets_buffer = Buffer::from(entry_offsets.to_byte_slice()); |
| 294 | |
| 295 | let map_data = ArrayData::builder(map_data_type) |
| 296 | .len(entry_offsets.len() - 1) |
| 297 | .add_buffer(entry_offsets_buffer) |
| 298 | .add_child_data(entry_struct.to_data()) |
| 299 | .build()?; |
no test coverage detected
searching dependent graphs…