Explorar el Código

HPCC-16697 Fix problem commoning conditional and unconditional expressions

If the first use of an expression is conditional, but subsequent uses
are unconditional, then the common expression must be evaluated
unconditionally.  This includes if the graph is inside a scalar
conditional context.

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday hace 8 años
padre
commit
2b99de3312
Se han modificado 2 ficheros con 26 adiciones y 7 borrados
  1. 24 7
      ecl/hqlcpp/hqlttcpp.cpp
  2. 2 0
      ecl/hqlcpp/hqlttcpp.ipp

+ 24 - 7
ecl/hqlcpp/hqlttcpp.cpp

@@ -8305,6 +8305,18 @@ void AutoScopeMigrateTransformer::analyseExpr(IHqlExpression * expr)
     activityDepth = savedDepth;
 }
 
+void AutoScopeMigrateTransformer::doAnalyseConditionalExpr(IHqlExpression * expr, unsigned firstConditional)
+{
+    bool wasConditional = isConditional;
+    ForEachChild(i, expr)
+    {
+        if (i == firstConditional)
+            isConditional = true;
+       analyseExpr(expr->queryChild(i));
+    }
+    isConditional = wasConditional;
+}
+
 void AutoScopeMigrateTransformer::doAnalyseExpr(IHqlExpression * expr)
 {
     AutoScopeMigrateInfo * extra = queryBodyExtra(expr);
@@ -8336,15 +8348,11 @@ void AutoScopeMigrateTransformer::doAnalyseExpr(IHqlExpression * expr)
         return;
     case no_if:
     case no_choose:
+    case no_case:
         {
-            if (expr->isAction())
+            if (expr->isAction() || (graphDepth == 0))
             {
-                bool wasConditional = isConditional;
-                analyseExpr(expr->queryChild(0));
-                isConditional = true;
-                ForEachChildFrom(i, expr, 1)
-                    analyseExpr(expr->queryChild(i));
-                isConditional = wasConditional;
+                doAnalyseConditionalExpr(expr, 1);
                 return;
             }
             break;
@@ -8359,13 +8367,22 @@ void AutoScopeMigrateTransformer::doAnalyseExpr(IHqlExpression * expr)
             return;
         }
         break;
+    case no_map:
+        if (expr->isAction() || (graphDepth == 0))
+        {
+            doAnalyseConditionalExpr(expr, 0);
+            return;
+        }
+        break;
     case no_thor:
         //ignore thor attribute on a dataset..
         if (expr->queryType())
         {
             curGraph++;
+            graphDepth++;
             NewHqlTransformer::analyseExpr(expr);
             curGraph++;     // don't restore - new pseudo graph to aid cse between global branches separated by graphs
+            graphDepth--;
             return;
         }
         break;

+ 2 - 0
ecl/hqlcpp/hqlttcpp.ipp

@@ -744,6 +744,7 @@ protected:
     IHqlExpression * hoist(IHqlExpression * expr, IHqlExpression * hoisted);
     IHqlExpression * transformCond(IHqlExpression * expr);
     void doAnalyseExpr(IHqlExpression * expr);
+    void doAnalyseConditionalExpr(IHqlExpression * expr, unsigned firstConditional);
 
     inline AutoScopeMigrateInfo * queryBodyExtra(IHqlExpression * expr)     { return static_cast<AutoScopeMigrateInfo *>(queryTransformExtra(expr->queryBody())); }
 
@@ -755,6 +756,7 @@ private:
     bool hasCandidate;
     bool isSequential;
     unsigned curGraph;
+    unsigned graphDepth = 0;
     HqlExprArray graphActions;
     unsigned activityDepth;
     HqlExprArray * globalTarget;