aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordcherednik <dcherednik@ydb.tech>2022-07-07 21:40:36 +0300
committerdcherednik <dcherednik@ydb.tech>2022-07-07 21:40:36 +0300
commitab94a1757236fc714e4bc730928e83e60afa9506 (patch)
treed3baff73ae9ef4ea46e1b0f4318072d1a70eedd5
parent996ba6df0ac5b5f030b5608ea4221286c8b8c122 (diff)
downloadydb-ab94a1757236fc714e4bc730928e83e60afa9506.tar.gz
SQL MOVE INDEX support.
-rw-r--r--ydb/core/grpc_services/rpc_alter_table.cpp43
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_exec.cpp18
-rw-r--r--ydb/core/kqp/provider/yql_kikimr_type_ann.cpp3
-rw-r--r--ydb/core/kqp/ut/kqp_scheme_ut.cpp63
-rw-r--r--ydb/core/protos/flat_scheme_op.proto1
-rw-r--r--ydb/core/testlib/test_client.cpp3
-rw-r--r--ydb/core/testlib/test_client.h2
-rw-r--r--ydb/core/tx/datashard/export_common.h1
-rw-r--r--ydb/core/tx/schemeshard/schemeshard__operation_move_index.cpp7
-rw-r--r--ydb/core/tx/schemeshard/ut_helpers/helpers.cpp15
-rw-r--r--ydb/core/tx/schemeshard/ut_helpers/helpers.h8
-rw-r--r--ydb/core/tx/schemeshard/ut_move.cpp16
-rw-r--r--ydb/core/tx/schemeshard/ut_move_reboots.cpp6
-rw-r--r--ydb/library/yql/sql/v1/SQLv1.g.in2
-rw-r--r--ydb/library/yql/sql/v1/node.h4
-rw-r--r--ydb/library/yql/sql/v1/query.cpp12
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp20
-rw-r--r--ydb/public/api/protos/ydb_table.proto11
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 {