aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials
diff options
context:
space:
mode:
authoryentsovsemyon <yentsovsemyon@yandex-team.com>2024-11-21 13:46:41 +0300
committeryentsovsemyon <yentsovsemyon@yandex-team.com>2024-11-21 13:58:12 +0300
commit4743a95fdc5925c514371b534d56b4dfd26cda0c (patch)
treedf69ace67cb5276dfa6f1ca6bcf2375b30116170 /yql/essentials
parent90a8f8cc3c8915e9573196a81d7bd33b598fcd77 (diff)
downloadydb-4743a95fdc5925c514371b534d56b4dfd26cda0c.tar.gz
Extend TTL syntax to support tiers
RFC: **[nda.ya.ru/t/JsIT3hp679nYxn](https://nda.ya.ru/t/JsIT3hp679nYxn)** commit_hash:a0a4f65b24ee591cb76fd3cf253ffe24a01bfaf5
Diffstat (limited to 'yql/essentials')
-rw-r--r--yql/essentials/sql/v1/SQLv1.g.in8
-rw-r--r--yql/essentials/sql/v1/SQLv1Antlr4.g.in8
-rw-r--r--yql/essentials/sql/v1/format/sql_format.cpp62
-rw-r--r--yql/essentials/sql/v1/format/sql_format_ut.h10
-rw-r--r--yql/essentials/sql/v1/node.cpp21
-rw-r--r--yql/essentials/sql/v1/node.h11
-rw-r--r--yql/essentials/sql/v1/query.cpp12
-rw-r--r--yql/essentials/sql/v1/sql_translation.cpp65
-rw-r--r--yql/essentials/sql/v1/sql_ut.cpp80
-rw-r--r--yql/essentials/sql/v1/sql_ut_antlr4.cpp80
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;