summaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1
diff options
context:
space:
mode:
authorflown4qqqq <[email protected]>2025-02-05 22:20:57 +0300
committerflown4qqqq <[email protected]>2025-02-05 22:40:05 +0300
commit2fafd6772a4b43efae52727fded1faa51113be46 (patch)
tree7ce383f52366f828d631a70f51a4330a27daf09a /yql/essentials/sql/v1
parent11b913e7a551a59247de97b626f909a5699ea8a1 (diff)
init commit
commit_hash:0564ecb94145bde9e411b0f6786c93e4e5d1d503
Diffstat (limited to 'yql/essentials/sql/v1')
-rw-r--r--yql/essentials/sql/v1/SQLv1.g.in6
-rw-r--r--yql/essentials/sql/v1/SQLv1Antlr4.g.in6
-rw-r--r--yql/essentials/sql/v1/format/sql_format.cpp6
-rw-r--r--yql/essentials/sql/v1/format/sql_format_ut.h9
-rw-r--r--yql/essentials/sql/v1/node.h5
-rw-r--r--yql/essentials/sql/v1/query.cpp66
-rw-r--r--yql/essentials/sql/v1/source.h2
-rw-r--r--yql/essentials/sql/v1/sql.cpp1
-rw-r--r--yql/essentials/sql/v1/sql_query.cpp24
-rw-r--r--yql/essentials/sql/v1/sql_ut.cpp17
-rw-r--r--yql/essentials/sql/v1/sql_ut_antlr4.cpp17
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);