Browse Source

HPCC-21876 Allow ONCE to be used inside workflow items

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 6 years ago
parent
commit
693bf9d998

+ 6 - 28
ecl/hqlcpp/hqlttcpp.cpp

@@ -5919,7 +5919,6 @@ WorkflowTransformer::WorkflowTransformer(IWorkUnit * _wu, HqlCppTranslator & _tr
     const HqlCppOptions & options = translator.queryOptions();
     trivialStoredWfid = 0;
     nextInternalFunctionId = 0;
-    onceWfid = 0;
     combineAllStored = options.combineAllStored;
     combineTrivialStored = options.combineTrivialStored;
     expandPersistInputDependencies = options.expandPersistInputDependencies;
@@ -6326,22 +6325,9 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
 
         if (info.persistOp == no_once)
         {
-            //MORE: Error if refers to stored or persist
+            //MORE: Error if refers to stored or persist - this test could be relaxed
             if (queryDirectDependencies(setValue).ordinality())
                 translator.ERRORAT(queryLocation(untransformed), HQLERR_OnceCannotAccessStored);
-
-            if (onceWfid == 0)
-            {
-                onceWfid = wfid;
-            }
-            else
-            {
-                wfid = onceWfid;
-                wfidCount--;
-            }
-            if (!onceExprs.contains(*setValue))
-                onceExprs.append(*LINK(setValue));
-            done = true;
         }
 
         if (combineTrivialStored && isTrivialStored(setValue))
@@ -6429,7 +6415,10 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
                 inheritDependencies(cluster);
                 setValue.set(cluster);
             }
-            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(setValue), conts, info.queryCluster(), info.queryLabel());
+            WFMode wfMode = (info.persistOp == no_once) ? WFModeOnce : WFModeNormal;
+            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, wfMode, queryDirectDependencies(setValue), conts, info.queryCluster(), info.queryLabel());
+            if (info.persistOp == no_once)
+                wf->setScheduledNow();
             addWorkflowItem(*createWorkflowItem(setValue, wfid, info.persistOp, info.queryLabel()));
         }
     }
@@ -6795,7 +6784,7 @@ bool WorkflowTransformer::hasNonTrivialDependencies(IHqlExpression * expr)
     ForEachItemIn(i, dependencies)
     {
         unsigned cur = dependencies.item(i);
-        if ((cur != trivialStoredWfid) && (cur != onceWfid))
+        if (cur != trivialStoredWfid)
             return true;
     }
     return false;
@@ -7138,8 +7127,6 @@ IHqlExpression * WorkflowTransformer::transformSequentialEtc(IHqlExpression * ex
     //Ignore differences in access to trivial stored variables.
     if (trivialStoredWfid)
         cumulativeDependencies.append(trivialStoredWfid);
-    if (onceWfid)
-        cumulativeDependencies.append(onceWfid);
     OwnedHqlExpr ret = transformRootAction(expr);
     restoreDependencies(mark);
     return ret.getClear();
@@ -7257,15 +7244,6 @@ void WorkflowTransformer::transformRoot(const HqlExprArray & in, WorkflowArray &
             transformed.append(*ret.getClear());
     }
 
-    if (onceExprs.length())
-    {
-        //By definition they don't have any dependencies, so no need to call inheritDependencies.
-        OwnedHqlExpr onceExpr = createActionList(onceExprs);
-        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(onceWfid, WFTypeNormal, WFModeOnce, queryDirectDependencies(onceExpr), NULL, "ONCE");
-        wf->setScheduledNow();
-        addWorkflowItem(*createWorkflowItem(onceExpr, onceWfid, no_once, "ONCE"));
-    }
-
     if (trivialStoredExprs.length())
     {
         //By definition they don't have any dependencies, so no need to call inheritDependencies.

+ 0 - 2
ecl/hqlcpp/hqlttcpp.ipp

@@ -541,10 +541,8 @@ protected:
     HqlExprArray              alreadyProcessedUntransformed;
     HqlExprCopyArray          activeLocations;
     unsigned                  trivialStoredWfid;
-    unsigned                  onceWfid;
     unsigned                  nextInternalFunctionId;
     HqlExprArray              trivialStoredExprs;
-    HqlExprArray              onceExprs;
     bool                      combineAllStored;
     bool                      combineTrivialStored;
     bool                      isRootAction;

+ 23 - 0
ecl/regress/issue21876.ecl

@@ -0,0 +1,23 @@
+// H := 0;
+H := 0 : ONCE;
+
+ds := DATASET([
+
+{1,0,0,0,0}
+,
+
+{2,0,0,0,0}
+],
+
+{UNSIGNED1 rec,UNSIGNED Ival, UNSIGNED Gval , UNSIGNED Hval, UNSIGNED Aval }
+);
+
+RECORDOF(ds) XF(ds L) := TRANSFORM
+SELF.Hval := H;
+SELF := L;
+END;
+
+P1 := PROJECT(ds,XF(left)) : PERSIST('~RTTEST::PERSIST::IndependentVsGlobal1');
+
+OUTPUT(P1); 
+

+ 32 - 0
ecl/regress/issue21876orig.ecl

@@ -0,0 +1,32 @@
+I := RANDOM() : INDEPENDENT; //calculated once, period
+G := RANDOM() : GLOBAL; //calculated once in each graph
+// H := 0;
+H := RANDOM() : ONCE;
+
+ds := DATASET([
+
+{1,0,0,0,0}
+,
+
+{2,0,0,0,0}
+],
+
+{UNSIGNED1 rec,UNSIGNED Ival, UNSIGNED Gval , UNSIGNED Hval, UNSIGNED Aval }
+);
+
+RECORDOF(ds) XF(ds L) := TRANSFORM
+SELF.Ival := I;
+SELF.Gval := G;
+SELF.Hval := H;
+SELF.Aval := RANDOM(); //calculated each time used
+SELF := L;
+END;
+
+P1 := PROJECT(ds,XF(left)) : PERSIST('~RTTEST::PERSIST::IndependentVsGlobal1');
+P2 := PROJECT(ds,XF(left)) : PERSIST('~RTTEST::PERSIST::IndependentVsGlobal2');
+
+OUTPUT(P1); 
+OUTPUT(P2); //this gets the same Ival values as P1, but the Gval value is different than P1
+
+OUTPUT(P1); 
+OUTPUT(P2); //this gets the same Ival values as P1, but the Gval value is different than P1

+ 1 - 1
testing/regress/ecl/once2.ecl

@@ -22,4 +22,4 @@ d2 := DICTIONARY([{3=>4}], { unsigned a=>unsigned b}) : ONCE;
 
 unsigned v := 0 : STORED('v');
 
-d1[v].b + d2[v].b;
+d1[v].b + d2[v].b : independent;