diff options
-rw-r--r-- | ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp | 4 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/SQLv1.g.in | 7 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/format/sql_format.cpp | 9 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/format/sql_format_ut.cpp | 12 | ||||
-rw-r--r-- | ydb/library/yql/sql/v1/sql.cpp | 91 |
5 files changed, 120 insertions, 3 deletions
diff --git a/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp b/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp index dd9b001f30..3ae75412bb 100644 --- a/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp +++ b/ydb/core/kqp/ut/scheme/kqp_scheme_ut.cpp @@ -4984,8 +4984,8 @@ Y_UNIT_TEST_SUITE(KqpOlapScheme) { { schema.push_back(TTestHelper::TColumnSchema().SetName("new_column").SetType(NScheme::NTypeIds::Uint64)); - auto alterQuery = TStringBuilder() << "ALTER OBJECT `" << testTableStore.GetName() << "` (TYPE TABLESTORE) SET (ACTION=NEW_COLUMN, NAME=new_column, TYPE=Uint64);"; - + auto alterQuery = TStringBuilder() << "ALTER TABLESTORE `" << testTableStore.GetName() << "` ADD COLUMN new_column Uint64;"; + auto alterResult = testHelper.GetSession().ExecuteSchemeQuery(alterQuery).GetValueSync(); UNIT_ASSERT_VALUES_EQUAL_C(alterResult.GetStatus(), EStatus::SUCCESS, alterResult.GetIssues().ToString()); } diff --git a/ydb/library/yql/sql/v1/SQLv1.g.in b/ydb/library/yql/sql/v1/SQLv1.g.in index 10e3be734e..a3e142b3c0 100644 --- a/ydb/library/yql/sql/v1/SQLv1.g.in +++ b/ydb/library/yql/sql/v1/SQLv1.g.in @@ -56,6 +56,7 @@ sql_stmt_core: | drop_topic_stmt | grant_permissions_stmt | revoke_permissions_stmt + | alter_table_store_stmt ; expr: @@ -532,6 +533,12 @@ alter_table_action: | alter_table_rename_index_to ; +alter_table_store_stmt: ALTER TABLESTORE object_ref alter_table_store_action (COMMA alter_table_store_action)*; +alter_table_store_action: + alter_table_add_column + | alter_table_drop_column +; + alter_table_add_column: ADD COLUMN? column_schema; alter_table_drop_column: DROP COLUMN? an_id; alter_table_alter_column: ALTER COLUMN an_id SET family_relation; diff --git a/ydb/library/yql/sql/v1/format/sql_format.cpp b/ydb/library/yql/sql/v1/format/sql_format.cpp index 8c903e33b7..26e4949131 100644 --- a/ydb/library/yql/sql/v1/format/sql_format.cpp +++ b/ydb/library/yql/sql/v1/format/sql_format.cpp @@ -907,6 +907,12 @@ private: PopCurrentIndent(); } + void VisitAlterTableStore(const TRule_alter_table_store_stmt& msg) { + PosFromToken(msg.GetToken1()); + NewLine(); + VisitAllFields(TRule_alter_table_store_stmt::GetDescriptor(), msg); + } + void VisitDo(const TRule_do_stmt& msg) { PosFromToken(msg.GetToken1()); NewLine(); @@ -2106,7 +2112,8 @@ TStaticData::TStaticData() {TRule_alter_topic_stmt::GetDescriptor(), MakeFunctor(&TVisitor::VisitAlterTopic)}, {TRule_drop_topic_stmt::GetDescriptor(), MakeFunctor(&TVisitor::VisitDropTopic)}, {TRule_grant_permissions_stmt::GetDescriptor(), MakeFunctor(&TVisitor::VisitGrantPermissions)}, - {TRule_revoke_permissions_stmt::GetDescriptor(), MakeFunctor(&TVisitor::VisitRevokePermissions)} + {TRule_revoke_permissions_stmt::GetDescriptor(), MakeFunctor(&TVisitor::VisitRevokePermissions)}, + {TRule_alter_table_store_stmt::GetDescriptor(), MakeFunctor(&TVisitor::VisitAlterTableStore)} }) { // ensure that all statements has a visitor diff --git a/ydb/library/yql/sql/v1/format/sql_format_ut.cpp b/ydb/library/yql/sql/v1/format/sql_format_ut.cpp index 3f5e8fd70f..04256a191e 100644 --- a/ydb/library/yql/sql/v1/format/sql_format_ut.cpp +++ b/ydb/library/yql/sql/v1/format/sql_format_ut.cpp @@ -312,6 +312,18 @@ Y_UNIT_TEST_SUITE(CheckSqlFormatter) { TSetup setup; setup.Run(cases); } + + Y_UNIT_TEST(TableStoreOperations) { + TCases cases = { + {"alter tableStore uSer aDd column usEr int32", + "ALTER TABLESTORE uSer ADD COLUMN usEr int32;\n\n"}, + {"alter tableStore uSer drOp column usEr", + "ALTER TABLESTORE uSer DROP COLUMN usEr;\n\n"} + }; + + TSetup setup; + setup.Run(cases); + } Y_UNIT_TEST(ExternalDataSourceOperations) { TCases cases = { diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp index 8ccaa59387..d0449e9746 100644 --- a/ydb/library/yql/sql/v1/sql.cpp +++ b/ydb/library/yql/sql/v1/sql.cpp @@ -9192,6 +9192,7 @@ private: 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); + bool ParseTableStoreFeatures(std::map<TString, TDeferredAtom> & result, const TRule_alter_table_store_action & actions); TNodePtr Build(const TRule_delete_stmt& stmt); @@ -10166,6 +10167,29 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& AddStatementToBlocks(blocks, BuildRevokePermissions(pos, service, cluster, permissions, schemaPathes, roleNames, Ctx.Scoped)); break; } + case TRule_sql_stmt_core::kAltSqlStmtCore38: + { + // ALTER TABLESTORE object_ref alter_table_store_action (COMMA alter_table_store_action)*; + auto& node = core.GetAlt_sql_stmt_core38().GetRule_alter_table_store_stmt1(); + TObjectOperatorContext context(Ctx.Scoped); + + if (node.GetRule_object_ref3().HasBlock1()) { + if (!ClusterExpr(node.GetRule_object_ref3().GetBlock1().GetRule_cluster_expr1(), + false, context.ServiceId, context.Cluster)) { + return false; + } + } + + const TString& objectId = Id(node.GetRule_object_ref3().GetRule_id_or_at2(), *this).second; + const TString& typeId = "TABLESTORE"; + std::map<TString, TDeferredAtom> kv; + if (!ParseTableStoreFeatures(kv, node.GetRule_alter_table_store_action4())) { + return false; + } + + AddStatementToBlocks(blocks, BuildAlterObjectOperation(Ctx.Pos(), objectId, typeId, std::move(kv), context)); + break; + } default: Ctx.IncrementMonCounter("sql_errors", "UnknownStatement" + internalStatementName); AltNotImplemented("sql_stmt_core", core); @@ -11738,6 +11762,73 @@ bool TSqlTranslation::ParseObjectFeatures(std::map<TString, TDeferredAtom>& resu } return true; } +namespace { + + static bool BuildColumnFeatures(std::map<TString, TDeferredAtom>& result, const TRule_column_schema& columnSchema, const NYql::TPosition& pos, TSqlTranslation& transaction) { + const bool nullable = !columnSchema.HasBlock4() || !columnSchema.GetBlock4().HasBlock1(); + const TString columnName(Id(columnSchema.GetRule_an_id_schema1(), transaction)); + TString columnType; + + auto& typeBind = columnSchema.GetRule_type_name_or_bind2(); + switch (typeBind.Alt_case()) { + case TRule_type_name_or_bind::kAltTypeNameOrBind1: + { + auto& typeNameOrBind = typeBind.GetAlt_type_name_or_bind1().GetRule_type_name1(); + if (typeNameOrBind.Alt_case() != TRule_type_name::kAltTypeName2) { + return false; + } + auto& alt = typeNameOrBind.GetAlt_type_name2(); + auto& block = alt.GetBlock1(); + auto& simpleType = block.GetAlt2().GetRule_type_name_simple1(); + columnType = Id(simpleType.GetRule_an_id_pure1(), transaction); + if (columnType.empty()) { + return false; + } + break; + } + case TRule_type_name_or_bind::kAltTypeNameOrBind2: + return false; + default: + Y_FAIL("You should change implementation according to grammar changes"); + } + + result["NAME"] = TDeferredAtom(pos, columnName); + YQL_ENSURE(columnType, "Unknown column type"); + result["TYPE"] = TDeferredAtom(pos, columnType); + if (!nullable) { + result["NOT_NULL"] = TDeferredAtom(pos, "true"); + } + return true; + } +} + +bool TSqlQuery::ParseTableStoreFeatures(std::map<TString, TDeferredAtom> & result, const TRule_alter_table_store_action & actions) { + switch (actions.Alt_case()) { + case TRule_alter_table_store_action::kAltAlterTableStoreAction1: { + // ADD COLUMN + const auto& addRule = actions.GetAlt_alter_table_store_action1().GetRule_alter_table_add_column1(); + if (!BuildColumnFeatures(result, addRule.GetRule_column_schema3(), Ctx.Pos(), *this)) { + return false; + } + result["ACTION"] = TDeferredAtom(Ctx.Pos(), "NEW_COLUMN"); + break; + } + case TRule_alter_table_store_action::kAltAlterTableStoreAction2: { + // DROP COLUMN + const auto& dropRule = actions.GetAlt_alter_table_store_action2().GetRule_alter_table_drop_column1(); + TString columnName = Id(dropRule.GetRule_an_id3(), *this); + if (!columnName) { + return false; + } + result["NAME"] = TDeferredAtom(Ctx.Pos(), columnName); + result["ACTION"] = TDeferredAtom(Ctx.Pos(), "DROP_COLUMN"); + break; + } + default: + Y_FAIL("You should change implementation according to grammar changes"); + } + return true; +} bool TSqlTranslation::StoreDataSourceSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) { YQL_ENSURE(value); |