Skip to content

Commit f36b8b5

Browse files
authored
Alter index is not supported for vector index (#7005)
1 parent 833f929 commit f36b8b5

File tree

10 files changed

+146
-42
lines changed

10 files changed

+146
-42
lines changed

ydb/core/base/table_index.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ bool IsCompatibleIndex(NKikimrSchemeOp::EIndexType indexType, const TTableColumn
143143
return true;
144144
}
145145

146+
TVector<TString> GetImplTables(NKikimrSchemeOp::EIndexType indexType) {
147+
if (indexType == NKikimrSchemeOp::EIndexType::EIndexTypeGlobalVectorKmeansTree) {
148+
return { NTableVectorKmeansTreeIndex::LevelTable, NTableVectorKmeansTreeIndex::PostingTable };
149+
} else {
150+
return { ImplTable };
151+
}
152+
}
153+
146154
bool IsImplTable(std::string_view tableName) {
147155
return Contains(ImplTables, tableName);
148156
}

ydb/core/base/table_index.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ inline constexpr const char* ImplTable = "indexImplTable";
2323

2424
bool IsCompatibleIndex(NKikimrSchemeOp::EIndexType type, const TTableColumns& table, const TIndexColumns& index, TString& explain);
2525
TTableColumns CalcTableImplDescription(NKikimrSchemeOp::EIndexType type, const TTableColumns& table, const TIndexColumns& index);
26+
27+
TVector<TString> GetImplTables(NKikimrSchemeOp::EIndexType indexType);
2628
bool IsImplTable(std::string_view tableName);
2729
bool IsTmpImplTable(std::string_view tableName);
2830

ydb/core/grpc_services/rpc_describe_table.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ class TDescribeTableRPC : public TRpcSchemeRequestActor<TDescribeTableRPC, TEvDe
2828
if (AppData()->AllowPrivateTableDescribeForTest) {
2929
return true;
3030
}
31-
32-
if (path.EndsWith(TStringBuilder() << "/" << NTableIndex::ImplTable)) {
31+
32+
auto pathElements = ::NKikimr::SplitPath(path);
33+
if (pathElements.size() != 0 && NTableIndex::IsImplTable(pathElements.back())) {
3334
return true;
3435
}
3536

ydb/core/kqp/gateway/kqp_metadata_loader.cpp

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -616,38 +616,39 @@ NThreading::TFuture<TTableMetadataResult> TKqpTableMetadataLoader::LoadIndexMeta
616616

617617
for (size_t i = 0; i < indexesCount; i++) {
618618
const auto& index = tableMetadata->Indexes[i];
619-
auto indexTablePath = NSchemeHelpers::CreateIndexTablePath(tableName, index.Name);
620-
621-
if (!index.SchemaVersion) {
622-
LOG_DEBUG_S(*ActorSystem, NKikimrServices::KQP_GATEWAY, "Load index metadata without schema version check index: " << index.Name);
623-
children.push_back(
624-
LoadTableMetadata(cluster, indexTablePath,
625-
TLoadTableMetadataSettings().WithPrivateTables(true), database, userToken)
626-
.Apply([i, tableMetadata](const TFuture<TTableMetadataResult>& result) {
627-
auto value = result.GetValue();
628-
UpdateMetadataIfSuccess(tableMetadata, i, value);
629-
return static_cast<TGenericResult>(value);
630-
})
631-
);
619+
const auto indexTablePaths = NSchemeHelpers::CreateIndexTablePath(tableName, index.Type, index.Name);
620+
for (const auto& indexTablePath : indexTablePaths) {
621+
if (!index.SchemaVersion) {
622+
LOG_DEBUG_S(*ActorSystem, NKikimrServices::KQP_GATEWAY, "Load index metadata without schema version check index: " << index.Name);
623+
children.push_back(
624+
LoadTableMetadata(cluster, indexTablePath,
625+
TLoadTableMetadataSettings().WithPrivateTables(true), database, userToken)
626+
.Apply([i, tableMetadata](const TFuture<TTableMetadataResult>& result) {
627+
auto value = result.GetValue();
628+
UpdateMetadataIfSuccess(tableMetadata, i, value);
629+
return static_cast<TGenericResult>(value);
630+
})
631+
);
632632

633-
} else {
634-
LOG_DEBUG_S(*ActorSystem, NKikimrServices::KQP_GATEWAY, "Load index metadata with schema version check"
635-
<< "index: " << index.Name
636-
<< "pathId: " << index.LocalPathId
637-
<< "ownerId: " << index.PathOwnerId
638-
<< "schemaVersion: " << index.SchemaVersion
639-
<< "tableOwnerId: " << tableOwnerId);
640-
auto ownerId = index.PathOwnerId ? index.PathOwnerId : tableOwnerId; //for compat with 20-2
641-
children.push_back(
642-
LoadIndexMetadataByPathId(cluster,
643-
NKikimr::TIndexId(ownerId, index.LocalPathId, index.SchemaVersion), indexTablePath, database, userToken)
644-
.Apply([i, tableMetadata](const TFuture<TTableMetadataResult>& result) {
645-
auto value = result.GetValue();
646-
UpdateMetadataIfSuccess(tableMetadata, i, value);
647-
return static_cast<TGenericResult>(value);
648-
})
649-
);
633+
} else {
634+
LOG_DEBUG_S(*ActorSystem, NKikimrServices::KQP_GATEWAY, "Load index metadata with schema version check"
635+
<< "index: " << index.Name
636+
<< "pathId: " << index.LocalPathId
637+
<< "ownerId: " << index.PathOwnerId
638+
<< "schemaVersion: " << index.SchemaVersion
639+
<< "tableOwnerId: " << tableOwnerId);
640+
auto ownerId = index.PathOwnerId ? index.PathOwnerId : tableOwnerId; //for compat with 20-2
641+
children.push_back(
642+
LoadIndexMetadataByPathId(cluster,
643+
NKikimr::TIndexId(ownerId, index.LocalPathId, index.SchemaVersion), indexTablePath, database, userToken)
644+
.Apply([i, tableMetadata](const TFuture<TTableMetadataResult>& result) {
645+
auto value = result.GetValue();
646+
UpdateMetadataIfSuccess(tableMetadata, i, value);
647+
return static_cast<TGenericResult>(value);
648+
})
649+
);
650650

651+
}
651652
}
652653
}
653654

ydb/core/kqp/gateway/utils/scheme_helpers.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,14 @@ bool SplitTablePath(const TString& tableName, const TString& database, std::pair
4646
}
4747
}
4848

49-
TString CreateIndexTablePath(const TString& tableName, const TString& indexName) {
50-
return tableName + "/" + indexName + "/" + NTableIndex::ImplTable;
49+
TVector<TString> CreateIndexTablePath(const TString& tableName, NYql::TIndexDescription::EType indexType, const TString& indexName) {
50+
auto implTables = NTableIndex::GetImplTables(NYql::TIndexDescription::ConvertIndexType(indexType));
51+
TVector<TString> paths;
52+
paths.reserve(implTables.size());
53+
for (const auto& implTable : implTables) {
54+
paths.emplace_back(TStringBuilder() << tableName << "/" << indexName << "/" << implTable);
55+
}
56+
return paths;
5157
}
5258

5359
bool SetDatabaseForLoginOperation(TString& result, bool getDomainLoginOnly, TMaybe<TString> domainName,

ydb/core/kqp/gateway/utils/scheme_helpers.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ bool TrySplitTablePath(const TString& path, std::pair<TString, TString>& result,
2222
bool SplitTablePath(const TString& tableName, const TString& database, std::pair<TString, TString>& pathPair,
2323
TString& error, bool createDir);
2424

25-
TString CreateIndexTablePath(const TString& tableName, const TString& indexName);
25+
TVector<TString> CreateIndexTablePath(const TString& tableName, NYql::TIndexDescription::EType indexType, const TString& indexName);
2626

2727
bool SetDatabaseForLoginOperation(TString& result, bool getDomainLoginOnly, TMaybe<TString> domainName,
2828
const TString& database);

ydb/core/kqp/provider/yql_kikimr_exec.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1682,9 +1682,25 @@ class TKiSinkCallableExecutionTransformer : public TAsyncCallbackTransformer<TKi
16821682
for (const auto& indexSetting : listNode) {
16831683
auto settingName = indexSetting.Name().Value();
16841684
if (settingName == "indexName") {
1685-
auto indexName = indexSetting.Value().Cast<TCoAtom>().StringValue();
1686-
auto indexTablePath = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(table.Metadata->Name, indexName);
1687-
alterTableRequest.set_path(std::move(indexTablePath));
1685+
const auto indexName = indexSetting.Value().Cast<TCoAtom>().StringValue();
1686+
const auto indexIter = std::find_if(table.Metadata->Indexes.begin(), table.Metadata->Indexes.end(), [&indexName] (const auto& index) {
1687+
return index.Name == indexName;
1688+
});
1689+
if (indexIter == table.Metadata->Indexes.end()) {
1690+
ctx.AddError(
1691+
YqlIssue(ctx.GetPosition(indexSetting.Name().Pos()),
1692+
TIssuesIds::KIKIMR_SCHEME_ERROR,
1693+
TStringBuilder() << "Unknown index name: " << indexName));
1694+
return SyncError();
1695+
}
1696+
auto indexTablePaths = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(table.Metadata->Name, indexIter->Type, indexName);
1697+
if (indexTablePaths.size() != 1) {
1698+
ctx.AddError(
1699+
TIssue(ctx.GetPosition(indexSetting.Name().Pos()),
1700+
TStringBuilder() << "Only index with one impl table is supported"));
1701+
return SyncError();
1702+
}
1703+
alterTableRequest.set_path(std::move(indexTablePaths[0]));
16881704
} else if (settingName == "tableSettings") {
16891705
auto tableSettings = indexSetting.Value().Cast<TCoNameValueTupleList>();
16901706
for (const auto& tableSetting : tableSettings) {

ydb/core/kqp/provider/yql_kikimr_opt_build.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,16 @@ struct TKiExploreTxResults {
130130
auto view = key.GetView();
131131
if (view && view->Name) {
132132
const auto& indexName = view->Name;
133-
const auto indexTablePath = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(tableMeta->Name, indexName);
134133

135134
auto indexIt = std::find_if(tableMeta->Indexes.begin(), tableMeta->Indexes.end(), [&indexName](const auto& index){
136135
return index.Name == indexName;
137136
});
138137
YQL_ENSURE(indexIt != tableMeta->Indexes.end(), "Index not found");
139138

139+
const auto indexTablePaths = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(tableMeta->Name, indexIt->Type, indexName);
140+
YQL_ENSURE(indexTablePaths.size() == 1, "Only index with one impl table is supported");
141+
const auto indexTablePath = indexTablePaths[0];
142+
140143
THashSet<TString> indexColumns;
141144
indexColumns.reserve(indexIt->KeyColumns.size() + indexIt->DataColumns.size());
142145
for (const auto& keyColumn : indexIt->KeyColumns) {
@@ -180,7 +183,9 @@ struct TKiExploreTxResults {
180183
continue;
181184
}
182185

183-
const auto indexTable = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(tableMeta->Name, index.Name);
186+
const auto indexTables = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(tableMeta->Name, index.Type, index.Name);
187+
YQL_ENSURE(indexTables.size() == 1, "Only index with one impl table is supported");
188+
const auto indexTable = indexTables[0];
184189

185190
ops[tableMeta->Name] |= TPrimitiveYdbOperation::Read;
186191
ops[indexTable] = TPrimitiveYdbOperation::Write;
@@ -202,7 +207,10 @@ struct TKiExploreTxResults {
202207
continue;
203208
}
204209

205-
const auto indexTable = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(tableMeta->Name, index.Name);
210+
const auto indexTables = NKikimr::NKqp::NSchemeHelpers::CreateIndexTablePath(tableMeta->Name, index.Type, index.Name);
211+
YQL_ENSURE(indexTables.size() == 1, "Only index with one impl table is supported");
212+
const auto indexTable = indexTables[0];
213+
206214
for (const auto& column : index.KeyColumns) {
207215
if (updateColumns.contains(column)) {
208216
// delete old index values and upsert rows into index table

ydb/core/kqp/ut/common/kqp_ut_common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ void TKikimrRunner::Initialize(const TKikimrSettings& settings) {
502502
SetupLogLevelFromTestParam(NKikimrServices::KQP_TASKS_RUNNER);
503503
SetupLogLevelFromTestParam(NKikimrServices::KQP_EXECUTER);
504504
SetupLogLevelFromTestParam(NKikimrServices::TX_PROXY_SCHEME_CACHE);
505+
SetupLogLevelFromTestParam(NKikimrServices::TX_PROXY);
505506
SetupLogLevelFromTestParam(NKikimrServices::SCHEME_BOARD_REPLICA);
506507
SetupLogLevelFromTestParam(NKikimrServices::KQP_WORKER);
507508
SetupLogLevelFromTestParam(NKikimrServices::KQP_SESSION);

ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2472,6 +2472,59 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
24722472
}
24732473
}
24742474

2475+
Y_UNIT_TEST(AlterTableAlterVectorIndex) {
2476+
NKikimrConfig::TFeatureFlags featureFlags;
2477+
featureFlags.SetEnableVectorIndex(true);
2478+
auto settings = TKikimrSettings().SetFeatureFlags(featureFlags);
2479+
TKikimrRunner kikimr(settings);
2480+
auto db = kikimr.GetTableClient();
2481+
auto session = db.CreateSession().GetValueSync().GetSession();
2482+
{
2483+
TString create_index_query = R"(
2484+
--!syntax_v1
2485+
CREATE TABLE `/Root/TestTable` (
2486+
Key Uint64,
2487+
Embedding String,
2488+
PRIMARY KEY (Key),
2489+
INDEX vector_idx
2490+
GLOBAL USING vector_kmeans_tree
2491+
ON (Embedding)
2492+
WITH (similarity=cosine, vector_type=bit, vector_dimension=1)
2493+
);
2494+
)";
2495+
auto result = session.ExecuteSchemeQuery(create_index_query).ExtractValueSync();
2496+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
2497+
}
2498+
{
2499+
auto describe = session.DescribeTable("/Root/TestTable/vector_idx/indexImplPostingTable").GetValueSync();
2500+
UNIT_ASSERT_C(describe.IsSuccess(), describe.GetIssues().ToString());
2501+
auto indexDesc = describe.GetTableDescription();
2502+
constexpr int defaultPartitionSizeMb = 2048;
2503+
UNIT_ASSERT_VALUES_EQUAL(indexDesc.GetPartitioningSettings().GetPartitionSizeMb(), defaultPartitionSizeMb);
2504+
}
2505+
{
2506+
auto result = session.ExecuteSchemeQuery(R"(
2507+
ALTER TABLE `/Root/TestTable` ALTER INDEX vector_idx SET AUTO_PARTITIONING_MIN_PARTITIONS_COUNT 1;
2508+
)").ExtractValueSync();
2509+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString());
2510+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Only index with one impl table is supported" );
2511+
}
2512+
}
2513+
2514+
Y_UNIT_TEST(AlterTableAlterMissedIndex) {
2515+
TKikimrRunner kikimr;
2516+
auto db = kikimr.GetTableClient();
2517+
auto session = db.CreateSession().GetValueSync().GetSession();
2518+
CreateSampleTablesWithIndex(session);
2519+
{
2520+
auto result = session.ExecuteSchemeQuery(R"(
2521+
ALTER TABLE `/Root/SecondaryKeys` ALTER INDEX WrongIndexName SET AUTO_PARTITIONING_MIN_PARTITIONS_COUNT 1;
2522+
)").ExtractValueSync();
2523+
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SCHEME_ERROR, result.GetIssues().ToString());
2524+
UNIT_ASSERT_STRING_CONTAINS(result.GetIssues().ToString(), "Unknown index name: WrongIndexName");
2525+
}
2526+
}
2527+
24752528
Y_UNIT_TEST(AlterIndexImplTable) {
24762529
TKikimrRunner kikimr;
24772530
auto db = kikimr.GetTableClient();
@@ -2695,6 +2748,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
26952748
WITH (similarity=inner_product, vector_type=float, vector_dimension=1024)
26962749
);
26972750
)";
2751+
26982752
auto result = session.ExecuteSchemeQuery(create_index_query).ExtractValueSync();
26992753

27002754
UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
@@ -2714,7 +2768,14 @@ Y_UNIT_TEST_SUITE(KqpScheme) {
27142768
UNIT_ASSERT_VALUES_EQUAL(indexDesc.GetVectorIndexSettings()->VectorType, NYdb::NTable::TVectorIndexSettings::EVectorType::Float);
27152769
UNIT_ASSERT_VALUES_EQUAL(indexDesc.GetVectorIndexSettings()->VectorDimension, 1024);
27162770
}
2717-
}
2771+
{
2772+
auto describeLevelTable = session.DescribeTable("/Root/TestTable/vector_idx/indexImplLevelTable").GetValueSync();
2773+
UNIT_ASSERT_C(describeLevelTable.IsSuccess(), describeLevelTable.GetIssues().ToString());
2774+
auto describePostingTable = session.DescribeTable("/Root/TestTable/vector_idx/indexImplPostingTable").GetValueSync();
2775+
UNIT_ASSERT_C(describePostingTable.IsSuccess(), describePostingTable.GetIssues().ToString());
2776+
}
2777+
}
2778+
27182779

27192780
Y_UNIT_TEST(CreateTableWithVectorIndexCovered) {
27202781
NKikimrConfig::TFeatureFlags featureFlags;

0 commit comments

Comments
 (0)