2323#include < arrow/array/builder_primitive.h>
2424#include < arrow/extension_type.h>
2525#include < arrow/json/from_string.h>
26+ #include < arrow/scalar.h>
2627#include < arrow/type.h>
2728#include < arrow/util/decimal.h>
2829#include < avro/Generic.hh>
@@ -90,7 +91,7 @@ Status AppendStructToBuilder(const ::avro::NodePtr& avro_node,
9091 } else if (field_projection.kind == FieldProjection::Kind::kNull ) {
9192 ICEBERG_ARROW_RETURN_NOT_OK (field_builder->AppendNull ());
9293 } else if (field_projection.kind == FieldProjection::Kind::kDefault ) {
93- ICEBERG_RETURN_UNEXPECTED (arrow:: AppendDefaultToBuilder (
94+ ICEBERG_RETURN_UNEXPECTED (AppendDefaultToBuilder (
9495 std::get<Literal>(field_projection.from ), field_builder));
9596 } else if (field_projection.kind == FieldProjection::Kind::kMetadata ) {
9697 int32_t field_id = expected_field.field_id ();
@@ -468,8 +469,7 @@ Status AppendFieldToBuilder(const ::avro::NodePtr& avro_node,
468469 }
469470
470471 if (projection.kind == FieldProjection::Kind::kDefault ) {
471- return arrow::AppendDefaultToBuilder (std::get<Literal>(projection.from ),
472- array_builder);
472+ return AppendDefaultToBuilder (std::get<Literal>(projection.from ), array_builder);
473473 }
474474
475475 if (avro_node->type () == ::avro::AVRO_UNION ) {
@@ -496,6 +496,29 @@ Status AppendFieldToBuilder(const ::avro::NodePtr& avro_node,
496496
497497} // namespace
498498
499+ Status AppendDefaultToBuilder (const Literal& literal, ::arrow::ArrayBuilder* builder) {
500+ // The builder's own memory pool is not exposed, so the small scalar buffer uses the
501+ // default pool.
502+ ICEBERG_ASSIGN_OR_RAISE (std::shared_ptr<::arrow::Scalar> scalar,
503+ arrow::ToArrowScalar (literal, ::arrow::default_memory_pool ()));
504+
505+ // For an extension builder (e.g. `arrow.uuid`) target its storage type: ToArrowScalar
506+ // yields the storage scalar (fixed_size_binary(16) for uuid) and Scalar::CastTo has no
507+ // kernel that targets an extension type. This mirrors MakeDefaultArray's extension
508+ // handling.
509+ std::shared_ptr<::arrow::DataType> target_type = builder->type ();
510+ if (target_type->id () == ::arrow::Type::EXTENSION ) {
511+ target_type = internal::checked_cast<const ::arrow::ExtensionType&>(*target_type)
512+ .storage_type ();
513+ }
514+
515+ if (!scalar->type ->Equals (*target_type)) {
516+ ICEBERG_ARROW_ASSIGN_OR_RETURN (scalar, scalar->CastTo (target_type));
517+ }
518+ ICEBERG_ARROW_RETURN_NOT_OK (builder->AppendScalar (*scalar));
519+ return {};
520+ }
521+
499522Status AppendDatumToBuilder (const ::avro::NodePtr& avro_node,
500523 const ::avro::GenericDatum& avro_datum,
501524 const SchemaProjection& projection,
0 commit comments