diff options
author | dcherednik <dcherednik@ydb.tech> | 2022-07-07 21:40:36 +0300 |
---|---|---|
committer | dcherednik <dcherednik@ydb.tech> | 2022-07-07 21:40:36 +0300 |
commit | ab94a1757236fc714e4bc730928e83e60afa9506 (patch) | |
tree | d3baff73ae9ef4ea46e1b0f4318072d1a70eedd5 | |
parent | 996ba6df0ac5b5f030b5608ea4221286c8b8c122 (diff) | |
download | ydb-ab94a1757236fc714e4bc730928e83e60afa9506.tar.gz |
SQL MOVE INDEX support.
-rw-r--r-- | ydb/core/grpc_services/rpc_alter_table.cpp | 43 | ||||
-rw-r--r-- | ydb/core/kqp/provider/yql_kikimr_exec.cpp | 18 | ||||
-rw-r--r-- | ydb/core/kqp/provider/yql_kikimr_type_ann.cpp | 3 | ||||
-rw-r--r-- | ydb/core/kqp/ut/kqp_scheme_ut.cpp | 63 | ||||
-rw-r--r-- | ydb/core/protos/flat_scheme_op.proto | 1 | ||||
-rw-r--r-- | ydb/core/testlib/test_client.cpp | 3 | ||||
-rw-r--r-- | ydb/core/testlib/test_client.h | 2 | ||||
-rw-r--r-- | ydb/core/tx/datashard/export_common.h | 1 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp | 7 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_helpers/helpers.cpp | 15 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_helpers/helpers.h | 8 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_move.cpp | 16 | ||||
-rw-r--r-- | ydb/core/tx/schemeshard/ut_move_reboots.cpp | 6 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/SQLv1.g.in | 2 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/node.h | 4 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/query.cpp | 12 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/sql.cpp | 20 | ||||
-rw-r--r-- | ydb/public/api/protos/ydb_table.proto | 11 |
18 files changed, 207 insertions, 28 deletions
diff --git a/ydb/core/grpc_services/rpc_alter_table.cpp b/ydb/core/grpc_services/rpc_alter_table.cpp index 9907b516f0..93a6f0c792 100644 --- a/ydb/core/grpc_services/rpc_alter_table.cpp +++ b/ydb/core/grpc_services/rpc_alter_table.cpp @@ -106,6 +106,8 @@ class TAlterTableRPC : public TRpcSchemeRequestActor<TAlterTableRPC, TEvAlterTab AddChangefeed, // drop changefeeds DropChangefeed, + // rename index + RenameIndex, }; THashSet<EOp> GetOps() const { @@ -142,6 +144,10 @@ class TAlterTableRPC : public TRpcSchemeRequestActor<TAlterTableRPC, TEvAlterTab ops.emplace(EOp::Attribute); } + if (req->rename_indexes_size()) { + ops.emplace(EOp::RenameIndex); + } + return ops; } @@ -224,6 +230,15 @@ public: case EOp::Attribute: AlterUserAttributes(ctx); break; + + case EOp::RenameIndex: + if (req->rename_indexes_size() == 1) { + RenameIndex(ctx); + } else { + return Reply(StatusIds::UNSUPPORTED, "Only one index can be renamed by one operation", + NKikimrIssues::TIssuesIds::DEFAULT_ERROR, ctx); + } + break; } Become(&TAlterTableRPC::AlterStateWork); @@ -622,6 +637,34 @@ private: ctx.Send(MakeTxProxyID(), proposeRequest.release()); } + void RenameIndex(const TActorContext &ctx) { + const auto req = GetProtoRequest(); + + std::pair<TString, TString> pathPair; + try { + pathPair = SplitPath(req->path()); + } catch (const std::exception&) { + return ReplyWithStatus(StatusIds::BAD_REQUEST, ctx); + } + + const auto& workingDir = pathPair.first; + + std::unique_ptr<TEvTxUserProxy::TEvProposeTransaction> proposeRequest = CreateProposeTransaction(); + auto& record = proposeRequest->Record; + auto& modifyScheme = *record.MutableTransaction()->MutableModifyScheme(); + + modifyScheme.SetWorkingDir(workingDir); + modifyScheme.SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpMoveIndex); + + auto& alter = *modifyScheme.MutableMoveIndex(); + alter.SetTablePath(req->path()); + alter.SetSrcPath(req->rename_indexes(0).source_name()); + alter.SetDstPath(req->rename_indexes(0).destination_name()); + alter.SetAllowOverwrite(req->rename_indexes(0).replace_destination()); + + ctx.Send(MakeTxProxyID(), proposeRequest.release()); + } + void ReplyWithStatus(StatusIds::StatusCode status, const TActorContext &ctx) { Request_->ReplyWithYdbStatus(status); diff --git a/ydb/core/kqp/provider/yql_kikimr_exec.cpp b/ydb/core/kqp/provider/yql_kikimr_exec.cpp index 499aa3d974..5ff0685bb0 100644 --- a/ydb/core/kqp/provider/yql_kikimr_exec.cpp +++ b/ydb/core/kqp/provider/yql_kikimr_exec.cpp @@ -883,6 +883,24 @@ public: } else if (name == "dropChangefeed") { auto nameNode = action.Value().Cast<TCoAtom>(); alterTableRequest.add_drop_changefeeds(TString(nameNode.Value())); + } else if (name == "renameIndexTo") { + auto listNode = action.Value().Cast<TExprList>(); + auto renameIndexes = alterTableRequest.add_rename_indexes(); + for (size_t i = 0; i < listNode.Size(); ++i) { + auto item = listNode.Item(i); + auto columnTuple = item.Cast<TExprList>(); + auto nameNode = columnTuple.Item(0).Cast<TCoAtom>(); + auto name = TString(nameNode.Value()); + if (name == "src") { + renameIndexes->set_source_name(columnTuple.Item(1).Cast<TCoAtom>().StringValue()); + } else if (name == "dst") { + renameIndexes->set_destination_name(columnTuple.Item(1).Cast<TCoAtom>().StringValue()); + } else { + ctx.AddError(TIssue(ctx.GetPosition(action.Name().Pos()), + TStringBuilder() << "Unknown renameIndexTo param: " << name)); + return SyncError(); + } + } } else { ctx.AddError(TIssue(ctx.GetPosition(action.Name().Pos()), TStringBuilder() << "Unknown alter table action: " << name)); diff --git a/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp b/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp index 6fb991b94d..29edd90cba 100644 --- a/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp +++ b/ydb/core/kqp/provider/yql_kikimr_type_ann.cpp @@ -1024,7 +1024,8 @@ private: && name != "alterColumnFamilies" && name != "setTableSettings" && name != "addChangefeed" - && name != "dropChangefeed") + && name != "dropChangefeed" + && name != "renameIndexTo") { ctx.AddError(TIssue(ctx.GetPosition(action.Name().Pos()), TStringBuilder() << "Unknown alter table action: " << name)); diff --git a/ydb/core/kqp/ut/kqp_scheme_ut.cpp b/ydb/core/kqp/ut/kqp_scheme_ut.cpp index 260768024b..46bb6eeb08 100644 --- a/ydb/core/kqp/ut/kqp_scheme_ut.cpp +++ b/ydb/core/kqp/ut/kqp_scheme_ut.cpp @@ -470,7 +470,7 @@ Y_UNIT_TEST_SUITE(KqpScheme) { { kikimr.GetTestServer().GetRuntime()->GetAppData().AdministrationAllowedSIDs.push_back("root@builtin"); - auto reply = kikimr.GetTestClient().MoveIndex("/Root/KeyValue", "value_index", "moved_value_index", "root@builtin"); + auto reply = kikimr.GetTestClient().MoveIndex("/Root/KeyValue", "value_index", "moved_value_index", true, "root@builtin"); const NKikimrClient::TResponse &response = reply->Record; UNIT_ASSERT_VALUES_EQUAL((NMsgBusProxy::EResponseStatus)response.GetStatus(), NMsgBusProxy::MSTATUS_OK); } @@ -1142,6 +1142,16 @@ Y_UNIT_TEST_SUITE(KqpScheme) { { auto query = TStringBuilder() << R"( --!syntax_v1 + ALTER TABLE `/Root/table` RENAME TO `/Root/second`; + )"; + + const auto result = session.ExecuteSchemeQuery(query << ";").GetValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::GENERIC_ERROR, result.GetIssues().ToString()); + } + + { + auto query = TStringBuilder() << R"( + --!syntax_v1 DROP TABLE `/Root/second`; ALTER TABLE `/Root/table` RENAME TO `/Root/second`; )"; @@ -2123,6 +2133,57 @@ Y_UNIT_TEST_SUITE(KqpScheme) { AlterTableAddIndex(EIndexTypeSql::GlobalAsync, true); } + Y_UNIT_TEST(AlterTableRenameIndex) { + TKikimrRunner kikimr; + auto db = kikimr.GetTableClient(); + auto session = db.CreateSession().GetValueSync().GetSession(); + CreateSampleTablesWithIndex(session); + { + auto status = session.ExecuteSchemeQuery(R"( + --!syntax_v1 + ALTER TABLE `/Root/SecondaryKeys` RENAME INDEX Index TO RenamedIndex; + )").ExtractValueSync(); + UNIT_ASSERT_VALUES_EQUAL_C(status.GetStatus(), EStatus::SUCCESS, status.GetIssues().ToString()); + } + + { + TDescribeTableResult describe = session.DescribeTable("/Root/SecondaryKeys").GetValueSync(); + UNIT_ASSERT_EQUAL(describe.GetStatus(), EStatus::SUCCESS); + auto indexDesc = describe.GetTableDescription().GetIndexDescriptions(); + UNIT_ASSERT_VALUES_EQUAL(indexDesc.size(), 1); + UNIT_ASSERT_VALUES_EQUAL(indexDesc.back().GetIndexName(), "RenamedIndex"); + UNIT_ASSERT_VALUES_EQUAL(indexDesc.back().GetIndexColumns().size(), 1); + UNIT_ASSERT_VALUES_EQUAL(indexDesc.back().GetDataColumns().size(), 0); + } + } + + Y_UNIT_TEST(AlterTableReplaceIndex) { + TKikimrRunner kikimr; + auto db = kikimr.GetTableClient(); + auto session = db.CreateSession().GetValueSync().GetSession(); + CreateSampleTablesWithIndex(session); + + { + TString create_index_query = R"( + --!syntax_v1 + ALTER TABLE `/Root/SecondaryKeys` ADD INDEX ValueIndex GLOBAL SYNC ON (`Value`); + )"; + auto result = session.ExecuteSchemeQuery(create_index_query).ExtractValueSync(); + + UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString()); + } + + { + auto status = session.ExecuteSchemeQuery(R"( + --!syntax_v1 + ALTER TABLE `/Root/SecondaryKeys` RENAME INDEX Index TO ValueIndex; + )").ExtractValueSync(); + + UNIT_ASSERT_VALUES_EQUAL_C(status.GetStatus(), EStatus::SCHEME_ERROR, status.GetIssues().ToString()); + } + } + + Y_UNIT_TEST(AlterTableWithDecimalColumn) { TKikimrRunner kikimr; auto db = kikimr.GetTableClient(); diff --git a/ydb/core/protos/flat_scheme_op.proto b/ydb/core/protos/flat_scheme_op.proto index 3f710d1270..2db6d7e036 100644 --- a/ydb/core/protos/flat_scheme_op.proto +++ b/ydb/core/protos/flat_scheme_op.proto @@ -1078,6 +1078,7 @@ message TMoveIndex { optional string TablePath = 1; optional string SrcPath = 2; optional string DstPath = 3; + optional bool AllowOverwrite = 4; } message TSequenceDescription { diff --git a/ydb/core/testlib/test_client.cpp b/ydb/core/testlib/test_client.cpp index 41fa8a4312..accd76b1b3 100644 --- a/ydb/core/testlib/test_client.cpp +++ b/ydb/core/testlib/test_client.cpp @@ -1526,7 +1526,7 @@ namespace Tests { return dynamic_cast<NMsgBusProxy::TBusResponse *>(reply.Release()); } - TAutoPtr<NMsgBusProxy::TBusResponse> TClient::MoveIndex(const TString& table, const TString& src, const TString& dst, const TString& userToken) { + TAutoPtr<NMsgBusProxy::TBusResponse> TClient::MoveIndex(const TString& table, const TString& src, const TString& dst, bool allowOverwrite, const TString& userToken) { TAutoPtr<NMsgBusProxy::TBusSchemeOperation> request(new NMsgBusProxy::TBusSchemeOperation()); auto *op = request->Record.MutableTransaction()->MutableModifyScheme(); op->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpMoveIndex); @@ -1534,6 +1534,7 @@ namespace Tests { descr->SetTablePath(table); descr->SetSrcPath(src); descr->SetDstPath(dst); + descr->SetAllowOverwrite(allowOverwrite); TAutoPtr<NBus::TBusMessage> reply; if (userToken) { request->Record.SetSecurityToken(userToken); diff --git a/ydb/core/testlib/test_client.h b/ydb/core/testlib/test_client.h index 5c788dab40..37b6c3f202 100644 --- a/ydb/core/testlib/test_client.h +++ b/ydb/core/testlib/test_client.h @@ -390,7 +390,7 @@ namespace Tests { TAutoPtr<NMsgBusProxy::TBusResponse> AlterTable(const TString& parent, const NKikimrSchemeOp::TTableDescription& update, const TString& userToken); TAutoPtr<NMsgBusProxy::TBusResponse> AlterTable(const TString& parent, const TString& alter, const TString& userToken); - TAutoPtr<NMsgBusProxy::TBusResponse> MoveIndex(const TString& table, const TString& src, const TString& dst, const TString& userToken); + TAutoPtr<NMsgBusProxy::TBusResponse> MoveIndex(const TString& table, const TString& src, const TString& dst, bool allowOverwrite, const TString& userToken); NMsgBusProxy::EResponseStatus CreateOlapStore(const TString& parent, const TString& scheme); NMsgBusProxy::EResponseStatus CreateOlapStore(const TString& parent, const NKikimrSchemeOp::TColumnStoreDescription& store); diff --git a/ydb/core/tx/datashard/export_common.h b/ydb/core/tx/datashard/export_common.h index b9ccffe2a1..5e4290d0ed 100644 --- a/ydb/core/tx/datashard/export_common.h +++ b/ydb/core/tx/datashard/export_common.h @@ -3,7 +3,6 @@ #include "datashard_user_table.h" #include <ydb/core/protos/flat_scheme_op.pb.h> -#include <ydb/public/api/protos/ydb_table.pb.h> #include <util/generic/map.h> #include <util/generic/maybe.h> diff --git a/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp b/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp index 67f67a39bc..fb3b4f2a81 100644 --- a/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp +++ b/ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp @@ -510,6 +510,7 @@ TVector<ISubOperationBase::TPtr> CreateConsistentMoveIndex(TOperationId nextId, const auto& mainTable = moving.GetTablePath(); const auto& srcIndex = moving.GetSrcPath(); const auto& dstIndex = moving.GetDstPath(); + bool allowOverwrite = moving.HasAllowOverwrite() && moving.GetAllowOverwrite(); TPath mainTablePath = TPath::Resolve(mainTable, context.SS); { @@ -594,6 +595,12 @@ TVector<ISubOperationBase::TPtr> CreateConsistentMoveIndex(TOperationId nextId, .IsTableIndex(); if (checks) { + if (!allowOverwrite) { + TString errStr = TStringBuilder() + << "Index " << dstIndex + << "exists, but overwrite flag has not been set"; + return {CreateReject(nextId, NKikimrScheme::StatusSchemeError, errStr)}; + } { auto indexDropping = TransactionTemplate(mainTablePath.PathString(), NKikimrSchemeOp::EOperationType::ESchemeOpDropTableIndex); auto operation = indexDropping.MutableDrop(); diff --git a/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp b/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp index 216001fc02..37d8562be7 100644 --- a/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp +++ b/ydb/core/tx/schemeshard/ut_helpers/helpers.cpp @@ -391,7 +391,7 @@ namespace NSchemeShardUT_Private { TestModificationResults(runtime, txId, expectedResults); } - TEvSchemeShard::TEvModifySchemeTransaction* MoveIndexRequest(ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, ui64 schemeShard, const TApplyIf& applyIf) { + TEvSchemeShard::TEvModifySchemeTransaction* MoveIndexRequest(ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, bool allowOverwrite, ui64 schemeShard, const TApplyIf& applyIf) { THolder<TEvSchemeShard::TEvModifySchemeTransaction> evTx = MakeHolder<TEvSchemeShard::TEvModifySchemeTransaction>(txId, schemeShard); auto transaction = evTx->Record.AddTransaction(); transaction->SetOperationType(NKikimrSchemeOp::EOperationType::ESchemeOpMoveIndex); @@ -401,21 +401,22 @@ namespace NSchemeShardUT_Private { descr->SetTablePath(tablePath); descr->SetSrcPath(srcPath); descr->SetDstPath(dstPath); + descr->SetAllowOverwrite(allowOverwrite); return evTx.Release(); } - void AsyncMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, ui64 schemeShard) { + void AsyncMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, bool allowOverwrite, ui64 schemeShard) { TActorId sender = runtime.AllocateEdgeActor(); - ForwardToTablet(runtime, schemeShard, sender, MoveIndexRequest(txId, tablePath, srcPath, dstPath, schemeShard)); + ForwardToTablet(runtime, schemeShard, sender, MoveIndexRequest(txId, tablePath, srcPath, dstPath, allowOverwrite, schemeShard)); } - void TestMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& src, const TString& dst, const TVector<TEvSchemeShard::EStatus>& expectedResults) { - TestMoveIndex(runtime, TTestTxConfig::SchemeShard, txId, tablePath, src, dst, expectedResults); + void TestMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& src, const TString& dst, bool allowOverwrite, const TVector<TEvSchemeShard::EStatus>& expectedResults) { + TestMoveIndex(runtime, TTestTxConfig::SchemeShard, txId, tablePath, src, dst, allowOverwrite, expectedResults); } - void TestMoveIndex(TTestActorRuntime& runtime, ui64 schemeShard, ui64 txId, const TString& tablePath, const TString& src, const TString& dst, const TVector<TEvSchemeShard::EStatus>& expectedResults) { - AsyncMoveIndex(runtime, txId, tablePath, src, dst, schemeShard); + void TestMoveIndex(TTestActorRuntime& runtime, ui64 schemeShard, ui64 txId, const TString& tablePath, const TString& src, const TString& dst, bool allowOverwrite, const TVector<TEvSchemeShard::EStatus>& expectedResults) { + AsyncMoveIndex(runtime, txId, tablePath, src, dst, allowOverwrite, schemeShard); TestModificationResults(runtime, txId, expectedResults); } diff --git a/ydb/core/tx/schemeshard/ut_helpers/helpers.h b/ydb/core/tx/schemeshard/ut_helpers/helpers.h index c005063fb9..e3015f9ca5 100644 --- a/ydb/core/tx/schemeshard/ut_helpers/helpers.h +++ b/ydb/core/tx/schemeshard/ut_helpers/helpers.h @@ -249,10 +249,10 @@ namespace NSchemeShardUT_Private { void TestMoveTable(TTestActorRuntime& runtime, ui64 schemeShard, ui64 txId, const TString& srcMove, const TString& dstMove, const TVector<TEvSchemeShard::EStatus>& expectedResults = {NKikimrScheme::StatusAccepted}); // move index - TEvTx* MoveIndexRequest(ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, ui64 schemeShard = TTestTxConfig::SchemeShard, const TApplyIf& applyIf = {}); - void AsyncMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, ui64 schemeShard = TTestTxConfig::SchemeShard); - void TestMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& srcMove, const TString& dstMove, const TVector<TEvSchemeShard::EStatus>& expectedResults = {NKikimrScheme::StatusAccepted}); - void TestMoveIndex(TTestActorRuntime& runtime, ui64 schemeShard, ui64 txId, const TString& tablePath, const TString& srcMove, const TString& dstMove, const TVector<TEvSchemeShard::EStatus>& expectedResults = {NKikimrScheme::StatusAccepted}); + TEvTx* MoveIndexRequest(ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, bool allowOverwrite, ui64 schemeShard = TTestTxConfig::SchemeShard, const TApplyIf& applyIf = {}); + void AsyncMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& srcPath, const TString& dstPath, bool allowOverwrite, ui64 schemeShard = TTestTxConfig::SchemeShard); + void TestMoveIndex(TTestActorRuntime& runtime, ui64 txId, const TString& tablePath, const TString& srcMove, const TString& dstMove, bool allowOverwrite, const TVector<TEvSchemeShard::EStatus>& expectedResults = {NKikimrScheme::StatusAccepted}); + void TestMoveIndex(TTestActorRuntime& runtime, ui64 schemeShard, ui64 txId, const TString& tablePath, const TString& srcMove, const TString& dstMove, bool allowOverwrite, const TVector<TEvSchemeShard::EStatus>& expectedResults = {NKikimrScheme::StatusAccepted}); // locks TEvTx* LockRequest(ui64 txId, const TString &parentPath, const TString& name); diff --git a/ydb/core/tx/schemeshard/ut_move.cpp b/ydb/core/tx/schemeshard/ut_move.cpp index 225dae7ada..6007936f6e 100644 --- a/ydb/core/tx/schemeshard/ut_move.cpp +++ b/ydb/core/tx/schemeshard/ut_move.cpp @@ -766,10 +766,10 @@ Y_UNIT_TEST_SUITE(TSchemeShardMoveTest) { NLs::CheckColumns("Table", {"key", "value0", "value1", "valueFloat"}, {}, {"key"}), NLs::IndexesCount(2)}); - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Sync", "MovedSync"); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Sync", "MovedSync", false); env.TestWaitNotification(runtime, txId); - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Async", "MovedAsync"); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Async", "MovedAsync", false); env.TestWaitNotification(runtime, txId); TestDescribeResult(DescribePath(runtime, "/MyRoot/Table"), @@ -833,10 +833,10 @@ Y_UNIT_TEST_SUITE(TSchemeShardMoveTest) { NLs::CheckColumns("Table", {"key", "value0", "value1", "valueFloat"}, {}, {"key"}), NLs::IndexesCount(2)}); - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Sync", "Sync", {NKikimrScheme::StatusInvalidParameter}); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Sync", "Sync", true, {NKikimrScheme::StatusInvalidParameter}); env.TestWaitNotification(runtime, txId); - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Async", "Async", {NKikimrScheme::StatusInvalidParameter}); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Async", "Async", true, {NKikimrScheme::StatusInvalidParameter}); env.TestWaitNotification(runtime, txId); TestDescribeResult(DescribePath(runtime, "/MyRoot/Table"), @@ -900,10 +900,10 @@ Y_UNIT_TEST_SUITE(TSchemeShardMoveTest) { NLs::CheckColumns("Table", {"key", "value0", "value1", "valueFloat"}, {}, {"key"}), NLs::IndexesCount(2)}); - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "BlaBla", "Sync", {NKikimrScheme::StatusPathDoesNotExist}); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "BlaBla", "Sync", true, {NKikimrScheme::StatusPathDoesNotExist}); env.TestWaitNotification(runtime, txId); - TestMoveIndex(runtime, ++txId, "/MyRoot/TableBlaBla", "Async", "Async", {NKikimrScheme::StatusPathDoesNotExist}); + TestMoveIndex(runtime, ++txId, "/MyRoot/TableBlaBla", "Async", "Async", false, {NKikimrScheme::StatusPathDoesNotExist}); env.TestWaitNotification(runtime, txId); TestDescribeResult(DescribePath(runtime, "/MyRoot/Table"), @@ -961,12 +961,12 @@ Y_UNIT_TEST_SUITE(TSchemeShardMoveTest) { WaitForSuppressed(runtime, suppressed, 1, observer); { - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Sync", "MovedSync", {NKikimrScheme::StatusMultipleModifications}); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "Sync", "MovedSync", false, {NKikimrScheme::StatusMultipleModifications}); env.TestWaitNotification(runtime, txId); } { - TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "SomeIndex", "Sync", {NKikimrScheme::StatusMultipleModifications}); + TestMoveIndex(runtime, ++txId, "/MyRoot/Table", "SomeIndex", "Sync", false, {NKikimrScheme::StatusMultipleModifications}); env.TestWaitNotification(runtime, txId); } diff --git a/ydb/core/tx/schemeshard/ut_move_reboots.cpp b/ydb/core/tx/schemeshard/ut_move_reboots.cpp index 6a90c1bc4f..f20fd34c17 100644 --- a/ydb/core/tx/schemeshard/ut_move_reboots.cpp +++ b/ydb/core/tx/schemeshard/ut_move_reboots.cpp @@ -237,10 +237,10 @@ Y_UNIT_TEST_SUITE(TSchemeShardMoveRebootsTest) { {NLs::PathExist}); } - TestMoveIndex(runtime, ++t.TxId, "/MyRoot/Table", "Sync", "MovedSync"); + TestMoveIndex(runtime, ++t.TxId, "/MyRoot/Table", "Sync", "MovedSync", false); t.TestEnv->TestWaitNotification(runtime, t.TxId); - TestMoveIndex(runtime, ++t.TxId, "/MyRoot/Table", "Async", "MovedAsync"); + TestMoveIndex(runtime, ++t.TxId, "/MyRoot/Table", "Async", "MovedAsync", false); t.TestEnv->TestWaitNotification(runtime, t.TxId); { TInactiveZone inactive(activeZone); @@ -294,7 +294,7 @@ Y_UNIT_TEST_SUITE(TSchemeShardMoveRebootsTest) { {NLs::PathExist}); } - TestMoveIndex(runtime, ++t.TxId, "/MyRoot/Table", "Sync", "Sync1"); + TestMoveIndex(runtime, ++t.TxId, "/MyRoot/Table", "Sync", "Sync1", true); t.TestEnv->TestWaitNotification(runtime, t.TxId); { diff --git a/ydb/library/yql/sql/v1/SQLv1.g.in b/ydb/library/yql/sql/v1/SQLv1.g.in index b9a92f10f3..7385be2253 100644 --- a/ydb/library/yql/sql/v1/SQLv1.g.in +++ b/ydb/library/yql/sql/v1/SQLv1.g.in @@ -479,6 +479,7 @@ alter_table_action: | alter_table_add_changefeed | alter_table_alter_changefeed | alter_table_drop_changefeed + | alter_table_rename_index_to ; alter_table_add_column: ADD COLUMN? column_schema; @@ -492,6 +493,7 @@ alter_table_reset_table_setting: RESET LPAREN an_id (COMMA an_id)* RPAREN; alter_table_add_index: ADD table_index; alter_table_drop_index: DROP INDEX an_id; alter_table_rename_to: RENAME TO an_id_table; +alter_table_rename_index_to: RENAME INDEX an_id TO an_id; alter_table_add_changefeed: ADD changefeed; alter_table_alter_changefeed: ALTER CHANGEFEED an_id changefeed_alter_settings; alter_table_drop_changefeed: DROP CHANGEFEED an_id; diff --git a/ydb/library/yql/sql/v1/node.h b/ydb/library/yql/sql/v1/node.h index 92e9c83cd8..f1f0787601 100644 --- a/ydb/library/yql/sql/v1/node.h +++ b/ydb/library/yql/sql/v1/node.h @@ -1152,6 +1152,7 @@ namespace NSQLTranslationV1 { TVector<TChangefeedDescription> AddChangefeeds; TVector<TChangefeedDescription> AlterChangefeeds; TVector<TIdentifier> DropChangefeeds; + TMaybe<std::pair<TIdentifier, TIdentifier>> RenameIndexTo; bool IsEmpty() const { return AddColumns.empty() && DropColumns.empty() && AlterColumns.empty() @@ -1159,7 +1160,8 @@ namespace NSQLTranslationV1 { && !TableSettings.IsSet() && AddIndexes.empty() && DropIndexes.empty() && !RenameTo.Defined() - && AddChangefeeds.empty() && AlterChangefeeds.empty() && DropChangefeeds.empty(); + && AddChangefeeds.empty() && AlterChangefeeds.empty() && DropChangefeeds.empty() + && !RenameIndexTo.Defined(); } }; diff --git a/ydb/library/yql/sql/v1/query.cpp b/ydb/library/yql/sql/v1/query.cpp index d054a38395..9d7b22ec9f 100644 --- a/ydb/library/yql/sql/v1/query.cpp +++ b/ydb/library/yql/sql/v1/query.cpp @@ -1046,6 +1046,18 @@ public: actions = L(actions, Q(Y(Q("renameTo"), destination))); } + if (Params.RenameIndexTo) { + auto src = BuildQuotedAtom(Params.RenameIndexTo->first.Pos, Params.RenameIndexTo->first.Name); + auto dst = BuildQuotedAtom(Params.RenameIndexTo->second.Pos, Params.RenameIndexTo->second.Name); + + auto desc = Y(); + + desc = L(desc, Q(Y(Q("src"), src))); + desc = L(desc, Q(Y(Q("dst"), dst))); + + actions = L(actions, Q(Y(Q("renameIndexTo"), Q(desc)))); + } + for (const auto& cf : Params.AddChangefeeds) { const auto& desc = CreateChangefeedDesc(cf, *this); actions = L(actions, Q(Y(Q("addChangefeed"), Q(desc)))); diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp index b689f8c20c..27f1adcad7 100644 --- a/ydb/library/yql/sql/v1/sql.cpp +++ b/ydb/library/yql/sql/v1/sql.cpp @@ -8380,6 +8380,7 @@ private: bool AlterTableAddChangefeed(const TRule_alter_table_add_changefeed& node, TAlterTableParameters& params); bool AlterTableAlterChangefeed(const TRule_alter_table_alter_changefeed& node, TAlterTableParameters& params); void AlterTableDropChangefeed(const TRule_alter_table_drop_changefeed& node, TAlterTableParameters& params); + void AlterTableRenameIndexTo(const TRule_alter_table_rename_index_to& node, TAlterTableParameters& params); TNodePtr PragmaStatement(const TRule_pragma_stmt& stmt, bool& success); void AddStatementToBlocks(TVector<TNodePtr>& blocks, TNodePtr node); @@ -9170,6 +9171,18 @@ bool TSqlQuery::AlterTableAction(const TRule_alter_table_action& node, TAlterTab AlterTableDropChangefeed(rule, params); break; } + case TRule_alter_table_action::kAltAlterTableAction15: { + // RENAME INDEX TO + if (!params.IsEmpty()) { + // rename action follows some other actions + Error() << "RENAME INDEX TO can not be used together with another table action"; + return false; + } + + const auto& renameTo = node.GetAlt_alter_table_action15().GetRule_alter_table_rename_index_to1(); + AlterTableRenameIndexTo(renameTo, params); + break; + } default: AltNotImplemented("alter_table_action", node); @@ -9316,6 +9329,13 @@ void TSqlQuery::AlterTableRenameTo(const TRule_alter_table_rename_to& node, TAlt params.RenameTo = IdEx(node.GetRule_an_id_table3(), *this); } +void TSqlQuery::AlterTableRenameIndexTo(const TRule_alter_table_rename_index_to& node, TAlterTableParameters& params) { + auto src = IdEx(node.GetRule_an_id3(), *this); + auto dst = IdEx(node.GetRule_an_id5(), *this); + + params.RenameIndexTo = std::make_pair(src, dst); +} + bool TSqlQuery::AlterTableAddChangefeed(const TRule_alter_table_add_changefeed& node, TAlterTableParameters& params) { return CreateChangefeed(node.GetRule_changefeed2(), *this, params.AddChangefeeds); } diff --git a/ydb/public/api/protos/ydb_table.proto b/ydb/public/api/protos/ydb_table.proto index 307188191e..efc4c8b46a 100644 --- a/ydb/public/api/protos/ydb_table.proto +++ b/ydb/public/api/protos/ydb_table.proto @@ -500,6 +500,15 @@ message DropTableResponse { Ydb.Operations.Operation operation = 1; } +message RenameIndexItem { + // Index name to rename + string source_name = 1; + // Target index name + string destination_name = 2; + // Move options + bool replace_destination = 3; +} + // Alter table with given path message AlterTableRequest { // Session identifier @@ -543,6 +552,8 @@ message AlterTableRequest { repeated Changefeed add_changefeeds = 19; // Remove change feeds (by its names) repeated string drop_changefeeds = 20; + // Rename existed index + repeated RenameIndexItem rename_indexes = 21; } message AlterTableResponse { |