瀏覽代碼

HPCC-15075 Implement inline COMBINE generation

Signed-off-by: Jake Smith <jake.smith@lexisnexis.com>
Jake Smith 9 年之前
父節點
當前提交
6c1e8cacc7
共有 4 個文件被更改,包括 70 次插入14 次删除
  1. 12 12
      ecl/hqlcpp/hqlcpp.cpp
  2. 4 0
      ecl/hqlcpp/hqlcpp.ipp
  3. 42 2
      ecl/hqlcpp/hqlcppds.cpp
  4. 12 0
      ecl/hqlcpp/hqlinline.cpp

+ 12 - 12
ecl/hqlcpp/hqlcpp.cpp

@@ -7972,25 +7972,25 @@ void HqlCppTranslator::doBuildAssignUnicodeOrder(BuildCtx & ctx, const CHqlBound
 //---------------------------------------------------------------------------
 //-- no_order --
 
-static void buildIteratorFirst(HqlCppTranslator & translator, BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row)
+static void buildIteratorIsValid(BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row, CHqlBoundExpr & bound)
 {
-    StringBuffer s;
-    translator.generateExprCpp(s, row).append(" = (byte*)");
-    translator.generateExprCpp(s, iter).append(".first();");
-    ctx.addQuoted(s);
+    bound.expr.set(row);
 }
 
-static void buildIteratorNext(HqlCppTranslator & translator, BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row)
+void HqlCppTranslator::buildIteratorFirst(BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row)
 {
     StringBuffer s;
-    translator.generateExprCpp(s, row).append(" = (byte*)");
-    translator.generateExprCpp(s, iter).append(".next();");
+    generateExprCpp(s, row).append(" = (byte*)");
+    generateExprCpp(s, iter).append(".first();");
     ctx.addQuoted(s);
 }
 
-static void buildIteratorIsValid(BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row, CHqlBoundExpr & bound)
+void HqlCppTranslator::buildIteratorNext(BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row)
 {
-    bound.expr.set(row);
+    StringBuffer s;
+    generateExprCpp(s, row).append(" = (byte*)");
+    generateExprCpp(s, iter).append(".next();");
+    ctx.addQuoted(s);
 }
 
 void HqlCppTranslator::doBuildAssignCompareRow(BuildCtx & ctx, EvaluateCompareInfo & info, IHqlExpression * left, IHqlExpression * right)
@@ -8021,7 +8021,7 @@ void HqlCppTranslator::doBuildAssignCompareTable(BuildCtx & ctx, EvaluateCompare
     HqlExprAttr leftIter, leftRow;
     Owned<IHqlCppDatasetCursor> cursor = createDatasetSelector(subctx, left);
     cursor->buildIterateClass(subctx, leftIter, leftRow);
-    buildIteratorFirst(*this, subctx, leftIter, leftRow);
+    buildIteratorFirst(subctx, leftIter, leftRow);
 
     // i2; forEachIn(i2); {
     CHqlBoundExpr isValid;
@@ -8070,7 +8070,7 @@ void HqlCppTranslator::doBuildAssignCompareTable(BuildCtx & ctx, EvaluateCompare
         }
 
         //     i1.next();
-        buildIteratorNext(*this, loopctx, leftIter, leftRow);
+        buildIteratorNext(loopctx, leftIter, leftRow);
     }
 
     buildIteratorIsValid(subctx, leftIter, leftRow, isValid);

+ 4 - 0
ecl/hqlcpp/hqlcpp.ipp

@@ -1239,6 +1239,7 @@ public:
 
     void buildDatasetAssignAggregate(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr);
     void buildDatasetAssignChoose(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr);
+    void buildDatasetAssignCombine(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr);
     void buildDatasetAssignInlineTable(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr);
     void buildDatasetAssignDatasetFromTransform(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr);
     void buildDatasetAssignJoin(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr);
@@ -1270,6 +1271,7 @@ public:
     void doBuildRowAssignAggregate(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
     void doBuildRowAssignAggregateClear(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
     void doBuildRowAssignAggregateNext(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr, bool isSingleExists, IHqlExpression * guard);
+    void doBuildRowAssignCombine(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
     void doBuildRowAssignNullRow(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
     void doBuildRowAssignProject(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
     void doBuildRowAssignUserTable(BuildCtx & ctx, IReferenceSelector * target, IHqlExpression * expr);
@@ -1787,6 +1789,8 @@ public:
     void filterExpandAssignments(BuildCtx & ctx, TransformBuilder * builder, HqlExprArray & assigns, IHqlExpression * expr);
 
 protected:
+    void buildIteratorFirst(BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row);
+    void buildIteratorNext(BuildCtx & ctx, IHqlExpression * iter, IHqlExpression * row);
     bool shouldEvaluateSelectAsAlias(BuildCtx & ctx, IHqlExpression * expr);
     IWUResult * createWorkunitResult(int sequence, IHqlExpression * nameExpr);
     void noteFilename(ActivityInstance & instance, const char * name, IHqlExpression * expr, bool isDynamic);

+ 42 - 2
ecl/hqlcpp/hqlcppds.cpp

@@ -3236,6 +3236,42 @@ public:
     }
 };
 
+void HqlCppTranslator::buildDatasetAssignCombine(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr)
+{
+    BuildCtx iterctx(ctx);
+    IHqlExpression *left = expr->queryChild(0);
+    IHqlExpression *right = expr->queryChild(1);
+
+    iterctx.addGroup();  // stop bound cursors leaking outside the block.
+
+    // i1 iter1; i1.first();
+    HqlExprAttr rightIter, rightRow;
+    Owned<IHqlCppDatasetCursor> cursor = createDatasetSelector(iterctx, right);
+    cursor->buildIterateClass(iterctx, rightIter, rightRow);
+    buildIteratorFirst(iterctx, rightIter, rightRow);
+
+    BoundRow * sourceCursor = buildDatasetIterate(iterctx, left, false);
+    if (!sourceCursor)
+        return;
+
+    bindTableCursor(iterctx, right, rightRow, no_right, querySelSeq(expr));
+
+    BoundRow * targetRow = target->buildCreateRow(iterctx);
+
+    Owned<IReferenceSelector> targetRef = buildActiveRow(iterctx, targetRow->querySelector());
+    doBuildRowAssignProject(iterctx, targetRef, expr);
+
+    target->finishRow(iterctx, targetRow);
+
+    //     i1.next();
+    buildIteratorNext(iterctx, rightIter, rightRow);
+
+    /* TODO: Need to check -
+     * a) Whether excess rhs rows and fail with error
+     * b) Whether hit end of stream on RHS..
+     */
+}
+
 void HqlCppTranslator::buildDatasetAssignProject(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr)
 {
     BuildCtx iterctx(ctx);
@@ -3287,7 +3323,6 @@ void HqlCppTranslator::buildDatasetAssignProject(BuildCtx & ctx, IHqlCppDatasetB
     }
 }
 
-
 void HqlCppTranslator::buildDatasetAssignJoin(BuildCtx & ctx, IHqlCppDatasetBuilder * target, IHqlExpression * expr)
 {
     IHqlExpression * left = expr->queryChild(0);
@@ -3480,6 +3515,9 @@ void HqlCppTranslator::buildDatasetAssign(BuildCtx & ctx, IHqlCppDatasetBuilder
     case no_newusertable:
         buildDatasetAssignProject(subctx, target, expr);
         return;
+    case no_combine:
+        buildDatasetAssignCombine(subctx, target, expr);
+        return;
     case no_compound_childread:
     case no_compound_childnormalize:
     case no_compound_childaggregate:
@@ -4312,7 +4350,9 @@ void HqlCppTranslator::doBuildRowAssignProject(BuildCtx & ctx, IReferenceSelecto
     IHqlExpression * selSeq = querySelSeq(expr);
     OwnedHqlExpr leftSelect = createSelector(no_left, dataset, selSeq);
     OwnedHqlExpr activeDataset = ensureActiveRow(dataset->queryNormalizedSelector());
-    OwnedHqlExpr transform = queryNewReplaceSelector(expr->queryChild(1), leftSelect, activeDataset);
+
+    // queryChild(1) should be changed to queryTransformExpr()...
+    OwnedHqlExpr transform = queryNewReplaceSelector(queryNewColumnProvider(expr), leftSelect, activeDataset);
     Owned<BoundRow> selfCursor;
     if (!transform)
     {

+ 12 - 0
ecl/hqlcpp/hqlinline.cpp

@@ -139,6 +139,18 @@ static unsigned calcInlineFlags(BuildCtx * ctx, IHqlExpression * expr)
             //Always effectively requires a temporary
             return RETassign;
         }
+    case no_combine:
+		{
+			//can't do a skip inside an inline combine - since the generated code doesn't allow "continue" to be used.
+			if (transformContainsSkip(expr->queryChild(2)))
+				return 0;
+			unsigned lhsChildFlags = getInlineFlags(ctx, expr->queryChild(0));
+			unsigned rhsChildFlags = getInlineFlags(ctx, expr->queryChild(1));
+
+			if (lhsChildFlags && rhsChildFlags)
+				return RETiterate;
+			return 0;
+		}
     case no_hqlproject:
         //can't do a skip inside an inline project - since the generated code doesn't allow "continue" to be used.
         if (transformContainsSkip(expr->queryChild(1)))