|
1 | 1 | use crate::serializer::{FlightResult, SerializerTrait}; |
2 | 2 | use crate::Value; |
3 | | -use arrow::array::{ |
4 | | - Array, ArrayData, BooleanArray, Date32Array, Date64Array, DurationMicrosecondArray, |
5 | | - DurationMillisecondArray, DurationNanosecondArray, DurationSecondArray, Float16Array, |
6 | | - Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, RecordBatch, |
7 | | - StringArray, StringViewArray, Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, |
8 | | - Time64NanosecondArray, TimestampMicrosecondArray, TimestampMillisecondArray, |
9 | | - TimestampNanosecondArray, TimestampSecondArray, UInt16Array, UInt32Array, UInt64Array, |
10 | | - UInt8Array, |
11 | | -}; |
| 3 | +use arrow::array::{Array, ArrayData, ArrayRef, BooleanArray, Date32Array, Date64Array, DurationMicrosecondArray, DurationMillisecondArray, DurationNanosecondArray, DurationSecondArray, FixedSizeListArray, Float16Array, Float32Array, Float64Array, Int16Array, Int32Array, Int64Array, Int8Array, LargeListArray, ListArray, RecordBatch, StringArray, StringViewArray, Time32MillisecondArray, Time32SecondArray, Time64MicrosecondArray, Time64NanosecondArray, TimestampMicrosecondArray, TimestampMillisecondArray, TimestampNanosecondArray, TimestampSecondArray, UInt16Array, UInt32Array, UInt64Array, UInt8Array}; |
12 | 4 | use arrow::datatypes::{DataType, TimeUnit}; |
13 | 5 | use napi_derive::napi; |
14 | 6 | use std::collections::HashMap; |
@@ -244,6 +236,33 @@ impl LibrarySerializer { |
244 | 236 | DataType::Time64(time_unit) => { |
245 | 237 | Self::serialize_time64_column(&array_data, time_unit, row_count, &mut column_values); |
246 | 238 | } |
| 239 | + DataType::FixedSizeList(field, size) => { |
| 240 | + let arr = FixedSizeListArray::from(array_data); |
| 241 | + let list_size = *size as usize; |
| 242 | + |
| 243 | + for i in 0..row_count { |
| 244 | + if arr.is_null(i) { |
| 245 | + column_values.push(None); |
| 246 | + } else { |
| 247 | + let child_array = arr.value(i); |
| 248 | + let list_values = Self::extract_fixed_list_values(child_array, field.data_type(), list_size); |
| 249 | + column_values.push(Some(Value::FixedList(list_values))); |
| 250 | + } |
| 251 | + } |
| 252 | + } |
| 253 | + DataType::List(field) | DataType::LargeList(field) => { |
| 254 | + let arr = ListArray::from(array_data); |
| 255 | + |
| 256 | + for i in 0..row_count { |
| 257 | + if arr.is_null(i) { |
| 258 | + column_values.push(None); |
| 259 | + } else { |
| 260 | + let child_array = arr.value(i); |
| 261 | + let list_values = Self::extract_list_values(child_array, field.data_type()); |
| 262 | + column_values.push(Some(Value::List(list_values))); |
| 263 | + } |
| 264 | + } |
| 265 | + } |
247 | 266 | _ => { |
248 | 267 | column_values.resize(row_count, Some(Value::Fallback)); |
249 | 268 | } |
@@ -423,4 +442,103 @@ impl LibrarySerializer { |
423 | 442 | } |
424 | 443 | } |
425 | 444 | } |
| 445 | + |
| 446 | + fn extract_fixed_list_values(array: ArrayRef, data_type: &DataType, size: usize) -> Vec<Value> { |
| 447 | + let mut values = Vec::with_capacity(size); |
| 448 | + |
| 449 | + for i in 0..size { |
| 450 | + if array.is_null(i) { |
| 451 | + values.push(Value::Null); |
| 452 | + continue; |
| 453 | + } |
| 454 | + |
| 455 | + let value = match data_type { |
| 456 | + DataType::Int32 => { |
| 457 | + let arr = array.as_any().downcast_ref::<Int32Array>().unwrap(); |
| 458 | + Value::Int32(arr.value(i)) |
| 459 | + } |
| 460 | + DataType::Int64 => { |
| 461 | + let arr = array.as_any().downcast_ref::<Int64Array>().unwrap(); |
| 462 | + Value::Int64(arr.value(i)) |
| 463 | + } |
| 464 | + DataType::Float32 => { |
| 465 | + let arr = array.as_any().downcast_ref::<Float32Array>().unwrap(); |
| 466 | + Value::F32(arr.value(i)) |
| 467 | + } |
| 468 | + DataType::Float64 => { |
| 469 | + let arr = array.as_any().downcast_ref::<Float64Array>().unwrap(); |
| 470 | + Value::F64(arr.value(i)) |
| 471 | + } |
| 472 | + DataType::Utf8 | DataType::LargeUtf8 => { |
| 473 | + let arr = array.as_any().downcast_ref::<StringArray>().unwrap(); |
| 474 | + Value::String(arr.value(i).to_string()) |
| 475 | + } |
| 476 | + DataType::Boolean => { |
| 477 | + let arr = array.as_any().downcast_ref::<BooleanArray>().unwrap(); |
| 478 | + Value::Bool(arr.value(i)) |
| 479 | + } |
| 480 | + _ => Value::Fallback, |
| 481 | + }; |
| 482 | + |
| 483 | + values.push(value); |
| 484 | + } |
| 485 | + |
| 486 | + values |
| 487 | + } |
| 488 | + |
| 489 | + fn extract_list_values(array: ArrayRef, data_type: &DataType) -> Vec<Value> { |
| 490 | + let size = array.len(); |
| 491 | + let mut values = Vec::with_capacity(size); |
| 492 | + |
| 493 | + for i in 0..size { |
| 494 | + if array.is_null(i) { |
| 495 | + values.push(Value::Null); |
| 496 | + continue; |
| 497 | + } |
| 498 | + |
| 499 | + let value = match data_type { |
| 500 | + DataType::Int32 => { |
| 501 | + let arr = array.as_any().downcast_ref::<Int32Array>().unwrap(); |
| 502 | + Value::Int32(arr.value(i)) |
| 503 | + } |
| 504 | + DataType::Int64 => { |
| 505 | + let arr = array.as_any().downcast_ref::<Int64Array>().unwrap(); |
| 506 | + Value::Int64(arr.value(i)) |
| 507 | + } |
| 508 | + DataType::Float32 => { |
| 509 | + let arr = array.as_any().downcast_ref::<Float32Array>().unwrap(); |
| 510 | + Value::F32(arr.value(i)) |
| 511 | + } |
| 512 | + DataType::Float64 => { |
| 513 | + let arr = array.as_any().downcast_ref::<Float64Array>().unwrap(); |
| 514 | + Value::F64(arr.value(i)) |
| 515 | + } |
| 516 | + DataType::Utf8 | DataType::LargeUtf8 => { |
| 517 | + let arr = array.as_any().downcast_ref::<StringArray>().unwrap(); |
| 518 | + Value::String(arr.value(i).to_string()) |
| 519 | + } |
| 520 | + DataType::Boolean => { |
| 521 | + let arr = array.as_any().downcast_ref::<BooleanArray>().unwrap(); |
| 522 | + Value::Bool(arr.value(i)) |
| 523 | + } |
| 524 | + // Можно добавить рекурсивную обработку вложенных списков |
| 525 | + DataType::List(nested_field) => { |
| 526 | + let nested_list_array = array.as_any().downcast_ref::<ListArray>().unwrap(); |
| 527 | + let nested_child = nested_list_array.value(i); |
| 528 | + let nested_values = Self::extract_list_values(nested_child, nested_field.data_type()); |
| 529 | + Value::List(nested_values) |
| 530 | + } |
| 531 | + DataType::FixedSizeList(nested_field, _) => { |
| 532 | + let nested_list_array = array.as_any().downcast_ref::<FixedSizeListArray>().unwrap(); |
| 533 | + let nested_child = nested_list_array.value(i); |
| 534 | + let nested_values = Self::extract_list_values(nested_child, nested_field.data_type()); |
| 535 | + Value::FixedList(nested_values) |
| 536 | + } |
| 537 | + _ => Value::Fallback, |
| 538 | + }; |
| 539 | + |
| 540 | + values.push(value); |
| 541 | + } |
| 542 | + values |
| 543 | + } |
426 | 544 | } |
0 commit comments