summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvvvv <[email protected]>2022-04-14 21:37:07 +0300
committervvvv <[email protected]>2022-04-14 21:37:07 +0300
commit9deb212a09271e440fe97d70ac945fa104dc25aa (patch)
tree3ddeffc8c88318503134fc0322a2d7a5c2fbe60e
parentd0faf340baa9391225f3f723a7f573463da3c927 (diff)
YQL-13710 Integration of Pg agg functions into V1 parser
ref:436402e06973c2e5be7f43e2d43c8e0254473e62
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_core.cpp3
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_list.cpp51
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_list.h2
-rw-r--r--ydb/library/yql/core/type_ann/type_ann_pg.cpp35
-rw-r--r--ydb/library/yql/sql/v1/aggregation.cpp101
-rw-r--r--ydb/library/yql/sql/v1/builtin.cpp42
-rw-r--r--ydb/library/yql/sql/v1/node.cpp13
-rw-r--r--ydb/library/yql/sql/v1/node.h2
8 files changed, 214 insertions, 35 deletions
diff --git a/ydb/library/yql/core/type_ann/type_ann_core.cpp b/ydb/library/yql/core/type_ann/type_ann_core.cpp
index 74572bac4e2..f448c0a206f 100644
--- a/ydb/library/yql/core/type_ann/type_ann_core.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_core.cpp
@@ -11212,6 +11212,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["WinOnGroups"] = &WinOnWrapper;
Functions["WinOnRange"] = &WinOnWrapper;
Functions["WindowTraits"] = &WindowTraitsWrapper;
+ Functions["ToWindowTraits"] = &ToWindowTraitsWrapper;
Functions["CalcOverWindow"] = &CalcOverWindowWrapper;
Functions["CalcOverSessionWindow"] = &CalcOverWindowWrapper;
Functions["CalcOverWindowGroup"] = &CalcOverWindowGroupWrapper;
@@ -11266,6 +11267,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["PgNot"] = &PgBoolOpWrapper;
Functions["PgAggregationTraits"] = &PgAggregationTraitsWrapper;
Functions["PgWindowTraits"] = &PgAggregationTraitsWrapper;
+ Functions["PgAggregationTraitsTuple"] = &PgAggregationTraitsWrapper;
+ Functions["PgWindowTraitsTuple"] = &PgAggregationTraitsWrapper;
Functions["PgInternal0"] = &PgInternal0Wrapper;
Functions["AutoDemuxList"] = &AutoDemuxListWrapper;
Functions["AggrCountInit"] = &AggrCountInitWrapper;
diff --git a/ydb/library/yql/core/type_ann/type_ann_list.cpp b/ydb/library/yql/core/type_ann/type_ann_list.cpp
index ee3f2d6979e..b36a65e4f47 100644
--- a/ydb/library/yql/core/type_ann/type_ann_list.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_list.cpp
@@ -71,12 +71,22 @@ namespace {
TExprNode::TListType defValueArgs;
auto traitsFactory = node.ChildPtr(2);
- if (!traitsFactory->Child(1)->IsCallable("AggregationTraits") && !traitsFactory->Child(1)->IsCallable("WindowTraits")) {
+ auto traitsFactoryBody = traitsFactory->ChildPtr(1);
+ if (traitsFactoryBody->IsCallable("ToWindowTraits")) {
+ if (!traitsFactoryBody->Head().IsCallable("AggregationTraits")) {
+ ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Expected AggregationTraits inside ToWindowTraits"));
+ return nullptr;
+ }
+
+ traitsFactoryBody = ExpandToWindowTraits(traitsFactoryBody->Head(), ctx);
+ }
+
+ if (!traitsFactoryBody->IsCallable("AggregationTraits") && !traitsFactoryBody->IsCallable("WindowTraits")) {
ctx.AddError(TIssue(ctx.GetPosition(node.Pos()), "Expected AggregationTraits or WindowTraits"));
return nullptr;
}
- bool onWindow = traitsFactory->Child(1)->IsCallable("WindowTraits");
+ bool onWindow = traitsFactoryBody->IsCallable("WindowTraits");
bool isNullDefValue = true;
bool isLambdaDefValue = false;
@@ -121,7 +131,7 @@ namespace {
factoryReplaces[traitsFactory->Head().Child(0)] = listType ? ExpandType(node.Pos(), *listType->GetItemType(), ctx) : node.HeadPtr();
factoryReplaces[traitsFactory->Head().Child(1)] = extractor;
- auto traits = ctx.ReplaceNodes(traitsFactory->ChildPtr(1), factoryReplaces);
+ auto traits = ctx.ReplaceNodes(TExprNode::TPtr(traitsFactoryBody), factoryReplaces);
ctx.Step.Repeat(TExprStep::ExpandApplyForLambdas);
auto status = ExpandApply(traits, traits, ctx);
if (status == IGraphTransformer::TStatus::Error) {
@@ -5035,6 +5045,22 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
+ IGraphTransformer::TStatus ToWindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ if (!input->Head().IsCallable("AggregationTraits")) {
+ ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Pos()),
+ "Expected AggregationTraits"));
+ return IGraphTransformer::TStatus::Error;
+ }
+
+ const auto& traits = input->Head();
+ output = ExpandToWindowTraits(traits, ctx.Expr);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
IGraphTransformer::TStatus WindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 6, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -6358,5 +6384,24 @@ namespace {
input->SetTypeAnn(ctx.Expr.MakeType<TFlowExprType>(ctx.Expr.MakeType<TListExprType>(itemType)));
return IGraphTransformer::TStatus::Ok;
}
+
+ TExprNode::TPtr ExpandToWindowTraits(const TExprNode& input, TExprContext& ctx) {
+ YQL_ENSURE(input.IsCallable("AggregationTraits"));
+ return ctx.Builder(input.Pos())
+ .Callable("WindowTraits")
+ .Add(0, input.ChildPtr(0))
+ .Add(1, input.ChildPtr(1))
+ .Add(2, input.ChildPtr(2))
+ .Lambda(3)
+ .Param("value")
+ .Param("state")
+ .Callable("Void")
+ .Seal()
+ .Seal()
+ .Add(4, input.ChildPtr(6))
+ .Add(5, input.ChildPtr(7))
+ .Seal()
+ .Build();
+ }
} // namespace NTypeAnnImpl
}
diff --git a/ydb/library/yql/core/type_ann/type_ann_list.h b/ydb/library/yql/core/type_ann/type_ann_list.h
index 2c0fd69ed13..3fd48517da4 100644
--- a/ydb/library/yql/core/type_ann/type_ann_list.h
+++ b/ydb/library/yql/core/type_ann/type_ann_list.h
@@ -9,6 +9,7 @@ namespace NYql {
namespace NTypeAnnImpl {
IGraphTransformer::TStatus InferPositionalUnionType(TPositionHandle pos, const TExprNode::TListType& children,
TColumnOrder& resultColumnOrder, const TStructExprType*& resultStructType, TExtContext& ctx);
+ TExprNode::TPtr ExpandToWindowTraits(const TExprNode& input, TExprContext& ctx);
IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
template <bool InverseCondition>
@@ -99,6 +100,7 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus SkipNullElementsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WinOnWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ToWindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus CalcOverWindowWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus CalcOverWindowGroupWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WinLeadLagWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
diff --git a/ydb/library/yql/core/type_ann/type_ann_pg.cpp b/ydb/library/yql/core/type_ann/type_ann_pg.cpp
index 128503e749b..4ef0adb5b7e 100644
--- a/ydb/library/yql/core/type_ann/type_ann_pg.cpp
+++ b/ydb/library/yql/core/type_ann/type_ann_pg.cpp
@@ -794,7 +794,8 @@ IGraphTransformer::TStatus PgCastWrapper(const TExprNode::TPtr& input, TExprNode
}
IGraphTransformer::TStatus PgAggregationTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
- const bool onWindow = input->IsCallable("PgWindowTraits");
+ const bool onWindow = input->Content().StartsWith("PgWindowTraits");
+ const bool tupleExtractor = input->Content().EndsWith("Tuple");
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -824,6 +825,33 @@ IGraphTransformer::TStatus PgAggregationTraitsWrapper(const TExprNode::TPtr& inp
return IGraphTransformer::TStatus::Repeat;
}
+ if (tupleExtractor) {
+ // convert lambda with tuple type into multi lambda
+ auto args = input->ChildrenList();
+ if (lambda->GetTypeAnn()->GetKind() == ETypeAnnotationKind::Tuple) {
+ Y_ENSURE(lambda->ChildrenSize() == 2);
+ auto tupleTypeSize = lambda->GetTypeAnn()->Cast<TTupleExprType>()->GetSize();
+ auto newArg = ctx.Expr.NewArgument(lambda->Pos(), "row");
+ auto newBody = ctx.Expr.ReplaceNode(lambda->TailPtr(), lambda->Head().Head(), newArg);
+ TExprNode::TListType bodies;
+ for (ui32 i = 0; i < tupleTypeSize; ++i) {
+ bodies.push_back(ctx.Expr.Builder(lambda->Pos())
+ .Callable("Nth")
+ .Add(0, newBody)
+ .Atom(1, ToString(i))
+ .Seal()
+ .Build());
+ }
+
+ args[2] = ctx.Expr.NewLambda(lambda->Pos(), ctx.Expr.NewArguments(lambda->Pos(), { newArg }), std::move(bodies));
+ }
+
+ output = ctx.Expr.NewCallable(input->Pos(), input->Content().substr(0, input->Content().Size() - 5), std::move(args));
+ //ctx.Expr.Step.Repeat(TExprStep::ExpandApplyForLambdas);
+ //return IGraphTransformer::TStatus(IGraphTransformer::TStatus::Repeat, true);
+ return IGraphTransformer::TStatus::Repeat;
+ }
+
TVector<ui32> argTypes;
bool needRetype = false;
for (ui32 i = 1; i < lambda->ChildrenSize(); ++i) {
@@ -842,7 +870,7 @@ IGraphTransformer::TStatus PgAggregationTraitsWrapper(const TExprNode::TPtr& inp
}
if (needRetype) {
- lambda = ctx.Expr.DeepCopyLambda(*lambda);
+ auto newLambda = ctx.Expr.DeepCopyLambda(*lambda);
for (ui32 i = 1; i < lambda->ChildrenSize(); ++i) {
auto type = lambda->Child(i)->GetTypeAnn();
ui32 argType;
@@ -852,10 +880,11 @@ IGraphTransformer::TStatus PgAggregationTraitsWrapper(const TExprNode::TPtr& inp
}
if (convertToPg) {
- lambda->ChildRef(i) = ctx.Expr.NewCallable(lambda->Child(i)->Pos(), "ToPg", { lambda->ChildPtr(i) });
+ newLambda->ChildRef(i) = ctx.Expr.NewCallable(lambda->Child(i)->Pos(), "ToPg", { lambda->ChildPtr(i) });
}
}
+ lambda = newLambda;
return IGraphTransformer::TStatus::Repeat;
}
diff --git a/ydb/library/yql/sql/v1/aggregation.cpp b/ydb/library/yql/sql/v1/aggregation.cpp
index 4b8ce470458..d35ea3d814b 100644
--- a/ydb/library/yql/sql/v1/aggregation.cpp
+++ b/ydb/library/yql/sql/v1/aggregation.cpp
@@ -31,10 +31,11 @@ namespace {
class TAggregationFactory : public IAggregation {
public:
- TAggregationFactory(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode, bool multi = false)
+ TAggregationFactory(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode,
+ bool multi = false, bool validateArgs = true)
: IAggregation(pos, name, func, aggMode), Factory(!func.empty() ?
BuildBind(Pos, aggMode == EAggregateMode::OverWindow ? "window_module" : "aggregate_module", func) : nullptr),
- Multi(multi), DynamicFactory(!Factory)
+ Multi(multi), ValidateArgs(validateArgs), DynamicFactory(!Factory)
{
if (!Factory) {
FakeSource = BuildFakeSource(pos);
@@ -43,30 +44,42 @@ public:
protected:
bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) override {
- ui32 expectedArgs = !Factory ? 2 : (isFactory ? 0 : 1);
- if (!Factory) {
- YQL_ENSURE(!isFactory);
+ if (ValidateArgs || isFactory) {
+ ui32 expectedArgs = ValidateArgs && !Factory ? 2 : (isFactory ? 0 : 1);
+ if (!Factory && ValidateArgs) {
+ YQL_ENSURE(!isFactory);
+ }
+
+ if (expectedArgs != exprs.size()) {
+ ctx.Error(Pos) << "Aggregation function " << (isFactory ? "factory " : "") << Name
+ << " requires exactly " << expectedArgs << " argument(s), given: " << exprs.size();
+ return false;
+ }
}
- if (expectedArgs != exprs.size()) {
- ctx.Error(Pos) << "Aggregation function " << (isFactory ? "factory " : "") << Name
- << " requires exactly " << expectedArgs << " argument(s), given: " << exprs.size();
- return false;
+ if (!ValidateArgs) {
+ Exprs = exprs;
}
if (BlockWindowAggregationWithoutFrameSpec(Pos, GetName(), src, ctx)) {
return false;
}
- if (!Factory) {
- Factory = exprs[1];
+ if (ValidateArgs) {
+ if (!Factory) {
+ Factory = exprs[1];
+ }
}
if (!isFactory) {
- Expr = exprs.front();
+ if (ValidateArgs) {
+ Expr = exprs.front();
+ }
+
Name = src->MakeLocalName(Name);
}
+
if (!Init(ctx, src)) {
return false;
}
@@ -98,6 +111,20 @@ protected:
}
bool DoInit(TContext& ctx, ISource* src) override {
+ if (!ValidateArgs) {
+ for (auto x : Exprs) {
+ if (!x->Init(ctx, src)) {
+ return false;
+ }
+ if (x->IsAggregated() && !x->IsAggregationKey() && !IsOverWindow()) {
+ ctx.Error(Pos) << "Aggregation of aggregated values is forbidden";
+ return false;
+ }
+ }
+
+ return true;
+ }
+
if (!Expr) {
return true;
}
@@ -144,14 +171,7 @@ protected:
if (AggMode == EAggregateMode::OverWindow) {
Factory = BuildLambda(Pos, Y("type", "extractor"), Y("block", Q(Y(
Y("let", "x", Y("Apply", Factory, "type", "extractor")),
- Y("return", Y("WindowTraits",
- Y("NthArg", Q("0"), "x"),
- Y("NthArg", Q("1"), "x"),
- Y("NthArg", Q("2"), "x"),
- BuildLambda(Pos, Y("value", "state"), Y("Void")),
- Y("NthArg", Q("6"), "x"),
- Y("NthArg", Q("7"), "x")
- ))
+ Y("return", Y("ToWindowTraits", "x"))
))));
}
}
@@ -162,6 +182,8 @@ protected:
TNodePtr Factory;
TNodePtr Expr;
bool Multi;
+ bool ValidateArgs;
+ TVector<TNodePtr> Exprs;
private:
TSourcePtr FakeSource;
@@ -1208,4 +1230,43 @@ TAggregationPtr BuildCountAggregation(TPosition pos, const TString& name, const
return new TCountAggregation(pos, name, func, aggMode);
}
+class TPGFactoryAggregation final : public TAggregationFactory {
+public:
+ TPGFactoryAggregation(TPosition pos, const TString& name, EAggregateMode aggMode)
+ : TAggregationFactory(pos, name, "", aggMode, false, false)
+ , PgFunc(Name)
+ {}
+
+ bool InitAggr(TContext& ctx, bool isFactory, ISource* src, TAstListNode& node, const TVector<TNodePtr>& exprs) override {
+ auto ret = TAggregationFactory::InitAggr(ctx, isFactory, src, node, exprs);
+ if (ret) {
+ if (isFactory) {
+ Factory = BuildLambda(Pos, Y("type", "extractor"), Y(AggMode == EAggregateMode::OverWindow ? "PgWindowTraitsTuple" : "PgAggregationTraitsTuple",
+ Q(PgFunc), Y("ListItemType", "type"), "extractor"));
+ } else {
+ Lambda = BuildLambda(Pos, Y("row"), exprs);
+ }
+ }
+
+ return ret;
+ }
+
+ TNodePtr GetApply(const TNodePtr& type) const final {
+ return Y(AggMode == EAggregateMode::OverWindow ? "PgWindowTraits" : "PgAggregationTraits",
+ Q(PgFunc), Y("ListItemType", type), Lambda);
+ }
+
+private:
+ TNodePtr DoClone() const final {
+ return new TPGFactoryAggregation(Pos, Name, AggMode);
+ }
+
+ TString PgFunc;
+ TNodePtr Lambda;
+};
+
+TAggregationPtr BuildPGFactoryAggregation(TPosition pos, const TString& name, EAggregateMode aggMode) {
+ return new TPGFactoryAggregation(pos, name, aggMode);
+}
+
} // namespace NSQLTranslationV1
diff --git a/ydb/library/yql/sql/v1/builtin.cpp b/ydb/library/yql/sql/v1/builtin.cpp
index aa754c79fe2..07f6d718f10 100644
--- a/ydb/library/yql/sql/v1/builtin.cpp
+++ b/ydb/library/yql/sql/v1/builtin.cpp
@@ -10,6 +10,7 @@
#include <ydb/library/yql/minikql/mkql_program_builder.h>
#include <ydb/library/yql/minikql/mkql_type_ops.h>
#include <ydb/library/yql/public/issue/yql_issue_id.h>
+#include <ydb/library/yql/parser/pg_catalog/catalog.h>
#include <library/cpp/charset/ci_string.h>
#include <library/cpp/yson/node/node_io.h>
@@ -2421,7 +2422,8 @@ enum EAggrFuncTypeCallback {
TOP_BY,
COUNT_DISTINCT_ESTIMATE,
LIST,
- UDAF
+ UDAF,
+ PG
};
struct TCoreFuncInfo {
@@ -2502,6 +2504,9 @@ TAggrFuncFactoryCallback BuildAggrFuncFactoryCallback(
case UDAF:
factory = BuildUserDefinedFactoryAggregation(pos, realFunctionName, factoryName, aggMode);
break;
+ case PG:
+ factory = BuildPGFactoryAggregation(pos, realFunctionName, aggMode);
+ break;
}
if (isFactory) {
auto realArgs = args;
@@ -3131,10 +3136,19 @@ TNodePtr BuildBuiltinFunc(TContext& ctx, TPosition pos, TString name, const TVec
} else if (ns == "datetime2" && (name == "Format" || name == "Parse")) {
return BuildUdf(ctx, pos, nameSpace, name, args);
} else if (ns == "pg") {
- TVector<TNodePtr> pgCallArgs;
- pgCallArgs.push_back(BuildLiteralRawString(pos, name));
- pgCallArgs.insert(pgCallArgs.end(), args.begin(), args.end());
- return new TYqlPgCall(pos, pgCallArgs);
+ const bool isAggregateFunc = NYql::NPg::HasAggregation(name);
+ if (isAggregateFunc) {
+ if (aggMode == EAggregateMode::Distinct) {
+ return new TInvalidBuiltin(pos, "Distinct is not supported yet for PG aggregation ");
+ }
+
+ return BuildAggrFuncFactoryCallback(name, "", EAggrFuncTypeCallback::PG)(pos, args, aggMode, false);
+ } else {
+ TVector<TNodePtr> pgCallArgs;
+ pgCallArgs.push_back(BuildLiteralRawString(pos, name));
+ pgCallArgs.insert(pgCallArgs.end(), args.begin(), args.end());
+ return new TYqlPgCall(pos, pgCallArgs);
+ }
} else if (name == "MakeLibraPreprocessor") {
if (args.size() != 1) {
return new TInvalidBuiltin(pos, TStringBuilder() << name << " requires exactly one argument");
@@ -3273,15 +3287,25 @@ TNodePtr BuildBuiltinFunc(TContext& ctx, TPosition pos, TString name, const TVec
return new TInvalidBuiltin(pos, "MULTI_AGGREGATE_BY is not allowed to use with AGGREGATION_FACTORY");
}
+ if (aggMode == EAggregateMode::Distinct) {
+ return new TInvalidBuiltin(pos, "DISTINCT can only be used in aggregation functions");
+ }
+
+ if (to_lower(*args[0]->GetLiteral("String")).StartsWith("pg::")) {
+ auto name = args[0]->GetLiteral("String")->substr(4);
+ const bool isAggregateFunc = NYql::NPg::HasAggregation(name);
+ if (!isAggregateFunc) {
+ return new TInvalidBuiltin(pos, TStringBuilder() << "Unknown aggregation function: " << *args[0]->GetLiteral("String"));
+ }
+
+ return BuildAggrFuncFactoryCallback(name, "", EAggrFuncTypeCallback::PG)(pos, args, aggMode, true);
+ }
+
auto aggrCallback = aggrFuncs.find(aggNormalizedName);
if (aggrCallback == aggrFuncs.end()) {
return new TInvalidBuiltin(pos, TStringBuilder() << "Unknown aggregation function: " << *args[0]->GetLiteral("String"));
}
- if (aggMode == EAggregateMode::Distinct) {
- return new TInvalidBuiltin(pos, "DISTINCT can only be used in aggregation functions");
- }
-
return (*aggrCallback).second(pos, args, aggMode, true).Release();
}
diff --git a/ydb/library/yql/sql/v1/node.cpp b/ydb/library/yql/sql/v1/node.cpp
index 3fc66734678..734c9d6b381 100644
--- a/ydb/library/yql/sql/v1/node.cpp
+++ b/ydb/library/yql/sql/v1/node.cpp
@@ -3123,6 +3123,15 @@ public:
Add("lambda", Q(params), body);
}
+ TLambdaNode(TPosition pos, TNodePtr params, TVector<TNodePtr> bodies)
+ : TAstListNode(pos)
+ {
+ Add("lambda", Q(params));
+ for (const auto& b : bodies) {
+ Add(b);
+ }
+ }
+
protected:
TPtr DoClone() const final {
return {};
@@ -3137,6 +3146,10 @@ TNodePtr BuildLambda(TPosition pos, TNodePtr params, TNodePtr body, const TStrin
return new TLambdaNode(pos, params, body, resName);
}
+TNodePtr BuildLambda(TPosition pos, TNodePtr params, const TVector<TNodePtr>& bodies) {
+ return new TLambdaNode(pos, params, bodies);
+}
+
TNodePtr BuildDataType(TPosition pos, const TString& typeName) {
return new TCallNodeImpl(pos, "DataType", {BuildQuotedAtom(pos, typeName, TNodeFlags::Default)});
}
diff --git a/ydb/library/yql/sql/v1/node.h b/ydb/library/yql/sql/v1/node.h
index 9ad0097b1c9..92e9c83cd8c 100644
--- a/ydb/library/yql/sql/v1/node.h
+++ b/ydb/library/yql/sql/v1/node.h
@@ -1210,6 +1210,7 @@ namespace NSQLTranslationV1 {
TNodePtr BuildAccess(TPosition pos, const TVector<INode::TIdPart>& ids, bool isLookup);
TNodePtr BuildBind(TPosition pos, const TString& module, const TString& alias);
TNodePtr BuildLambda(TPosition pos, TNodePtr params, TNodePtr body, const TString& resName = TString());
+ TNodePtr BuildLambda(TPosition pos, TNodePtr params, const TVector<TNodePtr>& bodies);
TNodePtr BuildDataType(TPosition pos, const TString& typeName);
TMaybe<TString> LookupSimpleType(const TStringBuf& alias, bool flexibleTypes, bool isPgType);
TNodePtr BuildSimpleType(TContext& ctx, TPosition pos, const TString& typeName, bool dataOnly);
@@ -1237,6 +1238,7 @@ namespace NSQLTranslationV1 {
TAggregationPtr BuildPercentileFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode);
TAggregationPtr BuildCountAggregation(TPosition pos, const TString& name, const TString& func, EAggregateMode aggMode);
TAggregationPtr BuildUserDefinedFactoryAggregation(TPosition pos, const TString& name, const TString& factory, EAggregateMode aggMode);
+ TAggregationPtr BuildPGFactoryAggregation(TPosition pos, const TString& name, EAggregateMode aggMode);
// Implemented in builtin.cpp