diff options
author | yentsovsemyon <yentsovsemyon@yandex-team.com> | 2024-11-21 13:46:41 +0300 |
---|---|---|
committer | yentsovsemyon <yentsovsemyon@yandex-team.com> | 2024-11-21 13:58:12 +0300 |
commit | 4743a95fdc5925c514371b534d56b4dfd26cda0c (patch) | |
tree | df69ace67cb5276dfa6f1ca6bcf2375b30116170 | |
parent | 90a8f8cc3c8915e9573196a81d7bd33b598fcd77 (diff) | |
download | ydb-4743a95fdc5925c514371b534d56b4dfd26cda0c.tar.gz |
Extend TTL syntax to support tiers
RFC: **[nda.ya.ru/t/JsIT3hp679nYxn](https://nda.ya.ru/t/JsIT3hp679nYxn)**
commit_hash:a0a4f65b24ee591cb76fd3cf253ffe24a01bfaf5
-rw-r--r-- | yql/essentials/sql/v1/SQLv1.g.in | 8 | ||||
-rw-r--r-- | yql/essentials/sql/v1/SQLv1Antlr4.g.in | 8 | ||||
-rw-r--r-- | yql/essentials/sql/v1/format/sql_format.cpp | 62 | ||||
-rw-r--r-- | yql/essentials/sql/v1/format/sql_format_ut.h | 10 | ||||
-rw-r--r-- | yql/essentials/sql/v1/node.cpp | 21 | ||||
-rw-r--r-- | yql/essentials/sql/v1/node.h | 11 | ||||
-rw-r--r-- | yql/essentials/sql/v1/query.cpp | 12 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_translation.cpp | 65 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_ut.cpp | 80 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_ut_antlr4.cpp | 80 |
10 files changed, 332 insertions, 25 deletions
diff --git a/yql/essentials/sql/v1/SQLv1.g.in b/yql/essentials/sql/v1/SQLv1.g.in index 9369b111a9..d2cc702174 100644 --- a/yql/essentials/sql/v1/SQLv1.g.in +++ b/yql/essentials/sql/v1/SQLv1.g.in @@ -791,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; diff --git a/yql/essentials/sql/v1/SQLv1Antlr4.g.in b/yql/essentials/sql/v1/SQLv1Antlr4.g.in index 229b15dfae..02282d8ebf 100644 --- a/yql/essentials/sql/v1/SQLv1Antlr4.g.in +++ b/yql/essentials/sql/v1/SQLv1Antlr4.g.in @@ -790,10 +790,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; diff --git a/yql/essentials/sql/v1/format/sql_format.cpp b/yql/essentials/sql/v1/format/sql_format.cpp index 80ce5d139e..262f9b2919 100644 --- a/yql/essentials/sql/v1/format/sql_format.cpp +++ b/yql/essentials/sql/v1/format/sql_format.cpp @@ -2495,6 +2495,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 +2843,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)}, diff --git a/yql/essentials/sql/v1/format/sql_format_ut.h b/yql/essentials/sql/v1/format/sql_format_ut.h index 6d92bd29eb..021d57c8b1 100644 --- a/yql/essentials/sql/v1/format/sql_format_ut.h +++ b/yql/essentials/sql/v1/format/sql_format_ut.h @@ -226,6 +226,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..53f606cc6b 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 { diff --git a/yql/essentials/sql/v1/query.cpp b/yql/essentials/sql/v1/query.cpp index 56dd8bd63d..dc71f57381 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))))); 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..a9720a6c68 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; diff --git a/yql/essentials/sql/v1/sql_ut_antlr4.cpp b/yql/essentials/sql/v1/sql_ut_antlr4.cpp index e2a05cc229..28690f89a4 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; |