diff options
19 files changed, 439 insertions, 371 deletions
diff --git a/yql/essentials/core/type_ann/type_ann_core.cpp b/yql/essentials/core/type_ann/type_ann_core.cpp index 1b1f95c254..fdba180472 100644 --- a/yql/essentials/core/type_ann/type_ann_core.cpp +++ b/yql/essentials/core/type_ann/type_ann_core.cpp @@ -13018,7 +13018,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot> Functions["NextValue"] = &NextValueWrapper; Functions["MatchRecognize"] = &MatchRecognizeWrapper; - Functions["MatchRecognizeMeasuresAggregates"] = &MatchRecognizeMeasuresAggregatesWrapper; + Functions["MatchRecognizeMeasuresCallables"] = &MatchRecognizeMeasuresCallablesWrapper; + Functions["MatchRecognizeMeasuresCallable"] = &MatchRecognizeMeasuresCallableWrapper; Functions["MatchRecognizeParams"] = &MatchRecognizeParamsWrapper; Functions["MatchRecognizeMeasures"] = &MatchRecognizeMeasuresWrapper; Functions["MatchRecognizePattern"] = &MatchRecognizePatternWrapper; diff --git a/yql/essentials/core/type_ann/type_ann_match_recognize.cpp b/yql/essentials/core/type_ann/type_ann_match_recognize.cpp index 696435cd31..120b83ee4e 100644 --- a/yql/essentials/core/type_ann/type_ann_match_recognize.cpp +++ b/yql/essentials/core/type_ann/type_ann_match_recognize.cpp @@ -1,10 +1,13 @@ #include "type_ann_match_recognize.h" +#include <yql/essentials/core/expr_nodes/yql_expr_nodes.h> #include <yql/essentials/core/sql_types/match_recognize.h> #include <yql/essentials/core/yql_match_recognize.h> namespace NYql::NTypeAnnImpl { +using namespace NNodes; + namespace { const TStructExprType* GetMatchedRowsRangesType(const TExprNode::TPtr& patternVars, TContext &ctx) { @@ -72,15 +75,14 @@ IGraphTransformer::TStatus MatchRecognizeWrapper(const TExprNode::TPtr& input, T return IGraphTransformer::TStatus::Ok; } -IGraphTransformer::TStatus MatchRecognizeMeasuresAggregatesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) { - if (!EnsureMinArgsCount(*input, 4, ctx.Expr)) { +IGraphTransformer::TStatus MatchRecognizeMeasuresCallablesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) { + if (!EnsureArgsCount(*input, 4, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } const auto inputRowType = input->Child(0); const auto patternVars = input->Child(1); const auto names = input->Child(2); - const auto vars = input->Child(3); - constexpr size_t FirstLambdaIndex = 4; + const auto callablesItems = input->Child(3); if (!EnsureType(*inputRowType, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -91,42 +93,85 @@ IGraphTransformer::TStatus MatchRecognizeMeasuresAggregatesWrapper(const TExprNo if (!EnsureTupleOfAtoms(*names, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } - if (!EnsureTupleOfAtoms(*vars, ctx.Expr)) { + if (!EnsureTupleSize(*callablesItems, names->ChildrenSize(), ctx.Expr)) { return IGraphTransformer::TStatus::Error; } - if (!EnsureArgsCount(*vars, names->ChildrenSize(), ctx.Expr)) { + + TVector<const TItemExprType*> items; + for (size_t i = 0; i < callablesItems->ChildrenSize(); ++i) { + const auto name = names->Child(i)->Content(); + const auto type = callablesItems->Child(i)->GetTypeAnn(); + items.push_back(ctx.Expr.MakeType<TItemExprType>(name, type)); + } + input->SetTypeAnn(ctx.Expr.MakeType<TStructExprType>(items)); + return IGraphTransformer::TStatus::Ok; +} + +IGraphTransformer::TStatus MatchRecognizeMeasuresCallableWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) { + if (!EnsureArgsCount(*input, 3, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } - if (!EnsureArgsCount(*input, FirstLambdaIndex + names->ChildrenSize(), ctx.Expr)) { + auto& lambda = input->ChildRef(0); + const auto vars = input->Child(1); + const auto aggregates = input->Child(2); + + if (!EnsureTuple(*aggregates, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + if (!EnsureTupleOfAtoms(*vars, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + if (!EnsureTupleSize(*aggregates, vars->ChildrenSize(), ctx.Expr)) { return IGraphTransformer::TStatus::Error; } TVector<const TItemExprType*> items; - for (size_t i = 0; i < names->ChildrenSize(); ++i) { - auto lambda = input->Child(FirstLambdaIndex + i); - if (const auto varName = vars->Child(i)->Content()) { - const auto traits = input->Child(FirstLambdaIndex + i); - if (!EnsureTupleMinSize(*traits, 2, ctx.Expr)) { - return IGraphTransformer::TStatus::Error; - } - if (!EnsureTupleMaxSize(*traits, 3, ctx.Expr)) { - return IGraphTransformer::TStatus::Error; - } - if (!EnsureAtom(traits->Head(), ctx.Expr)) { - return IGraphTransformer::TStatus::Error; - } - lambda = traits->Child(1)->Child(NNodes::TCoAggregationTraits::idx_FinishHandler); + for (const auto& aggregate : aggregates->Children()) { + if (!EnsureTupleMinSize(*aggregate, 2, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; } - if (auto type = lambda->GetTypeAnn()) { - if (type->GetKind() != ETypeAnnotationKind::Optional) { - type = ctx.Expr.MakeType<TOptionalExprType>(type); - } - items.push_back(ctx.Expr.MakeType<TItemExprType>(names->Child(i)->Content(), type)); - } else { - return IGraphTransformer::TStatus::Repeat; + if (!EnsureTupleMaxSize(*aggregate, 3, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + const auto key = aggregate->Child(0); + if (!EnsureAtom(*key, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; } + + const auto traits = aggregate->Child(1); + if (!traits->IsCallable(TCoAggregationTraits::CallableName())) { + ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(aggregate->Pos()), TStringBuilder() + << "Expected AggregationTraits, but got: " << aggregate->Content())); + return IGraphTransformer::TStatus::Error; + } + + if (aggregate->ChildrenSize() == 3 && !EnsureAtom(*aggregate->Child(2), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + + auto finishType = traits->Child(TCoAggregationTraits::idx_DefVal)->IsCallable("Null") + ? traits->Child(TCoAggregationTraits::idx_FinishHandler)->GetTypeAnn() + : traits->Child(TCoAggregationTraits::idx_DefVal)->GetTypeAnn(); + if (!finishType->IsOptionalOrNull()) { + finishType = ctx.Expr.MakeType<TOptionalExprType>(finishType); + } + items.push_back(ctx.Expr.MakeType<TItemExprType>(key->Content(), finishType)); } - input->SetTypeAnn(ctx.Expr.MakeType<TStructExprType>(items)); + const auto status = ConvertToLambda(lambda, ctx.Expr, 1, 1); + if (status != IGraphTransformer::TStatus::Ok) { + return status; + } + if (!UpdateLambdaAllArgumentsTypes(lambda, {ctx.Expr.MakeType<TStructExprType>(items)}, ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + if (!lambda->GetTypeAnn()) { + return IGraphTransformer::TStatus::Repeat; + } + if (!EnsureComputableType(lambda->Pos(), *lambda->GetTypeAnn(), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + input->SetTypeAnn(lambda->GetTypeAnn()); return IGraphTransformer::TStatus::Ok; } @@ -140,13 +185,13 @@ IGraphTransformer::TStatus MatchRecognizeParamsWrapper(const TExprNode::TPtr& in } IGraphTransformer::TStatus MatchRecognizeMeasuresWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) { - if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) { + constexpr size_t FirstLambdaIndex = 3; + if (!EnsureMinArgsCount(*input, FirstLambdaIndex, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } const auto inputRowType = input->Child(0); const auto patternVars = input->Child(1); const auto names = input->Child(2); - constexpr size_t FirstLambdaIndex = 3; if (!EnsureType(*inputRowType, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -190,11 +235,13 @@ IGraphTransformer::TStatus MatchRecognizeMeasuresWrapper(const TExprNode::TPtr& ctx.Expr)) { return IGraphTransformer::TStatus::Error; } - if (auto type = lambda->GetTypeAnn()) { - items.push_back(ctx.Expr.MakeType<TItemExprType>(names->Child(i)->Content(), type)); - } else { + if (!lambda->GetTypeAnn()) { return IGraphTransformer::TStatus::Repeat; } + if (!EnsureComputableType(lambda->Pos(), *lambda->GetTypeAnn(), ctx.Expr)) { + return IGraphTransformer::TStatus::Error; + } + items.push_back(ctx.Expr.MakeType<TItemExprType>(names->Child(i)->Content(), lambda->GetTypeAnn())); } input->SetTypeAnn(ctx.Expr.MakeType<TStructExprType>(items)); return IGraphTransformer::TStatus::Ok; @@ -206,13 +253,13 @@ IGraphTransformer::TStatus MatchRecognizePatternWrapper(const TExprNode::TPtr& i } IGraphTransformer::TStatus MatchRecognizeDefinesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext &ctx) { - if (!EnsureMinArgsCount(*input, 3, ctx.Expr)) { + constexpr size_t FirstLambdaIndex = 3; + if (!EnsureMinArgsCount(*input, FirstLambdaIndex, ctx.Expr)) { return IGraphTransformer::TStatus::Error; } const auto inputRowType = input->Child(0); const auto patternVars = input->Child(1); const auto names = input->Child(2); - constexpr size_t FirstLambdaIndex = 3; if (!EnsureType(*inputRowType, ctx.Expr)) { return IGraphTransformer::TStatus::Error; @@ -246,16 +293,14 @@ IGraphTransformer::TStatus MatchRecognizeDefinesWrapper(const TExprNode::TPtr& i ctx.Expr)) { return IGraphTransformer::TStatus::Error; } - if (auto type = lambda->GetTypeAnn()) { - if (IsBoolLike(*type)) { - items.push_back(ctx.Expr.MakeType<TItemExprType>(names->Child(i)->Content(), type)); - } else { - ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), "DEFINE expression must be a predicate")); - return IGraphTransformer::TStatus::Error; - } - } else { + if (!lambda->GetTypeAnn()) { return IGraphTransformer::TStatus::Repeat; } + if (!IsBoolLike(*lambda->GetTypeAnn())) { + ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(lambda->Pos()), "DEFINE expression must be a predicate")); + return IGraphTransformer::TStatus::Error; + } + items.push_back(ctx.Expr.MakeType<TItemExprType>(names->Child(i)->Content(), lambda->GetTypeAnn())); } input->SetTypeAnn(ctx.Expr.MakeType<TStructExprType>(items)); return IGraphTransformer::TStatus::Ok; diff --git a/yql/essentials/core/type_ann/type_ann_match_recognize.h b/yql/essentials/core/type_ann/type_ann_match_recognize.h index d21b7f36b4..409a5876fd 100644 --- a/yql/essentials/core/type_ann/type_ann_match_recognize.h +++ b/yql/essentials/core/type_ann/type_ann_match_recognize.h @@ -8,7 +8,8 @@ namespace NYql::NTypeAnnImpl { IGraphTransformer::TStatus MatchRecognizeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); -IGraphTransformer::TStatus MatchRecognizeMeasuresAggregatesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); +IGraphTransformer::TStatus MatchRecognizeMeasuresCallablesWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); +IGraphTransformer::TStatus MatchRecognizeMeasuresCallableWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); IGraphTransformer::TStatus MatchRecognizeParamsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); IGraphTransformer::TStatus MatchRecognizeMeasuresWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); IGraphTransformer::TStatus MatchRecognizePatternWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx); diff --git a/yql/essentials/core/yql_opt_match_recognize.cpp b/yql/essentials/core/yql_opt_match_recognize.cpp index 30544f8333..4b6f6c7a80 100644 --- a/yql/essentials/core/yql_opt_match_recognize.cpp +++ b/yql/essentials/core/yql_opt_match_recognize.cpp @@ -32,95 +32,88 @@ bool IsStreaming(const TExprNode::TPtr& input, const TTypeAnnotationContext& typ } } -TExprNode::TPtr ExpandMatchRecognizeMeasuresAggregates(const TExprNode::TPtr& node, TExprContext& ctx, TTypeAnnotationContext& /* typeAnnCtx */) { - const auto pos = node->Pos(); - const auto vars = node->Child(3); - static constexpr size_t AggregatesLambdasStartPos = 4; +TExprNode::TPtr ExpandMatchRecognizeMeasuresCallables(const TExprNode::TPtr& node, TExprContext& ctx, TTypeAnnotationContext& /* typeAnnCtx */) { + YQL_CLOG(DEBUG, Core) << "Expand " << node->Content(); static constexpr size_t MeasuresLambdasStartPos = 3; - - return ctx.Builder(pos) + return ctx.Builder(node->Pos()) .Callable("MatchRecognizeMeasures") .Add(0, node->ChildPtr(0)) .Add(1, node->ChildPtr(1)) .Add(2, node->ChildPtr(2)) .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& { - for (size_t i = 0; i < vars->ChildrenSize(); ++i) { - const auto var = vars->Child(i)->Content(); - const auto handler = node->ChildPtr(AggregatesLambdasStartPos + i); - if (!var) { - auto value = handler->GetTypeAnn()->GetKind() != ETypeAnnotationKind::Optional - ? ctx.Builder(pos).Callable("Just").Add(0, handler).Seal().Build() - : handler; - parent.Add( - MeasuresLambdasStartPos + i, - ctx.Builder(pos) - .Lambda() - .Param("data") - .Param("vars") - .Add(0, std::move(value)) - .Seal() - .Build() - ); - continue; - } - parent.Add( - MeasuresLambdasStartPos + i, - ctx.Builder(pos) - .Lambda() - .Param("data") - .Param("vars") - .Callable(0, "Member") - .Callable(0, "Head") - .Callable(0, "Aggregate") - .Callable(0, "OrderedMap") - .Callable(0, "OrderedFlatMap") - .Callable(0, "Member") - .Arg(0, "vars") - .Atom(1, var) - .Seal() - .Lambda(1) - .Param("item") - .Callable(0, "ListFromRange") - .Callable(0, "Member") - .Arg(0, "item") - .Atom(1, "From") - .Seal() - .Callable(1, "+MayWarn") - .Callable(0, "Member") - .Arg(0, "item") - .Atom(1, "To") + const auto aggregatesItems = node->Child(3); + for (size_t i = 0; i < aggregatesItems->ChildrenSize(); ++i) { + const auto item = aggregatesItems->Child(i); + auto lambda = item->ChildPtr(0); + const auto vars = item->Child(1); + const auto aggregates = item->Child(2); + parent.Lambda(MeasuresLambdasStartPos + i, lambda->Pos()) + .Param("data") + .Param("vars") + .Apply(std::move(lambda)) + .With(0) + .Callable("FlattenMembers") + .Do([&](TExprNodeBuilder& parent) -> TExprNodeBuilder& { + for (size_t i = 0; i < aggregates->ChildrenSize(); ++i) { + const auto var = vars->Child(i)->Content(); + auto aggregate = aggregates->Child(i); + parent + .List(i) + .Atom(0, "") + .Callable(1, "Head") + .Callable(0, "Aggregate") + .Callable(0, "OrderedMap") + .Callable(0, "OrderedFlatMap") + .Callable(0, "Member") + .Arg(0, "vars") + .Atom(1, var) + .Seal() + .Lambda(1) + .Param("item") + .Callable(0, "ListFromRange") + .Callable(0, "Member") + .Arg(0, "item") + .Atom(1, "From") + .Seal() + .Callable(1, "+MayWarn") + .Callable(0, "Member") + .Arg(0, "item") + .Atom(1, "To") + .Seal() + .Callable(1, "Uint64") + .Atom(0, "1") + .Seal() + .Seal() + .Seal() + .Seal() .Seal() - .Callable(1, "Uint64") - .Atom(0, "1") + .Lambda(1) + .Param("index") + .Callable(0, "Unwrap") + .Callable(0, "Lookup") + .Callable(0, "ToIndexDict") + .Arg(0, "data") + .Seal() + .Arg(1, "index") + .Seal() + .Seal() .Seal() .Seal() - .Seal() - .Seal() - .Seal() - .Lambda(1) - .Param("index") - .Callable(0, "Unwrap") - .Callable(0, "Lookup") - .Callable(0, "ToIndexDict") - .Arg(0, "data") + .List(1).Seal() + .List(2) + .Add(0, std::move(aggregate)) .Seal() - .Arg(1, "index") + .List(3).Seal() .Seal() .Seal() - .Seal() - .Seal() - .List(1).Seal() - .List(2) - .Add(0, handler) - .Seal() - .List(3).Seal() - .Seal() - .Seal() - .Atom(1, handler->Child(0)->Content()) + .Seal(); + } + return parent; + }) .Seal() - .Seal() - .Build() - ); + .Done() + .Seal() + .Seal(); } return parent; }) @@ -128,13 +121,16 @@ TExprNode::TPtr ExpandMatchRecognizeMeasuresAggregates(const TExprNode::TPtr& no .Build(); } -THashSet<TStringBuf> FindUsedVars(const TExprNode::TPtr& params) { - THashSet<TStringBuf> result; +std::unordered_set<std::string_view> FindUsedVars(const TExprNode::TPtr& params) { + std::unordered_set<std::string_view> result; const auto measures = params->Child(0); - const auto measuresVars = measures->Child(3); - for (const auto& var : measuresVars->Children()) { - result.insert(var->Content()); + const auto callablesItems = measures->Child(3); + for (const auto& item : callablesItems->Children()) { + const auto vars = item->Child(1); + for (const auto& var : vars->Children()) { + result.insert(var->Content()); + } } const auto defines = params->Child(4); @@ -159,7 +155,7 @@ THashSet<TStringBuf> FindUsedVars(const TExprNode::TPtr& params) { return result; } -TExprNode::TPtr MarkUnusedPatternVars(const TExprNode::TPtr& node, TExprContext& ctx, const THashSet<TStringBuf>& usedVars, const TExprNode::TPtr& rowsPerMatch) { +TExprNode::TPtr MarkUnusedPatternVars(const TExprNode::TPtr& node, TExprContext& ctx, const std::unordered_set<std::string_view>& usedVars, const TExprNode::TPtr& rowsPerMatch) { const auto pos = node->Pos(); if (node->ChildrenSize() == 6 && node->Child(0)->IsAtom()) { const auto varName = node->Child(0)->Content(); @@ -262,7 +258,7 @@ TExprNode::TPtr ExpandMatchRecognize(const TExprNode::TPtr& node, TExprContext& return {}; } - auto measures = ExpandMatchRecognizeMeasuresAggregates(params->ChildPtr(0), ctx, typeAnnCtx); + auto measures = ExpandMatchRecognizeMeasuresCallables(params->ChildPtr(0), ctx, typeAnnCtx); auto rowsPerMatch = params->ChildPtr(1); const auto usedVars = FindUsedVars(params); auto pattern = MarkUnusedPatternVars(params->ChildPtr(3), ctx, usedVars, rowsPerMatch); diff --git a/yql/essentials/sql/v1/context.h b/yql/essentials/sql/v1/context.h index 1c7ef9ae82..c0f45e8fa9 100644 --- a/yql/essentials/sql/v1/context.h +++ b/yql/essentials/sql/v1/context.h @@ -236,6 +236,14 @@ namespace NSQLTranslationV1 { return true; } + [[nodiscard]] auto& GetMatchRecognizeAggregations() { + YQL_ENSURE(EColumnRefState::MatchRecognizeMeasures == ColumnReferenceState + || EColumnRefState::MatchRecognizeDefine == ColumnReferenceState + || EColumnRefState::MatchRecognizeDefineAggregate == ColumnReferenceState, + "MATCH_RECOGNIZE Var can only be accessed within processing of MATCH_RECOGNIZE lambdas"); + return MatchRecognizeAggregations; + } + TVector<NSQLTranslation::TSQLHint> PullHintForToken(NYql::TPosition tokenPos); void WarnUnusedHints(); @@ -258,6 +266,11 @@ namespace NSQLTranslationV1 { EColumnRefState TopLevelColumnReferenceState = EColumnRefState::Deny; TString MatchRecognizeDefineVar; TString MatchRecognizeAggrVar; + struct TMatchRecognizeAggregation { + TString Var; + TAggregationPtr Aggr; + }; + TVector<TMatchRecognizeAggregation> MatchRecognizeAggregations; TString NoColumnErrorContext = "in current scope"; TVector<TBlocks*> CurrentBlocks; diff --git a/yql/essentials/sql/v1/match_recognize.cpp b/yql/essentials/sql/v1/match_recognize.cpp index be2f508e87..6a0af3893a 100644 --- a/yql/essentials/sql/v1/match_recognize.cpp +++ b/yql/essentials/sql/v1/match_recognize.cpp @@ -50,13 +50,14 @@ public: BuildLookup("index"); break; default: - Y_ABORT("Unexpected column reference state"); + ctx.Error(Pos) << "Unexpected column reference state"; + return false; } return true; } TNodePtr DoClone() const override { - return new TMatchRecognizeColumnAccessNode(Pos, Var, Column); + return MakeIntrusive<TMatchRecognizeColumnAccessNode>(Pos, Var, Column); } private: @@ -89,14 +90,17 @@ public: } bool DoInit(TContext& ctx, ISource* src) override { - Y_DEBUG_ABORT_UNLESS(ctx.GetColumnReferenceState() == EColumnRefState::MatchRecognizeDefine); + if (EColumnRefState::MatchRecognizeDefine != ctx.GetColumnReferenceState()) { + ctx.Error(Pos) << "Unexpected column reference state"; + return false; + } TColumnRefScope scope(ctx, EColumnRefState::MatchRecognizeDefineAggregate, false, ctx.GetMatchRecognizeDefineVar()); if (Args.size() != 1) { ctx.Error() << "Exactly one argument is required in MATCH_RECOGNIZE navigation function"; return false; } const auto arg = Args[0]; - if (!arg->Init(ctx, src)) { + if (!arg || !arg->Init(ctx, src)) { return false; } @@ -118,7 +122,7 @@ public: } TNodePtr DoClone() const override { - return new TMatchRecognizeDefineAggregate(Pos, Name, Args); + return MakeIntrusive<TMatchRecognizeDefineAggregate>(Pos, Name, Args); } private: @@ -128,47 +132,42 @@ private: class TMatchRecognizeVarAccessNode final : public INode { public: - TMatchRecognizeVarAccessNode(TPosition pos, TNodePtr arg) + TMatchRecognizeVarAccessNode(TPosition pos, TNodePtr aggr) : INode(pos) - , Arg(std::move(arg)) { - } - - [[nodiscard]] const TString& GetVar() const noexcept { - return Var; - } - - TAggregationPtr GetAggregation() const override { - return Arg->GetAggregation(); + , Aggr(std::move(aggr)) { } bool DoInit(TContext& ctx, ISource* src) override { - if (!Arg->Init(ctx, src)) { + if (!Aggr || !Aggr->Init(ctx, src)) { return false; } - Var = ctx.ExtractMatchRecognizeAggrVar(); + auto var = ctx.ExtractMatchRecognizeAggrVar(); Expr = [&]() -> TNodePtr { switch (ctx.GetColumnReferenceState()) { - case EColumnRefState::MatchRecognizeMeasures: - return Arg; + case EColumnRefState::MatchRecognizeMeasures: { + ctx.GetMatchRecognizeAggregations().emplace_back(std::move(var), Aggr->GetAggregation()); + return Aggr; + } case EColumnRefState::MatchRecognizeDefine: return Y( "Apply", - BuildLambda(Pos, Y("item"), Arg), + BuildLambda(Pos, Y("item"), Aggr), Y( "Member", BuildAtom(ctx.Pos(), VarMatchedVarsName), - Q(Var) + Q(std::move(var)) ) ); default: - Y_ABORT("Unexpected column reference state"); + ctx.Error(Pos) << "Unexpected column reference state"; + return {}; } }(); - return Expr->Init(ctx, src); + return Expr && Expr->Init(ctx, src); } TNodePtr DoClone() const override { - return new TMatchRecognizeVarAccessNode(Pos, Arg); + return MakeIntrusive<TMatchRecognizeVarAccessNode>(Pos, Aggr); } TAstNode* Translate(TContext& ctx) const override { @@ -176,8 +175,7 @@ public: } private: - TString Var; - TNodePtr Arg; + TNodePtr Aggr; TNodePtr Expr; }; @@ -214,76 +212,81 @@ private: bool DoInit(TContext& ctx, ISource* src) override { auto inputRowType = Y("ListItemType", Y("TypeOf", Label)); - if (!PartitionKeySelector->Init(ctx, src)) { + if (!PartitionKeySelector || !PartitionKeySelector->Init(ctx, src)) { return false; } - if (!PartitionColumns->Init(ctx, src)) { + if (!PartitionColumns || !PartitionColumns->Init(ctx, src)) { return false; } const auto sortTraits = SortSpecs.empty() ? Y("Void") : src->BuildSortSpec(SortSpecs, Label, true, false); - if (!sortTraits->Init(ctx, src)) { + if (!sortTraits || !sortTraits->Init(ctx, src)) { return false; } auto measureNames = Y(); - for (const auto& m: Measures) { - measureNames->Add(BuildQuotedAtom(m.Callable->GetPos(), m.Name)); - } - auto measureVars = Y(); - for (const auto& m: Measures) { + auto measuresCallables = Y(); + for (auto& m: Measures) { TColumnRefScope scope(ctx, EColumnRefState::MatchRecognizeMeasures); - if (!m.Callable->Init(ctx, src)) { + if (!m.Callable || !m.Callable->Init(ctx, src)) { return false; } - const auto varAccess = dynamic_cast<TMatchRecognizeVarAccessNode*>(m.Callable.Get()); - auto var = varAccess ? varAccess->GetVar() : ""; - measureVars->Add(BuildQuotedAtom(m.Callable->GetPos(), std::move(var))); - } - auto measuresNode = Y("MatchRecognizeMeasuresAggregates", inputRowType, Q(PatternVars), Q(measureNames), Q(measureVars)); - for (const auto& m: Measures) { - auto aggr = m.Callable->GetAggregation(); - if (!aggr) { - // TODO(YQL-16508): support aggregations inside expressions - // ctx.Error(m.Callable->GetPos()) << "Cannot use aggregations inside expression"; - // return false; - measuresNode->Add(m.Callable); - } else { - const auto [traits, result] = aggr->AggregationTraits(Y("TypeOf", Label), false, false, false, ctx); + const auto pos = m.Callable->GetPos(); + measureNames = L(measureNames, BuildQuotedAtom(m.Callable->GetPos(), std::move(m.Name))); + auto measuresVars = Y(); + auto measuresAggregates = Y(); + for (auto& [var, aggr] : ctx.GetMatchRecognizeAggregations()) { + if (!aggr) { + return false; + } + auto [traits, result] = aggr->AggregationTraits(Y("TypeOf", Label), false, false, false, ctx); if (!result) { return false; } - measuresNode->Add(traits); + measuresVars = L(measuresVars, BuildQuotedAtom(pos, std::move(var))); + measuresAggregates = L(measuresAggregates, std::move(traits)); } + ctx.GetMatchRecognizeAggregations().clear(); + measuresCallables = L( + measuresCallables, + Y( + "MatchRecognizeMeasuresCallable", + BuildLambda(pos, Y("row"), std::move(m.Callable)), + Q(measuresVars), + Q(measuresAggregates) + ) + ); } + auto measuresNode = Y("MatchRecognizeMeasuresCallables", inputRowType, Q(PatternVars), Q(measureNames), Q(measuresCallables)); - if (!RowsPerMatch->Init(ctx, src)) { + if (!RowsPerMatch || !RowsPerMatch->Init(ctx, src)) { return false; } - if (!SkipTo->Init(ctx, src)) { + if (!SkipTo || !SkipTo->Init(ctx, src)) { return false; } - if (!Pattern->Init(ctx, src)) { + if (!Pattern || !Pattern->Init(ctx, src)) { return false; } - if (!PatternVars->Init(ctx, src)) { + if (!PatternVars || !PatternVars->Init(ctx, src)) { return false; } auto defineNames = Y(); - for (const auto& d: Definitions) { - defineNames->Add(BuildQuotedAtom(d.Callable->GetPos(), d.Name)); + for (auto& d: Definitions) { + defineNames = L(defineNames, BuildQuotedAtom(d.Callable->GetPos(), d.Name)); } auto defineNode = Y("MatchRecognizeDefines", inputRowType, Q(PatternVars), Q(defineNames)); - for (const auto& d: Definitions) { + for (auto& d: Definitions) { TColumnRefScope scope(ctx, EColumnRefState::MatchRecognizeDefine, true, d.Name); - if (!d.Callable->Init(ctx, src)) { + if (!d.Callable || !d.Callable->Init(ctx, src)) { return false; } - defineNode->Add(BuildLambda(d.Callable->GetPos(), Y(VarDataName, VarMatchedVarsName, VarLastRowIndexName), d.Callable)); + const auto pos = d.Callable->GetPos(); + defineNode = L(defineNode, BuildLambda(pos, Y(VarDataName, VarMatchedVarsName, VarLastRowIndexName), std::move(d.Callable))); } Add( @@ -319,7 +322,7 @@ private: } TNodePtr DoClone() const override { - return new TMatchRecognize( + return MakeIntrusive<TMatchRecognize>( Pos, Label, PartitionKeySelector, @@ -352,7 +355,7 @@ private: } // anonymous namespace TNodePtr TMatchRecognizeBuilder::Build(TContext& ctx, TString label, ISource* src) { - TNodePtr node = new TMatchRecognize( + const auto node = MakeIntrusive<TMatchRecognize>( Pos, std::move(label), std::move(PartitionKeySelector), @@ -381,8 +384,8 @@ TNodePtr BuildMatchRecognizeDefineAggregate(TPosition pos, TString name, TVector return BuildMatchRecognizeVarAccess(pos, std::move(result)); } -TNodePtr BuildMatchRecognizeVarAccess(TPosition pos, TNodePtr extractor) { - return MakeIntrusive<TMatchRecognizeVarAccessNode>(pos, std::move(extractor)); +TNodePtr BuildMatchRecognizeVarAccess(TPosition pos, TNodePtr aggr) { + return MakeIntrusive<TMatchRecognizeVarAccessNode>(pos, std::move(aggr)); } } // namespace NSQLTranslationV1 diff --git a/yql/essentials/sql/v1/sql_expression.cpp b/yql/essentials/sql/v1/sql_expression.cpp index 5316737b94..9a92a7abc5 100644 --- a/yql/essentials/sql/v1/sql_expression.cpp +++ b/yql/essentials/sql/v1/sql_expression.cpp @@ -976,6 +976,10 @@ TNodePtr TSqlExpression::UnaryCasualExpr(const TUnaryCasualExprRule& node, const EColumnRefState::MatchRecognizeDefine == Ctx.GetColumnReferenceState() || EColumnRefState::MatchRecognizeDefineAggregate == Ctx.GetColumnReferenceState() )) { + if (suffix.GetBlock1().size() != 1) { + Ctx.Error() << "Expected Var.Column, but got chain of " << suffix.GetBlock1().size() << " column accesses"; + return nullptr; + } return RowPatternVarAccess(std::move(name), b.GetAlt3().GetBlock2()); } break; diff --git a/yql/essentials/sql/v1/sql_match_recognize_ut.cpp b/yql/essentials/sql/v1/sql_match_recognize_ut.cpp index f599dc6e99..2604dc17ea 100644 --- a/yql/essentials/sql/v1/sql_match_recognize_ut.cpp +++ b/yql/essentials/sql/v1/sql_match_recognize_ut.cpp @@ -1,16 +1,11 @@ #include "sql_ut.h" -#include "match_recognize.h" -#include <yql/essentials/providers/common/provider/yql_provider_names.h> + #include <yql/essentials/core/sql_types/match_recognize.h> +#include <yql/essentials/providers/common/provider/yql_provider_names.h> #include <yql/essentials/sql/sql.h> -#include <util/generic/map.h> #include <library/cpp/testing/unittest/registar.h> -#include <util/string/split.h> - -using namespace NSQLTranslation; - NYql::TAstParseResult MatchRecognizeSqlToYql(const TString& query) { TString enablingPragma = R"( pragma FeatureR010="prototype"; @@ -25,25 +20,44 @@ const NYql::TAstNode* FindMatchRecognizeParam(const NYql::TAstNode* root, TStrin return paramNode->GetChild(2); } -bool IsQuotedListOfSize(const NYql::TAstNode* node, ui32 size) { - UNIT_ASSERT(node->IsListOfSize(2)); - if (!node->IsListOfSize(2)) - return false; - UNIT_ASSERT_EQUAL(node->GetChild(0)->GetContent(), "quote"); - if (node->GetChild(0)->GetContent() != "quote") - return false; - UNIT_ASSERT_EQUAL(node->GetChild(1)->GetChildrenCount(), size); - return node->GetChild(1)->IsListOfSize(size); +std::string_view GetAtom(const NYql::TAstNode* node) { + UNIT_ASSERT(node); + UNIT_ASSERT(node->IsAtom()); + return node->GetContent(); } -bool IsLambda(const NYql::TAstNode* node, ui32 numberOfArgs) { - if (!node->IsListOfSize(3)) { - return false; - } - if (!node->GetChild(0)->IsAtom() || node->GetChild(0)->GetContent() != "lambda") { - return false; +bool IsAtom(const NYql::TAstNode* node, std::string_view value) { + UNIT_ASSERT_NO_DIFF(GetAtom(node), value); + return true; +} + +bool IsListOfSize(const NYql::TAstNode* node, ui32 size) { + UNIT_ASSERT(node); + UNIT_ASSERT(node->IsList()); + UNIT_ASSERT_EQUAL(node->GetChildrenCount(), size); + return true; +} + +template<typename Proj = std::identity> +bool IsListOfAtoms(const NYql::TAstNode* node, std::vector<std::string_view> atoms, Proj proj = {}) { + UNIT_ASSERT(IsListOfSize(node, atoms.size())); + for (ui32 i = 0; i < atoms.size(); ++i) { + const auto child = std::invoke(proj, node->GetChild(i)); + UNIT_ASSERT(IsAtom(child, atoms[i])); } - return IsQuotedListOfSize(node->GetChild(1), numberOfArgs); + return true; +} + +const NYql::TAstNode* GetQuoted(const NYql::TAstNode* node) { + UNIT_ASSERT(IsListOfSize(node, 2)); + UNIT_ASSERT(IsAtom(node->GetChild(0), "quote")); + return node->GetChild(1); +} + +bool IsLambda(const NYql::TAstNode* node, ui32 numberOfArgs) { + UNIT_ASSERT(IsListOfSize(node, 3)); + UNIT_ASSERT(IsAtom(node->GetChild(0), "lambda")); + return IsListOfSize(GetQuoted(node->GetChild(1)), numberOfArgs); } Y_UNIT_TEST_SUITE(MatchRecognize) { @@ -64,7 +78,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(minValidMatchRecognizeSql); UNIT_ASSERT(r.IsOk()); auto input = FindMatchRecognizeParam(r.Root, "input"); - UNIT_ASSERT(input->IsAtom() && input->GetContent() == "core"); + UNIT_ASSERT(IsAtom(input, "core")); } Y_UNIT_TEST(MatchRecognizeAndSample) { @@ -83,9 +97,9 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(minValidMatchRecognizeSql); UNIT_ASSERT(r.IsOk()); auto partitionKeySelector = FindMatchRecognizeParam(r.Root, "partitionKeySelector"); - UNIT_ASSERT(IsQuotedListOfSize(partitionKeySelector->GetChild(2), 0)); //empty tuple + UNIT_ASSERT(IsListOfSize(GetQuoted(partitionKeySelector->GetChild(2)), 0)); //empty tuple auto partitionColumns = FindMatchRecognizeParam(r.Root, "partitionColumns"); - UNIT_ASSERT(IsQuotedListOfSize(partitionColumns, 0)); //empty tuple + UNIT_ASSERT(IsListOfSize(GetQuoted(partitionColumns), 0)); //empty tuple } Y_UNIT_TEST(PartitionBy) { @@ -101,9 +115,9 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto partitionKeySelector = FindMatchRecognizeParam(r.Root, "partitionKeySelector"); - UNIT_ASSERT(IsQuotedListOfSize(partitionKeySelector->GetChild(2), 3)); + UNIT_ASSERT(IsListOfSize(GetQuoted(partitionKeySelector->GetChild(2)), 3)); auto partitionColumns = FindMatchRecognizeParam(r.Root, "partitionColumns"); - UNIT_ASSERT(IsQuotedListOfSize(partitionColumns, 3)); + UNIT_ASSERT(IsListOfSize(GetQuoted(partitionColumns), 3)); //TODO check partitioner lambdas(alias/no alias) } @@ -111,8 +125,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(minValidMatchRecognizeSql); UNIT_ASSERT(r.IsOk()); auto sortTraits = FindMatchRecognizeParam(r.Root, "sortTraits"); - UNIT_ASSERT(sortTraits && sortTraits->IsListOfSize(1)); - UNIT_ASSERT(sortTraits->GetChild(0)->GetContent() == "Void"); + UNIT_ASSERT(IsListOfAtoms(sortTraits, {"Void"})); } Y_UNIT_TEST(OrderBy) { @@ -128,10 +141,10 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto sortTraits = FindMatchRecognizeParam(r.Root, "sortTraits"); - UNIT_ASSERT(sortTraits && sortTraits->IsListOfSize(4)); - UNIT_ASSERT(sortTraits->GetChild(0)->GetContent() == "SortTraits"); - UNIT_ASSERT(IsQuotedListOfSize(sortTraits->GetChild(2), 3)); - UNIT_ASSERT(IsQuotedListOfSize(sortTraits->GetChild(3)->GetChild(2), 3)); + UNIT_ASSERT(IsListOfSize(sortTraits, 4)); + UNIT_ASSERT(IsAtom(sortTraits->GetChild(0), "SortTraits")); + UNIT_ASSERT(IsListOfSize(GetQuoted(sortTraits->GetChild(2)), 3)); + UNIT_ASSERT(IsListOfSize(GetQuoted(sortTraits->GetChild(3)->GetChild(2)), 3)); } Y_UNIT_TEST(Measures) { auto stmt = R"( @@ -148,13 +161,13 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); const auto measures = FindMatchRecognizeParam(r.Root, "measures"); - UNIT_ASSERT_VALUES_EQUAL(7, measures->GetChildrenCount()); - const auto columnNames = measures->GetChild(3); - UNIT_ASSERT(IsQuotedListOfSize(columnNames, 2)); - UNIT_ASSERT_VALUES_EQUAL("T", columnNames->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); - UNIT_ASSERT_VALUES_EQUAL("Key", columnNames->GetChild(1)->GetChild(1)->GetChild(1)->GetContent()); - UNIT_ASSERT(IsQuotedListOfSize(measures->GetChild(4), 2)); - UNIT_ASSERT(IsQuotedListOfSize(measures->GetChild(5), 2)); + UNIT_ASSERT(IsListOfSize(measures, 5)); + const auto patternVars = measures->GetChild(2); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(patternVars), {"Y", "Q"}, GetQuoted)); + const auto measuresNames = measures->GetChild(3); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(measuresNames), {"T", "Key"}, GetQuoted)); + const auto measuresCallables = measures->GetChild(4); + UNIT_ASSERT(IsListOfSize(GetQuoted(measuresCallables), 2)); } Y_UNIT_TEST(RowsPerMatch) { { @@ -170,7 +183,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto rowsPerMatch = FindMatchRecognizeParam(r.Root, "rowsPerMatch"); - UNIT_ASSERT_VALUES_EQUAL("RowsPerMatch_OneRow", rowsPerMatch->GetChild(1)->GetContent()); + UNIT_ASSERT(IsAtom(GetQuoted(rowsPerMatch), "RowsPerMatch_OneRow")); } { const auto stmt = R"( @@ -197,7 +210,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto rowsPerMatch = FindMatchRecognizeParam(r.Root, "rowsPerMatch"); - UNIT_ASSERT_VALUES_EQUAL("RowsPerMatch_OneRow", rowsPerMatch->GetChild(1)->GetContent()); + UNIT_ASSERT(IsAtom(GetQuoted(rowsPerMatch), "RowsPerMatch_OneRow")); } } @@ -215,7 +228,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto skipTo = FindMatchRecognizeParam(r.Root, "skipTo"); - UNIT_ASSERT_VALUES_EQUAL("AfterMatchSkip_NextRow", skipTo->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(skipTo), {"AfterMatchSkip_NextRow", ""}, GetQuoted)); } { const auto stmt = R"( @@ -230,7 +243,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto skipTo = FindMatchRecognizeParam(r.Root, "skipTo"); - UNIT_ASSERT_VALUES_EQUAL("AfterMatchSkip_PastLastRow", skipTo->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(skipTo), {"AfterMatchSkip_PastLastRow", ""}, GetQuoted)); } { const auto stmt = R"( @@ -245,8 +258,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto skipTo = FindMatchRecognizeParam(r.Root, "skipTo"); - UNIT_ASSERT_VALUES_EQUAL("AfterMatchSkip_ToFirst", skipTo->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); - UNIT_ASSERT_VALUES_EQUAL("Y", skipTo->GetChild(1)->GetChild(1)->GetChild(1)->GetContent()); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(skipTo), {"AfterMatchSkip_ToFirst", "Y"}, GetQuoted)); } { const auto stmt = R"( @@ -274,8 +286,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto skipTo = FindMatchRecognizeParam(r.Root, "skipTo"); - UNIT_ASSERT_VALUES_EQUAL("AfterMatchSkip_ToLast", skipTo->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); - UNIT_ASSERT_VALUES_EQUAL("Y", skipTo->GetChild(1)->GetChild(1)->GetChild(1)->GetContent()); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(skipTo), {"AfterMatchSkip_ToLast", "Y"}, GetQuoted)); } { const auto stmt = R"( @@ -303,8 +314,7 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); auto skipTo = FindMatchRecognizeParam(r.Root, "skipTo"); - UNIT_ASSERT_VALUES_EQUAL("AfterMatchSkip_To", skipTo->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); - UNIT_ASSERT_VALUES_EQUAL("Y", skipTo->GetChild(1)->GetChild(1)->GetChild(1)->GetContent()); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(skipTo), {"AfterMatchSkip_To", "Y"}, GetQuoted)); } { const auto stmt = R"( @@ -360,10 +370,9 @@ FROM Input MATCH_RECOGNIZE( const auto& r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); const auto& patternCallable = FindMatchRecognizeParam(r.Root, "pattern"); - UNIT_ASSERT_EQUAL(patternCallable->GetChild(0)->GetContent(), "MatchRecognizePattern"); - UNIT_ASSERT_EQUAL(patternCallable->GetChildrenCount(), 1 + 1); - const auto& term = patternCallable->GetChild(1); - UNIT_ASSERT(IsQuotedListOfSize(term, 3)); + UNIT_ASSERT(IsListOfSize(patternCallable, 1 + 1)); + UNIT_ASSERT(IsAtom(patternCallable->GetChild(0), "MatchRecognizePattern")); + UNIT_ASSERT(IsListOfSize(GetQuoted(patternCallable->GetChild(1)), 3)); } Y_UNIT_TEST(PatternMultiTerm) { @@ -378,10 +387,9 @@ FROM Input MATCH_RECOGNIZE( const auto& r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); const auto& patternCallable = FindMatchRecognizeParam(r.Root, "pattern"); - UNIT_ASSERT_EQUAL(patternCallable->GetChild(0)->GetContent(), "MatchRecognizePattern"); - UNIT_ASSERT_EQUAL(patternCallable->GetChildrenCount(), 1 + 4); - const auto& lastTerm = patternCallable->GetChild(4); - UNIT_ASSERT(IsQuotedListOfSize(lastTerm, 5)); + UNIT_ASSERT(IsListOfSize(patternCallable, 1 + 4)); + UNIT_ASSERT(IsAtom(patternCallable->GetChild(0), "MatchRecognizePattern")); + UNIT_ASSERT(IsListOfSize(GetQuoted(patternCallable->GetChild(4)), 5)); } Y_UNIT_TEST(PatternWithParanthesis) { @@ -398,18 +406,18 @@ FROM Input MATCH_RECOGNIZE( const auto& r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); const auto& patternCallable = FindMatchRecognizeParam(r.Root, "pattern"); - UNIT_ASSERT_EQUAL(patternCallable->GetChild(0)->GetContent(), "MatchRecognizePattern"); - UNIT_ASSERT_EQUAL(patternCallable->GetChildrenCount(), 1 + 2); + UNIT_ASSERT(IsListOfSize(patternCallable, 1 + 2)); + UNIT_ASSERT(IsAtom(patternCallable->GetChild(0), "MatchRecognizePattern")); const auto& firstTerm = patternCallable->GetChild(1); - UNIT_ASSERT(IsQuotedListOfSize(firstTerm, 1)); + UNIT_ASSERT(IsListOfSize(GetQuoted(firstTerm), 1)); const auto& lastTerm = patternCallable->GetChild(2); - UNIT_ASSERT(IsQuotedListOfSize(lastTerm, 3)); + UNIT_ASSERT(IsListOfSize(GetQuoted(lastTerm), 3)); const auto& firstFactorOfLastTerm = lastTerm->GetChild(1)->GetChild(0); - UNIT_ASSERT(IsQuotedListOfSize(firstFactorOfLastTerm, 6)); + UNIT_ASSERT(IsListOfSize(GetQuoted(firstFactorOfLastTerm), 6)); const auto nestedPattern = firstFactorOfLastTerm->GetChild(1)->GetChild(0); - UNIT_ASSERT_EQUAL(nestedPattern->GetChildrenCount(), 1 + 1); - UNIT_ASSERT_EQUAL(nestedPattern->GetChild(0)->GetContent(), "MatchRecognizePattern"); - UNIT_ASSERT(IsQuotedListOfSize(nestedPattern->GetChild(1), 2)); + UNIT_ASSERT(IsListOfSize(nestedPattern, 1 + 1)); + UNIT_ASSERT(IsAtom(nestedPattern->GetChild(0), "MatchRecognizePattern")); + UNIT_ASSERT(IsListOfSize(GetQuoted(nestedPattern->GetChild(1)), 2)); } Y_UNIT_TEST(PatternManyAlternatives) { @@ -471,12 +479,12 @@ FROM Input MATCH_RECOGNIZE( const auto& patternCallable = FindMatchRecognizeParam(root, "pattern"); const auto& factor = patternCallable->GetChild(1)->GetChild(1)->GetChild(0)->GetChild(1); return NYql::NMatchRecognize::TRowPatternFactor{ - TString(), //primary var or subexpression, not used in this test - FromString<uint64_t>(factor->GetChild(1)->GetChild(1)->GetContent()), //QuantityMin - FromString<uint64_t>(factor->GetChild(2)->GetChild(1)->GetContent()), //QuantityMax - FromString<bool>(factor->GetChild(3)->GetChild(1)->GetContent()), //Greedy - false, //Output, not used in this test - false, // Flag "Unused", not used in this test + TString(), // Primary var or subexpression, not used in this test + FromString<uint64_t>(GetAtom(GetQuoted(factor->GetChild(1)))), // QuantityMin + FromString<uint64_t>(GetAtom(GetQuoted(factor->GetChild(2)))), // QuantityMax + FromString<bool>(GetAtom(GetQuoted(factor->GetChild(3)))), // Greedy + FromString<bool>(GetAtom(GetQuoted(factor->GetChild(4)))), // Output, not used in this test + FromString<bool>(GetAtom(GetQuoted(factor->GetChild(5)))), // Flag "Unused", not used in this test }; }; { @@ -647,7 +655,7 @@ FROM Input MATCH_RECOGNIZE( const auto& patternCallable = FindMatchRecognizeParam(r.Root, "pattern"); const auto permutePattern = patternCallable->GetChild(1)->GetChild(1)->GetChild(0)->GetChild(1)->GetChild(0); - UNIT_ASSERT(permutePattern->IsListOfSize(1 + 120)); //CallableName + 5! + UNIT_ASSERT(IsListOfSize(permutePattern, 1 + 120)); //CallableName + 5! } Y_UNIT_TEST(PermuteTooMuch) { @@ -699,12 +707,9 @@ FROM Input MATCH_RECOGNIZE( auto r = MatchRecognizeSqlToYql(stmt); UNIT_ASSERT(r.IsOk()); const auto defines = FindMatchRecognizeParam(r.Root, "define"); - UNIT_ASSERT_VALUES_EQUAL(7, defines->GetChildrenCount()); + UNIT_ASSERT(IsListOfSize(defines, 7)); const auto varNames = defines->GetChild(3); - UNIT_ASSERT(IsQuotedListOfSize(varNames, 3)); - UNIT_ASSERT_VALUES_EQUAL("Y", varNames->GetChild(1)->GetChild(0)->GetChild(1)->GetContent()); - UNIT_ASSERT_VALUES_EQUAL("Q", varNames->GetChild(1)->GetChild(1)->GetChild(1)->GetContent()); - UNIT_ASSERT_VALUES_EQUAL("L", varNames->GetChild(1)->GetChild(2)->GetChild(1)->GetContent()); + UNIT_ASSERT(IsListOfAtoms(GetQuoted(varNames), {"Y", "Q", "L"}, GetQuoted)); UNIT_ASSERT(IsLambda(defines->GetChild(4), 3)); UNIT_ASSERT(IsLambda(defines->GetChild(5), 3)); diff --git a/yql/essentials/tests/sql/minirun/part0/canondata/result.json b/yql/essentials/tests/sql/minirun/part0/canondata/result.json index 5770f74200..d90bfc7598 100644 --- a/yql/essentials/tests/sql/minirun/part0/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part0/canondata/result.json @@ -717,9 +717,9 @@ ], "test.test[match_recognize-after_match_skip_past_last_row-default.txt-Debug]": [ { - "checksum": "ba5829938cca0f9da11d044432ba58c4", - "size": 1294, - "uri": "https://{canondata_backend}/1777230/d5f34e6dd6caad9e61f6ac66cc95521cc05a75cf/resource.tar.gz#test.test_match_recognize-after_match_skip_past_last_row-default.txt-Debug_/opt.yql" + "checksum": "8d1040bc0c24605941b1340b35184c51", + "size": 1462, + "uri": "https://{canondata_backend}/1600758/8de883b447eee7cc29abdf87f80f4f3b5a97e876/resource.tar.gz#test.test_match_recognize-after_match_skip_past_last_row-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-after_match_skip_past_last_row-default.txt-Results]": [ @@ -731,9 +731,9 @@ ], "test.test[match_recognize-alerts-streaming-default.txt-Debug]": [ { - "checksum": "d84be5a785956f5561d3871d773bb117", - "size": 6021, - "uri": "https://{canondata_backend}/1777230/d5f34e6dd6caad9e61f6ac66cc95521cc05a75cf/resource.tar.gz#test.test_match_recognize-alerts-streaming-default.txt-Debug_/opt.yql" + "checksum": "adda109dcb41f911e4775c1b1af43d02", + "size": 6661, + "uri": "https://{canondata_backend}/1600758/8de883b447eee7cc29abdf87f80f4f3b5a97e876/resource.tar.gz#test.test_match_recognize-alerts-streaming-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-alerts-streaming-default.txt-Results]": [ @@ -745,16 +745,16 @@ ], "test.test[match_recognize-test_type-default.txt-Debug]": [ { - "checksum": "332b177bb25cf91a2a59f949bc30997a", - "size": 2667, - "uri": "https://{canondata_backend}/1777230/d5f34e6dd6caad9e61f6ac66cc95521cc05a75cf/resource.tar.gz#test.test_match_recognize-test_type-default.txt-Debug_/opt.yql" + "checksum": "c8060b01415ca3f1f717f0c171167827", + "size": 2774, + "uri": "https://{canondata_backend}/1600758/8de883b447eee7cc29abdf87f80f4f3b5a97e876/resource.tar.gz#test.test_match_recognize-test_type-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-test_type-default.txt-Results]": [ { - "checksum": "568681ef1c935d6bdeabf22735cc4c63", - "size": 5138, - "uri": "https://{canondata_backend}/1777230/d5f34e6dd6caad9e61f6ac66cc95521cc05a75cf/resource.tar.gz#test.test_match_recognize-test_type-default.txt-Results_/results.txt" + "checksum": "02e86332916457371461fd277e2f0003", + "size": 4370, + "uri": "https://{canondata_backend}/1942100/6ea7bdc94febc162c165c9eafba66d971745efa9/resource.tar.gz#test.test_match_recognize-test_type-default.txt-Results_/results.txt" } ], "test.test[optimizers-or_absorption--Debug]": [ diff --git a/yql/essentials/tests/sql/minirun/part1/canondata/result.json b/yql/essentials/tests/sql/minirun/part1/canondata/result.json index cb5503d6f3..164e13258b 100644 --- a/yql/essentials/tests/sql/minirun/part1/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part1/canondata/result.json @@ -736,9 +736,9 @@ ], "test.test[match_recognize-alerts_without_order-streaming-default.txt-Debug]": [ { - "checksum": "da3c36fb5e54fd02cedfd15c0d0b9d0b", - "size": 5896, - "uri": "https://{canondata_backend}/937458/61af1cc3453c6ab9c5a837eeb404bf874f130293/resource.tar.gz#test.test_match_recognize-alerts_without_order-streaming-default.txt-Debug_/opt.yql" + "checksum": "679b07f8fd3c61f988cfddb5d6b8ffc0", + "size": 6538, + "uri": "https://{canondata_backend}/1775319/cb898029238571d4e51bfb0c4aca66d1d663f5d9/resource.tar.gz#test.test_match_recognize-alerts_without_order-streaming-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-alerts_without_order-streaming-default.txt-Results]": [ @@ -750,9 +750,9 @@ ], "test.test[match_recognize-greedy_quantifiers-default.txt-Debug]": [ { - "checksum": "66fb0a8ccd3814cb306c356fcecea0d1", - "size": 2147, - "uri": "https://{canondata_backend}/1777230/e0a11b3037046c8b251f0102af3c7cc58af5ef2c/resource.tar.gz#test.test_match_recognize-greedy_quantifiers-default.txt-Debug_/opt.yql" + "checksum": "c18f3e47c3dfa398bfa2405f25c81267", + "size": 2447, + "uri": "https://{canondata_backend}/1775319/cb898029238571d4e51bfb0c4aca66d1d663f5d9/resource.tar.gz#test.test_match_recognize-greedy_quantifiers-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-greedy_quantifiers-default.txt-Results]": [ diff --git a/yql/essentials/tests/sql/minirun/part2/canondata/result.json b/yql/essentials/tests/sql/minirun/part2/canondata/result.json index b9a3de5ee2..48c0652311 100644 --- a/yql/essentials/tests/sql/minirun/part2/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part2/canondata/result.json @@ -836,9 +836,9 @@ ], "test.test[match_recognize-simple_paritioning-default.txt-Debug]": [ { - "checksum": "459d2a84dbc7335c291bc01ab9573c6e", - "size": 3201, - "uri": "https://{canondata_backend}/1937492/74169e2f8afb099b48d4cfe4c1190fcfe62c417a/resource.tar.gz#test.test_match_recognize-simple_paritioning-default.txt-Debug_/opt.yql" + "checksum": "d9ccfb5fa5b16b57294abe924c9c942e", + "size": 3379, + "uri": "https://{canondata_backend}/1600758/271b0bb3d2a8c572c9fe73c826a3225e38e2e13b/resource.tar.gz#test.test_match_recognize-simple_paritioning-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-simple_paritioning-default.txt-Results]": [ diff --git a/yql/essentials/tests/sql/minirun/part4/canondata/result.json b/yql/essentials/tests/sql/minirun/part4/canondata/result.json index fa6c416555..b2ba2b1602 100644 --- a/yql/essentials/tests/sql/minirun/part4/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part4/canondata/result.json @@ -917,9 +917,9 @@ ], "test.test[match_recognize-alerts_many_order-default.txt-Debug]": [ { - "checksum": "1c97c57558496ad224101f316952ec58", - "size": 6069, - "uri": "https://{canondata_backend}/1931696/1c8734acb17a4f366e16957a48e555c2c4a06ce9/resource.tar.gz#test.test_match_recognize-alerts_many_order-default.txt-Debug_/opt.yql" + "checksum": "3c4a225c79eb3c1505473aa9a652e73c", + "size": 6709, + "uri": "https://{canondata_backend}/1600758/8a8a3c6886c9215b591165a3c6d6f6bfeb12d1e4/resource.tar.gz#test.test_match_recognize-alerts_many_order-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-alerts_many_order-default.txt-Results]": [ @@ -931,16 +931,16 @@ ], "test.test[match_recognize-measures_aggregate-default.txt-Debug]": [ { - "checksum": "57fd3f8f46c4a0ab7bf9ef9a4842ea75", - "size": 5880, - "uri": "https://{canondata_backend}/1775059/fa3782efce42b73c9d2a91d53e640bb71168f31f/resource.tar.gz#test.test_match_recognize-measures_aggregate-default.txt-Debug_/opt.yql" + "checksum": "c13d3c4d5d8a04d1d867a55080d29ab3", + "size": 7725, + "uri": "https://{canondata_backend}/1600758/8a8a3c6886c9215b591165a3c6d6f6bfeb12d1e4/resource.tar.gz#test.test_match_recognize-measures_aggregate-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-measures_aggregate-default.txt-Results]": [ { - "checksum": "58ad2a60431fd720f1968f892142143e", + "checksum": "389501474d7d322ebff7e04ffb97d0cd", "size": 11093, - "uri": "https://{canondata_backend}/1775059/fa3782efce42b73c9d2a91d53e640bb71168f31f/resource.tar.gz#test.test_match_recognize-measures_aggregate-default.txt-Results_/results.txt" + "uri": "https://{canondata_backend}/1942671/e4312945cd8a2559b8969a23966ed2960d1c5c1d/resource.tar.gz#test.test_match_recognize-measures_aggregate-default.txt-Results_/results.txt" } ], "test.test[optimizers-coalesce_propagate-default.txt-Debug]": [ diff --git a/yql/essentials/tests/sql/minirun/part5/canondata/result.json b/yql/essentials/tests/sql/minirun/part5/canondata/result.json index c15133e45f..277ca7e742 100644 --- a/yql/essentials/tests/sql/minirun/part5/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part5/canondata/result.json @@ -1119,9 +1119,9 @@ ], "test.test[match_recognize-alerts-default.txt-Debug]": [ { - "checksum": "9f76da8aa8f0d280d8a98e4eb3f892b1", - "size": 6023, - "uri": "https://{canondata_backend}/1130705/e4b7d47d9742325daff68c922887a7262afbacba/resource.tar.gz#test.test_match_recognize-alerts-default.txt-Debug_/opt.yql" + "checksum": "a6f1a68396bb11dc68f8885a093611b2", + "size": 6663, + "uri": "https://{canondata_backend}/1937027/5b97bc5d483007a0a4f01b6cfb69fc69faa834ae/resource.tar.gz#test.test_match_recognize-alerts-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-alerts-default.txt-Results]": [ @@ -1133,9 +1133,9 @@ ], "test.test[match_recognize-all_rows_per_match-default.txt-Debug]": [ { - "checksum": "d165424c12b99f87fd8aca943b72458e", - "size": 3852, - "uri": "https://{canondata_backend}/1130705/e4b7d47d9742325daff68c922887a7262afbacba/resource.tar.gz#test.test_match_recognize-all_rows_per_match-default.txt-Debug_/opt.yql" + "checksum": "68bce7d5a531eae68007c4becc8caa3e", + "size": 4209, + "uri": "https://{canondata_backend}/1937027/5b97bc5d483007a0a4f01b6cfb69fc69faa834ae/resource.tar.gz#test.test_match_recognize-all_rows_per_match-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-all_rows_per_match-default.txt-Results]": [ diff --git a/yql/essentials/tests/sql/minirun/part6/canondata/result.json b/yql/essentials/tests/sql/minirun/part6/canondata/result.json index 07c8cc0c20..dc02c1edb0 100644 --- a/yql/essentials/tests/sql/minirun/part6/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part6/canondata/result.json @@ -849,9 +849,9 @@ ], "test.test[match_recognize-alerts_without_order-default.txt-Debug]": [ { - "checksum": "594f151e529e79595efe63067ad0cf67", - "size": 5900, - "uri": "https://{canondata_backend}/1775059/35c89b22136cd01420b6cc7ddf223a627fc65f0b/resource.tar.gz#test.test_match_recognize-alerts_without_order-default.txt-Debug_/opt.yql" + "checksum": "617ad997b55cab0792da8c20f2fdeb07", + "size": 6542, + "uri": "https://{canondata_backend}/1775319/3ef954185b644201cea09c5679c59afb01e842e4/resource.tar.gz#test.test_match_recognize-alerts_without_order-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-alerts_without_order-default.txt-Results]": [ diff --git a/yql/essentials/tests/sql/minirun/part7/canondata/result.json b/yql/essentials/tests/sql/minirun/part7/canondata/result.json index bd0cea5780..6094e83958 100644 --- a/yql/essentials/tests/sql/minirun/part7/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part7/canondata/result.json @@ -644,16 +644,16 @@ ], "test.test[match_recognize-test_type-streaming-default.txt-Debug]": [ { - "checksum": "78f9d1127f6c378a383e746f8e7ca2b6", - "size": 2582, - "uri": "https://{canondata_backend}/1900335/96f474c83eaaa22aac9f78dae9544c91548b2f2f/resource.tar.gz#test.test_match_recognize-test_type-streaming-default.txt-Debug_/opt.yql" + "checksum": "80517cbe048c0f7fdd74cc8c06a36633", + "size": 2689, + "uri": "https://{canondata_backend}/1689644/5e433493fb75da7cc94e8cba4e3a9f34c6b2e0c6/resource.tar.gz#test.test_match_recognize-test_type-streaming-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-test_type-streaming-default.txt-Results]": [ { - "checksum": "3c7b40f6b2281e1f94394cedd06f6f54", - "size": 5142, - "uri": "https://{canondata_backend}/1900335/96f474c83eaaa22aac9f78dae9544c91548b2f2f/resource.tar.gz#test.test_match_recognize-test_type-streaming-default.txt-Results_/results.txt" + "checksum": "a426ea78777873f86c83681342304e1a", + "size": 4374, + "uri": "https://{canondata_backend}/937458/a11a861fa6095eb151eeed7a61afe98ed99c8db4/resource.tar.gz#test.test_match_recognize-test_type-streaming-default.txt-Results_/results.txt" } ], "test.test[order_by-order_by_missing_project_column_nosimple--Debug]": [ diff --git a/yql/essentials/tests/sql/minirun/part8/canondata/result.json b/yql/essentials/tests/sql/minirun/part8/canondata/result.json index d1df68cd62..53cd1141ef 100644 --- a/yql/essentials/tests/sql/minirun/part8/canondata/result.json +++ b/yql/essentials/tests/sql/minirun/part8/canondata/result.json @@ -903,9 +903,9 @@ ], "test.test[match_recognize-permute-default.txt-Debug]": [ { - "checksum": "f33a6938ad6524015fe493f9e45a9a1a", - "size": 2300, - "uri": "https://{canondata_backend}/1900335/3c460c2946ea734b521d2f5710a7c3237ef371b3/resource.tar.gz#test.test_match_recognize-permute-default.txt-Debug_/opt.yql" + "checksum": "d85f6b9f632284167abb3f3ac686e0f9", + "size": 2611, + "uri": "https://{canondata_backend}/1775319/f257079dc0d081343649ad4fb6863469b53dedfb/resource.tar.gz#test.test_match_recognize-permute-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-permute-default.txt-Results]": [ @@ -917,9 +917,9 @@ ], "test.test[match_recognize-simple_paritioning-streaming-default.txt-Debug]": [ { - "checksum": "8e6443cf3e5f569f1e06dbf8207d334d", - "size": 3262, - "uri": "https://{canondata_backend}/1900335/3c460c2946ea734b521d2f5710a7c3237ef371b3/resource.tar.gz#test.test_match_recognize-simple_paritioning-streaming-default.txt-Debug_/opt.yql" + "checksum": "a1cbb74d2d471cdce5062f0b2392bad9", + "size": 3440, + "uri": "https://{canondata_backend}/1775319/f257079dc0d081343649ad4fb6863469b53dedfb/resource.tar.gz#test.test_match_recognize-simple_paritioning-streaming-default.txt-Debug_/opt.yql" } ], "test.test[match_recognize-simple_paritioning-streaming-default.txt-Results]": [ diff --git a/yql/essentials/tests/sql/sql2yql/canondata/result.json b/yql/essentials/tests/sql/sql2yql/canondata/result.json index cf6b7c866c..1db06fe887 100644 --- a/yql/essentials/tests/sql/sql2yql/canondata/result.json +++ b/yql/essentials/tests/sql/sql2yql/canondata/result.json @@ -4166,114 +4166,114 @@ ], "test_sql2yql.test[match_recognize-after_match_skip_past_last_row]": [ { - "checksum": "6455d6bae63fe3d95a749a7952863604", - "size": 3104, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-after_match_skip_past_last_row_/sql.yql" + "checksum": "8c019a9e653e16decf0c5d7eee2fe567", + "size": 3254, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-after_match_skip_past_last_row_/sql.yql" } ], "test_sql2yql.test[match_recognize-alerts-streaming]": [ { - "checksum": "55a3af0bf19e627ca6dec04367c179c1", - "size": 10044, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-alerts-streaming_/sql.yql" + "checksum": "2507b2c3f80cdf3496546660d3f8dcff", + "size": 10570, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-alerts-streaming_/sql.yql" } ], "test_sql2yql.test[match_recognize-alerts]": [ { - "checksum": "abe472c1e4dd4d38ce3af7954c0a4425", - "size": 10046, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_/sql.yql" + "checksum": "eaadceeaf0eb02f8f253a14c978278be", + "size": 10572, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_/sql.yql" } ], "test_sql2yql.test[match_recognize-alerts_many_order]": [ { - "checksum": "fdeefb622f27f8c368c9537f17c846de", - "size": 10104, - "uri": "https://{canondata_backend}/1031349/7f77f1776a126968836df92c4cf004ce943df620/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_many_order_/sql.yql" + "checksum": "14c92c1bdb9a0d937bdf22214cb64f6f", + "size": 10630, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_many_order_/sql.yql" } ], "test_sql2yql.test[match_recognize-alerts_many_order_streaming]": [ { - "checksum": "a093d5c833183bee040b38097922b312", - "size": 10102, - "uri": "https://{canondata_backend}/1130705/93ecf81217107a68bf7729220abc924ea185d802/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_many_order_streaming_/sql.yql" + "checksum": "0fd6159893b768f3704d926f748ba9a7", + "size": 10628, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_many_order_streaming_/sql.yql" } ], "test_sql2yql.test[match_recognize-alerts_without_order-streaming]": [ { - "checksum": "2544bb720aab6ef9d8d57f909f58ce8f", - "size": 9925, - "uri": "https://{canondata_backend}/1925842/7d0ab953a9979e9baa7ae26ebae2128b1cbe8128/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_without_order-streaming_/sql.yql" + "checksum": "b835198f88e21f0a220b8cad93078632", + "size": 10451, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_without_order-streaming_/sql.yql" } ], "test_sql2yql.test[match_recognize-alerts_without_order]": [ { - "checksum": "7e6cd1cda9ddc8a2fe0f41ace902517e", - "size": 9927, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_without_order_/sql.yql" + "checksum": "f3dd13610f051c3cfdbd2165387eabd6", + "size": 10453, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-alerts_without_order_/sql.yql" } ], "test_sql2yql.test[match_recognize-all_rows_per_match]": [ { - "checksum": "4eca671d5cbce0a4457b1b7918ff3a7b", - "size": 6627, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-all_rows_per_match_/sql.yql" + "checksum": "40bd4ea7cf5fbd310c4893fd50c35423", + "size": 6928, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-all_rows_per_match_/sql.yql" } ], "test_sql2yql.test[match_recognize-greedy_quantifiers]": [ { - "checksum": "a37f9b7a1bbf0e3ab25d265bfb1cdf95", - "size": 4214, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-greedy_quantifiers_/sql.yql" + "checksum": "71abe51c07a68e660a2a53cd2f973e2b", + "size": 4439, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-greedy_quantifiers_/sql.yql" } ], "test_sql2yql.test[match_recognize-measures_aggregate]": [ { - "checksum": "a5c9c77b24db505963aa1c7af3e9e9ba", - "size": 7401, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-measures_aggregate_/sql.yql" + "checksum": "6cb03f6151f4f81c4b543308ffa4639c", + "size": 9149, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-measures_aggregate_/sql.yql" } ], "test_sql2yql.test[match_recognize-permute]": [ { - "checksum": "319494095f46f445b1334166cb139412", - "size": 5237, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-permute_/sql.yql" + "checksum": "473e0083ea382c8e3eba6878778096b7", + "size": 5464, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-permute_/sql.yql" } ], "test_sql2yql.test[match_recognize-simple_paritioning-streaming]": [ { - "checksum": "517bd077b852e7e35f5ef61b6ce5ab2e", - "size": 4882, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-simple_paritioning-streaming_/sql.yql" + "checksum": "0b35e6a3dbc82010cbe3de9bf55d48c1", + "size": 5032, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-simple_paritioning-streaming_/sql.yql" } ], "test_sql2yql.test[match_recognize-simple_paritioning]": [ { - "checksum": "07184284d8c30188d7345a28f0cb4c8d", - "size": 4851, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-simple_paritioning_/sql.yql" + "checksum": "bd9f6b287a3da240b63ea7ecef422da5", + "size": 5001, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-simple_paritioning_/sql.yql" } ], "test_sql2yql.test[match_recognize-test_type-streaming]": [ { - "checksum": "26d2b2f5b48b4f537d82a9c70f2509e5", - "size": 9394, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-test_type-streaming_/sql.yql" + "checksum": "6a97948d3ed28606b65f55f52cfe6c66", + "size": 9601, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-test_type-streaming_/sql.yql" } ], "test_sql2yql.test[match_recognize-test_type]": [ { - "checksum": "9782d694d28decb54e3194bddadcaf87", - "size": 9399, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-test_type_/sql.yql" + "checksum": "cbd08e2722f211e25f126b3b6d24a1b1", + "size": 9606, + "uri": "https://{canondata_backend}/1937367/e7b738910596b51d0b9e27369e0446763f8c5243/resource.tar.gz#test_sql2yql.test_match_recognize-test_type_/sql.yql" } ], "test_sql2yql.test[match_recognize-test_type_predicate]": [ { - "checksum": "bebea49359906f66cdfff88c13f467ec", - "size": 3221, - "uri": "https://{canondata_backend}/1920236/5e37b541c71c89b1b95dee0463a5a2e9bc5999f4/resource.tar.gz#test_sql2yql.test_match_recognize-test_type_predicate_/sql.yql" + "checksum": "6c67c1b229328b7b6eaac5e7b555ed9e", + "size": 3220, + "uri": "https://{canondata_backend}/937458/48f7c08aeea2b81122c2d3efab2783a2c7764b0a/resource.tar.gz#test_sql2yql.test_match_recognize-test_type_predicate_/sql.yql" } ], "test_sql2yql.test[optimizers-and_absorption]": [ diff --git a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_match_recognize-measures_aggregate_/formatted.sql b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_match_recognize-measures_aggregate_/formatted.sql index 3178e73e9c..2b0d7ed135 100644 --- a/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_match_recognize-measures_aggregate_/formatted.sql +++ b/yql/essentials/tests/sql/sql2yql/canondata/test_sql_format.test_match_recognize-measures_aggregate_/formatted.sql @@ -21,7 +21,7 @@ FROM ORDER BY CAST(time AS Timestamp) MEASURES - SUM(A.value + 1u + LENGTH(A.name)) AS aggr_expr, + SUM(A.value + 1u + LENGTH(A.name)) + SUM(B.value + 1u + LENGTH(B.name)) AS aggr_expr, FIRST(A.value) AS first_a, LAST(A.value) AS last_a, COUNT(A.value) AS count_a, diff --git a/yql/essentials/tests/sql/suites/match_recognize/measures_aggregate.sql b/yql/essentials/tests/sql/suites/match_recognize/measures_aggregate.sql index eec70ff8bc..94ea32d72d 100644 --- a/yql/essentials/tests/sql/suites/match_recognize/measures_aggregate.sql +++ b/yql/essentials/tests/sql/suites/match_recognize/measures_aggregate.sql @@ -12,7 +12,7 @@ $input = SELECT * FROM AS_TABLE([ SELECT * FROM $input MATCH_RECOGNIZE ( ORDER BY CAST(time AS Timestamp) MEASURES - SUM(A.value + 1u + LENGTH(A.name)) AS aggr_expr, + SUM(A.value + 1u + LENGTH(A.name)) + SUM(B.value + 1u + LENGTH(B.name)) AS aggr_expr, FIRST(A.value) AS first_a, LAST(A.value) AS last_a, COUNT(A.value) AS count_a, |