Browse Source

HPCC-16715 Improve generated code for COUNT(DATASET(<set>, record))

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 8 years ago
parent
commit
b8f7673fdd
3 changed files with 28 additions and 3 deletions
  1. 7 0
      ecl/hql/hqlfold.cpp
  2. 3 0
      ecl/hqlcpp/hqlcppds.cpp
  3. 18 3
      ecl/hqlcpp/hqlttcpp.cpp

+ 7 - 0
ecl/hql/hqlfold.cpp

@@ -5474,6 +5474,13 @@ IHqlExpression * CExprFolderTransformer::doFoldTransformed(IHqlExpression * unfo
                 if (isNoSkipInlineDataset(child))
                     return createConstant(expr->queryType()->castFrom(false, (__int64)child->queryChild(0)->numChildren()));
                 break;
+            case no_temptable:
+            {
+                IHqlExpression * values = child->queryChild(0);
+                if (values->isList())
+                    return createValue(no_countlist, expr->getType(), LINK(values));
+                break;
+            }
             case no_null:
                 return createNullValue(expr);
 #if 0

+ 3 - 0
ecl/hqlcpp/hqlcppds.cpp

@@ -1092,6 +1092,9 @@ bool HqlCppTranslator::canBuildOptimizedCount(BuildCtx & ctx, IHqlExpression * d
     case no_rows:
     case no_id2blob:
         break;
+    case no_temptable:
+        //Temp table always calculates the entire dataset first - so the count will be available
+        break;
     case no_inlinetable:
     {
         OwnedHqlExpr count = queryFixedRowCount(dataset);

+ 18 - 3
ecl/hqlcpp/hqlttcpp.cpp

@@ -4731,6 +4731,23 @@ void OptimizeActivityTransformer::analyseExpr(IHqlExpression * expr)
     NewHqlTransformer::analyseExpr(expr);
 }
 
+static bool isWorthLimitingDataset(IHqlExpression * ds)
+{
+    node_operator dsOp = ds->getOperator();
+    switch (dsOp)
+    {
+    //Any dataset expression which is evaluated in a single go, rather than iterated is likely to be better
+    //especially if it is evaluated as an inline operation.
+    case no_select:
+    case no_choosen:
+    case no_rows:
+    case no_temptable:
+    case no_getresult:
+        return false;
+    }
+    return true;
+}
+
 //either a simple count, or isCountAggregate is guaranteed to be true - so structure is well defined
 IHqlExpression * OptimizeActivityTransformer::insertChoosen(IHqlExpression * lhs, IHqlExpression * limit, __int64 limitDelta)
 {
@@ -4746,9 +4763,7 @@ IHqlExpression * OptimizeActivityTransformer::insertChoosen(IHqlExpression * lhs
     case no_count:
     case no_newaggregate:
         {
-            //count on a child dataset is better if not limited...
-            node_operator dsOp = ds->getOperator();
-            if ((dsOp == no_select) || (dsOp == no_choosen) || (dsOp == no_rows))
+            if (!isWorthLimitingDataset(ds))
                 return NULL;
             args.append(*createDataset(no_choosen, LINK(ds), adjustValue(limit, limitDelta)));
             break;