Skip to content

Commit 5098767

Browse files
committed
fix comments
1 parent be933ba commit 5098767

3 files changed

Lines changed: 80 additions & 1 deletion

File tree

docs/source/user_guide/system_tables.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ from multiple LSM levels during query planning and reading. The tradeoff is that
3838
the result may lag behind the latest committed data until a full compaction
3939
publishes the newest records into the highest level.
4040

41+
This stale view is not guaranteed to correspond to any single historical table
42+
snapshot. Full compaction may finish independently for different buckets. When
43+
``$ro`` scans the latest snapshot, the selected highest-level files can
44+
therefore combine bucket states produced by full-compaction commits at different
45+
snapshot IDs.
46+
4147
For primary-key tables, ``$ro`` also enables value-stats filtering, so file-level
4248
pruning of the reader predicate can be more aggressive than the base table.
4349

@@ -48,7 +54,8 @@ Limitations
4854
~~~~~~~~~~~
4955

5056
- Primary-key ``$ro`` scans are batch-only. Streaming scans are not supported.
51-
- Freshness depends on full compaction frequency.
57+
- Freshness depends on full compaction frequency, and the result may not match
58+
any single historical snapshot across buckets.
5259
- Primary-key tables in bucket-unaware mode are not supported by the current C++
5360
scan path.
5461

src/paimon/core/table/system/read_optimized_system_table.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <string>
2121
#include <utility>
2222

23+
#include "arrow/c/bridge.h"
2324
#include "paimon/common/types/data_field.h"
2425
#include "paimon/core/schema/table_schema.h"
2526
#include "paimon/core/table/source/read_optimized_scan_options.h"
@@ -110,6 +111,13 @@ Result<std::unique_ptr<TableRead>> ReadOptimizedSystemTable::NewRead(
110111
.WithCache(context->GetCache())
111112
.SetReadFieldNames(context->GetReadFieldNames())
112113
.SetReadFieldIds(context->GetReadFieldIds());
114+
if (context->HasReadSchema()) {
115+
PAIMON_ASSIGN_OR_RAISE_FROM_ARROW(std::shared_ptr<arrow::Schema> read_schema,
116+
arrow::ImportSchema(context->GetReadSchema()));
117+
auto c_read_schema = std::make_unique<::ArrowSchema>();
118+
PAIMON_RETURN_NOT_OK_FROM_ARROW(arrow::ExportSchema(*read_schema, c_read_schema.get()));
119+
builder.SetReadSchema(std::move(c_read_schema));
120+
}
113121
if (context->GetSpecificTableSchema().has_value()) {
114122
builder.SetTableSchema(context->GetSpecificTableSchema().value());
115123
}

test/inte/read_inte_test.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,70 @@ TEST(SystemTableReadInteTest, TestReadOptimizedPrimaryKeyProjectionAndPredicateP
985985
ASSERT_TRUE(result->Equals(expected)) << result->ToString();
986986
}
987987

988+
TEST(SystemTableReadInteTest, TestReadOptimizedSystemTableNestedProjection) {
989+
auto payload_type =
990+
arrow::struct_({arrow::field("a", arrow::int32()), arrow::field("b", arrow::utf8())});
991+
arrow::FieldVector fields = {
992+
arrow::field("k", arrow::int32()),
993+
arrow::field("payload", payload_type),
994+
arrow::field("extra", arrow::int32()),
995+
};
996+
auto schema = arrow::schema(fields);
997+
std::map<std::string, std::string> options = {{Options::FILE_SYSTEM, "local"},
998+
{Options::FILE_FORMAT, "parquet"},
999+
{Options::MANIFEST_FORMAT, "avro"},
1000+
{Options::BUCKET, "1"},
1001+
{Options::BUCKET_KEY, "k"}};
1002+
auto dir = UniqueTestDirectory::Create();
1003+
ASSERT_TRUE(dir);
1004+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<TestHelper> helper,
1005+
TestHelper::Create(dir->Str(), schema,
1006+
/*partition_keys=*/{}, /*primary_keys=*/{"k"}, options,
1007+
/*is_streaming_mode=*/true));
1008+
std::string table_path = PathUtil::JoinPath(dir->Str(), "foo.db/bar");
1009+
1010+
ASSERT_OK_AND_ASSIGN(
1011+
std::unique_ptr<RecordBatch> batch,
1012+
TestHelper::MakeRecordBatch(arrow::struct_(fields),
1013+
R"([[1, [10, "x"], 100], [2, [20, "y"], 200]])",
1014+
/*partition_map=*/{}, /*bucket=*/0, {}));
1015+
ASSERT_OK(WriteAndFullCompact(std::move(batch), /*commit_identifier=*/0, helper.get()));
1016+
1017+
ScanContextBuilder scan_context_builder(table_path + "$ro");
1018+
scan_context_builder.SetOptions(options);
1019+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<ScanContext> scan_context, scan_context_builder.Finish());
1020+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<TableScan> table_scan,
1021+
TableScan::Create(std::move(scan_context)));
1022+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<Plan> plan, table_scan->CreatePlan());
1023+
1024+
auto projected_schema = arrow::schema({
1025+
arrow::field("k", arrow::int32()),
1026+
arrow::field("payload", arrow::struct_({arrow::field("a", arrow::int32())})),
1027+
});
1028+
auto c_projected_schema = std::make_unique<ArrowSchema>();
1029+
ASSERT_TRUE(arrow::ExportSchema(*projected_schema, c_projected_schema.get()).ok());
1030+
ReadContextBuilder read_context_builder(table_path + "$ro");
1031+
read_context_builder.SetOptions(options).SetReadSchema(std::move(c_projected_schema));
1032+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<ReadContext> read_context, read_context_builder.Finish());
1033+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<TableRead> table_read,
1034+
TableRead::Create(std::move(read_context)));
1035+
ASSERT_OK_AND_ASSIGN(std::unique_ptr<BatchReader> batch_reader,
1036+
table_read->CreateReader(plan->Splits()));
1037+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<arrow::ChunkedArray> result,
1038+
ReadResultCollector::CollectResult(batch_reader.get()));
1039+
1040+
std::shared_ptr<arrow::DataType> expected_type = arrow::struct_({
1041+
arrow::field("_VALUE_KIND", arrow::int8()),
1042+
arrow::field("k", arrow::int32()),
1043+
arrow::field("payload", arrow::struct_({arrow::field("a", arrow::int32())})),
1044+
});
1045+
std::shared_ptr<arrow::ChunkedArray> expected;
1046+
ASSERT_TRUE(arrow::ipc::internal::json::ChunkedArrayFromJSON(
1047+
expected_type, {R"([[0, 1, [10]], [0, 2, [20]]])"}, &expected)
1048+
.ok());
1049+
ASSERT_TRUE(result->Equals(expected)) << result->ToString();
1050+
}
1051+
9881052
TEST(SystemTableReadInteTest, TestReadOptimizedSystemTableWithBranch) {
9891053
arrow::FieldVector fields = {
9901054
arrow::field("k", arrow::int32()),

0 commit comments

Comments
 (0)