@@ -590,12 +590,11 @@ Status PrepareStructDefaultScalars(std::span<FieldProjection> projections,
590590 auto * field_builder = struct_builder->field_builder (static_cast <int >(i));
591591
592592 if (field_projection.kind == FieldProjection::Kind::kDefault ) {
593- if (dynamic_cast <const AvroDefaultAttributes*>(field_projection.attributes .get ()) !=
594- nullptr ) {
593+ if (field_projection.attributes != nullptr ) {
595594 continue ;
596595 }
597- auto attrs = std::make_shared<AvroDefaultAttributes >();
598- ICEBERG_ASSIGN_OR_RAISE (attrs->scalar ,
596+ auto attrs = std::make_shared<AvroExtraAttributes >();
597+ ICEBERG_ASSIGN_OR_RAISE (attrs->default_scalar ,
599598 MakeDefaultScalar (std::get<Literal>(field_projection.from ),
600599 field_builder->type ()));
601600 field_projection.attributes = std::move (attrs);
@@ -624,11 +623,15 @@ Status AppendDefaultToBuilder(const Literal& literal, ::arrow::ArrayBuilder* bui
624623
625624Status AppendDefaultToBuilder (const FieldProjection& projection,
626625 ::arrow::ArrayBuilder* builder) {
627- if (const auto * attrs =
628- dynamic_cast <const AvroDefaultAttributes*>(projection.attributes .get ());
629- attrs != nullptr && attrs->scalar != nullptr ) {
630- ICEBERG_ARROW_RETURN_NOT_OK (builder->AppendScalar (*attrs->scalar ));
631- return {};
626+ // Avro projections carry a single attributes type, so once one is attached it is an
627+ // AvroExtraAttributes; use checked_cast instead of a per-row dynamic_cast.
628+ if (projection.attributes != nullptr ) {
629+ const auto & attrs =
630+ internal::checked_cast<const AvroExtraAttributes&>(*projection.attributes );
631+ if (attrs.default_scalar != nullptr ) {
632+ ICEBERG_ARROW_RETURN_NOT_OK (builder->AppendScalar (*attrs.default_scalar ));
633+ return {};
634+ }
632635 }
633636 return AppendDefaultToBuilder (std::get<Literal>(projection.from ), builder);
634637}
0 commit comments