(
records: &[Value],
name: &str,
row_type: &RowType,
num_rows: usize,
)
| 529 | } |
| 530 | |
| 531 | fn build_row_column( |
| 532 | records: &[Value], |
| 533 | name: &str, |
| 534 | row_type: &RowType, |
| 535 | num_rows: usize, |
| 536 | ) -> crate::Result<Arc<dyn arrow_array::Array>> { |
| 537 | let idx = field_index(records, name); |
| 538 | let sub_records: Vec<Value> = (0..num_rows) |
| 539 | .map(|i| match get_field_at(&records[i], idx) { |
| 540 | Some(v @ Value::Record(_)) => v.clone(), |
| 541 | _ => Value::Record(vec![]), |
| 542 | }) |
| 543 | .collect(); |
| 544 | |
| 545 | let mut child_columns: Vec<Arc<dyn arrow_array::Array>> = Vec::new(); |
| 546 | let mut arrow_fields: Vec<Arc<arrow_schema::Field>> = Vec::new(); |
| 547 | |
| 548 | for field in row_type.fields() { |
| 549 | let col = build_column(&sub_records, field.name(), field.data_type(), num_rows)?; |
| 550 | let arrow_type = crate::arrow::paimon_type_to_arrow(field.data_type())?; |
| 551 | arrow_fields.push(Arc::new(arrow_schema::Field::new( |
| 552 | field.name(), |
| 553 | arrow_type, |
| 554 | field.data_type().is_nullable(), |
| 555 | ))); |
| 556 | child_columns.push(col); |
| 557 | } |
| 558 | |
| 559 | let nulls = NullBuffer::new(BooleanBuffer::from( |
| 560 | (0..num_rows) |
| 561 | .map(|i| get_field_at(&records[i], idx).is_some()) |
| 562 | .collect::<Vec<_>>(), |
| 563 | )); |
| 564 | |
| 565 | let struct_arr = StructArray::try_new(arrow_fields.into(), child_columns, Some(nulls)) |
| 566 | .map_err(|e| Error::UnexpectedError { |
| 567 | message: format!("Failed to build StructArray: {e}"), |
| 568 | source: Some(Box::new(e)), |
| 569 | })?; |
| 570 | Ok(Arc::new(struct_arr)) |
| 571 | } |
| 572 | |
| 573 | /// Parse a decimal string (e.g. "999.99") into unscaled i128 with the given scale. |
| 574 | /// For example, "999.99" with scale=2 → 99999; "0.000000000000000001" with scale=18 → 1. |
no test coverage detected