Browse Source

Merge pull request #4650 from ghalliday/issue9707

HPCC-9707 Ensure scalar and set datasets are always hoisted

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 12 năm trước cách đây
mục cha
commit
39a7ec1595

+ 19 - 3
ecl/hqlcpp/hqlresource.cpp

@@ -1003,6 +1003,7 @@ ResourcerInfo::ResourcerInfo(IHqlExpression * _original, CResourceOptions * _opt
     balanced = true;
     balanced = true;
     currentSource = 0;
     currentSource = 0;
     linkedFromChild = false;
     linkedFromChild = false;
+    forceHoist = false;
     neverSplit = false;
     neverSplit = false;
     isConditionalFilter = false;
     isConditionalFilter = false;
     projectResult = true; // projected must also be non empty to actually project this dataset
     projectResult = true; // projected must also be non empty to actually project this dataset
@@ -1353,6 +1354,19 @@ bool ResourcerInfo::okToSpillThrough()
     return (options->allowThroughSpill && !options->createSpillAsDataset);
     return (options->allowThroughSpill && !options->createSpillAsDataset);
 }
 }
 
 
+void ResourcerInfo::noteUsedFromChild(bool _forceHoist)
+{
+    linkedFromChild = true;
+    outputToUseForSpill = NULL;
+    if (_forceHoist)
+        forceHoist = true;
+}
+
+unsigned ResourcerInfo::numInternalUses()
+{
+    return numUses - numExternalUses - aggregates.ordinality();
+}
+
 bool ResourcerInfo::spillSharesSplitter()
 bool ResourcerInfo::spillSharesSplitter()
 {
 {
     if (outputToUseForSpill || useGraphResult() || useGlobalResult())
     if (outputToUseForSpill || useGraphResult() || useGlobalResult())
@@ -1480,6 +1494,8 @@ bool ResourcerInfo::expandRatherThanSpill(bool noteOtherSpills)
         ResourcerInfo * info = queryResourceInfo(expr);
         ResourcerInfo * info = queryResourceInfo(expr);
         if (info && info->neverSplit)
         if (info && info->neverSplit)
             return true;
             return true;
+        if (info && info->forceHoist)
+            return false;
 
 
         node_operator op = expr->getOperator();
         node_operator op = expr->getOperator();
         switch (op)
         switch (op)
@@ -1996,7 +2012,7 @@ public:
             if (!hoisted)
             if (!hoisted)
                 hoisted = expr;
                 hoisted = expr;
 
 
-            CChildDependent & depend = * new CChildDependent(expr, hoisted, alwaysHoist, alwaysSingle);
+            CChildDependent & depend = * new CChildDependent(expr, hoisted, alwaysHoist, alwaysSingle, false);
             matched.append(depend);
             matched.append(depend);
         }
         }
         else
         else
@@ -2061,7 +2077,7 @@ public:
                 hoisted.setown(createRow(no_createrow, LINK(transform)));
                 hoisted.setown(createRow(no_createrow, LINK(transform)));
             }
             }
 
 
-            CChildDependent & depend = * new CChildDependent(expr, hoisted, true, true);
+            CChildDependent & depend = * new CChildDependent(expr, hoisted, true, true, true);
             depend.projected = projected;
             depend.projected = projected;
             matched.append(depend);
             matched.append(depend);
         }
         }
@@ -3809,7 +3825,7 @@ void EclResourcer::addDependencies(IHqlExpression * expr, ResourceGraphInfo * gr
 
 
             ResourcerInfo * sourceInfo = queryResourceInfo(cur.projectedHoisted);
             ResourcerInfo * sourceInfo = queryResourceInfo(cur.projectedHoisted);
             if (cur.isSingleNode)
             if (cur.isSingleNode)
-                sourceInfo->noteUsedFromChild();
+                sourceInfo->noteUsedFromChild(cur.forceHoist);
             ResourceGraphLink * link = new ResourceGraphDependencyLink(sourceInfo->graph, cur.projectedHoisted, graph, expr);
             ResourceGraphLink * link = new ResourceGraphDependencyLink(sourceInfo->graph, cur.projectedHoisted, graph, expr);
             graph->dependsOn.append(*link);
             graph->dependsOn.append(*link);
             links.append(*link);
             links.append(*link);

+ 6 - 4
ecl/hqlcpp/hqlresource.ipp

@@ -206,8 +206,8 @@ public:
 class CChildDependent : public CInterface
 class CChildDependent : public CInterface
 {
 {
 public:
 public:
-    CChildDependent(IHqlExpression * _original, IHqlExpression * _hoisted, bool _alwaysHoist, bool _isSingleNode)
-    : original(_original), hoisted(_hoisted), alwaysHoist(_alwaysHoist), isSingleNode(_isSingleNode)
+    CChildDependent(IHqlExpression * _original, IHqlExpression * _hoisted, bool _alwaysHoist, bool _isSingleNode, bool _forceHoist)
+    : original(_original), hoisted(_hoisted), alwaysHoist(_alwaysHoist), isSingleNode(_isSingleNode), forceHoist(_forceHoist)
     {
     {
         projectedHoisted.set(hoisted);
         projectedHoisted.set(hoisted);
         projected = NULL;
         projected = NULL;
@@ -217,6 +217,7 @@ public:
     IHqlExpression * original;
     IHqlExpression * original;
     LinkedHqlExpr hoisted;
     LinkedHqlExpr hoisted;
     LinkedHqlExpr projectedHoisted;
     LinkedHqlExpr projectedHoisted;
+    bool forceHoist;
     bool alwaysHoist;
     bool alwaysHoist;
     bool isSingleNode;
     bool isSingleNode;
     IHqlExpression * projected;
     IHqlExpression * projected;
@@ -251,8 +252,8 @@ public:
     bool isSplit();
     bool isSplit();
     bool isSpilledWrite();
     bool isSpilledWrite();
     bool okToSpillThrough();
     bool okToSpillThrough();
-    void noteUsedFromChild()            { linkedFromChild = true; outputToUseForSpill = NULL; }
-    unsigned numInternalUses()          { return numUses - numExternalUses - aggregates.ordinality(); }
+    void noteUsedFromChild(bool _forceHoist);
+    unsigned numInternalUses();
     unsigned numSplitPaths();
     unsigned numSplitPaths();
     void setConditionSource(IHqlExpression * condition, bool isFirst);
     void setConditionSource(IHqlExpression * condition, bool isFirst);
 
 
@@ -323,6 +324,7 @@ public:
     bool balanced;
     bool balanced;
     bool isAlreadyInScope;
     bool isAlreadyInScope;
     bool linkedFromChild;
     bool linkedFromChild;
+    bool forceHoist;
     bool neverSplit;
     bool neverSplit;
     byte pathToExpr;
     byte pathToExpr;
     bool isConditionalFilter;
     bool isConditionalFilter;