summaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql
diff options
context:
space:
mode:
authorshumkovnd <[email protected]>2024-11-21 22:29:26 +0300
committershumkovnd <[email protected]>2024-11-21 22:51:14 +0300
commit74e7baa2f49d69b2f0385db557749750b6121a20 (patch)
tree6e7f4732613e61769184fa4aeaca53dc8913c761 /yql/essentials/sql
parent56de0f56882d2401ca734478ff95d91878e5bdbd (diff)
Support ALTER SEQUENCE command
<https://github.com/ydb-platform/ydb/issues/11763> commit_hash:5611cbe2f0e09543749e9866c5db8d427649e754
Diffstat (limited to 'yql/essentials/sql')
-rw-r--r--yql/essentials/sql/v1/SQLv1.g.in21
-rw-r--r--yql/essentials/sql/v1/SQLv1Antlr4.g.in21
-rw-r--r--yql/essentials/sql/v1/format/sql_format.cpp7
-rw-r--r--yql/essentials/sql/v1/format/sql_format_ut.h11
-rw-r--r--yql/essentials/sql/v1/node.h8
-rw-r--r--yql/essentials/sql/v1/query.cpp104
-rw-r--r--yql/essentials/sql/v1/source.h1
-rw-r--r--yql/essentials/sql/v1/sql.cpp27
-rw-r--r--yql/essentials/sql/v1/sql_query.cpp101
-rw-r--r--yql/essentials/sql/v1/sql_query.h3
-rw-r--r--yql/essentials/sql/v1/sql_ut.cpp147
-rw-r--r--yql/essentials/sql/v1/sql_ut_antlr4.cpp147
12 files changed, 584 insertions, 14 deletions
diff --git a/yql/essentials/sql/v1/SQLv1.g.in b/yql/essentials/sql/v1/SQLv1.g.in
index d2cc702174c..1b645f0b898 100644
--- a/yql/essentials/sql/v1/SQLv1.g.in
+++ b/yql/essentials/sql/v1/SQLv1.g.in
@@ -75,6 +75,7 @@ sql_stmt_core:
| drop_resource_pool_classifier_stmt
| backup_stmt
| restore_stmt
+ | alter_sequence_stmt
;
expr:
@@ -1054,6 +1055,14 @@ analyze_table: simple_table_ref (LPAREN column_list RPAREN)?;
analyze_table_list: analyze_table (COMMA analyze_table)* COMMA?;
analyze_stmt: ANALYZE analyze_table_list;
+alter_sequence_stmt: ALTER SEQUENCE (IF EXISTS)? object_ref alter_sequence_action+;
+alter_sequence_action:
+ START WITH? integer
+ | RESTART WITH? integer
+ | RESTART
+ | INCREMENT BY? integer
+;
+
// Special rules that allow to use certain keywords as identifiers.
identifier: ID_PLAIN | ID_QUOTED;
id: identifier | keyword;
@@ -1339,6 +1348,7 @@ keyword_as_compat:
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1413,6 +1423,7 @@ keyword_as_compat:
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
// | RESULT
@@ -1430,7 +1441,9 @@ keyword_as_compat:
| SETS
| SHOW
| SKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1557,6 +1570,7 @@ keyword_compat: (
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1631,6 +1645,7 @@ keyword_compat: (
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
| RESULT
@@ -1648,7 +1663,9 @@ keyword_compat: (
| SETS
| SHOW
| SKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1903,6 +1920,7 @@ ILIKE: I L I K E;
IMMEDIATE: I M M E D I A T E;
IMPORT: I M P O R T;
IN: I N;
+INCREMENT: I N C R E M E N T;
INCREMENTAL: I N C R E M E N T A L;
INDEX: I N D E X;
INDEXED: I N D E X E D;
@@ -1992,6 +2010,7 @@ REPLICATION: R E P L I C A T I O N;
RESET: R E S E T;
RESOURCE: R E S O U R C E;
RESPECT: R E S P E C T;
+RESTART: R E S T A R T;
RESTORE: R E S T O R E;
RESTRICT: R E S T R I C T;
RESULT: R E S U L T;
@@ -2016,7 +2035,9 @@ SET: S E T;
SETS: S E T S;
SHOW: S H O W;
SKIP: S K I P;
+SEQUENCE: S E Q U E N C E;
SOURCE: S O U R C E;
+START: S T A R T;
STREAM: S T R E A M;
STRUCT: S T R U C T;
SUBQUERY: S U B Q U E R Y;
diff --git a/yql/essentials/sql/v1/SQLv1Antlr4.g.in b/yql/essentials/sql/v1/SQLv1Antlr4.g.in
index 02282d8ebf0..54355353365 100644
--- a/yql/essentials/sql/v1/SQLv1Antlr4.g.in
+++ b/yql/essentials/sql/v1/SQLv1Antlr4.g.in
@@ -74,6 +74,7 @@ sql_stmt_core:
| drop_resource_pool_classifier_stmt
| backup_stmt
| restore_stmt
+ | alter_sequence_stmt
;
expr:
@@ -1053,6 +1054,14 @@ analyze_table: simple_table_ref (LPAREN column_list RPAREN)?;
analyze_table_list: analyze_table (COMMA analyze_table)* COMMA?;
analyze_stmt: ANALYZE analyze_table_list;
+alter_sequence_stmt: ALTER SEQUENCE (IF EXISTS)? object_ref alter_sequence_action+;
+alter_sequence_action:
+ START WITH? integer
+ | RESTART WITH? integer
+ | RESTART
+ | INCREMENT BY? integer
+;
+
// Special rules that allow to use certain keywords as identifiers.
identifier: ID_PLAIN | ID_QUOTED;
id: identifier | keyword;
@@ -1338,6 +1347,7 @@ keyword_as_compat:
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1412,6 +1422,7 @@ keyword_as_compat:
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
// | RESULT
@@ -1429,7 +1440,9 @@ keyword_as_compat:
| SETS
| SHOW
| TSKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1556,6 +1569,7 @@ keyword_compat: (
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1630,6 +1644,7 @@ keyword_compat: (
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
| RESULT
@@ -1647,7 +1662,9 @@ keyword_compat: (
| SETS
| SHOW
| TSKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1902,6 +1919,7 @@ ILIKE: I L I K E;
IMMEDIATE: I M M E D I A T E;
IMPORT: I M P O R T;
IN: I N;
+INCREMENT: I N C R E M E N T;
INCREMENTAL: I N C R E M E N T A L;
INDEX: I N D E X;
INDEXED: I N D E X E D;
@@ -1991,6 +2009,7 @@ REPLICATION: R E P L I C A T I O N;
RESET: R E S E T;
RESOURCE: R E S O U R C E;
RESPECT: R E S P E C T;
+RESTART: R E S T A R T;
RESTORE: R E S T O R E;
RESTRICT: R E S T R I C T;
RESULT: R E S U L T;
@@ -2015,7 +2034,9 @@ SET: S E T;
SETS: S E T S;
SHOW: S H O W;
TSKIP: S K I P;
+SEQUENCE: S E Q U E N C E;
SOURCE: S O U R C E;
+START: S T A R T;
STREAM: S T R E A M;
STRUCT: S T R U C T;
SUBQUERY: S U B Q U E R Y;
diff --git a/yql/essentials/sql/v1/format/sql_format.cpp b/yql/essentials/sql/v1/format/sql_format.cpp
index 262f9b29198..3cc18b141bb 100644
--- a/yql/essentials/sql/v1/format/sql_format.cpp
+++ b/yql/essentials/sql/v1/format/sql_format.cpp
@@ -962,6 +962,12 @@ private:
VisitAllFields(TRule_use_stmt::GetDescriptor(), msg);
}
+ void VisitAlterSequence(const TRule_alter_sequence_stmt& msg) {
+ PosFromToken(msg.GetToken1());
+ NewLine();
+ VisitAllFields(TRule_alter_sequence_stmt::GetDescriptor(), msg);
+ }
+
void VisitIntoTable(const TRule_into_table_stmt& msg) {
switch (msg.GetBlock1().Alt_case()) {
case TRule_into_table_stmt_TBlock1::AltCase::kAlt1:
@@ -2915,6 +2921,7 @@ TStaticData::TStaticData()
{TRule_drop_resource_pool_classifier_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitDropResourcePoolClassifier)},
{TRule_backup_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitBackup)},
{TRule_restore_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitRestore)},
+ {TRule_alter_sequence_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitAlterSequence)},
})
, 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 021d57c8b13..fc919b38c43 100644
--- a/yql/essentials/sql/v1/format/sql_format_ut.h
+++ b/yql/essentials/sql/v1/format/sql_format_ut.h
@@ -115,6 +115,17 @@ Y_UNIT_TEST(AlterGroup) {
setup.Run(cases);
}
+Y_UNIT_TEST(AlterSequence) {
+ TCases cases = {
+ {"use plato;alter sequence sequence start with 10 increment 2 restart with 5;","USE plato;\n\nALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5;\n"},
+ {"use plato;alter sequence if exists sequence increment 1000 start 100 restart;","USE plato;\n\nALTER SEQUENCE IF EXISTS sequence INCREMENT 1000 START 100 RESTART;\n"},
+ };
+
+ TSetup setup;
+ setup.Run(cases);
+}
+
+
Y_UNIT_TEST(Use) {
TCases cases = {
{"use user;","USE user;\n"},
diff --git a/yql/essentials/sql/v1/node.h b/yql/essentials/sql/v1/node.h
index 53f606cc6b0..99f42f353cd 100644
--- a/yql/essentials/sql/v1/node.h
+++ b/yql/essentials/sql/v1/node.h
@@ -1300,6 +1300,14 @@ namespace NSQLTranslationV1 {
TVector<TDeferredAtom> Roles;
};
+ struct TSequenceParameters {
+ bool MissingOk = false;
+ TMaybe<TDeferredAtom> StartValue;
+ bool IsRestart = false;
+ TMaybe<TDeferredAtom> RestartValue;
+ TMaybe<TDeferredAtom> Increment;
+ };
+
struct TTopicConsumerSettings {
struct TLocalSinkSettings {
// no special settings
diff --git a/yql/essentials/sql/v1/query.cpp b/yql/essentials/sql/v1/query.cpp
index dc71f573811..8e71da31460 100644
--- a/yql/essentials/sql/v1/query.cpp
+++ b/yql/essentials/sql/v1/query.cpp
@@ -2049,6 +2049,110 @@ TNodePtr BuildAlterUser(TPosition pos, const TString& service, const TDeferredAt
return new TAlterUser(pos, service, cluster, name, params, scoped);
}
+class TAlterSequence final: public TAstListNode {
+public:
+ TAlterSequence(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TString& id, const TSequenceParameters& params, TScopedStatePtr scoped)
+ : TAstListNode(pos)
+ , Service(service)
+ , Cluster(cluster)
+ , Id(id)
+ , Params(params)
+ , Scoped(scoped)
+ {
+ FakeSource = BuildFakeSource(pos);
+ scoped->UseCluster(service, cluster);
+ }
+
+ bool DoInit(TContext& ctx, ISource* src) override {
+ Y_UNUSED(src);
+
+ TNodePtr cluster = Scoped->WrapCluster(Cluster, ctx);
+
+ if (!cluster->Init(ctx, FakeSource.Get())) {
+ return false;
+ }
+
+ auto options = Y();
+ TString mode = Params.MissingOk ? "alter_if_exists" : "alter";
+ options = L(options, Q(Y(Q("mode"), Q(mode))));
+
+ if (Params.IsRestart) {
+ if (Params.RestartValue) {
+ TString strValue = Params.RestartValue->Build()->GetLiteralValue();
+ ui64 value = FromString<ui64>(strValue);
+ ui64 maxValue = ui64(std::numeric_limits<i64>::max());
+ ui64 minValue = 1;
+ if (value > maxValue) {
+ ctx.Error(Pos) << "Restart value: " << value << " cannot be greater than max value: " << maxValue;
+ return false;
+ }
+ if (value < minValue) {
+ ctx.Error(Pos) << "Restart value: " << value << " cannot be less than min value: " << minValue;
+ return false;
+ }
+ options = L(options, Q(Y(Q("restart"), Q(ToString(value)))));
+ } else {
+ options = L(options, Q(Y(Q("restart"), Q(TString()))));
+ }
+ }
+ if (Params.StartValue) {
+ TString strValue = Params.StartValue->Build()->GetLiteralValue();
+ ui64 value = FromString<ui64>(strValue);
+ ui64 maxValue = ui64(std::numeric_limits<i64>::max());
+ ui64 minValue = 1;
+ if (value > maxValue) {
+ ctx.Error(Pos) << "Start value: " << value << " cannot be greater than max value: " << maxValue;
+ return false;
+ }
+ if (value < minValue) {
+ ctx.Error(Pos) << "Start value: " << value << " cannot be less than min value: " << minValue;
+ return false;
+ }
+ options = L(options, Q(Y(Q("start"), Q(ToString(value)))));
+ }
+
+ if (Params.Increment) {
+ TString strValue = Params.Increment->Build()->GetLiteralValue();
+ ui64 value = FromString<ui64>(strValue);
+ ui64 maxValue = ui64(std::numeric_limits<i64>::max());
+ if (value > maxValue) {
+ ctx.Error(Pos) << "Increment: " << value << " cannot be greater than max value: " << maxValue;
+ return false;
+ }
+ if (value == 0) {
+ ctx.Error(Pos) << "Increment must not be zero";
+ return false;
+ }
+ options = L(options, Q(Y(Q("increment"), Q(ToString(value)))));
+ }
+
+ Add("block", Q(Y(
+ Y("let", "sink", Y("DataSink", BuildQuotedAtom(Pos, TString(KikimrProviderName)),
+ Scoped->WrapCluster(Cluster, ctx))),
+ Y("let", "world", Y(TString(WriteName), "world", "sink", Y("Key", Q(Y(Q("sequence"), Y("String", BuildQuotedAtom(Pos, Id))))), Y("Void"), 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 TString Service;
+ TDeferredAtom Cluster;
+ TString Id;
+ const TSequenceParameters Params;
+
+ TScopedStatePtr Scoped;
+ TSourcePtr FakeSource;
+};
+
+TNodePtr BuildAlterSequence(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TString& id, const TSequenceParameters& params, TScopedStatePtr scoped) {
+ return new TAlterSequence(pos, service, cluster, id, params, scoped);
+}
+
class TRenameRole final: public TAstListNode {
public:
TRenameRole(TPosition pos, bool isUser, const TString& service, const TDeferredAtom& cluster, const TDeferredAtom& name, const TDeferredAtom& newName, TScopedStatePtr scoped)
diff --git a/yql/essentials/sql/v1/source.h b/yql/essentials/sql/v1/source.h
index 35129fffbb8..ba904d6c21e 100644
--- a/yql/essentials/sql/v1/source.h
+++ b/yql/essentials/sql/v1/source.h
@@ -312,6 +312,7 @@ namespace NSQLTranslationV1 {
TNodePtr BuildWriteTable(TPosition pos, const TString& label, const TTableRef& table, EWriteColumnMode mode, TNodePtr options,
TScopedStatePtr scoped);
TNodePtr BuildAnalyze(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TAnalyzeParams& params, TScopedStatePtr scoped);
+ TNodePtr BuildAlterSequence(TPosition pos, const TString& service, const TDeferredAtom& cluster, const TString& id, const TSequenceParameters& params, TScopedStatePtr scoped);
TSourcePtr TryMakeSourceFromExpression(TPosition pos, TContext& ctx, const TString& currService, const TDeferredAtom& currCluster,
TNodePtr node, const TString& view = {});
void MakeTableFromExpression(TPosition pos, TContext& ctx, TNodePtr node, TDeferredAtom& table, const TString& prefix = {});
diff --git a/yql/essentials/sql/v1/sql.cpp b/yql/essentials/sql/v1/sql.cpp
index 506b3950d54..3e5dba78f3c 100644
--- a/yql/essentials/sql/v1/sql.cpp
+++ b/yql/essentials/sql/v1/sql.cpp
@@ -140,22 +140,22 @@ bool NeedUseForAllStatements(const TRule_sql_stmt_core::AltCase& subquery) {
case TRule_sql_stmt_core::kAltSqlStmtCore17: // do
case TRule_sql_stmt_core::kAltSqlStmtCore19: // if
case TRule_sql_stmt_core::kAltSqlStmtCore20: // for
- case TRule_sql_stmt_core::kAltSqlStmtCore21: // values
+ case TRule_sql_stmt_core::kAltSqlStmtCore21: // values
case TRule_sql_stmt_core::kAltSqlStmtCore22: // create user
case TRule_sql_stmt_core::kAltSqlStmtCore23: // alter user
case TRule_sql_stmt_core::kAltSqlStmtCore24: // create group
- case TRule_sql_stmt_core::kAltSqlStmtCore25: // alter group
- case TRule_sql_stmt_core::kAltSqlStmtCore26: // drop role
- case TRule_sql_stmt_core::kAltSqlStmtCore27: // create object
- case TRule_sql_stmt_core::kAltSqlStmtCore28: // alter object
- case TRule_sql_stmt_core::kAltSqlStmtCore29: // drop object
- case TRule_sql_stmt_core::kAltSqlStmtCore30: // create external data source
- case TRule_sql_stmt_core::kAltSqlStmtCore31: // alter external data source
- case TRule_sql_stmt_core::kAltSqlStmtCore32: // drop external data source
- case TRule_sql_stmt_core::kAltSqlStmtCore33: // create replication
- case TRule_sql_stmt_core::kAltSqlStmtCore34: // drop replication
- case TRule_sql_stmt_core::kAltSqlStmtCore35: // create topic
- case TRule_sql_stmt_core::kAltSqlStmtCore36: // alter topic
+ case TRule_sql_stmt_core::kAltSqlStmtCore25: // alter group
+ case TRule_sql_stmt_core::kAltSqlStmtCore26: // drop role
+ case TRule_sql_stmt_core::kAltSqlStmtCore27: // create object
+ case TRule_sql_stmt_core::kAltSqlStmtCore28: // alter object
+ case TRule_sql_stmt_core::kAltSqlStmtCore29: // drop object
+ case TRule_sql_stmt_core::kAltSqlStmtCore30: // create external data source
+ case TRule_sql_stmt_core::kAltSqlStmtCore31: // alter external data source
+ case TRule_sql_stmt_core::kAltSqlStmtCore32: // drop external data source
+ case TRule_sql_stmt_core::kAltSqlStmtCore33: // create replication
+ case TRule_sql_stmt_core::kAltSqlStmtCore34: // drop replication
+ case TRule_sql_stmt_core::kAltSqlStmtCore35: // create topic
+ case TRule_sql_stmt_core::kAltSqlStmtCore36: // alter topic
case TRule_sql_stmt_core::kAltSqlStmtCore37: // drop topic
case TRule_sql_stmt_core::kAltSqlStmtCore38: // grant permissions
case TRule_sql_stmt_core::kAltSqlStmtCore39: // revoke permissions
@@ -176,6 +176,7 @@ bool NeedUseForAllStatements(const TRule_sql_stmt_core::AltCase& subquery) {
case TRule_sql_stmt_core::kAltSqlStmtCore54: // drop resource pool classifier
case TRule_sql_stmt_core::kAltSqlStmtCore55: // backup
case TRule_sql_stmt_core::kAltSqlStmtCore56: // restore
+ case TRule_sql_stmt_core::kAltSqlStmtCore57: // alter sequence
return false;
}
}
diff --git a/yql/essentials/sql/v1/sql_query.cpp b/yql/essentials/sql/v1/sql_query.cpp
index 5f2f31d7763..4d9f30a4525 100644
--- a/yql/essentials/sql/v1/sql_query.cpp
+++ b/yql/essentials/sql/v1/sql_query.cpp
@@ -1674,6 +1674,50 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core&
context));
break;
}
+ case TRule_sql_stmt_core::kAltSqlStmtCore57: {
+ // alter_sequence_stmt: ALTER SEQUENCE (IF EXISTS)? object_ref alter_sequence_action (COMMA alter_sequence_action)*;
+ Ctx.BodyPart();
+ auto& node = core.GetAlt_sql_stmt_core57().GetRule_alter_sequence_stmt1();
+
+ Ctx.Token(node.GetToken1());
+ const TPosition pos = Ctx.Pos();
+
+ TString service = Ctx.Scoped->CurrService;
+ TDeferredAtom cluster = Ctx.Scoped->CurrCluster;
+ if (cluster.Empty()) {
+ Error() << "USE statement is missing - no default cluster is selected";
+ return false;
+ }
+ TObjectOperatorContext context(Ctx.Scoped);
+
+ if (node.GetRule_object_ref4().HasBlock1()) {
+ if (!ClusterExpr(node.GetRule_object_ref4().GetBlock1().GetRule_cluster_expr1(),
+ false, context.ServiceId, context.Cluster)) {
+ return false;
+ }
+ }
+
+ const TString id = Id(node.GetRule_object_ref4().GetRule_id_or_at2(), *this).second;
+
+ TSequenceParameters params;
+
+ if (node.HasBlock3()) { // IF EXISTS
+ params.MissingOk = true;
+ Y_DEBUG_ABORT_UNLESS(
+ IS_TOKEN(node.GetBlock3().GetToken1().GetId(), IF) &&
+ IS_TOKEN(node.GetBlock3().GetToken2().GetId(), EXISTS)
+ );
+ }
+
+ for (const auto& block : node.GetBlock5()) {
+ if (!AlterSequenceAction(block.GetRule_alter_sequence_action1(), params)) {
+ return false;
+ }
+ }
+
+ AddStatementToBlocks(blocks, BuildAlterSequence(pos, service, cluster, id, params, Ctx.Scoped));
+ break;
+ }
case TRule_sql_stmt_core::ALT_NOT_SET:
Ctx.IncrementMonCounter("sql_errors", "UnknownStatement" + internalStatementName);
AltNotImplemented("sql_stmt_core", core);
@@ -2177,6 +2221,63 @@ bool TSqlQuery::AlterTableAlterIndex(const TRule_alter_table_alter_index& node,
return true;
}
+bool TSqlQuery::AlterSequenceAction(const TRule_alter_sequence_action& node, TSequenceParameters& params) {
+ switch (node.Alt_case()) {
+ case TRule_alter_sequence_action::kAltAlterSequenceAction1: {
+ if (params.StartValue) {
+ Ctx.Error(Ctx.Pos()) << "Start value defined more than once";
+ return false;
+ }
+ auto literalNumber = LiteralNumber(Ctx, node.GetAlt_alter_sequence_action1().GetRule_integer3());
+ if (literalNumber) {
+ params.StartValue = TDeferredAtom(literalNumber, Ctx);
+ } else {
+ return false;
+ }
+ break;
+ }
+ case TRule_alter_sequence_action::kAltAlterSequenceAction2: {
+ if (params.IsRestart) {
+ Ctx.Error(Ctx.Pos()) << "Restart value defined more than once";
+ return false;
+ }
+ auto literalNumber = LiteralNumber(Ctx, node.GetAlt_alter_sequence_action2().GetRule_integer3());
+ if (literalNumber) {
+ params.IsRestart = true;
+ params.RestartValue = TDeferredAtom(literalNumber, Ctx);
+ } else {
+ return false;
+ }
+ break;
+ }
+ case TRule_alter_sequence_action::kAltAlterSequenceAction3: {
+ if (params.IsRestart) {
+ Ctx.Error(Ctx.Pos()) << "Restart value defined more than once";
+ return false;
+ }
+ params.IsRestart = true;
+ break;
+ }
+ case TRule_alter_sequence_action::kAltAlterSequenceAction4: {
+ if (params.Increment) {
+ Ctx.Error(Ctx.Pos()) << "Increment defined more than once";
+ return false;
+ }
+ auto literalNumber = LiteralNumber(Ctx, node.GetAlt_alter_sequence_action4().GetRule_integer3());
+ if (literalNumber) {
+ params.Increment = TDeferredAtom(literalNumber, Ctx);
+ } else {
+ return false;
+ }
+ break;
+ }
+ case TRule_alter_sequence_action::ALT_NOT_SET:
+ Y_ABORT("You should change implementation according to grammar changes");
+ }
+
+ return true;
+}
+
bool TSqlQuery::AlterTableAlterColumnDropNotNull(const TRule_alter_table_alter_column_drop_not_null& node, TAlterTableParameters& params) {
TString name = Id(node.GetRule_an_id3(), *this);
const TPosition pos(Context().Pos());
diff --git a/yql/essentials/sql/v1/sql_query.h b/yql/essentials/sql/v1/sql_query.h
index 99e1a9c4efd..03fd85df6b3 100644
--- a/yql/essentials/sql/v1/sql_query.h
+++ b/yql/essentials/sql/v1/sql_query.h
@@ -42,6 +42,7 @@ private:
void AlterTableDropChangefeed(const TRule_alter_table_drop_changefeed& node, TAlterTableParameters& params);
void AlterTableRenameIndexTo(const TRule_alter_table_rename_index_to& node, TAlterTableParameters& params);
bool AlterTableAlterIndex(const TRule_alter_table_alter_index& node, TAlterTableParameters& params);
+ bool AlterSequenceAction(const TRule_alter_sequence_action& node, TSequenceParameters& 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);
@@ -64,7 +65,7 @@ private:
if (!Ctx.Settings.Antlr4Parser) {
const auto pos = descr.find(": ");
Y_DEBUG_ABORT_UNLESS(pos != TString::npos);
- Split(TString(descr.begin() + pos + 2, descr.end()), "_", parts);
+ Split(TString(descr.begin() + pos + 2, descr.end()), "_", parts);
} else {
Split(descr, "_", parts);
}
diff --git a/yql/essentials/sql/v1/sql_ut.cpp b/yql/essentials/sql/v1/sql_ut.cpp
index a9720a6c68c..45272879c01 100644
--- a/yql/essentials/sql/v1/sql_ut.cpp
+++ b/yql/essentials/sql/v1/sql_ut.cpp
@@ -2690,6 +2690,153 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["\'mode \'alter"]);
}
+ Y_UNIT_TEST(AlterSequence) {
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence INCREMENT 2;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence INCREMENT 2 START 1000;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence RESTART START 1000;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE IF EXISTS sequence INCREMENT 1000 START 100 RESTART;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE IF EXISTS sequence RESTART 1000 START WITH 100 INCREMENT BY 7;
+ )").IsOk());
+ }
+
+ Y_UNIT_TEST(AlterSequenceIncorrect) {
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5 RESTART;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:75: Error: Restart value defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 START 100 RESTART WITH 5;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:60: Error: Start value defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence INCREMENT BY 7 START WITH 10 INCREMENT 2 RESTART WITH 5 RESTART;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:62: Error: Increment defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 100 START WITH 10 INCREMENT 2 RESTART WITH 5;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:77: Error: Restart value defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1234234543563435151456 START WITH 10 INCREMENT 2;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:49: Error: Failed to parse number from string: 1234234543563435151456, number limit overflow\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 9223372036854775817 INCREMENT 4;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Start value: 9223372036854775817 cannot be greater than max value: 9223372036854775807\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 9223372036854775827 START WITH 5 INCREMENT 4;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Restart value: 9223372036854775827 cannot be greater than max value: 9223372036854775807\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 4 INCREMENT 0;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Increment must not be zero\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 0 START WITH 4 INCREMENT 1;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Restart value: 0 cannot be less than min value: 1\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 0 INCREMENT 1;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Start value: 0 cannot be less than min value: 1\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 1 INCREMENT 9223372036854775837;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Increment: 9223372036854775837 cannot be greater than max value: 9223372036854775807\n");
+ }
+ }
+
+ Y_UNIT_TEST(AlterSequenceCorrect) {
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5;");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("sequence"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alter"));
+ UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("alter_if_exists"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("start"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("increment"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("restart"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE IF EXISTS sequence INCREMENT 2 RESTART;");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("sequence"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alter_if_exists"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("increment"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("restart"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE IF EXISTS sequence START 10 INCREMENT BY 2;");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("sequence"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alter_if_exists"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("start"));
+ UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("restart"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("increment"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+ }
+
Y_UNIT_TEST(OptionalAliases) {
UNIT_ASSERT(SqlToYql("USE plato; SELECT foo FROM (SELECT key foo FROM Input);").IsOk());
UNIT_ASSERT(SqlToYql("USE plato; SELECT a.x FROM Input1 a JOIN Input2 b ON a.key = b.key;").IsOk());
diff --git a/yql/essentials/sql/v1/sql_ut_antlr4.cpp b/yql/essentials/sql/v1/sql_ut_antlr4.cpp
index 28690f89a4c..91b85e92e8f 100644
--- a/yql/essentials/sql/v1/sql_ut_antlr4.cpp
+++ b/yql/essentials/sql/v1/sql_ut_antlr4.cpp
@@ -2690,6 +2690,153 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["\'mode \'alter"]);
}
+ Y_UNIT_TEST(AlterSequence) {
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence INCREMENT 2;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence INCREMENT 2 START 1000;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE sequence RESTART START 1000;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE IF EXISTS sequence INCREMENT 1000 START 100 RESTART;
+ )").IsOk());
+ UNIT_ASSERT(SqlToYql(R"(
+ USE plato;
+ ALTER SEQUENCE IF EXISTS sequence RESTART 1000 START WITH 100 INCREMENT BY 7;
+ )").IsOk());
+ }
+
+ Y_UNIT_TEST(AlterSequenceIncorrect) {
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5 RESTART;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:75: Error: Restart value defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 START 100 RESTART WITH 5;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:60: Error: Start value defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence INCREMENT BY 7 START WITH 10 INCREMENT 2 RESTART WITH 5 RESTART;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:62: Error: Increment defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 100 START WITH 10 INCREMENT 2 RESTART WITH 5;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:77: Error: Restart value defined more than once\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1234234543563435151456 START WITH 10 INCREMENT 2;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:49: Error: Failed to parse number from string: 1234234543563435151456, number limit overflow\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 9223372036854775817 INCREMENT 4;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Start value: 9223372036854775817 cannot be greater than max value: 9223372036854775807\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 9223372036854775827 START WITH 5 INCREMENT 4;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Restart value: 9223372036854775827 cannot be greater than max value: 9223372036854775807\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 4 INCREMENT 0;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Increment must not be zero\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 0 START WITH 4 INCREMENT 1;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Restart value: 0 cannot be less than min value: 1\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 0 INCREMENT 1;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Start value: 0 cannot be less than min value: 1\n");
+ }
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence RESTART WITH 1 START WITH 1 INCREMENT 9223372036854775837;");
+ UNIT_ASSERT(!res.Root);
+ UNIT_ASSERT_NO_DIFF(Err2Str(res), "<main>:1:12: Error: Increment: 9223372036854775837 cannot be greater than max value: 9223372036854775807\n");
+ }
+ }
+
+ Y_UNIT_TEST(AlterSequenceCorrect) {
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE sequence START WITH 10 INCREMENT 2 RESTART WITH 5;");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("sequence"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alter"));
+ UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("alter_if_exists"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("start"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("increment"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("restart"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE IF EXISTS sequence INCREMENT 2 RESTART;");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("sequence"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alter_if_exists"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("increment"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("restart"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ {
+ NYql::TAstParseResult res = SqlToYql("USE plato; ALTER SEQUENCE IF EXISTS sequence START 10 INCREMENT BY 2;");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("sequence"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alter_if_exists"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("start"));
+ UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("restart"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("increment"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+ }
+
Y_UNIT_TEST(OptionalAliases) {
UNIT_ASSERT(SqlToYql("USE plato; SELECT foo FROM (SELECT key foo FROM Input);").IsOk());
UNIT_ASSERT(SqlToYql("USE plato; SELECT a.x FROM Input1 a JOIN Input2 b ON a.key = b.key;").IsOk());