@@ -5570,7 +5570,7 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
5570
5570
std::string_view arrowFunctionName;
5571
5571
const bool rewriteAsIs = node->IsCallable({"AssumeStrict", "AssumeNonStrict", "Likely"});
5572
5572
if (node->IsList() || rewriteAsIs ||
5573
- node->IsCallable({"And", "Or", "Xor", "Not", "Coalesce", "Exists", "If", "Just", "Member", "Nth", "ToPg", "FromPg", "PgResolvedCall", "PgResolvedOp"}))
5573
+ node->IsCallable({"And", "Or", "Xor", "Not", "Coalesce", "Exists", "If", "Just", "AsStruct", " Member", "Nth", "ToPg", "FromPg", "PgResolvedCall", "PgResolvedOp"}))
5574
5574
{
5575
5575
if (node->IsCallable() && !IsSupportedAsBlockType(node->Pos(), *node->GetTypeAnn(), ctx, types)) {
5576
5576
return true;
@@ -5609,6 +5609,29 @@ bool CollectBlockRewrites(const TMultiExprType* multiInputType, bool keepInputCo
5609
5609
}
5610
5610
}
5611
5611
5612
+ // <AsStruct> arguments (i.e. members of the resulting structure)
5613
+ // are literal tuples, that don't propagate their child rewrites.
5614
+ // Hence, process these rewrites the following way: wrap the
5615
+ // complete expressions, supported by the block engine, with
5616
+ // <AsScalar> callable or apply the rewrite of one is found.
5617
+ // Otherwise, abort this <AsStruct> rewrite, since one of its
5618
+ // arguments is neither block nor scalar.
5619
+ if (node->IsCallable("AsStruct")) {
5620
+ for (ui32 index = 0; index < node->ChildrenSize(); index++) {
5621
+ auto member = funcArgs[index];
5622
+ auto child = member->TailPtr();
5623
+ TExprNodePtr rewrite;
5624
+ if (child->IsComplete() && IsSupportedAsBlockType(child->Pos(), *child->GetTypeAnn(), ctx, types)) {
5625
+ rewrite = ctx.NewCallable(child->Pos(), "AsScalar", { child });
5626
+ } else if (auto rit = rewrites.find(child.Get()); rit != rewrites.end()) {
5627
+ rewrite = rit->second;
5628
+ } else {
5629
+ return true;
5630
+ }
5631
+ funcArgs[index] = ctx.NewList(member->Pos(), {member->HeadPtr(), rewrite});
5632
+ }
5633
+ }
5634
+
5612
5635
const TString blockFuncName = rewriteAsIs ? ToString(node->Content()) :
5613
5636
(TString("Block") + (node->IsList() ? "AsTuple" : node->Content()));
5614
5637
if (node->IsCallable({"And", "Or", "Xor"}) && funcArgs.size() > 2) {
0 commit comments