Skip to content

Commit 5d8e4bf

Browse files
authored
Merge branch 'main' into codex/extend-map-column-allocator
2 parents ce92ec1 + 48ce42c commit 5d8e4bf

4 files changed

Lines changed: 77 additions & 7 deletions

File tree

include/paimon/global_index/global_index_scan.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,22 @@ class PAIMON_EXPORT GlobalIndexScan {
9797
const std::string& field_name,
9898
const std::optional<RowRangeIndex>& row_range_index) const = 0;
9999

100+
/// Creates a `GlobalIndexReader` for a specific field with a specific index type.
101+
/// @param field_name Name of the indexed column.
102+
/// @param index_type Name of index type.
103+
/// @param row_range_index Optional row range that limits the scan to a sub-range of row ids.
104+
/// If not provided, the entire row range is considered.
105+
/// @return A `Result` that is:
106+
/// - Successful with a reader(with global row id) if the index exists and loads
107+
/// correctly;
108+
/// - Successful with nullptr if no index was built for the given field with the given
109+
/// index type;
110+
/// - Error returns when loading fails (e.g., file corruption, I/O error,
111+
/// unsupported format).
112+
virtual Result<std::shared_ptr<GlobalIndexReader>> CreateReader(
113+
const std::string& field_name, const std::string& index_type,
114+
const std::optional<RowRangeIndex>& row_range_index) const = 0;
115+
100116
/// Creates several `GlobalIndexReader`s for a specific field (looked up by id),
101117
/// @param field_id Field id of the indexed column.
102118
/// @param row_range_index Optional row range that limits the scan to a sub-range of row ids.

src/paimon/core/global_index/global_index_scan_impl.cpp

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,27 +134,48 @@ Result<std::shared_ptr<GlobalIndexEvaluator>> GlobalIndexScanImpl::GetOrCreateIn
134134
Result<std::vector<std::shared_ptr<GlobalIndexReader>>> GlobalIndexScanImpl::CreateReaders(
135135
int32_t field_id, const std::optional<RowRangeIndex>& row_range_index) const {
136136
PAIMON_ASSIGN_OR_RAISE(DataField field, table_schema_->GetField(field_id));
137-
return CreateReaders(field, row_range_index);
137+
return CreateReaders(field, /*index_type=*/std::nullopt, row_range_index);
138138
}
139139

140140
Result<std::vector<std::shared_ptr<GlobalIndexReader>>> GlobalIndexScanImpl::CreateReaders(
141141
const std::string& field_name, const std::optional<RowRangeIndex>& row_range_index) const {
142142
PAIMON_ASSIGN_OR_RAISE(DataField field, table_schema_->GetField(field_name));
143-
return CreateReaders(field, row_range_index);
143+
return CreateReaders(field, /*index_type=*/std::nullopt, row_range_index);
144+
}
145+
146+
Result<std::shared_ptr<GlobalIndexReader>> GlobalIndexScanImpl::CreateReader(
147+
const std::string& field_name, const std::string& index_type,
148+
const std::optional<RowRangeIndex>& row_range_index) const {
149+
PAIMON_ASSIGN_OR_RAISE(DataField field, table_schema_->GetField(field_name));
150+
PAIMON_ASSIGN_OR_RAISE(
151+
std::vector<std::shared_ptr<GlobalIndexReader>> readers,
152+
CreateReaders(field, std::optional<std::string>(index_type), row_range_index));
153+
if (readers.empty()) {
154+
return std::shared_ptr<GlobalIndexReader>();
155+
}
156+
if (readers.size() != 1) {
157+
return Status::Invalid(
158+
fmt::format("invalid global index reader size, expected 1, actual {}", readers.size()));
159+
}
160+
return readers[0];
144161
}
145162

