aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1
diff options
context:
space:
mode:
authorAlexander Smirnov <alex@ydb.tech>2024-11-22 09:21:01 +0000
committerAlexander Smirnov <alex@ydb.tech>2024-11-22 09:21:01 +0000
commita7cac42c868ca5722777ccee944217410812e72c (patch)
tree7bff7ce2a3ade72f6f15dfc634490d13628066ee /yql/essentials/sql/v1
parenta18f18d81996ca8e681bb6cabd441b52833d99bf (diff)
parent9478cfdab4217d3710b96329466825bf47111d7d (diff)
downloadydb-a7cac42c868ca5722777ccee944217410812e72c.tar.gz
Merge branch 'rightlib' into mergelibs-241122-0919
Diffstat (limited to 'yql/essentials/sql/v1')
-rw-r--r--yql/essentials/sql/v1/SQLv1.g.in29
-rw-r--r--yql/essentials/sql/v1/SQLv1Antlr4.g.in29
-rw-r--r--yql/essentials/sql/v1/builtin.cpp3
-rw-r--r--yql/essentials/sql/v1/format/sql_format.cpp69
-rw-r--r--yql/essentials/sql/v1/format/sql_format_ut.h21
-rw-r--r--yql/essentials/sql/v1/node.cpp21
-rw-r--r--yql/essentials/sql/v1/node.h19
-rw-r--r--yql/essentials/sql/v1/query.cpp116
-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_translation.cpp65
-rw-r--r--yql/essentials/sql/v1/sql_ut.cpp227
-rw-r--r--yql/essentials/sql/v1/sql_ut_antlr4.cpp227
15 files changed, 919 insertions, 39 deletions
diff --git a/yql/essentials/sql/v1/SQLv1.g.in b/yql/essentials/sql/v1/SQLv1.g.in
index 9369b111a9..1b645f0b89 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:
@@ -791,10 +792,16 @@ table_setting_value:
| STRING_VALUE
| integer
| split_boundaries
- | expr ON an_id (AS (SECONDS | MILLISECONDS | MICROSECONDS | NANOSECONDS))?
+ | ttl_tier_list ON an_id (AS (SECONDS | MILLISECONDS | MICROSECONDS | NANOSECONDS))?
| bool_value
;
+ttl_tier_list: expr (ttl_tier_action (COMMA expr ttl_tier_action)*)?;
+ttl_tier_action:
+ TO EXTERNAL DATA SOURCE an_id
+ | DELETE
+;
+
family_entry: FAMILY an_id family_settings;
family_settings: LPAREN (family_settings_entry (COMMA family_settings_entry)*)? RPAREN;
family_settings_entry: an_id EQUALS family_setting_value;
@@ -1048,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;
@@ -1333,6 +1348,7 @@ keyword_as_compat:
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1407,6 +1423,7 @@ keyword_as_compat:
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
// | RESULT
@@ -1424,7 +1441,9 @@ keyword_as_compat:
| SETS
| SHOW
| SKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1551,6 +1570,7 @@ keyword_compat: (
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1625,6 +1645,7 @@ keyword_compat: (
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
| RESULT
@@ -1642,7 +1663,9 @@ keyword_compat: (
| SETS
| SHOW
| SKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1897,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;
@@ -1986,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;
@@ -2010,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 229b15dfae..5435535336 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:
@@ -790,10 +791,16 @@ table_setting_value:
| STRING_VALUE
| integer
| split_boundaries
- | expr ON an_id (AS (SECONDS | MILLISECONDS | MICROSECONDS | NANOSECONDS))?
+ | ttl_tier_list ON an_id (AS (SECONDS | MILLISECONDS | MICROSECONDS | NANOSECONDS))?
| bool_value
;
+ttl_tier_list: expr (ttl_tier_action (COMMA expr ttl_tier_action)*)?;
+ttl_tier_action:
+ TO EXTERNAL DATA SOURCE an_id
+ | DELETE
+;
+
family_entry: FAMILY an_id family_settings;
family_settings: LPAREN (family_settings_entry (COMMA family_settings_entry)*)? RPAREN;
family_settings_entry: an_id EQUALS family_setting_value;
@@ -1047,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;
@@ -1332,6 +1347,7 @@ keyword_as_compat:
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1406,6 +1422,7 @@ keyword_as_compat:
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
// | RESULT
@@ -1423,7 +1440,9 @@ keyword_as_compat:
| SETS
| SHOW
| TSKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1550,6 +1569,7 @@ keyword_compat: (
| IMMEDIATE
| IMPORT
| IN
+ | INCREMENT
| INCREMENTAL
| INDEX
| INDEXED
@@ -1624,6 +1644,7 @@ keyword_compat: (
| REPLICATION
| RESET
| RESPECT
+ | RESTART
| RESTORE
| RESTRICT
| RESULT
@@ -1641,7 +1662,9 @@ keyword_compat: (
| SETS
| SHOW
| TSKIP
+ | SEQUENCE
| SOURCE
+ | START
| SUBQUERY
| SUBSET
| SYMBOLS
@@ -1896,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;
@@ -1985,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;
@@ -2009,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/builtin.cpp b/yql/essentials/sql/v1/builtin.cpp
index e327c2d2ea..94d8a3bc16 100644
--- a/yql/essentials/sql/v1/builtin.cpp
+++ b/yql/essentials/sql/v1/builtin.cpp
@@ -2916,6 +2916,9 @@ struct TBuiltinFuncData {
{"listtopsort", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopSort", 2, 3)},
{"listtopsortasc", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopSortAsc", 2, 3)},
{"listtopsortdesc", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListTopSortDesc", 2, 3)},
+ {"listsample", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSample", 2, 3)},
+ {"listsamplen", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListSampleN", 2, 3)},
+ {"listshuffle", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("ListShuffle", 1, 2)},
// Dict builtins
{"dictlength", BuildNamedArgcBuiltinFactoryCallback<TCallNodeImpl>("Length", 1, 1)},
diff --git a/yql/essentials/sql/v1/format/sql_format.cpp b/yql/essentials/sql/v1/format/sql_format.cpp
index 80ce5d139e..3cc18b141b 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:
@@ -2495,6 +2501,66 @@ private:
Visit(msg.GetToken5());
}
+ void VisitTableSettingValue(const TRule_table_setting_value& msg) {
+ switch (msg.GetAltCase()) {
+ case TRule_table_setting_value::kAltTableSettingValue5: {
+ // | ttl_tier_list ON an_id (AS (SECONDS | MILLISECONDS | MICROSECONDS | NANOSECONDS))?
+ const auto& ttlSettings = msg.GetAlt_table_setting_value5();
+ const auto& tierList = ttlSettings.GetRule_ttl_tier_list1();
+ const bool needIndent = tierList.HasBlock2() && tierList.GetBlock2().Block2Size() > 0; // more then one tier
+ if (needIndent) {
+ NewLine();
+ PushCurrentIndent();
+ Visit(tierList.GetRule_expr1());
+ VisitTtlTierAction(tierList.GetBlock2().GetRule_ttl_tier_action1());
+
+ for (const auto& tierEntry : tierList.GetBlock2().GetBlock2()) {
+ Visit(tierEntry.GetToken1()); // comma
+ NewLine();
+ Visit(tierEntry.GetRule_expr2());
+ VisitTtlTierAction(tierEntry.GetRule_ttl_tier_action3());
+ }
+
+ PopCurrentIndent();
+ NewLine();
+ } else {
+ Visit(tierList.GetRule_expr1());
+ if (tierList.HasBlock2()) {
+ VisitTtlTierAction(tierList.GetBlock2().GetRule_ttl_tier_action1());
+ }
+ }
+
+ VisitKeyword(ttlSettings.GetToken2());
+ Visit(ttlSettings.GetRule_an_id3());
+ if (ttlSettings.HasBlock4()) {
+ VisitKeyword(ttlSettings.GetBlock4().GetToken1());
+ VisitKeyword(ttlSettings.GetBlock4().GetToken2());
+ }
+ } break;
+ default:
+ VisitAllFields(TRule_table_setting_value::GetDescriptor(), msg);
+ }
+ }
+
+ void VisitTtlTierAction(const TRule_ttl_tier_action& msg) {
+ switch (msg.GetAltCase()) {
+ case TRule_ttl_tier_action::kAltTtlTierAction1:
+ // | TO EXTERNAL DATA SOURCE an_id
+ VisitKeyword(msg.GetAlt_ttl_tier_action1().GetToken1());
+ VisitKeyword(msg.GetAlt_ttl_tier_action1().GetToken2());
+ VisitKeyword(msg.GetAlt_ttl_tier_action1().GetToken3());
+ VisitKeyword(msg.GetAlt_ttl_tier_action1().GetToken4());
+ Visit(msg.GetAlt_ttl_tier_action1().GetRule_an_id5());
+ break;
+ case TRule_ttl_tier_action::kAltTtlTierAction2:
+ // | DELETE
+ VisitKeyword(msg.GetAlt_ttl_tier_action2().GetToken1());
+ break;
+ case TRule_ttl_tier_action::ALT_NOT_SET:
+ break;
+ }
+ }
+
void VisitExpr(const TRule_expr& msg) {
if (msg.HasAlt_expr2()) {
Visit(msg.GetAlt_expr2());
@@ -2783,6 +2849,8 @@ TStaticData::TStaticData()
{TRule_case_expr::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitCaseExpr)},
{TRule_when_expr::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitWhenExpr)},
{TRule_with_table_settings::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitWithTableSettingsExpr)},
+ {TRule_table_setting_value::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitTableSettingValue)},
+ {TRule_ttl_tier_action::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitTtlTierAction)},
{TRule_expr::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitExpr)},
{TRule_or_subexpr::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitOrSubexpr)},
@@ -2853,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 6d92bd29eb..fc919b38c4 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"},
@@ -226,6 +237,16 @@ Y_UNIT_TEST(CreateTable) {
"CREATE TABLE user (\n\tuser int32\n)\nWITH (ttl = interval('P1D') ON user AS MICROSECONDS);\n"},
{"create table user(user int32) with (ttl=interval('P1D') on user as nAnOsEcOnDs)",
"CREATE TABLE user (\n\tuser int32\n)\nWITH (ttl = interval('P1D') ON user AS NANOSECONDS);\n"},
+ {"create table user(user int32) with (ttl=interval('P1D') delete on user as nAnOsEcOnDs)",
+ "CREATE TABLE user (\n\tuser int32\n)\nWITH (ttl = interval('P1D') DELETE ON user AS NANOSECONDS);\n"},
+ {"create table user(user int32) with (ttl=interval('P1D')to external data source tier1 ,interval('P10D')delete on user as seconds)",
+ "CREATE TABLE user (\n"
+ "\tuser int32\n"
+ ")\n"
+ "WITH (ttl =\n"
+ "\tinterval('P1D') TO EXTERNAL DATA SOURCE tier1,\n"
+ "\tinterval('P10D') DELETE\n"
+ "ON user AS SECONDS);\n"},
{"create table user(index user global unique sync on (user,user) with (user=user,user=user))",
"CREATE TABLE user (\n\tINDEX user GLOBAL UNIQUE SYNC ON (user, user) WITH (user = user, user = user)\n);\n"},
{"create table user(index user global async on (user) with (user=user,))",
diff --git a/yql/essentials/sql/v1/node.cpp b/yql/essentials/sql/v1/node.cpp
index c7cafda7a5..b285142909 100644
--- a/yql/essentials/sql/v1/node.cpp
+++ b/yql/essentials/sql/v1/node.cpp
@@ -1894,9 +1894,14 @@ TMaybe<TStringContent> StringContentOrIdContent(TContext& ctx, TPosition pos, co
(ctx.AnsiQuotedIdentifiers && input.StartsWith('"'))? EStringContentMode::AnsiIdent : EStringContentMode::Default);
}
-TTtlSettings::TTtlSettings(const TIdentifier& columnName, const TNodePtr& expr, const TMaybe<EUnit>& columnUnit)
+TTtlSettings::TTierSettings::TTierSettings(const TNodePtr& evictionDelay, const std::optional<TIdentifier>& storageName)
+ : EvictionDelay(evictionDelay)
+ , StorageName(storageName) {
+}
+
+TTtlSettings::TTtlSettings(const TIdentifier& columnName, const std::vector<TTierSettings>& tiers, const TMaybe<EUnit>& columnUnit)
: ColumnName(columnName)
- , Expr(expr)
+ , Tiers(tiers)
, ColumnUnit(columnUnit)
{
}
@@ -3131,10 +3136,10 @@ public:
Y_DEBUG_ABORT_UNLESS(FuncNode);
FuncNode->VisitTree(func, visited);
}
-
+
void CollectPreaggregateExprs(TContext& ctx, ISource& src, TVector<INode::TPtr>& exprs) override {
if (ctx.DistinctOverWindow) {
- FuncNode->CollectPreaggregateExprs(ctx, src, exprs);
+ FuncNode->CollectPreaggregateExprs(ctx, src, exprs);
} else {
INode::CollectPreaggregateExprs(ctx, src, exprs);
}
@@ -3274,7 +3279,7 @@ TSourcePtr TryMakeSourceFromExpression(TPosition pos, TContext& ctx, const TStri
return nullptr;
}
- auto wrappedNode = new TAstListNodeImpl(pos, {
+ auto wrappedNode = new TAstListNodeImpl(pos, {
new TAstAtomNodeImpl(pos, "EvaluateAtom", TNodeFlags::Default),
node
});
@@ -3303,7 +3308,7 @@ void MakeTableFromExpression(TPosition pos, TContext& ctx, TNodePtr node, TDefer
node = node->Y("Concat", node->Y("String", node->Q(prefix)), node);
}
- auto wrappedNode = new TAstListNodeImpl(pos, {
+ auto wrappedNode = new TAstListNodeImpl(pos, {
new TAstAtomNodeImpl(pos, "EvaluateAtom", TNodeFlags::Default),
node
});
@@ -3320,7 +3325,7 @@ TDeferredAtom MakeAtomFromExpression(TPosition pos, TContext& ctx, TNodePtr node
node = node->Y("Concat", node->Y("String", node->Q(prefix)), node);
}
- auto wrappedNode = new TAstListNodeImpl(pos, {
+ auto wrappedNode = new TAstListNodeImpl(pos, {
new TAstAtomNodeImpl(pos, "EvaluateAtom", TNodeFlags::Default),
node
});
@@ -3462,7 +3467,7 @@ bool TVectorIndexSettings::Validate(TContext& ctx) const {
if (!Distance && !Similarity) {
ctx.Error() << "either distance or similarity should be set";
return false;
- }
+ }
if (!VectorType) {
ctx.Error() << "vector_type should be set";
return false;
diff --git a/yql/essentials/sql/v1/node.h b/yql/essentials/sql/v1/node.h
index 5805f92042..99f42f353c 100644
--- a/yql/essentials/sql/v1/node.h
+++ b/yql/essentials/sql/v1/node.h
@@ -1112,11 +1112,18 @@ namespace NSQLTranslationV1 {
Nanoseconds /* "nanoseconds" */,
};
+ struct TTierSettings {
+ TNodePtr EvictionDelay;
+ std::optional<TIdentifier> StorageName;
+
+ TTierSettings(const TNodePtr& evictionDelay, const std::optional<TIdentifier>& storageName = std::nullopt);
+ };
+
TIdentifier ColumnName;
- TNodePtr Expr;
+ std::vector<TTierSettings> Tiers;
TMaybe<EUnit> ColumnUnit;
- TTtlSettings(const TIdentifier& columnName, const TNodePtr& expr, const TMaybe<EUnit>& columnUnit = {});
+ TTtlSettings(const TIdentifier& columnName, const std::vector<TTierSettings>& tiers, const TMaybe<EUnit>& columnUnit = {});
};
struct TTableSettings {
@@ -1293,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 56dd8bd63d..8e71da3146 100644
--- a/yql/essentials/sql/v1/query.cpp
+++ b/yql/essentials/sql/v1/query.cpp
@@ -240,7 +240,17 @@ static INode::TPtr CreateTableSettings(const TTableSettings& tableSettings, ETab
auto opts = Y();
opts = L(opts, Q(Y(Q("columnName"), BuildQuotedAtom(ttlSettings.ColumnName.Pos, ttlSettings.ColumnName.Name))));
- opts = L(opts, Q(Y(Q("expireAfter"), ttlSettings.Expr)));
+
+ auto tiersDesc = Y();
+ for (const auto& tier : ttlSettings.Tiers) {
+ auto tierDesc = Y();
+ tierDesc = L(tierDesc, Q(Y(Q("evictionDelay"), tier.EvictionDelay)));
+ if (tier.StorageName) {
+ tierDesc = L(tierDesc, Q(Y(Q("storageName"), BuildQuotedAtom(tier.StorageName->Pos, tier.StorageName->Name))));
+ }
+ tiersDesc = L(tiersDesc, Q(tierDesc));
+ }
+ opts = L(opts, Q(Y(Q("tiers"), Q(tiersDesc))));
if (ttlSettings.ColumnUnit) {
opts = L(opts, Q(Y(Q("columnUnit"), Q(ToString(*ttlSettings.ColumnUnit)))));
@@ -2039,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 35129fffbb..ba904d6c21 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 506b3950d5..3e5dba78f3 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 5f2f31d776..4d9f30a452 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 99e1a9c4ef..03fd85df6b 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_translation.cpp b/yql/essentials/sql/v1/sql_translation.cpp
index b298eb8abb..61a273b260 100644
--- a/yql/essentials/sql/v1/sql_translation.cpp
+++ b/yql/essentials/sql/v1/sql_translation.cpp
@@ -1963,19 +1963,68 @@ namespace {
return true;
}
- bool StoreTtlSettings(const TRule_table_setting_value& from, TResetableSetting<TTtlSettings, void>& to,
- TSqlExpression& expr, TContext& ctx, TTranslation& txc) {
+ bool FillTieringInterval(const TRule_expr& from, TNodePtr& tieringInterval, TSqlExpression& expr, TContext& ctx) {
+ auto exprNode = expr.Build(from);
+ if (!exprNode) {
+ return false;
+ }
+
+ if (exprNode->GetOpName() != "Interval") {
+ ctx.Error() << "Literal of Interval type is expected for TTL";
+ return false;
+ }
+
+ tieringInterval = exprNode;
+ return true;
+ }
+
+ bool FillTierAction(const TRule_ttl_tier_action& from, std::optional<TIdentifier>& storageName, TTranslation& txc) {
+ switch (from.GetAltCase()) {
+ case TRule_ttl_tier_action::kAltTtlTierAction1:
+ storageName = IdEx(from.GetAlt_ttl_tier_action1().GetRule_an_id5(), txc);
+ break;
+ case TRule_ttl_tier_action::kAltTtlTierAction2:
+ storageName.reset();
+ break;
+ case TRule_ttl_tier_action::ALT_NOT_SET:
+ Y_ABORT("You should change implementation according to grammar changes");
+ }
+ return true;
+ }
+
+ bool StoreTtlSettings(const TRule_table_setting_value& from, TResetableSetting<TTtlSettings, void>& to, TSqlExpression& expr, TContext& ctx,
+ TTranslation& txc) {
switch (from.Alt_case()) {
case TRule_table_setting_value::kAltTableSettingValue5: {
auto columnName = IdEx(from.GetAlt_table_setting_value5().GetRule_an_id3(), txc);
- auto exprNode = expr.Build(from.GetAlt_table_setting_value5().GetRule_expr1());
- if (!exprNode) {
+ auto tiersLiteral = from.GetAlt_table_setting_value5().GetRule_ttl_tier_list1();
+
+ TNodePtr firstInterval;
+ if (!FillTieringInterval(tiersLiteral.GetRule_expr1(), firstInterval, expr, ctx)) {
return false;
}
- if (exprNode->GetOpName() != "Interval") {
- ctx.Error() << "Literal of Interval type is expected for TTL";
- return false;
+ std::vector<TTtlSettings::TTierSettings> tiers;
+ if (!tiersLiteral.HasBlock2()) {
+ tiers.emplace_back(firstInterval);
+ } else {
+ std::optional<TIdentifier> firstStorageName;
+ if (!FillTierAction(tiersLiteral.GetBlock2().GetRule_ttl_tier_action1(), firstStorageName, txc)) {
+ return false;
+ }
+ tiers.emplace_back(firstInterval, firstStorageName);
+
+ for (const auto& tierLiteral : tiersLiteral.GetBlock2().GetBlock2()) {
+ TNodePtr intervalExpr;
+ if (!FillTieringInterval(tierLiteral.GetRule_expr2(), intervalExpr, expr, ctx)) {
+ return false;
+ }
+ std::optional<TIdentifier> storageName;
+ if (!FillTierAction(tierLiteral.GetRule_ttl_tier_action3(), storageName, txc)) {
+ return false;
+ }
+ tiers.emplace_back(intervalExpr, storageName);
+ }
}
TMaybe<TTtlSettings::EUnit> columnUnit;
@@ -1988,7 +2037,7 @@ namespace {
}
}
- to.Set(TTtlSettings(columnName, exprNode, columnUnit));
+ to.Set(TTtlSettings(columnName, tiers, columnUnit));
break;
}
default:
diff --git a/yql/essentials/sql/v1/sql_ut.cpp b/yql/essentials/sql/v1/sql_ut.cpp
index 65ec39af2c..45272879c0 100644
--- a/yql/essentials/sql/v1/sql_ut.cpp
+++ b/yql/essentials/sql/v1/sql_ut.cpp
@@ -2053,7 +2053,8 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
if (word == "Write") {
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
- UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("expireAfter"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
}
};
@@ -2075,7 +2076,8 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
if (word == "Write") {
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
- UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("expireAfter"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("columnUnit"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("seconds"));
@@ -2088,6 +2090,80 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
}
+ Y_UNIT_TEST(TtlTieringParseCorrect) {
+ NYql::TAstParseResult res = SqlToYql(
+ R"( USE plato;
+ CREATE TABLE tableName (Key Uint32, CreatedAt Uint32, PRIMARY KEY (Key))
+ WITH (TTL =
+ Interval("P1D") TO EXTERNAL DATA SOURCE Tier1,
+ Interval("P2D") TO EXTERNAL DATA SOURCE Tier2,
+ Interval("P30D") DELETE
+ ON CreatedAt AS SECONDS);)"
+ );
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("storageName"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier1"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier2"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("172800000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("2592000000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("columnUnit"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("seconds"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0} };
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ Y_UNIT_TEST(TtlTieringWithOtherActionsParseCorrect) {
+ NYql::TAstParseResult res = SqlToYql(
+ R"( USE plato;
+ ALTER TABLE tableName
+ ADD FAMILY cold (DATA = "rot"),
+ SET TTL
+ Interval("P1D") TO EXTERNAL DATA SOURCE Tier1,
+ Interval("P2D") TO EXTERNAL DATA SOURCE Tier2,
+ Interval("P30D") DELETE
+ ON CreatedAt,
+ ALTER COLUMN payload_v2 SET FAMILY cold,
+ ALTER FAMILY default SET DATA "ssd"
+ ;)"
+ );
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("addColumnFamilies"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("cold"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alterColumnFamilies"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("default"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("storageName"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier1"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier2"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("172800000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("2592000000"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0} };
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
Y_UNIT_TEST(TieringParseCorrect) {
NYql::TAstParseResult res = SqlToYql(
R"( USE plato;
@@ -2614,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 e2a05cc229..91b85e92e8 100644
--- a/yql/essentials/sql/v1/sql_ut_antlr4.cpp
+++ b/yql/essentials/sql/v1/sql_ut_antlr4.cpp
@@ -2053,7 +2053,8 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
if (word == "Write") {
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
- UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("expireAfter"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
}
};
@@ -2075,7 +2076,8 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
if (word == "Write") {
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
- UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("expireAfter"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("columnUnit"));
UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("seconds"));
@@ -2088,6 +2090,80 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
}
+ Y_UNIT_TEST(TtlTieringParseCorrect) {
+ NYql::TAstParseResult res = SqlToYql(
+ R"( USE plato;
+ CREATE TABLE tableName (Key Uint32, CreatedAt Uint32, PRIMARY KEY (Key))
+ WITH (TTL =
+ Interval("P1D") TO EXTERNAL DATA SOURCE Tier1,
+ Interval("P2D") TO EXTERNAL DATA SOURCE Tier2,
+ Interval("P30D") DELETE
+ On CreatedAt AS SECONDS);)"
+ );
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("storageName"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier1"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier2"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("172800000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("2592000000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("columnUnit"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("seconds"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0} };
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ Y_UNIT_TEST(TtlTieringWithOtherActionsParseCorrect) {
+ NYql::TAstParseResult res = SqlToYql(
+ R"( USE plato;
+ ALTER TABLE tableName
+ ADD FAMILY cold (DATA = "rot"),
+ SET TTL
+ Interval("P1D") TO EXTERNAL DATA SOURCE Tier1,
+ Interval("P2D") TO EXTERNAL DATA SOURCE Tier2,
+ Interval("P30D") DELETE
+ ON CreatedAt,
+ ALTER COLUMN payload_v2 SET FAMILY cold,
+ ALTER FAMILY default SET DATA "ssd"
+ ;)"
+ );
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("addColumnFamilies"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("cold"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("alterColumnFamilies"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("default"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("setTtlSettings"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("tiers"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("evictionDelay"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("storageName"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier1"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("Tier2"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("86400000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("172800000"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("2592000000"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0} };
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
Y_UNIT_TEST(TieringParseCorrect) {
NYql::TAstParseResult res = SqlToYql(
R"( USE plato;
@@ -2614,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());