blob: 9402eba87d35fa8b569e6622489b9a74537f869b [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <gtest/gtest.h>
#include "olap/inverted_index_parser.h"
#include "olap/tablet_schema.h"
namespace doris {
class TabletSchemaIndexTest : public testing::Test {
protected:
void SetUp() override {
// Setup common test data
_tablet_schema = std::make_shared<TabletSchema>();
}
TabletIndex create_test_index(int64_t index_id, IndexType type,
const std::vector<int32_t>& col_uids,
const std::string& suffix = "") {
TabletIndex index;
index._index_id = index_id;
index._index_type = type;
index._col_unique_ids = col_uids;
index.set_escaped_escaped_index_suffix_path(suffix);
return index;
}
TabletIndex create_test_index_with_pb(int64_t index_id, IndexType type,
const std::vector<int32_t>& col_uids,
const std::string& suffix = "",
const std::map<std::string, std::string>& properties = {},
const std::string& index_name = "") {
TabletIndexPB index_pb;
index_pb.set_index_id(index_id);
if (index_name.empty()) {
index_pb.set_index_name("test_index_" + std::to_string(index_id));
} else {
index_pb.set_index_name(index_name);
}
index_pb.set_index_type(type);
for (auto col_uid : col_uids) {
index_pb.add_col_unique_id(col_uid);
}
for (const auto& kv : properties) {
(*index_pb.mutable_properties())[kv.first] = kv.second;
}
index_pb.set_index_suffix_name(suffix);
TabletIndex index;
index.init_from_pb(index_pb);
return index;
}
std::shared_ptr<TabletSchema> _tablet_schema;
};
TEST_F(TabletSchemaIndexTest, TestAddInvertedIndex) {
// Add inverted index with suffix
TabletIndex index = create_test_index(1, IndexType::INVERTED, {100}, "suffix1");
_tablet_schema->append_index(std::move(index));
// Verify index mapping
auto found_indexs = _tablet_schema->inverted_indexs(100, "suffix1");
ASSERT_FALSE(found_indexs.empty());
EXPECT_EQ(found_indexs[0]->index_id(), 1);
EXPECT_EQ(found_indexs[0]->get_index_suffix(), "suffix1");
}
TEST_F(TabletSchemaIndexTest, TestRemoveIndex) {
// Add multiple indexes
_tablet_schema->append_index(create_test_index(1, IndexType::INVERTED, {100}, "suffix1"));
_tablet_schema->append_index(create_test_index(2, IndexType::INVERTED, {200}, "suffix2"));
// Remove index 1
_tablet_schema->remove_index(1);
// Verify index 1 removed
EXPECT_TRUE(_tablet_schema->inverted_indexs(100, "suffix1").empty());
// Verify index 2 still exists
auto found_indexs = _tablet_schema->inverted_indexs(200, "suffix2");
ASSERT_FALSE(found_indexs.empty());
EXPECT_EQ(found_indexs[0]->index_id(), 2);
}
TEST_F(TabletSchemaIndexTest, TestUpdateIndex) {
// Add initial index
_tablet_schema->append_index(create_test_index(1, IndexType::INVERTED, {100}, "old_suffix"));
ASSERT_FALSE(_tablet_schema->inverted_indexs(100, "old_suffix").empty());
// Update index with new suffix
_tablet_schema->remove_index(1);
_tablet_schema->append_index(create_test_index(1, IndexType::INVERTED, {100}, "new_suffix"));
// Verify update
EXPECT_TRUE(_tablet_schema->inverted_indexs(100, "old_suffix").empty());
auto found_indexs = _tablet_schema->inverted_indexs(100, "new_suffix");
ASSERT_FALSE(found_indexs.empty());
EXPECT_EQ(found_indexs[0]->get_index_suffix(), "new%5Fsuffix");
}
TEST_F(TabletSchemaIndexTest, TestMultipleColumnsIndex) {
// Add index with multiple columns
TabletIndex index = create_test_index(1, IndexType::INVERTED, {100, 200}, "multi_col");
_tablet_schema->append_index(std::move(index));
// Verify both columns mapped
auto index1 = _tablet_schema->inverted_indexs(100, "multi_col");
auto index2 = _tablet_schema->inverted_indexs(200, "multi_col");
ASSERT_FALSE(index1.empty());
ASSERT_FALSE(index2.empty());
ASSERT_EQ(index1[0]->index_id(), index2[0]->index_id()); // Should point to same index
}
TEST_F(TabletSchemaIndexTest, TestDuplicateIndexKey) {
// Add two indexes with same (type,col,suffix)
_tablet_schema->append_index(create_test_index(1, IndexType::INVERTED, {100}, "suffix"));
_tablet_schema->append_index(create_test_index(2, IndexType::INVERTED, {100}, "suffix"));
// The last added should override
auto found_indexs = _tablet_schema->inverted_indexs(100, "suffix");
ASSERT_FALSE(found_indexs.empty());
EXPECT_EQ(found_indexs[0]->index_id(), 1);
}
TEST_F(TabletSchemaIndexTest, TestClearIndexes) {
_tablet_schema->append_index(create_test_index(1, IndexType::INVERTED, {100}));
_tablet_schema->clear_index();
EXPECT_TRUE(_tablet_schema->inverted_indexs(100, "").empty());
EXPECT_TRUE(_tablet_schema->inverted_indexes().empty());
}
TEST_F(TabletSchemaIndexTest, TestUpdateIndexWithMultipleColumns) {
TabletColumn col1, col2;
col1.set_unique_id(300);
col2.set_unique_id(400);
_tablet_schema->append_column(col1);
_tablet_schema->append_column(col2);
TabletIndex old_multi_index = create_test_index(3, IndexType::INVERTED, {300, 400}, "multi");
_tablet_schema->append_index(std::move(old_multi_index));
TabletIndex new_multi_index = create_test_index(3, IndexType::NGRAM_BF, {300, 400});
_tablet_schema->append_index(std::move(new_multi_index));
EXPECT_FALSE(_tablet_schema->inverted_indexs(300, "multi").empty());
EXPECT_NE(_tablet_schema->get_ngram_bf_index(400), nullptr);
}
TEST_F(TabletSchemaIndexTest, TestRemoveParserAndAnalyzer) {
std::map<std::string, std::string> properties = {
{INVERTED_INDEX_PARSER_KEY, "english"},
{INVERTED_INDEX_ANALYZER_NAME_KEY, "my_analyzer"}};
TabletIndex index =
create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1", properties);
EXPECT_TRUE(index.properties().contains(INVERTED_INDEX_PARSER_KEY));
EXPECT_TRUE(index.properties().contains(INVERTED_INDEX_ANALYZER_NAME_KEY));
index.remove_parser_and_analyzer();
EXPECT_FALSE(index.properties().contains(INVERTED_INDEX_PARSER_KEY));
EXPECT_FALSE(index.properties().contains(INVERTED_INDEX_ANALYZER_NAME_KEY));
}
TEST_F(TabletSchemaIndexTest, TestIsSameExceptId) {
// Create two indexes with same properties but different IDs
std::map<std::string, std::string> properties = {{"prop1", "value1"}, {"prop2", "value2"}};
TabletIndex index1 = create_test_index_with_pb(1, IndexType::INVERTED, {100, 200}, "suffix1",
properties, "indexa");
TabletIndex index2 = create_test_index_with_pb(2, IndexType::INVERTED, {100, 200}, "suffix1",
properties, "indexa");
EXPECT_TRUE(index1.is_same_except_id(&index2));
EXPECT_TRUE(index2.is_same_except_id(&index1));
}
TEST_F(TabletSchemaIndexTest, TestIsSameExceptIdWithDifferentProperties) {
std::map<std::string, std::string> properties1 = {{"prop1", "value1"}};
std::map<std::string, std::string> properties2 = {{"prop1", "value2"}};
TabletIndex index1 =
create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1", properties1);
TabletIndex index2 =
create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1", properties2);
EXPECT_FALSE(index1.is_same_except_id(&index2));
}
TEST_F(TabletSchemaIndexTest, TestIsSameExceptIdWithDifferentTypes) {
TabletIndex index1 = create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1");
TabletIndex index2 = create_test_index_with_pb(1, IndexType::NGRAM_BF, {100}, "suffix1");
EXPECT_FALSE(index1.is_same_except_id(&index2));
}
TEST_F(TabletSchemaIndexTest, TestIsSameExceptIdWithDifferentColumns) {
TabletIndex index1 = create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1");
TabletIndex index2 = create_test_index_with_pb(1, IndexType::INVERTED, {200}, "suffix1");
EXPECT_FALSE(index1.is_same_except_id(&index2));
}
TEST_F(TabletSchemaIndexTest, TestIsSameExceptIdWithDifferentSuffix) {
TabletIndex index1 = create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1");
TabletIndex index2 = create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix2");
EXPECT_FALSE(index1.is_same_except_id(&index2));
}
TEST_F(TabletSchemaIndexTest, TestIsSameExceptIdWithSameId) {
std::map<std::string, std::string> properties = {{"prop1", "value1"}};
TabletIndex index1 =
create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1", properties);
TabletIndex index2 =
create_test_index_with_pb(1, IndexType::INVERTED, {100}, "suffix1", properties);
EXPECT_TRUE(index1.is_same_except_id(&index2));
}
} // namespace doris