146163
Result<std::vector<std::shared_ptr<GlobalIndexReader>>> GlobalIndexScanImpl::CreateReaders(
147-
const DataField& field, const std::optional<RowRangeIndex>& row_range_index) const {
164+
const DataField& field, const std::optional<std::string>& index_type,
165+
const std::optional<RowRangeIndex>& row_range_index) const {
148166
auto field_iter = index_metas_.find(field.Id());
149167
if (field_iter == index_metas_.end()) {
150168
return std::vector<std::shared_ptr<GlobalIndexReader>>();
151169
}
152170
const auto& index_type_to_metas = field_iter->second;
153171
std::vector<std::shared_ptr<GlobalIndexReader>> readers;
154-
readers.reserve(index_type_to_metas.size());
155-
for (const auto& [index_type, range_to_metas] : index_type_to_metas) {
172+
readers.reserve(index_type ? 1 : index_type_to_metas.size());
173+
for (const auto& [current_index_type, range_to_metas] : index_type_to_metas) {
174+
if (index_type && current_index_type != index_type.value()) {
175+
continue;
176+
}
156177
PAIMON_ASSIGN_OR_RAISE(std::unique_ptr<GlobalIndexer> indexer,
157-
GlobalIndexerFactory::Get(index_type, options_.ToMap()));
178+
GlobalIndexerFactory::Get(current_index_type, options_.ToMap()));
158179
if (!indexer) {
159180
continue;
160181
}

src/paimon/core/global_index/global_index_scan_impl.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include <map>
2020
#include <memory>
21+
#include <optional>
2122
#include <string>
2223
#include <vector>
2324

@@ -47,6 +48,10 @@ class GlobalIndexScanImpl : public GlobalIndexScan {
4748
const std::string& field_name,
4849
const std::optional<RowRangeIndex>& row_range_index) const override;
4950

51+
Result<std::shared_ptr<GlobalIndexReader>> CreateReader(
52+
const std::string& field_name, const std::string& index_type,
53+
const std::optional<RowRangeIndex>& row_range_index) const override;
54+
5055
Result<std::vector<std::shared_ptr<GlobalIndexReader>>> CreateReaders(
5156
int32_t field_id, const std::optional<RowRangeIndex>& row_range_index) const override;
5257

@@ -65,7 +70,8 @@ class GlobalIndexScanImpl : public GlobalIndexScan {
6570
Result<std::shared_ptr<GlobalIndexEvaluator>> GetOrCreateIndexEvaluator();
6671

6772
Result<std::vector<std::shared_ptr<GlobalIndexReader>>> CreateReaders(
68-
const DataField& field, const std::optional<RowRangeIndex>& row_range_index) const;
73+
const DataField& field, const std::optional<std::string>& index_type,
74+
const std::optional<RowRangeIndex>& row_range_index) const;
6975

7076
std::vector<GlobalIndexIOMeta> ToGlobalIndexIOMetas(
7177
const std::vector<std::shared_ptr<IndexFileMeta>>& metas) const;

test/inte/global_index_test.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2661,6 +2661,33 @@ TEST_P(GlobalIndexTest, TestBTreeAndBitmapCoexist) {
26612661
ASSERT_OK_AND_ASSIGN(auto index_readers, global_index_scan->CreateReaders("f0", std::nullopt));
26622662
ASSERT_EQ(index_readers.size(), 2u);
26632663

2664+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexReader> btree_reader,
2665+
global_index_scan->CreateReader("f0", "btree", std::nullopt));
2666+
ASSERT_TRUE(btree_reader);
2667+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexResult> btree_result,
2668+
btree_reader->VisitEqual(Literal(FieldType::STRING, "Bob", 3)));
2669+
ASSERT_TRUE(btree_result);
2670+
ASSERT_EQ(btree_result->ToString(), "{1,2}");
2671+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexResult> btree_less_than_result,
2672+
btree_reader->VisitLessThan(Literal(FieldType::STRING, "Emily", 5)));
2673+
ASSERT_TRUE(btree_less_than_result);
2674+
ASSERT_EQ(btree_less_than_result->ToString(), "{0,1,2}");
2675+
2676+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexReader> bitmap_reader,
2677+
global_index_scan->CreateReader("f0", "bitmap", std::nullopt));
2678+
ASSERT_TRUE(bitmap_reader);
2679+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexResult> bitmap_result,
2680+
bitmap_reader->VisitEqual(Literal(FieldType::STRING, "Bob", 3)));
2681+
ASSERT_TRUE(bitmap_result);
2682+
ASSERT_EQ(bitmap_result->ToString(), "{1,2}");
2683+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexResult> bitmap_less_than_result,
2684+
bitmap_reader->VisitLessThan(Literal(FieldType::STRING, "Emily", 5)));
2685+
ASSERT_FALSE(bitmap_less_than_result);
2686+
2687+
ASSERT_OK_AND_ASSIGN(std::shared_ptr<GlobalIndexReader> missing_reader,
2688+
global_index_scan->CreateReader("f0", "lucene", std::nullopt));
2689+
ASSERT_FALSE(missing_reader);
2690+
26642691
// Each reader individually should return the same result for Equal("Bob")
26652692
for (const auto& index_reader : index_readers) {
26662693
ASSERT_OK_AND_ASSIGN(auto result,

0 commit comments

Comments
 (0)