@@ -57,6 +57,20 @@ Status DecodeFieldToBuilder(const ::avro::NodePtr& avro_node,
5757 ::avro::Decoder* decoder, arrow::ArrayBuilder* array_builder,
5858 AvroDirectDecoder::DecodeContext* ctx);
5959
60+ Status ReserveBuilderCapacityImpl (int64_t capacity, arrow::ArrayBuilder* array_builder) {
61+ PAIMON_RETURN_NOT_OK_FROM_ARROW (array_builder->Reserve (capacity));
62+ if (array_builder->type ()->id () != arrow::Type::STRUCT ) {
63+ return Status::OK ();
64+ }
65+
66+ auto * struct_builder = checked_cast<arrow::StructBuilder*>(array_builder);
67+ for (int32_t i = 0 ; i < struct_builder->num_fields (); ++i) {
68+ PAIMON_RETURN_NOT_OK (
69+ ReserveBuilderCapacityImpl (capacity, struct_builder->field_builder (i)));
70+ }
71+ return Status::OK ();
72+ }
73+
6074// / \brief Skip an Avro value based on its schema without decoding
6175Status SkipAvroValue (const ::avro::NodePtr& avro_node, ::avro::Decoder* decoder) {
6276 switch (avro_node->type ()) {
@@ -193,6 +207,7 @@ Status DecodeListToBuilder(const ::avro::NodePtr& avro_node, ::avro::Decoder* de
193207 // Read array block count
194208 int64_t block_count = decoder->arrayStart ();
195209 while (block_count != 0 ) {
210+ PAIMON_RETURN_NOT_OK (ReserveBuilderCapacityImpl (block_count, value_builder));
196211 for (int64_t i = 0 ; i < block_count; ++i) {
197212 PAIMON_RETURN_NOT_OK (DecodeFieldToBuilder (element_node, /* projection=*/ std::nullopt ,
198213 decoder, value_builder, ctx));
@@ -221,6 +236,8 @@ Status DecodeMapToBuilder(const ::avro::NodePtr& avro_node, ::avro::Decoder* dec
221236 // Read map block count
222237 int64_t block_count = decoder->mapStart ();
223238 while (block_count != 0 ) {
239+ PAIMON_RETURN_NOT_OK (ReserveBuilderCapacityImpl (block_count, key_builder));
240+ PAIMON_RETURN_NOT_OK (ReserveBuilderCapacityImpl (block_count, item_builder));
224241 for (int64_t i = 0 ; i < block_count; ++i) {
225242 PAIMON_RETURN_NOT_OK (DecodeFieldToBuilder (key_node, /* projection=*/ std::nullopt ,
226243 decoder, key_builder, ctx));
@@ -248,6 +265,8 @@ Status DecodeMapToBuilder(const ::avro::NodePtr& avro_node, ::avro::Decoder* dec
248265 // Read array block count
249266 int64_t block_count = decoder->arrayStart ();
250267 while (block_count != 0 ) {
268+ PAIMON_RETURN_NOT_OK (ReserveBuilderCapacityImpl (block_count, key_builder));
269+ PAIMON_RETURN_NOT_OK (ReserveBuilderCapacityImpl (block_count, item_builder));
251270 for (int64_t i = 0 ; i < block_count; ++i) {
252271 PAIMON_RETURN_NOT_OK (DecodeFieldToBuilder (key_node, /* projection=*/ std::nullopt ,
253272 decoder, key_builder, ctx));
@@ -447,4 +466,9 @@ Status AvroDirectDecoder::DecodeAvroToBuilder(const ::avro::NodePtr& avro_node,
447466 return DecodeFieldToBuilder (avro_node, projection, decoder, array_builder, ctx);
448467}
449468
469+ Status AvroDirectDecoder::ReserveBuilderCapacity (int64_t capacity,
470+ arrow::ArrayBuilder* array_builder) {
471+ return ReserveBuilderCapacityImpl (capacity, array_builder);
472+ }
473+
450474} // namespace paimon::avro
0 commit comments