Skip to content

Commit 2fe0974

Browse files
committed
refactor a little
1 parent 7266d3a commit 2fe0974

12 files changed

Lines changed: 51 additions & 86 deletions

‎include/paimon/file_store_write.h‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,9 @@ class PAIMON_EXPORT FileStoreWrite {
6060
/// the corresponding array in `batch` must have zero null entries.
6161
virtual Status Write(std::unique_ptr<RecordBatch>&& batch) = 0;
6262

63-
/// Seals the current in-memory real-time segment without flushing it to a data file.
63+
/// Slices the current in-memory real-time data into a sealed segment so it can be reclaimed
64+
/// independently. A future implementation will support spilling sealed segments to a
65+
/// temporary directory; currently this method only creates the in-memory segment boundary.
6466
/// Calling this method on a non-real-time writer returns an error.
6567
virtual Status Seal();
6668

‎include/paimon/realtime/realtime_store.h‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,11 @@ class PAIMON_EXPORT RealtimeReadView {
110110

111111
/// Parameters used by a `RealtimeStore` to create readers for a query.
112112
struct PAIMON_EXPORT RealtimeQueryContext {
113-
/// Physical source schema the store must materialize. Query readers must include the mandatory
114-
/// `_VALUE_KIND` field in returned batches. Paimon may subsequently convert physical fields
115-
/// into the query's logical output schema, for example for selected-key MAP or VARIANT access.
116-
/// This schema is borrowed and remains valid only during `CreateQueryReaders`; plugins must
117-
/// import or copy it synchronously.
113+
/// Physical source schema the store must materialize. Every returned batch must match this
114+
/// schema exactly. Paimon may subsequently add framework fields or convert physical fields into
115+
/// the query's logical output schema, for example for selected-key MAP or VARIANT access. This
116+
/// schema is borrowed and remains valid only during `CreateQueryReaders`; plugins must import
117+
/// or copy it synchronously.
118118
::ArrowSchema* read_schema;
119119
/// Optional predicate using field indexes from `read_schema`. A non-null predicate allows the
120120
/// plugin to prune candidate rows. Exact filtering is applied by the Paimon read framework.
@@ -147,9 +147,9 @@ class PAIMON_EXPORT RealtimeStore {
147147
/// Creates readers that expose all rows in a sealed segment for Paimon file writing.
148148
///
149149
/// The returned readers collectively expose every sealed row exactly once. Append-mode readers
150-
/// preserve write order and contain `_VALUE_KIND`, `_REALTIME_OFFSET`, and table write fields.
151-
/// Primary-key readers contain the real-time primary-key store fields; each reader's
152-
/// complete stream is sorted by full primary key then sequence number.
150+
/// preserve write order and contain `_REALTIME_OFFSET` followed by the table write fields.
151+
/// Primary-key readers contain the real-time primary-key store fields; each reader's complete
152+
/// stream is sorted by full primary key then sequence number.
153153
virtual Result<std::vector<std::unique_ptr<BatchReader>>> CreateCommitReaders(
154154
const std::shared_ptr<RealtimeSegmentHandle>& segment) = 0;
155155

‎src/paimon/core/operation/key_value_file_store_write_test.cpp‎

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -468,12 +468,10 @@ TEST_F(KeyValueFileStoreWriteTest, TestRealtimeWrite) {
468468
ASSERT_NOK_WITH_MSG(writer->Write(MakeBatch(realtime_schema, R"([[30, 3, "backwards"]])")),
469469
"offset moved backwards or was duplicated");
470470
ASSERT_NOK(writer->Write(MakeBatch(realtime_schema, R"([[null, 3, "null-offset"]])")));
471-
using RealtimePrimaryKeyStoreRow = std::tuple<int8_t, int64_t, std::string, int64_t, int64_t>;
472-
ASSERT_OK_AND_ASSIGN(std::vector<RealtimePrimaryKeyStoreRow> store_rows,
473-
ReadRealtimePrimaryKeyStoreRows(realtime_context));
474-
ASSERT_EQ((std::vector<RealtimePrimaryKeyStoreRow>{
475-
{0, 1, "old", 0, 10}, {2, 1, "new", 2, 30}, {3, 2, "two", 1, 20}}),
476-
store_rows);
471+
ASSERT_OK_AND_ASSIGN(auto store_rows, ReadRealtimePrimaryKeyStoreRows(realtime_context));
472+
ASSERT_EQ(
473+
(decltype(store_rows){{0, 1, "old", 0, 10}, {2, 1, "new", 2, 30}, {3, 2, "two", 1, 20}}),
474+
store_rows);
477475
ASSERT_OK_AND_ASSIGN(std::vector<RealtimeCommitProgress> progresses,
478476
writer->PrepareCommitWithProgress(0));
479477
ASSERT_EQ(1, progresses.size());
@@ -523,10 +521,8 @@ TEST_F(KeyValueFileStoreWriteTest, TestRealtimePool) {
523521
ASSERT_GT(pool->allocation_count, allocations_before_write);
524522
ASSERT_OK(writer->Close());
525523
writer.reset();
526-
using RealtimePrimaryKeyStoreRow = std::tuple<int8_t, int64_t, std::string, int64_t, int64_t>;
527-
ASSERT_OK_AND_ASSIGN(std::vector<RealtimePrimaryKeyStoreRow> retained_rows,
528-
ReadRealtimePrimaryKeyStoreRows(realtime_context));
529-
ASSERT_EQ((std::vector<RealtimePrimaryKeyStoreRow>{{0, 1, "one", 0, 0}}), retained_rows);
524+
ASSERT_OK_AND_ASSIGN(auto retained_rows, ReadRealtimePrimaryKeyStoreRows(realtime_context));
525+
ASSERT_EQ((decltype(retained_rows){{0, 1, "one", 0, 0}}), retained_rows);
530526

531527
std::shared_ptr<TestingMemoryPool> rejecting_pool = std::make_shared<TestingMemoryPool>();
532528
ASSERT_OK_AND_ASSIGN(std::shared_ptr<RealtimeContext> rejecting_context,
@@ -546,8 +542,7 @@ TEST_F(KeyValueFileStoreWriteTest, TestRealtimePool) {
546542
ASSERT_NOK_WITH_MSG(rejecting_writer->Write(MakeBatch(realtime_schema, R"([[0, 2, "two"]])")),
547543
"Out of memory");
548544
ASSERT_GT(rejecting_pool->allocation_count, rejecting_allocations_before_write);
549-
ASSERT_OK_AND_ASSIGN(std::vector<RealtimePrimaryKeyStoreRow> rejected_rows,
550-
ReadRealtimePrimaryKeyStoreRows(rejecting_context));
545+
ASSERT_OK_AND_ASSIGN(auto rejected_rows, ReadRealtimePrimaryKeyStoreRows(rejecting_context));
551546
ASSERT_TRUE(rejected_rows.empty());
552547
ASSERT_OK(rejecting_writer->Close());
553548
}
@@ -606,18 +601,14 @@ TEST_F(KeyValueFileStoreWriteTest, TestRealtimeLimits) {
606601
FileStoreWrite::Create(std::move(write_context)));
607602
ASSERT_OK(
608603
writer->Write(MakeBatch(realtime_schema, fmt::format(R"([[{}, 1, "legal"]])", max - 1))));
609-
using RealtimePrimaryKeyStoreRow = std::tuple<int8_t, int64_t, std::string, int64_t, int64_t>;
610-
ASSERT_OK_AND_ASSIGN(std::vector<RealtimePrimaryKeyStoreRow> store_rows,
611-
ReadRealtimePrimaryKeyStoreRows(realtime_context));
612-
ASSERT_EQ((std::vector<RealtimePrimaryKeyStoreRow>{{0, 1, "legal", max - 1, max - 1}}),
613-
store_rows);
604+
ASSERT_OK_AND_ASSIGN(auto store_rows, ReadRealtimePrimaryKeyStoreRows(realtime_context));
605+
ASSERT_EQ((decltype(store_rows){{0, 1, "legal", max - 1, max - 1}}), store_rows);
614606

615607
ASSERT_NOK_WITH_MSG(
616608
writer->Write(MakeBatch(realtime_schema, fmt::format(R"([[{}, 2, "overflow"]])", max))),
617609
"real-time offset range exceeds INT64_MAX");
618610
ASSERT_OK_AND_ASSIGN(store_rows, ReadRealtimePrimaryKeyStoreRows(realtime_context));
619-
ASSERT_EQ((std::vector<RealtimePrimaryKeyStoreRow>{{0, 1, "legal", max - 1, max - 1}}),
620-
store_rows);
611+
ASSERT_EQ((decltype(store_rows){{0, 1, "legal", max - 1, max - 1}}), store_rows);
621612
ASSERT_OK_AND_ASSIGN(std::shared_ptr<RealtimeContextImpl> context_impl,
622613
RealtimeContextImpl::Cast(realtime_context));
623614
ASSERT_OK_AND_ASSIGN(RealtimeReadState read_state, context_impl->AcquireReadState());

‎src/paimon/core/realtime/arrow_realtime_store.cpp‎

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
#include "paimon/common/data/columnar/columnar_row.h"
3131
#include "paimon/common/metrics/metrics_impl.h"
3232
#include "paimon/common/predicate/predicate_filter.h"
33-
#include "paimon/common/reader/complete_row_kind_batch_reader.h"
3433
#include "paimon/common/reader/reader_utils.h"
3534
#include "paimon/common/utils/arrow/arrow_utils.h"
3635
#include "paimon/common/utils/arrow/mem_utils.h"
@@ -424,10 +423,7 @@ Result<std::vector<std::unique_ptr<BatchReader>>> ArrowRealtimeStore::CreateComm
424423
}
425424
std::vector<std::unique_ptr<BatchReader>> readers;
426425
if (mode_ == RealtimeStoreMode::APPEND_ONLY) {
427-
std::unique_ptr<BatchReader> reader =
428-
std::make_unique<AppendCommitBatchReader>(arrow_segment);
429-
readers.push_back(
430-
std::make_unique<CompleteRowKindBatchReader>(std::move(reader), arrow_pool_));
426+
readers.push_back(std::make_unique<AppendCommitBatchReader>(arrow_segment));
431427
return readers;
432428
}
433429
readers.reserve(arrow_segment->GetBatches().size());
@@ -486,7 +482,6 @@ Result<std::vector<std::unique_ptr<BatchReader>>> ArrowRealtimeStore::CreateQuer
486482
std::unique_ptr<BatchReader> reader = std::make_unique<AppendQueryBatchReader>(
487483
arrow_view, read_schema, predicate_filter, std::move(statistics_mapping), arrow_pool_,
488484
memory_pool_);
489-
reader = std::make_unique<CompleteRowKindBatchReader>(std::move(reader), arrow_pool_);
490485
readers.push_back(std::move(reader));
491486
return readers;
492487
}

‎src/paimon/core/realtime/arrow_realtime_store_test.cpp‎

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,19 @@ TEST_F(ArrowRealtimeStoreTest, TestQueryReaderClipsCommittedOffsetWithBitmap) {
173173
DataField::ConvertDataFieldToArrowField(SpecialFields::RealtimeOffset()),
174174
arrow::field("value", arrow::utf8()),
175175
});
176+
{
177+
std::unique_ptr<ArrowSchema> c_schema = MakeReadSchema(read_schema);
178+
RealtimeQueryContext context{c_schema.get(), /*predicate=*/nullptr};
179+
ASSERT_OK_AND_ASSIGN(std::vector<std::unique_ptr<BatchReader>> readers,
180+
store_->CreateQueryReaders(view, context));
181+
ASSERT_OK_AND_ASSIGN(BatchReader::ReadBatchWithBitmap batch,
182+
readers[0]->NextBatchWithBitmap());
183+
arrow::Result<std::shared_ptr<arrow::Array>> import_result =
184+
arrow::ImportArray(batch.first.first.get(), batch.first.second.get());
185+
ASSERT_TRUE(import_result.ok());
186+
std::shared_ptr<arrow::Array> array = std::move(import_result).ValueOrDie();
187+
ASSERT_TRUE(array->type()->Equals(arrow::struct_(read_schema->fields())));
188+
}
176189
{
177190
std::unique_ptr<ArrowSchema> c_schema = MakeReadSchema(read_schema);
178191
RealtimeQueryContext context{c_schema.get(), /*predicate=*/nullptr};
@@ -236,15 +249,9 @@ TEST_F(ArrowRealtimeStoreTest, TestCommitReaderPreservesSlicedBatch) {
236249
arrow::ImportArray(batch.first.get(), batch.second.get());
237250
ASSERT_TRUE(import_result.ok()) << import_result.status().ToString();
238251
std::shared_ptr<arrow::Array> actual_array = std::move(import_result).ValueOrDie();
239-
std::shared_ptr<arrow::DataType> expected_type = arrow::struct_({
240-
arrow::field("_VALUE_KIND", arrow::int8()),
241-
DataField::ConvertDataFieldToArrowField(SpecialFields::RealtimeOffset()),
242-
arrow::field("id", arrow::int64()),
243-
arrow::field("value", arrow::utf8()),
244-
});
252+
std::shared_ptr<arrow::DataType> expected_type = arrow::struct_(schema_->fields());
245253
std::shared_ptr<arrow::Array> expected_array =
246-
arrow::ipc::internal::json::ArrayFromJSON(expected_type,
247-
R"([[0, 0, 1, null], [0, 1, 2, "c"]])")
254+
arrow::ipc::internal::json::ArrayFromJSON(expected_type, R"([[0, 1, null], [1, 2, "c"]])")
248255
.ValueOrDie();
249256
ASSERT_TRUE(actual_array->Equals(*expected_array))
250257
<< "expected: " << expected_array->ToString() << ", actual: " << actual_array->ToString();

‎src/paimon/core/realtime/primary_key_realtime_store_test.cpp‎

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,7 @@ TEST(PrimaryKeyRealtimeStoreTest, TestCommitReaderPerStoredBatch) {
176176
std::shared_ptr<arrow::Array> expected,
177177
ArrayFromJson(actual->type(),
178178
R"([[6, 1, 1, 1, "before"], [5, 0, 0, 3, "three"], [7, 2, 2, 2, "after"]])"));
179-
ASSERT_TRUE(expected->Equals(actual)) << "expected:\n"
180-
<< expected->ToString() << "\nactual:\n"
181-
<< actual->ToString();
179+
ASSERT_TRUE(expected->Equals(actual));
182180
}
183181

184182
void AssertSlicedBatch(BatchReader* reader) {
@@ -283,9 +281,7 @@ TEST(PrimaryKeyRealtimeStoreTest, TestReclaimKeepsReadView) {
283281
std::shared_ptr<arrow::Array> expected,
284282
ArrayFromJson(actual->type(),
285283
R"([[0, 0, 4, 1, "one"], [1, 0, 5, 2, "two"], [2, 0, 6, 3, "three"]])"));
286-
ASSERT_TRUE(expected->Equals(actual)) << "expected:\n"
287-
<< expected->ToString() << "\nactual:\n"
288-
<< actual->ToString();
284+
ASSERT_TRUE(expected->Equals(actual));
289285
}
290286

291287
TEST(PrimaryKeyRealtimeStoreTest, TestQueryReaderPerStoredBatch) {
@@ -308,9 +304,7 @@ TEST(PrimaryKeyRealtimeStoreTest, TestQueryReaderPerStoredBatch) {
308304
ASSERT_OK_AND_ASSIGN(
309305
std::shared_ptr<arrow::Array> expected,
310306
ArrayFromJson(actual->type(), R"([[1, 0, 0, 2, "two"], [2, 0, 1, 1, "one"]])"));
311-
ASSERT_TRUE(expected->Equals(actual)) << "expected:\n"
312-
<< expected->ToString() << "\nactual:\n"
313-
<< actual->ToString();
307+
ASSERT_TRUE(expected->Equals(actual));
314308
}
315309

316310
TEST(PrimaryKeyRealtimeStoreTest, TestQueryBatchOutlivesStoreAndReader) {

‎src/paimon/core/realtime/realtime_append_only_writer.cpp‎

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -170,23 +170,6 @@ Status RealtimeAppendOnlyWriter::FlushSegment(
170170
}
171171
std::shared_ptr<arrow::StructArray> struct_array =
172172
checked_pointer_cast<arrow::StructArray>(imported);
173-
std::shared_ptr<arrow::Array> value_kind =
174-
struct_array->GetFieldByName(SpecialFields::ValueKind().Name());
175-
if (!value_kind || value_kind->type_id() != arrow::Type::INT8) {
176-
return Status::Invalid(
177-
"real-time store commit reader must return an INT8 _VALUE_KIND field");
178-
}
179-
std::shared_ptr<arrow::Int8Array> row_kinds =
180-
checked_pointer_cast<arrow::Int8Array>(value_kind);
181-
for (int64_t i = 0; i < row_kinds->length(); ++i) {
182-
if (row_kinds->IsNull(i) ||
183-
row_kinds->Value(i) != static_cast<int8_t>(RecordBatch::RowKind::INSERT)) {
184-
return Status::Invalid(
185-
"append real-time store commit reader returned a non-INSERT row");
186-
}
187-
}
188-
PAIMON_ASSIGN_OR_RAISE(struct_array, ArrowUtils::RemoveFieldFromStructArray(
189-
struct_array, SpecialFields::ValueKind().Name()));
190173
PAIMON_ASSIGN_OR_RAISE(struct_array,
191174
ArrowUtils::RemoveFieldFromStructArray(
192175
struct_array, SpecialFields::RealtimeOffset().Name()));

‎src/paimon/core/realtime/realtime_schema_layout.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ RealtimeSchemaLayout::RealtimeSchemaLayout(RealtimeStoreMode mode,
6262
: user_schema_(user_schema), input_schema_(Prepend({RealtimeOffsetField()}, user_schema_)) {
6363
if (mode == RealtimeStoreMode::APPEND_ONLY) {
6464
store_write_schema_ = input_schema_;
65-
store_commit_schema_ = Prepend({ValueKindField()}, input_schema_);
65+
store_commit_schema_ = store_write_schema_;
6666
commit_schema_ = user_schema_;
6767
query_schema_ = Prepend({ValueKindField()}, user_schema_);
6868
return;

‎src/paimon/core/realtime/realtime_schema_layout.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class RealtimeSchemaLayout {
5656
return store_write_schema_;
5757
}
5858

59-
/// Append-only fields: [_VALUE_KIND, _REALTIME_OFFSET, user fields].
59+
/// Append-only fields: [_REALTIME_OFFSET, user fields].
6060
/// Primary-key fields: [_SEQUENCE_NUMBER, _VALUE_KIND, _REALTIME_OFFSET, user fields].
6161
const std::shared_ptr<arrow::Schema>& StoreCommitSchema() const {
6262
return store_commit_schema_;

‎src/paimon/core/realtime/realtime_schema_layout_test.cpp‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ TEST(RealtimeSchemaLayoutTest, TestSchemaLayouts) {
3838
ASSERT_EQ((std::vector<std::string>{"_REALTIME_OFFSET", "key", "value"}),
3939
append_layout->InputSchema()->field_names());
4040
ASSERT_TRUE(append_layout->InputSchema()->Equals(*append_layout->StoreWriteSchema()));
41-
ASSERT_EQ((std::vector<std::string>{"_VALUE_KIND", "_REALTIME_OFFSET", "key", "value"}),
42-
append_layout->StoreCommitSchema()->field_names());
41+
ASSERT_TRUE(append_layout->StoreWriteSchema()->Equals(*append_layout->StoreCommitSchema()));
4342
ASSERT_TRUE(user_schema->Equals(*append_layout->CommitSchema()));
4443
ASSERT_EQ((std::vector<std::string>{"_VALUE_KIND", "key", "value"}),
4544
append_layout->QuerySchema()->field_names());

0 commit comments

Comments
 (0)