diff options
author | udovichenko-r <udovichenko-r@yandex-team.com> | 2024-11-12 22:07:02 +0300 |
---|---|---|
committer | udovichenko-r <udovichenko-r@yandex-team.com> | 2024-11-12 22:21:07 +0300 |
commit | fa5655229271d7a09cce8033d1097f1b03daf94e (patch) | |
tree | 5922c2db17789e411b6cc46069c66188e834f28b /yql/essentials/sql/v1 | |
parent | 77c13da33ae29c033359e516ac2eb55a6c3d5e9e (diff) | |
download | ydb-fa5655229271d7a09cce8033d1097f1b03daf94e.tar.gz |
Apply GH commits
Apply GH: Extract prefix and entries in backup-related sql (#10807)
Apply GH: Fix syntax for Column Family (#10781)
Apply GH: Case-insensitive mode for searching modules and functions (#10842)
Apply GH: Fixed i/o for pg_proc (#10914)
Apply GH: An option to render SQL transalation with Seq! (#11015)
commit_hash:d2d2fcdef2bbd0434236aef325aa071c7e39c526
Diffstat (limited to 'yql/essentials/sql/v1')
-rw-r--r-- | yql/essentials/sql/v1/context.cpp | 1 | ||||
-rw-r--r-- | yql/essentials/sql/v1/context.h | 1 | ||||
-rw-r--r-- | yql/essentials/sql/v1/node.h | 28 | ||||
-rw-r--r-- | yql/essentials/sql/v1/query.cpp | 169 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_query.cpp | 42 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_translation.cpp | 56 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_translation.h | 3 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_ut.cpp | 110 | ||||
-rw-r--r-- | yql/essentials/sql/v1/sql_ut_antlr4.cpp | 110 |
9 files changed, 427 insertions, 93 deletions
diff --git a/yql/essentials/sql/v1/context.cpp b/yql/essentials/sql/v1/context.cpp index 4637a3be9e..ab880f4315 100644 --- a/yql/essentials/sql/v1/context.cpp +++ b/yql/essentials/sql/v1/context.cpp @@ -65,6 +65,7 @@ THashMap<TStringBuf, TPragmaField> CTX_PRAGMA_FIELDS = { {"ValidateUnusedExprs", &TContext::ValidateUnusedExprs}, {"AnsiImplicitCrossJoin", &TContext::AnsiImplicitCrossJoin}, {"DistinctOverWindow", &TContext::DistinctOverWindow}, + {"SeqMode", &TContext::SeqMode}, }; typedef TMaybe<bool> TContext::*TPragmaMaybeField; diff --git a/yql/essentials/sql/v1/context.h b/yql/essentials/sql/v1/context.h index 4aa766e34a..61b2e4def3 100644 --- a/yql/essentials/sql/v1/context.h +++ b/yql/essentials/sql/v1/context.h @@ -325,6 +325,7 @@ namespace NSQLTranslationV1 { bool ValidateUnusedExprs = false; bool AnsiImplicitCrossJoin = false; // select * from A,B bool DistinctOverWindow = false; + bool SeqMode = false; }; class TColumnRefScope { diff --git a/yql/essentials/sql/v1/node.h b/yql/essentials/sql/v1/node.h index d9eb154031..5805f92042 100644 --- a/yql/essentials/sql/v1/node.h +++ b/yql/essentials/sql/v1/node.h @@ -1521,7 +1521,7 @@ namespace NSQLTranslationV1 { TNodePtr BuildWriteResult(TPosition pos, const TString& label, TNodePtr settings); TNodePtr BuildCommitClusters(TPosition pos); TNodePtr BuildRollbackClusters(TPosition pos); - TNodePtr BuildQuery(TPosition pos, const TVector<TNodePtr>& blocks, bool topLevel, TScopedStatePtr scoped); + TNodePtr BuildQuery(TPosition pos, const TVector<TNodePtr>& blocks, bool topLevel, TScopedStatePtr scoped, bool useSeq); TNodePtr BuildPragma(TPosition pos, const TString& prefix, const TString& name, const TVector<TDeferredAtom>& values, bool valueDefault); TNodePtr BuildSqlLambda(TPosition pos, TVector<TString>&& args, TVector<TNodePtr>&& exprSeq); TNodePtr BuildWorldIfNode(TPosition pos, TNodePtr predicate, TNodePtr thenNode, TNodePtr elseNode, bool isEvaluate); @@ -1534,23 +1534,39 @@ namespace NSQLTranslationV1 { TNodePtr BuildDropTopic(TPosition pos, const TTopicRef& topic, const TDropTopicParameters& params, TScopedStatePtr scoped); - TNodePtr BuildCreateBackupCollection(TPosition pos, const TString& id, + TNodePtr BuildCreateBackupCollection( + TPosition pos, + const TString& prefix, + const TString& id, const TCreateBackupCollectionParameters& params, const TObjectOperatorContext& context); - TNodePtr BuildAlterBackupCollection(TPosition pos, const TString& id, + TNodePtr BuildAlterBackupCollection( + TPosition pos, + const TString& prefix, + const TString& id, const TAlterBackupCollectionParameters& params, const TObjectOperatorContext& context); - TNodePtr BuildDropBackupCollection(TPosition pos, const TString& id, + TNodePtr BuildDropBackupCollection( + TPosition pos, + const TString& prefix, + const TString& id, const TDropBackupCollectionParameters& params, const TObjectOperatorContext& context); - TNodePtr BuildBackup(TPosition pos, const TString& id, + TNodePtr BuildBackup( + TPosition pos, + const TString& prefix, + const TString& id, const TBackupParameters& params, const TObjectOperatorContext& context); - TNodePtr BuildRestore(TPosition pos, const TString& id, + TNodePtr BuildRestore( + TPosition pos, + const TString& prefix, + const TString& id, const TRestoreParameters& params, const TObjectOperatorContext& context); + template<class TContainer> TMaybe<TString> FindMistypeIn(const TContainer& container, const TString& name) { for (auto& item: container) { diff --git a/yql/essentials/sql/v1/query.cpp b/yql/essentials/sql/v1/query.cpp index 5548587090..56dd8bd63d 100644 --- a/yql/essentials/sql/v1/query.cpp +++ b/yql/essentials/sql/v1/query.cpp @@ -2693,15 +2693,44 @@ TNodePtr BuildWriteResult(TPosition pos, const TString& label, TNodePtr settings class TYqlProgramNode: public TAstListNode { public: - TYqlProgramNode(TPosition pos, const TVector<TNodePtr>& blocks, bool topLevel, TScopedStatePtr scoped) + TYqlProgramNode(TPosition pos, const TVector<TNodePtr>& blocks, bool topLevel, TScopedStatePtr scoped, bool useSeq) : TAstListNode(pos) , Blocks(blocks) , TopLevel(topLevel) , Scoped(scoped) + , UseSeq(useSeq) {} bool DoInit(TContext& ctx, ISource* src) override { bool hasError = false; + INode::TPtr currentWorldsHolder; + INode::TPtr seqNode; + if (UseSeq) { + currentWorldsHolder = new TAstListNodeImpl(GetPos()); + seqNode = new TAstListNodeImpl(GetPos()); + seqNode->Add("Seq!","world"); + } + + INode* currentWorlds = UseSeq ? currentWorldsHolder.Get() : this; + auto flushCurrentWorlds = [&](bool changeSeq, bool finish) { + currentWorldsHolder->Add(Y("return","world")); + auto lambda = BuildLambda(GetPos(), Y("world"), Y("block", Q(currentWorldsHolder))); + seqNode->Add(lambda); + + if (finish) { + Add(Y("let", "world", seqNode)); + } else { + currentWorldsHolder = new TAstListNodeImpl(GetPos()); + currentWorlds = currentWorldsHolder.Get(); + } + + if (changeSeq) { + Add(Y("let", "world", seqNode)); + seqNode = new TAstListNodeImpl(GetPos()); + seqNode->Add("Seq!","world"); + } + }; + if (TopLevel) { for (auto& var: ctx.Variables) { if (!var.second.second->Init(ctx, src)) { @@ -2798,33 +2827,33 @@ public: auto resultSink = Y("DataSink", BuildQuotedAtom(Pos, TString(ResultProviderName))); for (const auto& warningPragma : ctx.WarningPolicy.GetRules()) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "Warning"), BuildQuotedAtom(Pos, warningPragma.GetPattern()), BuildQuotedAtom(Pos, to_lower(ToString(warningPragma.GetAction())))))); } if (ctx.ResultSizeLimit > 0) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", resultSink, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", resultSink, BuildQuotedAtom(Pos, "SizeLimit"), BuildQuotedAtom(Pos, ToString(ctx.ResultSizeLimit))))); } if (!ctx.PragmaPullUpFlatMapOverJoin) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "DisablePullUpFlatMapOverJoin")))); } if (ctx.FilterPushdownOverJoinOptionalSide) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "FilterPushdownOverJoinOptionalSide")))); } if (!ctx.RotateJoinTree) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "RotateJoinTree"), BuildQuotedAtom(Pos, "false")))); } if (ctx.DiscoveryMode) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "DiscoveryMode")))); } @@ -2835,12 +2864,12 @@ public: } else if (ctx.DqEngineForce) { mode = "force"; } - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "DqEngine"), BuildQuotedAtom(Pos, mode)))); } if (ctx.CostBasedOptimizer) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "CostBasedOptimizer"), BuildQuotedAtom(Pos, ctx.CostBasedOptimizer)))); } @@ -2850,43 +2879,43 @@ public: pragmaName = "JsonQueryReturnsJsonDocument"; } - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, pragmaName)))); + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, pragmaName)))); } if (ctx.OrderedColumns) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "OrderedColumns")))); } if (ctx.PqReadByRtmrCluster) { auto pqSourceAll = Y("DataSource", BuildQuotedAtom(Pos, TString(PqProviderName)), BuildQuotedAtom(Pos, "$all")); - Add(Y("let", "world", Y(TString(ConfigureName), "world", pqSourceAll, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", pqSourceAll, BuildQuotedAtom(Pos, "Attr"), BuildQuotedAtom(Pos, "PqReadByRtmrCluster_"), BuildQuotedAtom(Pos, ctx.PqReadByRtmrCluster)))); auto rtmrSourceAll = Y("DataSource", BuildQuotedAtom(Pos, TString(RtmrProviderName)), BuildQuotedAtom(Pos, "$all")); - Add(Y("let", "world", Y(TString(ConfigureName), "world", rtmrSourceAll, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", rtmrSourceAll, BuildQuotedAtom(Pos, "Attr"), BuildQuotedAtom(Pos, "PqReadByRtmrCluster_"), BuildQuotedAtom(Pos, ctx.PqReadByRtmrCluster)))); if (ctx.PqReadByRtmrCluster != "dq") { // set any dynamic settings for particular RTMR cluster for CommitAll! auto rtmrSource = Y("DataSource", BuildQuotedAtom(Pos, TString(RtmrProviderName)), BuildQuotedAtom(Pos, ctx.PqReadByRtmrCluster)); - Add(Y("let", "world", Y(TString(ConfigureName), "world", rtmrSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", rtmrSource, BuildQuotedAtom(Pos, "Attr"), BuildQuotedAtom(Pos, "Dummy_"), BuildQuotedAtom(Pos, "1")))); } } if (ctx.YsonCastToString.Defined()) { const TString pragmaName = *ctx.YsonCastToString ? "YsonCastToString" : "DisableYsonCastToString"; - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, pragmaName)))); + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, pragmaName)))); } if (ctx.UseBlocks) { - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "UseBlocks")))); + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "UseBlocks")))); } if (ctx.BlockEngineEnable) { TString mode = ctx.BlockEngineForce ? "force" : "auto"; - Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, + currentWorlds->Add(Y("let", "world", Y(TString(ConfigureName), "world", configSource, BuildQuotedAtom(Pos, "BlockEngine"), BuildQuotedAtom(Pos, mode)))); } } @@ -2914,22 +2943,41 @@ public: Add(Y("let", data.first, node)); } + if (UseSeq) { + flushCurrentWorlds(false, false); + } + for (auto& block: Blocks) { const auto subqueryAliasPtr = block->SubqueryAlias(); if (subqueryAliasPtr) { if (block->UsedSubquery()) { + if (UseSeq) { + flushCurrentWorlds(true, false); + } + const auto& ref = block->GetLabel(); YQL_ENSURE(!ref.empty()); Add(block); - Add(Y("let", "world", Y("Nth", *subqueryAliasPtr, Q("0")))); + currentWorlds->Add(Y("let", "world", Y("Nth", *subqueryAliasPtr, Q("0")))); Add(Y("let", ref, Y("Nth", *subqueryAliasPtr, Q("1")))); } } else { const auto& ref = block->GetLabel(); - Add(Y("let", ref ? ref : "world", block)); + if (ref) { + Add(Y("let", ref, block)); + } else { + currentWorlds->Add(Y("let", "world", block)); + if (UseSeq) { + flushCurrentWorlds(false, false); + } + } } } + if (UseSeq) { + flushCurrentWorlds(false, true); + } + if (TopLevel) { if (ctx.UniversalAliases) { decltype(Nodes) preparedNodes; @@ -2974,10 +3022,11 @@ private: TVector<TNodePtr> Blocks; const bool TopLevel; TScopedStatePtr Scoped; + const bool UseSeq; }; -TNodePtr BuildQuery(TPosition pos, const TVector<TNodePtr>& blocks, bool topLevel, TScopedStatePtr scoped) { - return new TYqlProgramNode(pos, blocks, topLevel, scoped); +TNodePtr BuildQuery(TPosition pos, const TVector<TNodePtr>& blocks, bool topLevel, TScopedStatePtr scoped, bool useSeq) { + return new TYqlProgramNode(pos, blocks, topLevel, scoped, useSeq); } class TPragmaNode final: public INode { @@ -3285,16 +3334,18 @@ class TBaseBackupCollectionNode public: TBaseBackupCollectionNode( TPosition pos, + const TString& prefix, const TString& objectId, const TObjectOperatorContext& context) : TBase(pos) , TObjectOperatorContext(context) + , Prefix(prefix) , Id(objectId) {} bool DoInit(TContext& ctx, ISource* src) final { auto keys = Y("Key"); - keys = L(keys, Q(Y(Q("backupCollection"), Y("String", BuildQuotedAtom(Pos, Id))))); + keys = L(keys, Q(Y(Q("backupCollection"), Y("String", BuildQuotedAtom(Pos, Id)), Y("String", BuildQuotedAtom(Pos, Prefix))))); auto options = this->FillOptions(ctx, Y()); Add("block", Q(Y( @@ -3309,6 +3360,7 @@ public: virtual INode::TPtr FillOptions(TContext& ctx, INode::TPtr options) const = 0; protected: + TString Prefix; TString Id; }; @@ -3319,10 +3371,11 @@ class TCreateBackupCollectionNode public: TCreateBackupCollectionNode( TPosition pos, + const TString& prefix, const TString& objectId, const TCreateBackupCollectionParameters& params, const TObjectOperatorContext& context) - : TBase(pos, objectId, context) + : TBase(pos, prefix, objectId, context) , Params(params) {} @@ -3331,7 +3384,7 @@ public: auto settings = Y(); for (auto& [key, value] : Params.Settings) { - settings->Add(Q(Y(BuildQuotedAtom(Pos, key), value.Build()))); + settings->Add(Q(Y(BuildQuotedAtom(Pos, key), Y("String", value.Build())))); } options->Add(Q(Y(Q("settings"), Q(settings)))); @@ -3349,7 +3402,7 @@ public: } TPtr DoClone() const final { - return new TCreateBackupCollectionNode(GetPos(), Id, Params, *this); + return new TCreateBackupCollectionNode(GetPos(), Prefix, Id, Params, *this); } private: @@ -3363,10 +3416,11 @@ class TAlterBackupCollectionNode public: TAlterBackupCollectionNode( TPosition pos, + const TString& prefix, const TString& objectId, const TAlterBackupCollectionParameters& params, const TObjectOperatorContext& context) - : TBase(pos, objectId, context) + : TBase(pos, prefix, objectId, context) , Params(params) {} @@ -3375,7 +3429,7 @@ public: auto settings = Y(); for (auto& [key, value] : Params.Settings) { - settings->Add(Q(Y(BuildQuotedAtom(Pos, key), value.Build()))); + settings->Add(Q(Y(BuildQuotedAtom(Pos, key), Y("String", value.Build())))); } options->Add(Q(Y(Q("settings"), Q(settings)))); @@ -3403,7 +3457,7 @@ public: } TPtr DoClone() const final { - return new TAlterBackupCollectionNode(GetPos(), Id, Params, *this); + return new TAlterBackupCollectionNode(GetPos(), Prefix, Id, Params, *this); } private: @@ -3417,10 +3471,11 @@ class TDropBackupCollectionNode public: TDropBackupCollectionNode( TPosition pos, + const TString& prefix, const TString& objectId, const TDropBackupCollectionParameters&, const TObjectOperatorContext& context) - : TBase(pos, objectId, context) + : TBase(pos, prefix, objectId, context) {} virtual INode::TPtr FillOptions(TContext&, INode::TPtr options) const final { @@ -3431,29 +3486,38 @@ public: TPtr DoClone() const final { TDropBackupCollectionParameters params; - return new TDropBackupCollectionNode(GetPos(), Id, params, *this); + return new TDropBackupCollectionNode(GetPos(), Prefix, Id, params, *this); } }; -TNodePtr BuildCreateBackupCollection(TPosition pos, const TString& id, +TNodePtr BuildCreateBackupCollection( + TPosition pos, + const TString& prefix, + const TString& id, const TCreateBackupCollectionParameters& params, const TObjectOperatorContext& context) { - return new TCreateBackupCollectionNode(pos, id, params, context); + return new TCreateBackupCollectionNode(pos, prefix, id, params, context); } -TNodePtr BuildAlterBackupCollection(TPosition pos, const TString& id, +TNodePtr BuildAlterBackupCollection( + TPosition pos, + const TString& prefix, + const TString& id, const TAlterBackupCollectionParameters& params, const TObjectOperatorContext& context) { - return new TAlterBackupCollectionNode(pos, id, params, context); + return new TAlterBackupCollectionNode(pos, prefix, id, params, context); } -TNodePtr BuildDropBackupCollection(TPosition pos, const TString& id, +TNodePtr BuildDropBackupCollection( + TPosition pos, + const TString& prefix, + const TString& id, const TDropBackupCollectionParameters& params, const TObjectOperatorContext& context) { - return new TDropBackupCollectionNode(pos, id, params, context); + return new TDropBackupCollectionNode(pos, prefix, id, params, context); } class TBackupNode final @@ -3464,11 +3528,13 @@ class TBackupNode final public: TBackupNode( TPosition pos, + const TString& prefix, const TString& id, const TBackupParameters& params, const TObjectOperatorContext& context) : TBase(pos) , TObjectOperatorContext(context) + , Prefix(prefix) , Id(id) , Params(params) { @@ -3477,13 +3543,14 @@ public: bool DoInit(TContext& ctx, ISource* src) override { auto keys = Y("Key"); - keys = L(keys, Q(Y(Q("backup"), Y("String", BuildQuotedAtom(Pos, Id))))); + keys = L(keys, Q(Y(Q("backup"), Y("String", BuildQuotedAtom(Pos, Id)), Y("String", BuildQuotedAtom(Pos, Prefix))))); auto opts = Y(); - opts->Add(Q(Y(Q("mode"), Q("backup")))); if (Params.Incremental) { - opts->Add(Q(Y(Q("incremental")))); + opts->Add(Q(Y(Q("mode"), Q("backupIncremental")))); + } else { + opts->Add(Q(Y(Q("mode"), Q("backup")))); } Add("block", Q(Y( @@ -3496,18 +3563,22 @@ public: } TPtr DoClone() const final { - return new TBackupNode(GetPos(), Id, Params, *this); + return new TBackupNode(GetPos(), Prefix, Id, Params, *this); } private: + TString Prefix; TString Id; TBackupParameters Params; }; -TNodePtr BuildBackup(TPosition pos, const TString& id, +TNodePtr BuildBackup( + TPosition pos, + const TString& prefix, + const TString& id, const TBackupParameters& params, const TObjectOperatorContext& context) { - return new TBackupNode(pos, id, params, context); + return new TBackupNode(pos, prefix, id, params, context); } class TRestoreNode final @@ -3518,11 +3589,13 @@ class TRestoreNode final public: TRestoreNode( TPosition pos, + const TString& prefix, const TString& id, const TRestoreParameters& params, const TObjectOperatorContext& context) : TBase(pos) , TObjectOperatorContext(context) + , Prefix(prefix) , Id(id) , Params(params) { @@ -3531,7 +3604,7 @@ public: bool DoInit(TContext& ctx, ISource* src) override { auto keys = Y("Key"); - keys = L(keys, Q(Y(Q("restore"), Y("String", BuildQuotedAtom(Pos, Id))))); + keys = L(keys, Q(Y(Q("restore"), Y("String", BuildQuotedAtom(Pos, Id)), Y("String", BuildQuotedAtom(Pos, Prefix))))); auto opts = Y(); opts->Add(Q(Y(Q("mode"), Q("restore")))); @@ -3550,18 +3623,22 @@ public: } TPtr DoClone() const final { - return new TRestoreNode(GetPos(), Id, Params, *this); + return new TRestoreNode(GetPos(), Prefix, Id, Params, *this); } private: + TString Prefix; TString Id; TRestoreParameters Params; }; -TNodePtr BuildRestore(TPosition pos, const TString& id, +TNodePtr BuildRestore( + TPosition pos, + const TString& prefix, + const TString& id, const TRestoreParameters& params, const TObjectOperatorContext& context) { - return new TRestoreNode(pos, id, params, context); + return new TRestoreNode(pos, prefix, id, params, context); } } // namespace NSQLTranslationV1 diff --git a/yql/essentials/sql/v1/sql_query.cpp b/yql/essentials/sql/v1/sql_query.cpp index f3755bf6f0..5f2f31d776 100644 --- a/yql/essentials/sql/v1/sql_query.cpp +++ b/yql/essentials/sql/v1/sql_query.cpp @@ -1420,7 +1420,8 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& const TString& objectId = Id(node.GetRule_backup_collection2().GetRule_object_ref3().GetRule_id_or_at2(), *this).second; AddStatementToBlocks(blocks, BuildCreateBackupCollection(Ctx.Pos(), - BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId), + TString(Ctx.GetPrefixPath(context.ServiceId, context.Cluster)), + objectId, TCreateBackupCollectionParameters { .Settings = std::move(kv), .Database = database, @@ -1482,7 +1483,8 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& const TString& objectId = Id(node.GetRule_backup_collection2().GetRule_object_ref3().GetRule_id_or_at2(), *this).second; AddStatementToBlocks(blocks, BuildAlterBackupCollection(Ctx.Pos(), - BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId), + TString(Ctx.GetPrefixPath(context.ServiceId, context.Cluster)), + objectId, TAlterBackupCollectionParameters { .Settings = std::move(kv), .SettingsToReset = std::move(toReset), @@ -1510,7 +1512,8 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& const TString& objectId = Id(node.GetRule_backup_collection2().GetRule_object_ref3().GetRule_id_or_at2(), *this).second; AddStatementToBlocks(blocks, BuildDropBackupCollection(Ctx.Pos(), - BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId), + TString(Ctx.GetPrefixPath(context.ServiceId, context.Cluster)), + objectId, TDropBackupCollectionParameters { .MissingOk = false, }, @@ -1630,7 +1633,8 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& AddStatementToBlocks(blocks, BuildBackup( Ctx.Pos(), - BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId), + TString(Ctx.GetPrefixPath(context.ServiceId, context.Cluster)), + objectId, TBackupParameters{ .Incremental = incremental, }, @@ -1662,7 +1666,8 @@ bool TSqlQuery::Statement(TVector<TNodePtr>& blocks, const TRule_sql_stmt_core& AddStatementToBlocks(blocks, BuildRestore( Ctx.Pos(), - BuildTablePath(Ctx.GetPrefixPath(context.ServiceId, context.Cluster), objectId), + TString(Ctx.GetPrefixPath(context.ServiceId, context.Cluster)), + objectId, TRestoreParameters{ .At = at, }, @@ -2022,22 +2027,29 @@ bool TSqlQuery::AlterTableAlterFamily(const TRule_alter_table_alter_column_famil << "' in one alter"; return false; } - const TString stringValue(Ctx.Token(value.GetAlt_family_setting_value1().GetToken1())); - entry->Data = BuildLiteralSmartString(Ctx, stringValue); + if (!StoreString(value, entry->Data, Ctx)) { + Ctx.Error() << to_upper(settingName.Name) << " value should be a string literal"; + return false; + } } else if (to_lower(settingName.Name) == "compression") { if (entry->Compression) { Ctx.Error() << "Redefinition of 'compression' setting for column family '" << name.Name << "' in one alter"; return false; } - const TString stringValue(Ctx.Token(value.GetAlt_family_setting_value1().GetToken1())); - entry->Compression = BuildLiteralSmartString(Ctx, stringValue); + if (!StoreString(value, entry->Compression, Ctx)) { + Ctx.Error() << to_upper(settingName.Name) << " value should be a string literal"; + return false; + } } else if (to_lower(settingName.Name) == "compression_level") { if (entry->CompressionLevel) { Ctx.Error() << "Redefinition of 'compression_level' setting for column family '" << name.Name << "' in one alter"; return false; } - entry->CompressionLevel = LiteralNumber(Ctx, value.GetAlt_family_setting_value2().GetRule_integer1()); + if (!StoreInt(value, entry->CompressionLevel, Ctx)) { + Ctx.Error() << to_upper(settingName.Name) << " value should be an integer"; + return false; + } } else { Ctx.Error() << "Unknown table setting: " << settingName.Name; return false; @@ -2954,6 +2966,12 @@ TNodePtr TSqlQuery::PragmaStatement(const TRule_pragma_stmt& stmt, bool& success } else if (normalizedPragma == "disabledistinctoverwindow") { Ctx.DistinctOverWindow = false; Ctx.IncrementMonCounter("sql_pragma", "DisableDistinctOverWindow"); + } else if (normalizedPragma == "seqmode") { + Ctx.SeqMode = true; + Ctx.IncrementMonCounter("sql_pragma", "SeqMode"); + } else if (normalizedPragma == "disableseqmode") { + Ctx.SeqMode = false; + Ctx.IncrementMonCounter("sql_pragma", "DisableSeqMode"); } else { Error() << "Unknown pragma: " << pragma; Ctx.IncrementMonCounter("sql_errors", "UnknownPragma"); @@ -3302,7 +3320,7 @@ TNodePtr TSqlQuery::Build(const TSQLv1ParserAST& ast) { AddStatementToBlocks(blocks, BuildCommitClusters(Ctx.Pos())); } - auto result = BuildQuery(Ctx.Pos(), blocks, true, Ctx.Scoped); + auto result = BuildQuery(Ctx.Pos(), blocks, true, Ctx.Scoped, Ctx.SeqMode); WarnUnusedNodes(); return result; } @@ -3372,7 +3390,7 @@ TNodePtr TSqlQuery::Build(const std::vector<::NSQLv1Generated::TRule_sql_stmt_co AddStatementToBlocks(blocks, BuildCommitClusters(Ctx.Pos())); } - auto result = BuildQuery(Ctx.Pos(), blocks, true, Ctx.Scoped); + auto result = BuildQuery(Ctx.Pos(), blocks, true, Ctx.Scoped, Ctx.SeqMode); return result; } namespace { diff --git a/yql/essentials/sql/v1/sql_translation.cpp b/yql/essentials/sql/v1/sql_translation.cpp index 4bcfb7de84..b298eb8abb 100644 --- a/yql/essentials/sql/v1/sql_translation.cpp +++ b/yql/essentials/sql/v1/sql_translation.cpp @@ -1567,17 +1567,59 @@ TNodePtr TSqlTranslation::SerialTypeNode(const TRule_type_name_or_bind& node) { return nullptr; } +bool StoreString(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx) { + switch (from.Alt_case()) { + case TRule_family_setting_value::kAltFamilySettingValue1: { + // STRING_VALUE + const TString stringValue(ctx.Token(from.GetAlt_family_setting_value1().GetToken1())); + TNodePtr literal = BuildLiteralSmartString(ctx, stringValue); + if (!literal) { + return false; + } + to = literal; + break; + } + default: + return false; + } + return true; +} + +bool StoreInt(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx) { + switch (from.Alt_case()) { + case TRule_family_setting_value::kAltFamilySettingValue2: { + // integer + TNodePtr literal = LiteralNumber(ctx, from.GetAlt_family_setting_value2().GetRule_integer1()); + if (!literal) { + return false; + } + to = literal; + break; + } + default: + return false; + } + return true; +} + bool TSqlTranslation::FillFamilySettingsEntry(const TRule_family_settings_entry& settingNode, TFamilyEntry& family) { TIdentifier id = IdEx(settingNode.GetRule_an_id1(), *this); const TRule_family_setting_value& value = settingNode.GetRule_family_setting_value3(); if (to_lower(id.Name) == "data") { - const TString stringValue(Ctx.Token(value.GetAlt_family_setting_value1().GetToken1())); - family.Data = BuildLiteralSmartString(Ctx, stringValue); + if (!StoreString(value, family.Data, Ctx)) { + Ctx.Error() << to_upper(id.Name) << " value should be a string literal"; + return false; + } } else if (to_lower(id.Name) == "compression") { - const TString stringValue(Ctx.Token(value.GetAlt_family_setting_value1().GetToken1())); - family.Compression = BuildLiteralSmartString(Ctx, stringValue); + if (!StoreString(value, family.Compression, Ctx)) { + Ctx.Error() << to_upper(id.Name) << " value should be a string literal"; + return false; + } } else if (to_lower(id.Name) == "compression_level") { - family.CompressionLevel = LiteralNumber(Ctx, value.GetAlt_family_setting_value2().GetRule_integer1()); + if (!StoreInt(value, family.CompressionLevel, Ctx)) { + Ctx.Error() << to_upper(id.Name) << " value should be an integer"; + return false; + } } else { Ctx.Error() << "Unknown table setting: " << id.Name; return false; @@ -4466,7 +4508,7 @@ TNodePtr TSqlTranslation::DoStatement(const TRule_do_stmt& stmt, bool makeLambda TBlocks innerBlocks; const bool hasValidBody = DefineActionOrSubqueryBody(query, innerBlocks, body); - auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped) : nullptr; + auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped, Ctx.SeqMode) : nullptr; WarnUnusedNodes(); Ctx.ScopeLevel--; Ctx.Scoped = saveScoped; @@ -4579,7 +4621,7 @@ bool TSqlTranslation::DefineActionOrSubqueryStatement(const TRule_define_action_ return false; } - auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped) : nullptr; + auto ret = hasValidBody ? BuildQuery(Ctx.Pos(), innerBlocks, false, Ctx.Scoped, Ctx.SeqMode) : nullptr; WarnUnusedNodes(); Ctx.Scoped = saveScoped; Ctx.ScopeLevel--; diff --git a/yql/essentials/sql/v1/sql_translation.h b/yql/essentials/sql/v1/sql_translation.h index 683647f16b..325640d74a 100644 --- a/yql/essentials/sql/v1/sql_translation.h +++ b/yql/essentials/sql/v1/sql_translation.h @@ -287,6 +287,9 @@ protected: TNodePtr LiteralNumber(TContext& ctx, const TRule_integer& node); +bool StoreString(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx); +bool StoreInt(const TRule_family_setting_value& from, TNodePtr& to, TContext& ctx); + template<typename TChar> struct TPatternComponent { TBasicString<TChar> Prefix; diff --git a/yql/essentials/sql/v1/sql_ut.cpp b/yql/essentials/sql/v1/sql_ut.cpp index a4251890a7..65ec39af2c 100644 --- a/yql/essentials/sql/v1/sql_ut.cpp +++ b/yql/essentials/sql/v1/sql_ut.cpp @@ -7081,7 +7081,9 @@ Y_UNIT_TEST_SUITE(BackupCollection) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"local")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag" (String '"test"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('entries '()))#"); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'create")); } }; @@ -7105,9 +7107,10 @@ Y_UNIT_TEST_SUITE(BackupCollection) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"local")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag" (String '"test"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('entries '('('('type 'database)))))#"); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'create")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'('type 'database)")); } }; @@ -7133,10 +7136,10 @@ Y_UNIT_TEST_SUITE(BackupCollection) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"local")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag" (String '"test"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('entries '('('('type 'table) '('path '"someTable")) '('('type 'table) '('path '"prefix/anotherTable")))))#"); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'create")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('('('type 'table) '('path '"someTable")))#")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('('('type 'table) '('path '"prefix/anotherTable")))#")); } }; @@ -7192,7 +7195,8 @@ Y_UNIT_TEST_SUITE(BackupCollection) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); UNIT_ASSERT_STRING_CONTAINS(line, R"#(('mode 'alter))#"); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('settings '('('"storage" '"remote") '('"tag1" '"123"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"remote")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag1" (String '"123"))))#"); UNIT_ASSERT_STRING_CONTAINS(line, R"#('('resetSettings '('"tag2" '"tag3")))#"); } }; @@ -7393,7 +7397,7 @@ Y_UNIT_TEST_SUITE(Backup) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("'incremental")); + UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("'Incremental")); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'backup")); } }; @@ -7414,8 +7418,7 @@ Y_UNIT_TEST_SUITE(Backup) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'incremental")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'backup")); + UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'backupIncremental")); } }; @@ -7470,7 +7473,7 @@ Y_UNIT_TEST_SUITE(Restore) { } Y_UNIT_TEST_SUITE(ColumnFamily) { - Y_UNIT_TEST(CompressionLevel) { + Y_UNIT_TEST(CompressionLevelCorrectUsage) { NYql::TAstParseResult res = SqlToYql(R"( use plato; CREATE TABLE tableName ( Key Uint32 FAMILY default, @@ -7503,4 +7506,89 @@ Y_UNIT_TEST_SUITE(ColumnFamily) { UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]); UNIT_ASSERT_VALUES_EQUAL(2, elementStat["compression_level"]); } + + Y_UNIT_TEST(FieldDataIsNotString) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + CREATE TABLE tableName ( + Key Uint32 FAMILY default, + PRIMARY KEY (Key), + FAMILY default ( + DATA = 1, + COMPRESSION = "lz4", + COMPRESSION_LEVEL = 5 + ) + ); + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "DATA value should be a string literal"); + } + + Y_UNIT_TEST(FieldCompressionIsNotString) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + CREATE TABLE tableName ( + Key Uint32 FAMILY default, + PRIMARY KEY (Key), + FAMILY default ( + DATA = "test", + COMPRESSION = 2, + COMPRESSION_LEVEL = 5 + ), + ); + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "COMPRESSION value should be a string literal"); + } + + Y_UNIT_TEST(FieldCompressionLevelIsNotInteger) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + CREATE TABLE tableName ( + Key Uint32 FAMILY default, + PRIMARY KEY (Key), + FAMILY default ( + DATA = "test", + COMPRESSION = "lz4", + COMPRESSION_LEVEL = "5" + ) + ); + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "COMPRESSION_LEVEL value should be an integer"); + } + + Y_UNIT_TEST(AlterCompressionCorrectUsage) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION "lz4"; + )"); + UNIT_ASSERT(res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 0); + } + + Y_UNIT_TEST(AlterCompressionFieldIsNotString) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION lz4; + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "Unexpected token 'lz4' : cannot match to any predicted input"); + } + + Y_UNIT_TEST(AlterCompressionLevelCorrectUsage) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION_LEVEL 5; + )"); + UNIT_ASSERT(res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 0); + } + + Y_UNIT_TEST(AlterCompressionLevelFieldIsNotInteger) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION_LEVEL "5"; + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "COMPRESSION_LEVEL value should be an integer"); + } } diff --git a/yql/essentials/sql/v1/sql_ut_antlr4.cpp b/yql/essentials/sql/v1/sql_ut_antlr4.cpp index 29a306cddf..e2a05cc229 100644 --- a/yql/essentials/sql/v1/sql_ut_antlr4.cpp +++ b/yql/essentials/sql/v1/sql_ut_antlr4.cpp @@ -7078,7 +7078,9 @@ Y_UNIT_TEST_SUITE(BackupCollection) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"local")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag" (String '"test"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('entries '()))#"); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'create")); } }; @@ -7102,9 +7104,10 @@ Y_UNIT_TEST_SUITE(BackupCollection) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"local")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag" (String '"test"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('entries '('('('type 'database)))))#"); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'create")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'('type 'database)")); } }; @@ -7130,10 +7133,10 @@ Y_UNIT_TEST_SUITE(BackupCollection) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('('"storage" '"local") '('"tag" '"test"))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"local")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag" (String '"test"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('entries '('('('type 'table) '('path '"someTable")) '('('type 'table) '('path '"prefix/anotherTable")))))#"); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'create")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('('('type 'table) '('path '"someTable")))#")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('('('type 'table) '('path '"prefix/anotherTable")))#")); } }; @@ -7189,7 +7192,8 @@ Y_UNIT_TEST_SUITE(BackupCollection) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); UNIT_ASSERT_STRING_CONTAINS(line, R"#(('mode 'alter))#"); - UNIT_ASSERT_STRING_CONTAINS(line, R"#('('settings '('('"storage" '"remote") '('"tag1" '"123"))))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"storage" (String '"remote")))#"); + UNIT_ASSERT_STRING_CONTAINS(line, R"#(('"tag1" (String '"123"))))#"); UNIT_ASSERT_STRING_CONTAINS(line, R"#('('resetSettings '('"tag2" '"tag3")))#"); } }; @@ -7365,7 +7369,7 @@ Y_UNIT_TEST_SUITE(Backup) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("'incremental")); + UNIT_ASSERT_VALUES_EQUAL(TString::npos, line.find("'Incremental")); UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'backup")); } }; @@ -7386,8 +7390,7 @@ Y_UNIT_TEST_SUITE(Backup) { TVerifyLineFunc verifyLine = [](const TString& word, const TString& line) { if (word == "Write") { UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find(R"#('"TestCollection")#")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'incremental")); - UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'backup")); + UNIT_ASSERT_VALUES_UNEQUAL(TString::npos, line.find("'backupIncremental")); } }; @@ -7442,7 +7445,7 @@ Y_UNIT_TEST_SUITE(Restore) { } Y_UNIT_TEST_SUITE(ColumnFamily) { - Y_UNIT_TEST(CompressionLevel) { + Y_UNIT_TEST(CompressionLevelCorrectUsage) { NYql::TAstParseResult res = SqlToYql(R"( use plato; CREATE TABLE tableName ( Key Uint32 FAMILY default, @@ -7475,4 +7478,89 @@ Y_UNIT_TEST_SUITE(ColumnFamily) { UNIT_ASSERT_VALUES_EQUAL(1, elementStat["Write"]); UNIT_ASSERT_VALUES_EQUAL(2, elementStat["compression_level"]); } + + Y_UNIT_TEST(FieldDataIsNotString) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + CREATE TABLE tableName ( + Key Uint32 FAMILY default, + PRIMARY KEY (Key), + FAMILY default ( + DATA = 1, + COMPRESSION = "lz4", + COMPRESSION_LEVEL = 5 + ) + ); + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "DATA value should be a string literal"); + } + + Y_UNIT_TEST(FieldCompressionIsNotString) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + CREATE TABLE tableName ( + Key Uint32 FAMILY default, + PRIMARY KEY (Key), + FAMILY default ( + DATA = "test", + COMPRESSION = 2, + COMPRESSION_LEVEL = 5 + ), + ); + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "COMPRESSION value should be a string literal"); + } + + Y_UNIT_TEST(FieldCompressionLevelIsNotInteger) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + CREATE TABLE tableName ( + Key Uint32 FAMILY default, + PRIMARY KEY (Key), + FAMILY default ( + DATA = "test", + COMPRESSION = "lz4", + COMPRESSION_LEVEL = "5" + ) + ); + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "COMPRESSION_LEVEL value should be an integer"); + } + + Y_UNIT_TEST(AlterCompressionCorrectUsage) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION "lz4"; + )"); + UNIT_ASSERT(res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 0); + } + + Y_UNIT_TEST(AlterCompressionFieldIsNotString) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION lz4; + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "mismatched input 'lz4' expecting {STRING_VALUE, DIGITS, INTEGER_VALUE}"); + } + + Y_UNIT_TEST(AlterCompressionLevelCorrectUsage) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION_LEVEL 5; + )"); + UNIT_ASSERT(res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 0); + } + + Y_UNIT_TEST(AlterCompressionLevelFieldIsNotInteger) { + NYql::TAstParseResult res = SqlToYql(R"( use plato; + ALTER TABLE tableName ALTER FAMILY default SET COMPRESSION_LEVEL "5"; + )"); + UNIT_ASSERT(!res.IsOk()); + UNIT_ASSERT(res.Issues.Size() == 1); + UNIT_ASSERT_STRING_CONTAINS(res.Issues.ToString(), "COMPRESSION_LEVEL value should be an integer"); + } } |