From 36225f583df2a2b2ff019005b3e4ab30e8ab2687 Mon Sep 17 00:00:00 2001 From: Gavin Halliday Date: Thu, 29 Sep 2022 16:05:17 +0100 Subject: [PATCH] HPCC-28338 Avoid re-evaluating the inputs to row PROJECT Signed-off-by: Gavin Halliday --- ecl/hqlcpp/hqlcppds.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/ecl/hqlcpp/hqlcppds.cpp b/ecl/hqlcpp/hqlcppds.cpp index 8fe3bd36043..f377252396d 100644 --- a/ecl/hqlcpp/hqlcppds.cpp +++ b/ecl/hqlcpp/hqlcppds.cpp @@ -4601,15 +4601,27 @@ void HqlCppTranslator::doBuildRowAssignProjectRow(BuildCtx & ctx, IReferenceSele IHqlExpression * srcRow = expr->queryChild(0); IHqlExpression * transform = expr->queryChild(1); + //Evaluate the row expression here - otherwise it could be re-evaluated lots of times depending on the context it is used Owned source = buildNewRow(ctx, srcRow); BuildCtx subctx(ctx); - OwnedHqlExpr leftSelect = createSelector(no_left, srcRow, querySelSeq(expr)); - OwnedHqlExpr newRow = srcRow->getOperator() == no_select ? LINK(srcRow) : createRow(no_newrow, LINK(srcRow)); - OwnedHqlExpr newTransform = replaceSelector(transform, leftSelect, newRow); + if (!source->isRoot()) + { + OwnedHqlExpr leftSelect = createSelector(no_left, srcRow, querySelSeq(expr)); + OwnedHqlExpr newRow = srcRow->getOperator() == no_select ? LINK(srcRow) : createRow(no_newrow, LINK(srcRow)); + OwnedHqlExpr newTransform = replaceSelector(transform, leftSelect, newRow); - Owned selfCursor = target->getRow(subctx); - doTransform(subctx, newTransform, selfCursor); + Owned selfCursor = target->getRow(subctx); + doTransform(subctx, newTransform, selfCursor); + } + else + { + //Alternative implementation that rebinds the selector and uses that directly + BoundRow * bound = source->getRow(subctx); + bindTableCursor(subctx, srcRow, bound->queryBound(), no_left, querySelSeq(expr)); + Owned selfCursor = target->getRow(subctx); + doTransform(subctx, transform, selfCursor); + } } void HqlCppTranslator::doBuildRowAssignSerializeRow(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr)