Skip to content

Commit 5584725

Browse files
committed
fix(format): reset avro reader on schema change
1 parent 7acda1d commit 5584725

2 files changed

Lines changed: 63 additions & 5 deletions

File tree

src/paimon/format/avro/avro_file_batch_reader.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,18 +142,27 @@ Status AvroFileBatchReader::SetReadSchema(::ArrowSchema* read_schema,
142142
if (selection_bitmap) {
143143
// TODO(menglingda.mld): support bitmap
144144
}
145-
previous_first_row_ = std::numeric_limits<uint64_t>::max();
146-
next_row_to_read_ = std::numeric_limits<uint64_t>::max();
147145
PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::Schema> arrow_read_schema,
148146
arrow::ImportSchema(read_schema));
149147
PAIMON_ASSIGN_OR_RAISE(std::shared_ptr<arrow::Schema> file_schema,
150148
ArrowUtils::DataTypeToSchema(file_data_type_));
151-
PAIMON_ASSIGN_OR_RAISE(read_fields_projection_,
149+
PAIMON_ASSIGN_OR_RAISE(std::set<size_t> read_fields_projection,
152150
CalculateReadFieldsProjection(file_schema, arrow_read_schema->fields()));
153-
array_builder_->Reset();
154151
std::shared_ptr<::arrow::DataType> read_data_type = arrow::struct_(arrow_read_schema->fields());
155-
PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(array_builder_,
152+
PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::unique_ptr<arrow::ArrayBuilder> array_builder,
156153
arrow::MakeBuilder(read_data_type, arrow_pool_.get()));
154+
PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<::avro::DataFileReaderBase> reader,
155+
CreateDataFileReader(input_stream_, pool_));
156+
157+
if (reader_) {
158+
reader_->close();
159+
}
160+
reader_ = std::move(reader);
161+
read_fields_projection_ = std::move(read_fields_projection);
162+
array_builder_ = std::move(array_builder);
163+
previous_first_row_ = std::numeric_limits<uint64_t>::max();
164+
next_row_to_read_ = std::numeric_limits<uint64_t>::max();
165+
close_ = false;
157166
return Status::OK();
158167
}
159168

src/paimon/format/avro/avro_file_batch_reader_test.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,55 @@ TEST_F(AvroFileBatchReaderTest, TestGetPreviousBatchFirstRowNumber) {
343343
ASSERT_TRUE(BatchReader::IsEofBatch(batch5));
344344
}
345345

346+
TEST_F(AvroFileBatchReaderTest, TestSetReadSchemaResetsReaderToFirstRow) {
347+
std::string file_path = PathUtil::JoinPath(dir_->Str(), "file.avro");
348+
349+
arrow::FieldVector fields = {
350+
arrow::field("f0", arrow::int32()),
351+
arrow::field("f1", arrow::int32()),
352+
};
353+
auto file_data_type = arrow::struct_(fields);
354+
auto src_array = arrow::ipc::internal::json::ArrayFromJSON(file_data_type, R"([
355+
[1, 10],
356+
[2, 20],
357+
[3, 30],
358+
[4, 40]
359+
])")
360+
.ValueOrDie();
361+
WriteData(src_array, file_path, /*compression=*/"null");
362+
363+
ASSERT_OK_AND_ASSIGN(auto reader_builder, file_format_->CreateReaderBuilder(/*batch_size=*/2));
364+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<InputStream> in, fs_->Open(file_path));
365+
ASSERT_OK_AND_ASSIGN(auto reader, reader_builder->Build(in));
366+
367+
ASSERT_OK_AND_ASSIGN(auto first_batch, reader->NextBatch());
368+
ASSERT_EQ(0, reader->GetPreviousBatchFirstRowNumber().value());
369+
auto first_array =
370+
arrow::ImportArray(first_batch.first.get(), first_batch.second.get()).ValueOrDie();
371+
ASSERT_TRUE(first_array->Equals(src_array->Slice(0, 2))) << first_array->ToString();
372+
373+
auto read_schema = arrow::schema({arrow::field("f1", arrow::int32())});
374+
std::unique_ptr<ArrowSchema> c_schema = std::make_unique<ArrowSchema>();
375+
ASSERT_TRUE(arrow::ExportSchema(*read_schema, c_schema.get()).ok());
376+
ASSERT_OK(reader->SetReadSchema(c_schema.get(), /*predicate=*/nullptr,
377+
/*selection_bitmap=*/std::nullopt));
378+
ASSERT_EQ(std::numeric_limits<uint64_t>::max(),
379+
reader->GetPreviousBatchFirstRowNumber().value());
380+
381+
ASSERT_OK_AND_ASSIGN(auto projected_batch, reader->NextBatch());
382+
ASSERT_EQ(0, reader->GetPreviousBatchFirstRowNumber().value());
383+
auto projected_array =
384+
arrow::ImportArray(projected_batch.first.get(), projected_batch.second.get()).ValueOrDie();
385+
auto expected_projected_array = arrow::ipc::internal::json::ArrayFromJSON(
386+
arrow::struct_({arrow::field("f1", arrow::int32())}),
387+
R"([
388+
[10],
389+
[20]
390+
])")
391+
.ValueOrDie();
392+
ASSERT_TRUE(projected_array->Equals(expected_projected_array)) << projected_array->ToString();
393+
}
394+
346395
TEST_F(AvroFileBatchReaderTest, TestGetNumberOfRows) {
347396
std::string file_path = PathUtil::JoinPath(dir_->Str(), "file.avro");
348397

0 commit comments

Comments
 (0)