summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorInnokentii Mokin <[email protected]>2024-08-05 16:36:16 +0300
committerGitHub <[email protected]>2024-08-05 16:36:16 +0300
commit63c9ea744bf7a7ecfad8a060f0caa2caa97fdc73 (patch)
treebb0a8efb0fe8afb5d3255ff24c47cf5c89436db6
parent7d65202191dcda49663ac6ba058751c79d6627a3 (diff)
Add backup collection sql (#7255)
-rw-r--r--ydb/core/testlib/basics/feature_flags.h1
-rw-r--r--ydb/library/yql/sql/v1/SQLv1.g.in22
-rw-r--r--ydb/library/yql/sql/v1/format/sql_format.cpp35
-rw-r--r--ydb/library/yql/sql/v1/format/sql_format_ut.cpp14
-rw-r--r--ydb/library/yql/sql/v1/sql.cpp3
-rw-r--r--ydb/library/yql/sql/v1/sql_query.cpp84
-rw-r--r--ydb/library/yql/sql/v1/sql_translation.cpp85
-rw-r--r--ydb/library/yql/sql/v1/sql_translation.h4
-rw-r--r--ydb/library/yql/sql/v1/sql_ut.cpp95
9 files changed, 340 insertions, 3 deletions
diff --git a/ydb/core/testlib/basics/feature_flags.h b/ydb/core/testlib/basics/feature_flags.h
index 25426b836d7..8553a4f861d 100644
--- a/ydb/core/testlib/basics/feature_flags.h
+++ b/ydb/core/testlib/basics/feature_flags.h
@@ -62,6 +62,7 @@ public:
FEATURE_FLAG_SETTER(EnableTableDatetime64)
FEATURE_FLAG_SETTER(EnableResourcePools)
FEATURE_FLAG_SETTER(EnableChangefeedsOnIndexTables)
+ FEATURE_FLAG_SETTER(EnableBackupService)
#undef FEATURE_FLAG_SETTER
};
diff --git a/ydb/library/yql/sql/v1/SQLv1.g.in b/ydb/library/yql/sql/v1/SQLv1.g.in
index 5f8f7b44c67..ec4aea282bd 100644
--- a/ydb/library/yql/sql/v1/SQLv1.g.in
+++ b/ydb/library/yql/sql/v1/SQLv1.g.in
@@ -66,6 +66,9 @@ sql_stmt_core:
| create_resource_pool_stmt
| alter_resource_pool_stmt
| drop_resource_pool_stmt
+ | create_backup_collection_stmt
+ | alter_backup_collection_stmt
+ | drop_backup_collection_stmt
;
expr:
@@ -644,6 +647,19 @@ create_table_entry:
| an_id_schema
;
+create_backup_collection_stmt: CREATE backup_collection WITH LPAREN backup_collection_settings RPAREN;
+alter_backup_collection_stmt: ALTER backup_collection alter_backup_collection_actions;
+drop_backup_collection_stmt: DROP backup_collection;
+
+alter_backup_collection_actions: alter_backup_collection_action (COMMA alter_backup_collection_action)*;
+alter_backup_collection_action:
+ alter_table_set_table_setting_compat
+ | alter_table_reset_table_setting
+;
+backup_collection: BACKUP COLLECTION object_ref;
+backup_collection_settings: backup_collection_settings_entry (COMMA backup_collection_settings_entry)*;
+backup_collection_settings_entry: an_id EQUALS table_setting_value;
+
table_inherits: INHERITS LPAREN simple_table_ref_core (COMMA simple_table_ref_core)* RPAREN;
table_partition_by: PARTITION BY HASH pure_column_list;
with_table_settings: WITH LPAREN table_settings_entry (COMMA table_settings_entry)* RPAREN;
@@ -1204,6 +1220,7 @@ keyword_as_compat:
| ATTACH
| ATTRIBUTES
| AUTOINCREMENT
+ | BACKUP
| BEFORE
| BEGIN
| BERNOULLI
@@ -1212,6 +1229,7 @@ keyword_as_compat:
| CHANGEFEED
| CHECK
// | COLLATE
+ | COLLECTION
| COMMIT
| CONDITIONAL
| CONFLICT
@@ -1416,6 +1434,7 @@ keyword_compat: (
| ATTACH
| ATTRIBUTES
| AUTOINCREMENT
+ | BACKUP
| BEFORE
| BEGIN
| BERNOULLI
@@ -1424,6 +1443,7 @@ keyword_compat: (
| CHANGEFEED
| CHECK
| COLLATE
+ | COLLECTION
| COMMIT
| CONDITIONAL
| CONFLICT
@@ -1727,6 +1747,8 @@ ATTACH: A T T A C H;
ATTRIBUTES: A T T R I B U T E S;
AUTOINCREMENT: A U T O I N C R E M E N T;
AUTOMAP: A U T O M A P;
+BACKUP: B A C K U P;
+COLLECTION: C O L L E C T I O N;
BEFORE: B E F O R E;
BEGIN: B E G I N;
BERNOULLI: B E R N O U L L I;
diff --git a/ydb/library/yql/sql/v1/format/sql_format.cpp b/ydb/library/yql/sql/v1/format/sql_format.cpp
index 0f1744306cc..746d1a0d7cf 100644
--- a/ydb/library/yql/sql/v1/format/sql_format.cpp
+++ b/ydb/library/yql/sql/v1/format/sql_format.cpp
@@ -1527,6 +1527,36 @@ private:
VisitAllFields(TRule_drop_resource_pool_stmt::GetDescriptor(), msg);
}
+ void VisitCreateBackupCollection(const TRule_create_backup_collection_stmt& msg) {
+ PosFromToken(msg.GetToken1());
+ NewLine();
+ VisitAllFields(TRule_create_backup_collection_stmt::GetDescriptor(), msg);
+ }
+
+ void VisitAlterBackupCollection(const TRule_alter_backup_collection_stmt& msg) {
+ PosFromToken(msg.GetToken1());
+ NewLine();
+ VisitToken(msg.GetToken1());
+ Visit(msg.GetRule_backup_collection2());
+
+ NewLine();
+ PushCurrentIndent();
+ Visit(msg.GetRule_alter_backup_collection_actions3().GetRule_alter_backup_collection_action1());
+ for (const auto& action : msg.GetRule_alter_backup_collection_actions3().GetBlock2()) {
+ Visit(action.GetToken1()); // comma
+ NewLine();
+ Visit(action.GetRule_alter_backup_collection_action2());
+ }
+
+ PopCurrentIndent();
+ }
+
+ void VisitDropBackupCollection(const TRule_drop_backup_collection_stmt& msg) {
+ PosFromToken(msg.GetToken1());
+ NewLine();
+ VisitAllFields(TRule_drop_backup_collection_stmt::GetDescriptor(), msg);
+ }
+
void VisitAllFields(const NProtoBuf::Descriptor* descr, const NProtoBuf::Message& msg) {
VisitAllFieldsImpl<TPrettyVisitor, &TPrettyVisitor::Visit>(this, descr, msg);
}
@@ -2743,7 +2773,10 @@ TStaticData::TStaticData()
{TRule_drop_view_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitDropView)},
{TRule_create_resource_pool_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitCreateResourcePool)},
{TRule_alter_resource_pool_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitAlterResourcePool)},
- {TRule_drop_resource_pool_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitDropResourcePool)}
+ {TRule_drop_resource_pool_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitDropResourcePool)},
+ {TRule_create_backup_collection_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitCreateBackupCollection)},
+ {TRule_alter_backup_collection_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitAlterBackupCollection)},
+ {TRule_drop_backup_collection_stmt::GetDescriptor(), MakePrettyFunctor(&TPrettyVisitor::VisitDropBackupCollection)},
})
, ObfuscatingVisitDispatch({
{TToken::GetDescriptor(), MakeObfuscatingFunctor(&TObfuscatingVisitor::VisitToken)},
diff --git a/ydb/library/yql/sql/v1/format/sql_format_ut.cpp b/ydb/library/yql/sql/v1/format/sql_format_ut.cpp
index 3e386d5999b..cc394463cd4 100644
--- a/ydb/library/yql/sql/v1/format/sql_format_ut.cpp
+++ b/ydb/library/yql/sql/v1/format/sql_format_ut.cpp
@@ -1605,4 +1605,18 @@ FROM Input MATCH_RECOGNIZE (PATTERN (A) DEFINE A AS A);
TSetup setup;
setup.Run(cases);
}
+
+ Y_UNIT_TEST(BackupCollectionOperations) {
+ TCases cases = {
+ {"creAte BackuP colLection `-naMe` wIth (a = \"b\")",
+ "CREATE BACKUP COLLECTION `-naMe` WITH (a = \"b\");\n"},
+ {"alTer bACKuP coLLECTION naMe resEt (b, c), seT (x=y, z=false)",
+ "ALTER BACKUP COLLECTION naMe\n\tRESET (b, c),\n\tSET (x = y, z = FALSE);\n"},
+ {"DROP backup collectiOn `/some/path`",
+ "DROP BACKUP COLLECTION `/some/path`;\n"},
+ };
+
+ TSetup setup;
+ setup.Run(cases);
+ }
}
diff --git a/ydb/library/yql/sql/v1/sql.cpp b/ydb/library/yql/sql/v1/sql.cpp
index e50c776269e..5f539744f8f 100644
--- a/ydb/library/yql/sql/v1/sql.cpp
+++ b/ydb/library/yql/sql/v1/sql.cpp
@@ -167,6 +167,9 @@ bool NeedUseForAllStatements(const TRule_sql_stmt_core::AltCase& subquery) {
case TRule_sql_stmt_core::kAltSqlStmtCore45: // create resource pool
case TRule_sql_stmt_core::kAltSqlStmtCore46: // alter resource pool
case TRule_sql_stmt_core::kAltSqlStmtCore47: // drop resource pool
+ case TRule_sql_stmt_core::kAltSqlStmtCore48: // create backup collection
+ case TRule_sql_stmt_core::kAltSqlStmtCore49: // alter backup collection
+ case TRule_sql_stmt_core::kAltSqlStmtCore50: // drop backup collection
return false;
}
}
diff --git a/ydb/library/yql/sql/v1/sql_query.cpp b/ydb/library/yql/sql/v1/sql_query.cpp
index 479330725dd..d374e89f803 100644
--- a/ydb/library/yql/sql/v1/sql_query.cpp
+++ b/ydb/library/yql/sql/v1/sql_query.cpp
@@ -1344,6 +1344,90 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core&
AddStatementToBlocks(blocks, BuildDropObjectOperation(Ctx.Pos(), objectId, "RESOURCE_POOL", false, {}, context));
break;
}
+ case TRule_sql_stmt_core::kAltSqlStmtCore48: {
+ // create_backup_collection_stmt: CREATE BACKUP COLLECTION name WITH (k=v,...);
+ auto& node = core.GetAlt_sql_stmt_core48().GetRule_create_backup_collection_stmt1();
+ TObjectOperatorContext context(Ctx.Scoped);
+ if (node.GetRule_backup_collection2().GetRule_object_ref3().HasBlock1()) {
+ if (!ClusterExpr(node.GetRule_backup_collection2().GetRule_object_ref3().GetBlock1().GetRule_cluster_expr1(),
+ false,
+ context.ServiceId,
+ context.Cluster)) {
+ return false;
+ }
+ }
+
+ std::map<TString, TDeferredAtom> kv;
+ if (!ParseBackupCollectionSettings(kv, node.GetRule_backup_collection_settings5())) {
+ return false;
+ }
+
+ const TString& objectId = Id(node.GetRule_backup_collection2().GetRule_object_ref3().GetRule_id_or_at2(), *this).second;
+ constexpr const char* typeId = "BACKUP_COLLECTION";
+ AddStatementToBlocks(blocks,
+ BuildCreateObjectOperation(Ctx.Pos(),
+ BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId),
+ typeId,
+ false,
+ false,
+ std::move(kv),
+ context));
+ break;
+ }
+ case TRule_sql_stmt_core::kAltSqlStmtCore49: {
+ // alter_backup_collection_stmt: ALTER BACKUP COLLECTION name alter_backup_collection_action (COMMA alter_backup_collection_action)*;
+ auto& node = core.GetAlt_sql_stmt_core49().GetRule_alter_backup_collection_stmt1();
+ TObjectOperatorContext context(Ctx.Scoped);
+ if (node.GetRule_backup_collection2().GetRule_object_ref3().HasBlock1()) {
+ if (!ClusterExpr(node.GetRule_backup_collection2().GetRule_object_ref3().GetBlock1().GetRule_cluster_expr1(),
+ false,
+ context.ServiceId,
+ context.Cluster)) {
+ return false;
+ }
+ }
+
+ std::map<TString, TDeferredAtom> kv;
+ std::set<TString> toReset;
+ if (!ParseBackupCollectionSettings(kv, toReset, node.GetRule_alter_backup_collection_actions3())) {
+ return false;
+ }
+
+ const TString& objectId = Id(node.GetRule_backup_collection2().GetRule_object_ref3().GetRule_id_or_at2(), *this).second;
+ constexpr const char* typeId = "BACKUP_COLLECTION";
+ AddStatementToBlocks(blocks,
+ BuildAlterObjectOperation(Ctx.Pos(),
+ BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId),
+ typeId,
+ std::move(kv),
+ std::move(toReset),
+ context));
+ break;
+ }
+ case TRule_sql_stmt_core::kAltSqlStmtCore50: {
+ // drop_backup_collection_stmt: DROP BACKUP COLLECTION name;
+ auto& node = core.GetAlt_sql_stmt_core50().GetRule_drop_backup_collection_stmt1();
+ TObjectOperatorContext context(Ctx.Scoped);
+ if (node.GetRule_backup_collection2().GetRule_object_ref3().HasBlock1()) {
+ if (!ClusterExpr(node.GetRule_backup_collection2().GetRule_object_ref3().GetBlock1().GetRule_cluster_expr1(),
+ false,
+ context.ServiceId,
+ context.Cluster)) {
+ return false;
+ }
+ }
+
+ const TString& objectId = Id(node.GetRule_backup_collection2().GetRule_object_ref3().GetRule_id_or_at2(), *this).second;
+ constexpr const char* typeId = "BACKUP_COLLECTION";
+ AddStatementToBlocks(blocks,
+ BuildDropObjectOperation(Ctx.Pos(),
+ BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId),
+ typeId,
+ false,
+ {},
+ context));
+ break;
+ }
case TRule_sql_stmt_core::ALT_NOT_SET:
Ctx.IncrementMonCounter("sql_errors", "UnknownStatement" + internalStatementName);
AltNotImplemented("sql_stmt_core", core);
diff --git a/ydb/library/yql/sql/v1/sql_translation.cpp b/ydb/library/yql/sql/v1/sql_translation.cpp
index fcd0f1ebb10..bf473573f4c 100644
--- a/ydb/library/yql/sql/v1/sql_translation.cpp
+++ b/ydb/library/yql/sql/v1/sql_translation.cpp
@@ -3872,6 +3872,91 @@ bool TSqlTranslation::PermissionNameClause(const TRule_permission_name_target& n
return true;
}
+bool TSqlTranslation::StoreStringSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result) {
+ YQL_ENSURE(value);
+
+ const TString key = to_lower(id.Name);
+ if (result.find(key) != result.end()) {
+ Ctx.Error() << to_upper(key) << " duplicate keys";
+ return false;
+ }
+
+ switch (value->Alt_case()) {
+ case TRule_table_setting_value::kAltTableSettingValue2:
+ return StoreString(*value, result[key], Ctx, to_upper(key));
+
+ default:
+ Ctx.Error() << to_upper(key) << " value should be a string literal";
+ return false;
+ }
+
+ return true;
+}
+
+bool TSqlTranslation::StoreStringSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result) {
+ const TIdentifier id = IdEx(entry.GetRule_an_id1(), *this);
+ return StoreStringSettingsEntry(id, &entry.GetRule_table_setting_value3(), result);
+}
+
+bool TSqlTranslation::ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, const TRule_backup_collection_settings& settings) {
+ const auto& firstEntry = settings.GetRule_backup_collection_settings_entry1();
+ if (!StoreStringSettingsEntry(IdEx(firstEntry.GetRule_an_id1(), *this), &firstEntry.GetRule_table_setting_value3(), result)) {
+ return false;
+ }
+ for (const auto& block : settings.GetBlock2()) {
+ const auto& entry = block.GetRule_backup_collection_settings_entry2();
+ if (!StoreStringSettingsEntry(IdEx(entry.GetRule_an_id1(), *this), &entry.GetRule_table_setting_value3(), result)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+bool TSqlTranslation::ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_backup_collection_actions& actions) {
+ auto parseAction = [&](auto& actionVariant) {
+ switch (actionVariant.Alt_case()) {
+ case TRule_alter_backup_collection_action::kAltAlterBackupCollectionAction1: {
+ const auto& action = actionVariant.GetAlt_alter_backup_collection_action1().GetRule_alter_table_set_table_setting_compat1();
+ if (!StoreStringSettingsEntry(action.GetRule_alter_table_setting_entry3(), result)) {
+ return false;
+ }
+ for (const auto& entry : action.GetBlock4()) {
+ if (!StoreStringSettingsEntry(entry.GetRule_alter_table_setting_entry2(), result)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ case TRule_alter_backup_collection_action::kAltAlterBackupCollectionAction2: {
+ const auto& action = actionVariant.GetAlt_alter_backup_collection_action2().GetRule_alter_table_reset_table_setting1();
+ const TString firstKey = to_lower(IdEx(action.GetRule_an_id3(), *this).Name);
+ toReset.insert(firstKey);
+ for (const auto& key : action.GetBlock4()) {
+ toReset.insert(to_lower(IdEx(key.GetRule_an_id2(), *this).Name));
+ }
+ return true;
+ }
+ case TRule_alter_backup_collection_action::ALT_NOT_SET:
+ Y_ABORT("You should change implementation according to grammar changes");
+ }
+ };
+
+ const auto& firstAction = actions.GetRule_alter_backup_collection_action1();
+ if (!parseAction(firstAction)) {
+ return false;
+ }
+
+ for (const auto& action : actions.GetBlock2()) {
+ if (!parseAction(action.GetRule_alter_backup_collection_action2())) {
+ return false;
+ }
+ }
+
+
+ return true;
+}
+
TString TSqlTranslation::FrameSettingsToString(EFrameSettings settings, bool isUnbounded) {
TString result;
switch (settings) {
diff --git a/ydb/library/yql/sql/v1/sql_translation.h b/ydb/library/yql/sql/v1/sql_translation.h
index 2646a20c987..997f1079d71 100644
--- a/ydb/library/yql/sql/v1/sql_translation.h
+++ b/ydb/library/yql/sql/v1/sql_translation.h
@@ -242,6 +242,10 @@ protected:
bool PermissionNameClause(const TRule_permission_name_target& node, TVector<TDeferredAtom>& result, bool withGrantOption);
bool PermissionNameClause(const TRule_permission_name& node, TDeferredAtom& result);
bool PermissionNameClause(const TRule_permission_id& node, TDeferredAtom& result);
+ bool StoreStringSettingsEntry(const TIdentifier& id, const TRule_table_setting_value* value, std::map<TString, TDeferredAtom>& result);
+ bool StoreStringSettingsEntry(const TRule_alter_table_setting_entry& entry, std::map<TString, TDeferredAtom>& result);
+ bool ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, const TRule_backup_collection_settings& settings);
+ bool ParseBackupCollectionSettings(std::map<TString, TDeferredAtom>& result, std::set<TString>& toReset, const TRule_alter_backup_collection_actions& actions);
bool ValidateAuthMethod(const std::map<TString, TDeferredAtom>& result);
bool ValidateExternalTable(const TCreateTableParameters& params);
diff --git a/ydb/library/yql/sql/v1/sql_ut.cpp b/ydb/library/yql/sql/v1/sql_ut.cpp
index 01a6f86e84d..ec86d34a8d5 100644
--- a/ydb/library/yql/sql/v1/sql_ut.cpp
+++ b/ydb/library/yql/sql/v1/sql_ut.cpp
@@ -2521,12 +2521,12 @@ Y_UNIT_TEST_SUITE(SqlParsingOnly) {
Y_UNIT_TEST(AlterTableAddIndexWithIsNotSupported) {
ExpectFailWithError("USE plato; ALTER TABLE table ADD INDEX idx GLOBAL ON (col) WITH (a=b)",
- "<main>:1:40: Error: with: alternative is not implemented yet: 726:20: global_index\n");
+ "<main>:1:40: Error: with: alternative is not implemented yet: 742:20: global_index\n");
}
Y_UNIT_TEST(AlterTableAddIndexLocalIsNotSupported) {
ExpectFailWithError("USE plato; ALTER TABLE table ADD INDEX idx LOCAL ON (col)",
- "<main>:1:40: Error: local: alternative is not implemented yet: 726:35: local_index\n");
+ "<main>:1:40: Error: local: alternative is not implemented yet: 742:35: local_index\n");
}
Y_UNIT_TEST(CreateTableAddIndexVector) {
@@ -7030,3 +7030,94 @@ Y_UNIT_TEST_SUITE(ResourcePool) {
UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
}
}
+
+Y_UNIT_TEST_SUITE(BackupCollection) {
+ Y_UNIT_TEST(CreateBackupCollection) {
+ NYql::TAstParseResult res = SqlToYql(R"sql(
+ USE plato;
+ CREATE BACKUP COLLECTION TestCollection WITH (
+ STORAGE="local",
+ TAG="test" -- for testing purposes, not a real thing
+ );
+ )sql");
+ UNIT_ASSERT_C(res.Root, res.Issues.ToString());
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#");
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("createObject"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0} };
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ Y_UNIT_TEST(CreateBackupCollectionWithBadArguments) {
+ ExpectFailWithError(R"sql(
+ USE plato;
+ CREATE BACKUP COLLECTION TestCollection;
+ )sql" , "<main>:3:55: Error: Unexpected token ';' : syntax error...\n\n");
+
+ ExpectFailWithError(R"sql(
+ USE plato;
+ CREATE BACKUP COLLECTION TestCollection WITH (
+ DUPLICATE_SETTING="first_value",
+ DUPLICATE_SETTING="second_value"
+ );
+ )sql" , "<main>:5:21: Error: DUPLICATE_SETTING duplicate keys\n");
+
+ ExpectFailWithError(R"sql(
+ USE plato;
+ CREATE BACKUP COLLECTION TestCollection WITH (
+ INT_SETTING=1
+ );
+ )sql" , "<main>:4:21: Error: INT_SETTING value should be a string literal\n");
+ }
+
+ Y_UNIT_TEST(AlterBackupCollection) {
+ NYql::TAstParseResult res = SqlToYql(R"sql(
+ USE plato;
+ ALTER BACKUP COLLECTION TestCollection
+ SET (STORAGE="remote"), -- also just for test
+ SET (TAG1 = "123"),
+ RESET (TAG2, TAG3);
+ )sql");
+ UNIT_ASSERT_C(res.Root, res.Issues.ToString());
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_STRING_CONTAINS(line, R"#(('mode 'alterObject))#");
+ UNIT_ASSERT_STRING_CONTAINS(line, R"#('('features '('('"storage" '"remote") '('"tag1" '"123"))))#");
+ UNIT_ASSERT_STRING_CONTAINS(line, R"#('('resetFeatures '('"tag2" '"tag3")))#");
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0} };
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+
+ Y_UNIT_TEST(DropBackupCollection) {
+ NYql::TAstParseResult res = SqlToYql(R"sql(
+ USE plato;
+ DROP BACKUP COLLECTION TestCollection;
+ )sql");
+ UNIT_ASSERT(res.Root);
+
+ TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) {
+ if (word == "Write") {
+ UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("'features"));
+ UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("dropObject"));
+ }
+ };
+
+ TWordCountHive elementStat = { {TString("Write"), 0}};
+ VerifyProgram(res, elementStat, verifyLine);
+
+ UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]);
+ }
+}