|
1 | 1 | #include <ydb/core/base/table_index.h>
|
2 | 2 | #include <ydb/core/tx/schemeshard/ut_helpers/helpers.h>
|
3 | 3 | #include <ydb/core/tx/schemeshard/schemeshard_billing_helpers.h>
|
| 4 | +#include <ydb/core/testlib/actors/block_events.h> |
4 | 5 | #include <ydb/core/testlib/tablet_helpers.h>
|
5 | 6 |
|
6 | 7 | #include <ydb/core/tx/datashard/datashard.h>
|
7 | 8 | #include <ydb/core/metering/metering.h>
|
8 | 9 |
|
| 10 | +#include <ydb/public/sdk/cpp/client/ydb_table/table.h> |
| 11 | + |
9 | 12 | using namespace NKikimr;
|
10 | 13 | using namespace NSchemeShard;
|
11 | 14 | using namespace NSchemeShardUT_Private;
|
@@ -225,4 +228,103 @@ Y_UNIT_TEST_SUITE (VectorIndexBuildTest) {
|
225 | 228 |
|
226 | 229 | UNIT_ASSERT_VALUES_EQUAL(billRecords.size(), 0);
|
227 | 230 | }
|
| 231 | + |
| 232 | + Y_UNIT_TEST(VectorIndexDescriptionIsPersisted) { |
| 233 | + TTestBasicRuntime runtime; |
| 234 | + TTestEnv env(runtime); |
| 235 | + ui64 txId = 100; |
| 236 | + |
| 237 | + TestCreateTable(runtime, ++txId, "/MyRoot", R"( |
| 238 | + Name: "vectors" |
| 239 | + Columns { Name: "id" Type: "Uint64" } |
| 240 | + Columns { Name: "embedding" Type: "String" } |
| 241 | + Columns { Name: "covered" Type: "String" } |
| 242 | + KeyColumnNames: [ "id" ] |
| 243 | + )"); |
| 244 | + env.TestWaitNotification(runtime, txId); |
| 245 | + |
| 246 | + const auto globalIndexSettings = []{ |
| 247 | + Ydb::Table::GlobalIndexSettings globalIndexSettings; |
| 248 | + UNIT_ASSERT(google::protobuf::TextFormat::ParseFromString(R"( |
| 249 | + partition_at_keys { |
| 250 | + split_points { |
| 251 | + type { tuple_type { elements { optional_type { item { type_id: UINT32 } } } } } |
| 252 | + value { items { uint32_value: 12345 } } |
| 253 | + } |
| 254 | + split_points { |
| 255 | + type { tuple_type { elements { optional_type { item { type_id: UINT32 } } } } } |
| 256 | + value { items { uint32_value: 54321 } } |
| 257 | + } |
| 258 | + } |
| 259 | + partitioning_settings { |
| 260 | + min_partitions_count: 3 |
| 261 | + max_partitions_count: 3 |
| 262 | + } |
| 263 | + )", &globalIndexSettings)); |
| 264 | + return NYdb::NTable::TGlobalIndexSettings::FromProto(globalIndexSettings); |
| 265 | + }(); |
| 266 | + |
| 267 | + auto vectorIndexSettings = []{ |
| 268 | + Ydb::Table::VectorIndexSettings vectorIndexSettings; |
| 269 | + UNIT_ASSERT(google::protobuf::TextFormat::ParseFromString(R"( |
| 270 | + distance: DISTANCE_COSINE, |
| 271 | + vector_type: VECTOR_TYPE_FLOAT, |
| 272 | + vector_dimension: 1024 |
| 273 | + )", &vectorIndexSettings)); |
| 274 | + using T = NYdb::NTable::TVectorIndexSettings; |
| 275 | + return std::make_unique<T>(T::FromProto(vectorIndexSettings)); |
| 276 | + }(); |
| 277 | + |
| 278 | + TBlockEvents<TEvSchemeShard::TEvModifySchemeTransaction> indexCreationBlocker(runtime, [](const auto& ev) { |
| 279 | + const auto& modifyScheme = ev->Get()->Record.GetTransaction(0); |
| 280 | + return modifyScheme.GetOperationType() == NKikimrSchemeOp::ESchemeOpCreateIndexBuild; |
| 281 | + }); |
| 282 | + |
| 283 | + const ui64 buildIndexTx = ++txId; |
| 284 | + TestBuildIndex(runtime, buildIndexTx, TTestTxConfig::SchemeShard, "/MyRoot", "/MyRoot/vectors", TBuildIndexConfig{ |
| 285 | + "by_embedding", NKikimrSchemeOp::EIndexTypeGlobalVectorKmeansTree, { "embedding" }, { "covered" }, |
| 286 | + { globalIndexSettings, globalIndexSettings }, std::move(vectorIndexSettings) |
| 287 | + }); |
| 288 | + |
| 289 | + RebootTablet(runtime, TTestTxConfig::SchemeShard, runtime.AllocateEdgeActor()); |
| 290 | + |
| 291 | + indexCreationBlocker.Stop().Unblock(); |
| 292 | + env.TestWaitNotification(runtime, buildIndexTx); |
| 293 | + |
| 294 | + auto buildIndexOperation = TestGetBuildIndex(runtime, TTestTxConfig::SchemeShard, "/MyRoot", buildIndexTx); |
| 295 | + UNIT_ASSERT_VALUES_EQUAL_C( |
| 296 | + buildIndexOperation.GetIndexBuild().GetState(), Ydb::Table::IndexBuildState::STATE_DONE, |
| 297 | + buildIndexOperation.DebugString() |
| 298 | + ); |
| 299 | + |
| 300 | + TestDescribeResult(DescribePrivatePath(runtime, "/MyRoot/vectors/by_embedding"), { |
| 301 | + NLs::PathExist, |
| 302 | + NLs::IndexState(NKikimrSchemeOp::EIndexStateReady), |
| 303 | + NLs::IndexType(NKikimrSchemeOp::EIndexTypeGlobalVectorKmeansTree), |
| 304 | + NLs::IndexKeys({"embedding"}), |
| 305 | + NLs::IndexDataColumns({"covered"}), |
| 306 | + NLs::VectorIndexDescription( |
| 307 | + Ydb::Table::VectorIndexSettings::DISTANCE_COSINE, |
| 308 | + Ydb::Table::VectorIndexSettings::SIMILARITY_UNSPECIFIED, |
| 309 | + Ydb::Table::VectorIndexSettings::VECTOR_TYPE_FLOAT, |
| 310 | + 1024 |
| 311 | + ) |
| 312 | + }); |
| 313 | + |
| 314 | + using namespace NKikimr::NTableIndex::NTableVectorKmeansTreeIndex; |
| 315 | + TestDescribeResult(DescribePrivatePath(runtime, JoinFsPaths("/MyRoot/vectors/by_embedding", LevelTable), true, true), { |
| 316 | + NLs::IsTable, |
| 317 | + NLs::PartitionCount(3), |
| 318 | + NLs::MinPartitionsCountEqual(3), |
| 319 | + NLs::MaxPartitionsCountEqual(3), |
| 320 | + NLs::SplitBoundaries<ui32>({12345, 54321}) |
| 321 | + }); |
| 322 | + TestDescribeResult(DescribePrivatePath(runtime, JoinFsPaths("/MyRoot/vectors/by_embedding", PostingTable), true, true), { |
| 323 | + NLs::IsTable, |
| 324 | + NLs::PartitionCount(3), |
| 325 | + NLs::MinPartitionsCountEqual(3), |
| 326 | + NLs::MaxPartitionsCountEqual(3), |
| 327 | + NLs::SplitBoundaries<ui32>({12345, 54321}) |
| 328 | + }); |
| 329 | + } |
228 | 330 | }
|
0 commit comments