@@ -368,21 +368,22 @@ IGraphTransformer::TStatus PgCallWrapper(const TExprNode::TPtr& input, TExprNode
368368 const auto procOrType = NPg::LookupProcWithCasts (TString (name), argTypes);
369369 auto children = input->ChildrenList ();
370370 if (const auto * procPtr = std::get_if<const NPg::TProcDesc*>(&procOrType)) {
371- auto idNode = ctx.Expr .NewAtom (input->Pos (), ToString ((*procPtr)->ProcId ));
371+ const auto & proc = *(*procPtr);
372+ auto idNode = ctx.Expr .NewAtom (input->Pos (), ToString (proc.ProcId ));
372373 children.insert (children.begin () + 1 , idNode);
373374
374- const auto & fargTypes = (*procPtr)-> ArgTypes ;
375+ const auto & fargTypes = proc. ArgTypes ;
375376 for (size_t i = 0 ; i < argTypes.size (); ++i) {
376- auto targetType = (i >= fargTypes.size ()) ? (*procPtr)-> VariadicType : fargTypes[i];
377+ auto targetType = (i >= fargTypes.size ()) ? proc. VariadicType : fargTypes[i];
377378 if (IsCastRequired (argTypes[i], targetType)) {
378379 children[i+3 ] = WrapWithPgCast (std::move (children[i+3 ]), targetType, ctx.Expr );
379380 }
380381 }
381382
382383 if (argTypes.size () < fargTypes.size ()) {
383- YQL_ENSURE (fargTypes.size () - argTypes.size () <= (*procPtr)-> DefaultArgs .size ());
384+ YQL_ENSURE (fargTypes.size () - argTypes.size () <= proc. DefaultArgs .size ());
384385 for (size_t i = argTypes.size (); i < fargTypes.size (); ++i) {
385- const auto & value = (*procPtr)-> DefaultArgs [i + (*procPtr)-> DefaultArgs .size () - fargTypes.size ()];
386+ const auto & value = proc. DefaultArgs [i + proc. DefaultArgs .size () - fargTypes.size ()];
386387 TExprNode::TPtr defNode;
387388 if (!value) {
388389 defNode = ctx.Expr .NewCallable (input->Pos (), " Null" , {});
@@ -399,6 +400,27 @@ IGraphTransformer::TStatus PgCallWrapper(const TExprNode::TPtr& input, TExprNode
399400 children.insert (children.end (), defNode);
400401 }
401402 }
403+
404+ if (proc.Lang == NPg::LangSQL) {
405+ if (!proc.ExprNode ) {
406+ throw yexception () << " Function " << proc.Name << " has no implementation" ;
407+ }
408+
409+ // substibute by lambda
410+ YQL_ENSURE (proc.ExprNode ->IsLambda ());
411+ YQL_ENSURE (proc.ExprNode ->Head ().ChildrenSize () == fargTypes.size ());
412+ TNodeOnNodeOwnedMap deepClones;
413+ YQL_ENSURE (NPg::GetSqlLanguageParser ());
414+ auto lambda = ctx.Expr .DeepCopy (*proc.ExprNode , NPg::GetSqlLanguageParser ()->GetContext (), deepClones, true , false );
415+ TNodeOnNodeOwnedMap replaces;
416+ for (ui32 i = 0 ; i < fargTypes.size (); ++i) {
417+ replaces[lambda->Head ().Child (i)] = children[i + 3 ];
418+ }
419+
420+ output = ctx.Expr .ReplaceNodes (lambda->TailPtr (), replaces);
421+ return IGraphTransformer::TStatus::Repeat;
422+ }
423+
402424 output = ctx.Expr .NewCallable (input->Pos (), " PgResolvedCall" , std::move (children));
403425 } else if (const auto * typePtr = std::get_if<const NPg::TTypeDesc*>(&procOrType)) {
404426 output = WrapWithPgCast (std::move (children[2 ]), (*typePtr)->TypeId , ctx.Expr );
0 commit comments