diff options
author | flown4qqqq <[email protected]> | 2025-02-05 22:20:57 +0300 |
---|---|---|
committer | flown4qqqq <[email protected]> | 2025-02-05 22:40:05 +0300 |
commit | 2fafd6772a4b43efae52727fded1faa51113be46 (patch) | |
tree | 7ce383f52366f828d631a70f51a4330a27daf09a /yql/essentials/sql/v1 | |
parent | 11b913e7a551a59247de97b626f909a5699ea8a1 (diff) |
init commit
commit_hash:0564ecb94145bde9e411b0f6786c93e4e5d1d503
Diffstat (limited to 'yql/essentials/sql/v1')
-rw-r--r-- | yql/essentials/sql/v1/SQLv1.g.in | 6 | ||||
-rw-r--r-- | yql/essentials/sql/v1/SQLv1Antlr4.g.in | 6 | ||||
-rw-r--r-- | yql/essentials/sql/v1/format/sql_format.cpp | 6 | ||||
-rw-r--r-- | yql/essentials/sql/v1/format/sql_format_ut.h | 9 | ||||
-rw-r--r-- | yql/essentials/sql/v1/node.h | 5 | ||||
-rw-r--r-- | yql/essentials/sql/v1/query.cpp | 66 | ||||
-rw-r--r-- | yql/essentials/sql/v1/source.h | 2 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql.cpp | 1 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_query.cpp | 24 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_ut.cpp | 17 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_ut_antlr4.cpp | 17 |
11 files changed, 159 insertions, 0 deletions
diff --git a/yql/essentials/sql/v1/SQLv1.g.in b/yql/essentials/sql/v1/SQLv1.g.in index d28661e68e1..9a8388b3407 100644 --- a/yql/essentials/sql/v1/SQLv1.g.in +++ b/yql/essentials/sql/v1/SQLv1.g.in @@ -79,6 +79,7 @@ sql_stmt_core: | create_transfer_stmt | alter_transfer_stmt | drop_transfer_stmt + | alter_database_stmt ; expr: @@ -691,6 +692,8 @@ table_tablestore: TABLESTORE simple_table_ref_core; table_settings_entry: an_id EQUALS table_setting_value; table_as_source: AS values_source; +alter_database_stmt: ALTER DATABASE an_id_schema OWNER TO role_name; + alter_table_stmt: ALTER TABLE simple_table_ref alter_table_action (COMMA alter_table_action)*; alter_table_action: alter_table_add_column @@ -1430,6 +1433,7 @@ keyword_as_compat: | OTHERS // | OUTER // | OVER + | OWNER | PARALLEL | PARTITION | PASSING @@ -1658,6 +1662,7 @@ keyword_compat: ( | OTHERS | OUTER | OVER + | OWNER | PARALLEL | PARTITION | PASSING @@ -2022,6 +2027,7 @@ ORDER: O R D E R; OTHERS: O T H E R S; OUTER: O U T E R; OVER: O V E R; +OWNER: O W N E R; PARALLEL: P A R A L L E L; PARTITION: P A R T I T I O N; PASSING: P A S S I N G; diff --git a/yql/essentials/sql/v1/SQLv1Antlr4.g.in b/yql/essentials/sql/v1/SQLv1Antlr4.g.in index 3f4089a93b0..20359450c97 100644 --- a/yql/essentials/sql/v1/SQLv1Antlr4.g.in +++ b/yql/essentials/sql/v1/SQLv1Antlr4.g.in @@ -78,6 +78,7 @@ sql_stmt_core: | create_transfer_stmt | alter_transfer_stmt | drop_transfer_stmt + | alter_database_stmt ; expr: @@ -683,6 +684,8 @@ backup_collection_settings_entry: an_id EQUALS table_setting_value; backup_stmt: BACKUP object_ref (INCREMENTAL)?; restore_stmt: RESTORE object_ref (AT STRING_VALUE)?; +alter_database_stmt: ALTER DATABASE an_id_schema OWNER TO role_name; + table_inherits: INHERITS LPAREN simple_table_ref_core (COMMA simple_table_ref_core)* RPAREN; table_partition_by: PARTITION BY HASH pure_column_list; with_table_settings: WITH LPAREN table_settings_entry (COMMA table_settings_entry)* RPAREN; @@ -1430,6 +1433,7 @@ keyword_as_compat: | OTHERS // | OUTER // | OVER + | OWNER | PARALLEL | PARTITION | PASSING @@ -1658,6 +1662,7 @@ keyword_compat: ( | OTHERS | OUTER | OVER + | OWNER | PARALLEL | PARTITION | PASSING @@ -2022,6 +2027,7 @@ ORDER: O R D E R; OTHERS: O T H E R S; OUTER: O U T E R; OVER: O V E R; +OWNER: O W N E R; PARALLEL: P A R A L L E L; PARTITION: P A R T I T I O N; PASSING: P A S S I N G; diff --git a/yql/essentials/sql/v1/format/sql_format.cpp b/yql/essentials/sql/v1/format/sql_format.cpp index 1240e073537..0ede01dd8fd 100644 --- a/yql/essentials/sql/v1/format/sql_format.cpp +++ b/yql/essentials/sql/v1/format/sql_format.cpp @@ -863,6 +863,11 @@ private: ExprLineIndent = 0; } + void VisitAlterDatabase(const TRule_alter_database_stmt& msg) { + NewLine(); + VisitAllFields(TRule_alter_database_stmt::GetDescriptor(), msg); + } + void VisitCreateTable(const TRule_create_table_stmt& msg) { NewLine(); Visit(msg.GetToken1()); @@ -3015,6 +3020,7 @@ TStaticData::TStaticData() {TRule_backup_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitBackup)}, {TRule_restore_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitRestore)}, {TRule_alter_sequence_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitAlterSequence)}, + {TRule_alter_database_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitAlterDatabase)}, }) , ObfuscatingVisitDispatch({ {TToken::GetDescriptor(), MakeObfuscatingFunctor(&TObfuscatingVisitor::VisitToken)}, diff --git a/yql/essentials/sql/v1/format/sql_format_ut.h b/yql/essentials/sql/v1/format/sql_format_ut.h index b7fbc66f937..15ab334a91e 100644 --- a/yql/essentials/sql/v1/format/sql_format_ut.h +++ b/yql/essentials/sql/v1/format/sql_format_ut.h @@ -20,6 +20,15 @@ Y_UNIT_TEST(DotAfterDigits) { setup.Run(cases); } +Y_UNIT_TEST(AlterDatabase) { + TCases cases { + {"use plato;alter database `/Root/test` owner to user1;", "USE plato;\n\nALTER DATABASE `/Root/test` OWNER TO user1;\n"}, + }; + + TSetup setup; + setup.Run(cases); +} + Y_UNIT_TEST(GrantPermissions) { TCases cases { {"use plato;grant connect, modify tables, list on `/Root` to user;", "USE plato;\n\nGRANT CONNECT, MODIFY TABLES, LIST ON `/Root` TO user;\n"}, diff --git a/yql/essentials/sql/v1/node.h b/yql/essentials/sql/v1/node.h index f3e3f5f5808..027b37bb69a 100644 --- a/yql/essentials/sql/v1/node.h +++ b/yql/essentials/sql/v1/node.h @@ -1277,6 +1277,11 @@ namespace NSQLTranslationV1 { bool Temporary = false; }; + struct TAlterDatabaseParameters { + TString DbPath; + std::optional<TDeferredAtom> Owner; + }; + struct TTableRef; struct TAnalyzeParams { std::shared_ptr<TTableRef> Table; diff --git a/yql/essentials/sql/v1/query.cpp b/yql/essentials/sql/v1/query.cpp index f80398b6cee..0b8b7c07a7b 100644 --- a/yql/essentials/sql/v1/query.cpp +++ b/yql/essentials/sql/v1/query.cpp @@ -1314,6 +1314,72 @@ TNodePtr BuildCreateTable(TPosition pos, const TTableRef& tr, bool existingOk, b return new TCreateTableNode(pos, tr, existingOk, replaceIfExists, params, std::move(values), scoped); } +class TAlterDatabaseNode final : public TAstListNode { +public: + TAlterDatabaseNode( + TPosition pos, + const TString& service, + const TDeferredAtom& cluster, + const TAlterDatabaseParameters& params, + TScopedStatePtr scoped + ) + : TAstListNode(pos) + , Params(params) + , Scoped(scoped) + , Cluster(cluster) + , Service(service) + { + scoped->UseCluster(service, cluster); + } + + bool DoInit(TContext& ctx, ISource* src) override { + TNodePtr cluster = Scoped->WrapCluster(Cluster, ctx); + + auto options = Y(Q(Y(Q("mode"), Q("alterDatabase")))); + + options = L(options, Q(Y(Q("dbPath"), Q(Params.DbPath)))); + + if (Params.Owner.has_value()) { + options = L(options, Q(Y(Q("owner"), Q(Params.Owner.value().Build())))); + } + + Add("block", Q(Y( + Y("let", "sink", Y("DataSink", BuildQuotedAtom(Pos, Service), cluster)), + Y("let", "world", Y(TString(WriteName), "world", "sink", Q(options))), + Y("return", ctx.PragmaAutoCommit ? Y(TString(CommitName), "world", "sink") : AstNode("world")) + ))); + + return TAstListNode::DoInit(ctx, src); + } + + TPtr DoClone() const final { + return {}; + } + +private: + const TAlterDatabaseParameters Params; + TScopedStatePtr Scoped; + TDeferredAtom Cluster; + TString Service; +}; + +TNodePtr BuildAlterDatabase( + TPosition pos, + const TString& service, + const TDeferredAtom& cluster, + const TAlterDatabaseParameters& params, + TScopedStatePtr scoped +) { + return new TAlterDatabaseNode( + pos, + service, + cluster, + params, + scoped + ); +} + + class TAlterTableNode final : public TAstListNode { public: TAlterTableNode(TPosition pos, const TTableRef& tr, const TAlterTableParameters& params, TScopedStatePtr scoped) diff --git a/yql/essentials/sql/v1/source.h b/yql/essentials/sql/v1/source.h index 991657ed155..3d2fefcb43f 100644 --- a/yql/essentials/sql/v1/source.h +++ b/yql/essentials/sql/v1/source.h @@ -304,6 +304,8 @@ namespace NSQLTranslationV1 { TNodePtr BuildBatchDelete(TPosition pos, TScopedStatePtr scoped, const TTableRef& table, TSourcePtr source, TNodePtr options = nullptr); // Implemented in query.cpp + TNodePtr BuildAlterTable(TPosition pos, const TTableRef& tr, const TAlterTableParameters& params, TScopedStatePtr scoped); + TNodePtr BuildAlterDatabase(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TAlterDatabaseParameters& params,TScopedStatePtr scoped); TNodePtr BuildTableKey(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TDeferredAtom& name, const TViewDescription& view); TNodePtr BuildTableKeys(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TString& func, const TVector<TTableArg>& args); TNodePtr BuildTopicKey(TPosition pos, const TDeferredAtom& cluster, const TDeferredAtom& name); diff --git a/yql/essentials/sql/v1/sql.cpp b/yql/essentials/sql/v1/sql.cpp index b7a7ef9e8f2..9e7c052b928 100644 --- a/yql/essentials/sql/v1/sql.cpp +++ b/yql/essentials/sql/v1/sql.cpp @@ -181,6 +181,7 @@ bool NeedUseForAllStatements(const TRule_sql_stmt_core::AltCase& subquery) { case TRule_sql_stmt_core::kAltSqlStmtCore58: // create transfer case TRule_sql_stmt_core::kAltSqlStmtCore59: // alter transfer case TRule_sql_stmt_core::kAltSqlStmtCore60: // drop transfer + case TRule_sql_stmt_core::kAltSqlStmtCore61: // alter database return false; } } diff --git a/yql/essentials/sql/v1/sql_query.cpp b/yql/essentials/sql/v1/sql_query.cpp index 7510acc4679..5db4995768d 100644 --- a/yql/essentials/sql/v1/sql_query.cpp +++ b/yql/essentials/sql/v1/sql_query.cpp @@ -1925,6 +1925,30 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& node.HasBlock4(), context)); break; } + case TRule_sql_stmt_core::kAltSqlStmtCore61: { + // alter_database_stmt: ALTER DATABASE an_id_schema OWNER TO role_name + auto& node = core.GetAlt_sql_stmt_core61().GetRule_alter_database_stmt1(); + + TDeferredAtom roleName; + { + bool allowSystemRoles = true; + if (!RoleNameClause(node.GetRule_role_name6(), roleName, allowSystemRoles)) { + return false; + } + } + + TAlterDatabaseParameters alterDatabaseParams; + alterDatabaseParams.Owner = roleName; + alterDatabaseParams.DbPath = Id(node.GetRule_an_id_schema3(), *this); + + const TPosition pos = Ctx.Pos(); + TString service = Ctx.Scoped->CurrService; + TDeferredAtom cluster = Ctx.Scoped->CurrCluster; + + auto stmt = BuildAlterDatabase(pos, service, cluster, alterDatabaseParams, Ctx.Scoped); + AddStatementToBlocks(blocks, stmt); + break; + } case TRule_sql_stmt_core::ALT_NOT_SET: Ctx.IncrementMonCounter("sql_errors", "UnknownStatement" + internalStatementName); AltNotImplemented("sql_stmt_core", core); diff --git a/yql/essentials/sql/v1/sql_ut.cpp b/yql/essentials/sql/v1/sql_ut.cpp index bd385c8feb5..d850dac37b5 100644 --- a/yql/essentials/sql/v1/sql_ut.cpp +++ b/yql/essentials/sql/v1/sql_ut.cpp @@ -969,6 +969,23 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) { UNIT_ASSERT_VALUES_EQUAL(1, elementStat["primarykey"]); } + Y_UNIT_TEST(AlterDatabaseAst) { + NYql::TAstParseResult request = SqlToYql("USE plato; ALTER DATABASE `/Root/test` OWNER TO user1;"); + UNIT_ASSERT(request.IsOk()); + + TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { + Y_UNUSED(word); + + UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find( + R"(let world (Write! world sink '('('mode 'alterDatabase) '('dbPath '/Root/test) '('owner ''"user1"))))" + )); + }; + + TWordCountHive elementStat({TString("\'mode \'alterDatabase")}); + VerifyProgram(request, elementStat, verifyLine); + UNIT_ASSERT_VALUES_EQUAL(1, elementStat["\'mode \'alterDatabase"]); + } + Y_UNIT_TEST(CreateTableNonNullableYqlTypeAstCorrect) { NYql::TAstParseResult res = SqlToYql("USE plato; CREATE TABLE t (a int32 not null);"); UNIT_ASSERT(res.Root); diff --git a/yql/essentials/sql/v1/sql_ut_antlr4.cpp b/yql/essentials/sql/v1/sql_ut_antlr4.cpp index 9463408886e..b591fd15a19 100644 --- a/yql/essentials/sql/v1/sql_ut_antlr4.cpp +++ b/yql/essentials/sql/v1/sql_ut_antlr4.cpp @@ -1087,6 +1087,23 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) { UNIT_ASSERT_VALUES_EQUAL(1, elementStat["primarykey"]); } + Y_UNIT_TEST(AlterDatabaseAst) { + NYql::TAstParseResult request = SqlToYql("USE plato; ALTER DATABASE `/Root/test` OWNER TO user1;"); + UNIT_ASSERT(request.IsOk()); + + TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { + Y_UNUSED(word); + + UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find( + R"(let world (Write! world sink '('('mode 'alterDatabase) '('dbPath '/Root/test) '('owner ''"user1"))))" + )); + }; + + TWordCountHive elementStat({TString("\'mode \'alterDatabase")}); + VerifyProgram(request, elementStat, verifyLine); + UNIT_ASSERT_VALUES_EQUAL(1, elementStat["\'mode \'alterDatabase"]); + } + Y_UNIT_TEST(CreateTableNonNullableYqlTypeAstCorrect) { NYql::TAstParseResult res = SqlToYql("USE plato; CREATE TABLE t (a int32 not null);"); UNIT_ASSERT(res.Root); |