|
23 | 23 | #include <arrow/array/builder_primitive.h> |
24 | 24 | #include <arrow/extension_type.h> |
25 | 25 | #include <arrow/json/from_string.h> |
| 26 | +#include <arrow/scalar.h> |
26 | 27 | #include <arrow/type.h> |
27 | 28 | #include <arrow/util/decimal.h> |
28 | 29 | #include <avro/Generic.hh> |
@@ -90,7 +91,7 @@ Status AppendStructToBuilder(const ::avro::NodePtr& avro_node, |
90 | 91 | } else if (field_projection.kind == FieldProjection::Kind::kNull) { |
91 | 92 | ICEBERG_ARROW_RETURN_NOT_OK(field_builder->AppendNull()); |
92 | 93 | } else if (field_projection.kind == FieldProjection::Kind::kDefault) { |
93 | | - ICEBERG_RETURN_UNEXPECTED(arrow::AppendDefaultToBuilder( |
| 94 | + ICEBERG_RETURN_UNEXPECTED(AppendDefaultToBuilder( |
94 | 95 | std::get<Literal>(field_projection.from), field_builder)); |
95 | 96 | } else if (field_projection.kind == FieldProjection::Kind::kMetadata) { |
96 | 97 | int32_t field_id = expected_field.field_id(); |
@@ -471,8 +472,7 @@ Status AppendFieldToBuilder(const ::avro::NodePtr& avro_node, |
471 | 472 | } |
472 | 473 |
|
473 | 474 | if (projection.kind == FieldProjection::Kind::kDefault) { |
474 | | - return arrow::AppendDefaultToBuilder(std::get<Literal>(projection.from), |
475 | | - array_builder); |
| 475 | + return AppendDefaultToBuilder(std::get<Literal>(projection.from), array_builder); |
476 | 476 | } |
477 | 477 |
|
478 | 478 | const bool is_row_lineage = |
@@ -506,6 +506,29 @@ Status AppendFieldToBuilder(const ::avro::NodePtr& avro_node, |
506 | 506 |
|
507 | 507 | } // namespace |
508 | 508 |
|
| 509 | +Status AppendDefaultToBuilder(const Literal& literal, ::arrow::ArrayBuilder* builder) { |
| 510 | + // The builder's own memory pool is not exposed, so the small scalar buffer uses the |
| 511 | + // default pool. |
| 512 | + ICEBERG_ASSIGN_OR_RAISE(std::shared_ptr<::arrow::Scalar> scalar, |
| 513 | + arrow::ToArrowScalar(literal, ::arrow::default_memory_pool())); |
| 514 | + |
| 515 | + // For an extension builder (e.g. `arrow.uuid`) target its storage type: ToArrowScalar |
| 516 | + // yields the storage scalar (fixed_size_binary(16) for uuid) and Scalar::CastTo has no |
| 517 | + // kernel that targets an extension type. This mirrors MakeDefaultArray's extension |
| 518 | + // handling. |
| 519 | + std::shared_ptr<::arrow::DataType> target_type = builder->type(); |
| 520 | + if (target_type->id() == ::arrow::Type::EXTENSION) { |
| 521 | + target_type = internal::checked_cast<const ::arrow::ExtensionType&>(*target_type) |
| 522 | + .storage_type(); |
| 523 | + } |
| 524 | + |
| 525 | + if (!scalar->type->Equals(*target_type)) { |
| 526 | + ICEBERG_ARROW_ASSIGN_OR_RETURN(scalar, scalar->CastTo(target_type)); |
| 527 | + } |
| 528 | + ICEBERG_ARROW_RETURN_NOT_OK(builder->AppendScalar(*scalar)); |
| 529 | + return {}; |
| 530 | +} |
| 531 | + |
509 | 532 | Status AppendDatumToBuilder(const ::avro::NodePtr& avro_node, |
510 | 533 | const ::avro::GenericDatum& avro_datum, |
511 | 534 | const SchemaProjection& projection, |
|
0 commit comments