Просмотр исходного кода

Merge pull request #10591 from ghalliday/issue18642

HPCC-18642 Allow user to set the label for independent workflow items

Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 7 лет назад
Родитель
Сommit
1f64f189ef

+ 1 - 0
common/workunit/workflow.cpp

@@ -175,6 +175,7 @@ public:
     virtual void         setState(WFState state) { setEnum(tree, "@state", state, wfstates); }
     virtual unsigned     queryScheduledWfid() const { return tree->getPropInt("@swfid", 0); }
     virtual void         setScheduledWfid(unsigned wfid) { tree->setPropInt("@swfid", wfid); }
+    virtual void         setLabel(const char * label) { tree->setProp("@label", label); }
     virtual bool         testAndDecRetries()
     {
         assertex(tree->hasProp("@retriesAllowed"));

+ 1 - 0
common/workunit/workunit.hpp

@@ -678,6 +678,7 @@ interface IWorkflowItem : extends IRuntimeWorkflowItem
     virtual void syncRuntimeData(const IConstWorkflowItem & other) = 0;
     virtual void setScheduledWfid(unsigned wfid) = 0;
     virtual void setCluster(const char * cluster) = 0;
+    virtual void setLabel(const char * label) = 0;
 };
 
 

+ 2 - 0
ecl/hql/hqlatoms.cpp

@@ -234,6 +234,7 @@ IAtom * jobTempAtom;
 IAtom * jsonAtom;
 IAtom * keepAtom;
 IAtom * keyedAtom;
+IAtom * labelAtom;
 IAtom * labeledAtom;
 IAtom * languageAtom;
 IAtom * lastAtom;
@@ -692,6 +693,7 @@ MODULE_INIT(INIT_PRIORITY_HQLATOM)
     MAKEATOM(json);
     MAKEATOM(keep);
     MAKEATOM(keyed);
+    MAKEATOM(label);
     MAKEATOM(labeled);
     MAKEATOM(language);
     MAKEATOM(last);

+ 1 - 0
ecl/hql/hqlatoms.hpp

@@ -238,6 +238,7 @@ extern HQL_API IAtom * jobTempAtom;
 extern HQL_API IAtom * jsonAtom;
 extern HQL_API IAtom * keepAtom;
 extern HQL_API IAtom * keyedAtom;
+extern HQL_API IAtom * labelAtom;
 extern HQL_API IAtom * labeledAtom;
 extern HQL_API IAtom * languageAtom;
 extern HQL_API IAtom * lastAtom;

+ 52 - 21
ecl/hql/hqlgram.y

@@ -272,6 +272,7 @@ static void eclsyntaxerror(HqlGram * parser, const char * s, short yystate, int
   KEYED
   KEYPATCH
   KEYUNICODE
+  LABEL
   LABELED
   LAST
   LEFT
@@ -1604,38 +1605,38 @@ failclause
     ;
 
 failure
-    : FAILURE '(' action ')'
+    : FAILURE '(' action commaIndependentOptions')'
                         {
-                            $$.setExpr(createValue(no_failure, $3.getExpr(), NULL), $1);
+                            $$.setExpr(createValueF(no_failure, makeNullType(), $3.getExpr(), $4.getExpr(), NULL), $1);
                         }
-    | SUCCESS '(' action ')'
+    | SUCCESS '(' action commaIndependentOptions ')'
                         {
-                            $$.setExpr(createValue(no_success, $3.getExpr(), NULL), $1);
+                            $$.setExpr(createValueF(no_success, makeNullType(), $3.getExpr(), $4.getExpr(), NULL), $1);
                         }
     | RECOVERY '(' action ')'
                         {
-                            $$.setExpr(createValue(no_recovery, $3.getExpr(), createConstant(1)), $1);
+                            $$.setExpr(createValue(no_recovery, makeNullType(), $3.getExpr(), createConstant(1)), $1);
                         }
     | RECOVERY '(' action ',' expression ')'
                         {
                             parser->normalizeExpression($5, type_int, true);
-                            $$.setExpr(createValue(no_recovery, $3.getExpr(), $5.getExpr()), $1);
+                            $$.setExpr(createValue(no_recovery, makeNullType(), $3.getExpr(), $5.getExpr()), $1);
                         }
     | WHEN '(' event ')'
                         {
                             parser->checkConstantEvent($3);
-                            $$.setExpr(createValue(no_when, $3.getExpr()), $1);
+                            $$.setExpr(createValue(no_when, makeNullType(), $3.getExpr()), $1);
                         }
     | WHEN '(' event ',' COUNT '(' expression ')'  ')'
                         {
                             parser->checkConstantEvent($3);
                             parser->normalizeExpression($7, type_int, true);
-                            $$.setExpr(createValue(no_when, $3.getExpr(), $7.getExpr()), $1);
+                            $$.setExpr(createValue(no_when, makeNullType(), $3.getExpr(), $7.getExpr()), $1);
                         }
     | PRIORITY '(' expression ')'
                         {
                             parser->normalizeExpression($3, type_int, true);
-                            $$.setExpr(createValue(no_priority, $3.getExpr()), $1);
+                            $$.setExpr(createValue(no_priority, makeNullType(), $3.getExpr()), $1);
                         }
     | PERSIST '(' expression ')'
                         {
@@ -1653,10 +1654,10 @@ failure
                             parser->normalizeExpression($5, type_string, true);
                             $$.setExpr(createValueF(no_persist, makeVoidType(), $3.getExpr(), $5.getExpr(), $6.getExpr(), NULL), $1);
                         }
-    | CRITICAL '(' expression ')'
+    | CRITICAL '(' expression commaIndependentOptions ')'
                         {
                             parser->normalizeExpression($3, type_string, true);
-                            $$.setExpr(createValueF(no_critical, makeVoidType(), $3.getExpr(), NULL), $1);
+                            $$.setExpr(createValueF(no_critical, makeVoidType(), $3.getExpr(), $4.getExpr(), NULL), $1);
                         }
     | STORED '(' startStoredAttrs expression ',' fewMany optStoredFieldFormat ')'
                         {
@@ -1675,28 +1676,28 @@ failure
                         }
     | GLOBAL                    
                         {
-                            $$.setExpr(createValue(no_global), $1);
+                            $$.setExpr(createValue(no_global, makeNullType()), $1);
                         }
     | GLOBAL '(' fewMany ')'
                         {
-                            $$.setExpr(createValue(no_global, $3.getExpr()), $1);
+                            $$.setExpr(createValue(no_global, makeNullType(), $3.getExpr()), $1);
                         }
     | GLOBAL '(' expression optFewMany ')'
                         {
                             parser->normalizeExpression($3, type_string, false);
-                            $$.setExpr(createValue(no_global, $3.getExpr(), $4.getExpr()), $1);
+                            $$.setExpr(createValue(no_global, makeNullType(), $3.getExpr(), $4.getExpr()), $1);
                         }
     | INDEPENDENT               
                         {
-                            $$.setExpr(createValue(no_independent), $1);
+                            $$.setExpr(createValue(no_independent, makeNullType()), $1);
                         }
-    | INDEPENDENT '(' fewMany ')'
+    | INDEPENDENT '(' independentOptions ')'
                         {
-                            $$.setExpr(createValue(no_independent, $3.getExpr()), $1);
+                            $$.setExpr(createValueF(no_independent, makeNullType(), $3.getExpr(), nullptr), $1);
                         }
-    | INDEPENDENT '(' expression optFewMany ')'
+    | INDEPENDENT '(' expression commaIndependentOptions ')'
                         {
-                            $$.setExpr(createValue(no_independent, $3.getExpr(), $4.getExpr()), $1);
+                            $$.setExpr(createValueF(no_independent, makeNullType(), $3.getExpr(), $4.getExpr(), nullptr), $1);
                         }
     | DEFINE '(' stringConstExpr ')'
                         {
@@ -1730,11 +1731,11 @@ failure
                         }
     | ONCE
                         {
-                            $$.setExpr(createValue(no_once, makeVoidType()), $1);
+                            $$.setExpr(createValue(no_once, makeNullType()), $1);
                         }
     | ONCE '(' fewMany ')'
                         {
-                            $$.setExpr(createValue(no_once, $3.getExpr()), $1);
+                            $$.setExpr(createValue(no_once, makeNullType(), $3.getExpr()), $1);
                         }
     ;
 
@@ -1777,6 +1778,11 @@ persistOpt
                             parser->normalizeExpression($3, type_int, true);
                             $$.setExpr(createExprAttribute(multipleAtom, $3.getExpr()), $1);
                         }
+    | LABEL '(' constExpression ')'
+                        {
+                            parser->normalizeExpression($3, type_string, true);
+                            $$.setExpr(createExprAttribute(labelAtom, $3.getExpr()), $1);
+                        }
     ;
 
 optStoredFieldFormat
@@ -1816,6 +1822,31 @@ optFewMany
     | ',' MANY          {   $$.setExpr(createAttribute(manyAtom), $1); }
     ;
 
+independentOptions
+    : independentOption
+    | independentOptions ',' independentOption
+                        {
+                            $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $3);
+                        }
+    ;
+
+commaIndependentOptions
+    :                   { $$.setNullExpr(); }
+    | commaIndependentOptions ',' independentOption
+                        {
+                            $$.setExpr(createComma($1.getExpr(), $3.getExpr()), $3);
+                        }
+    ;
+
+independentOption
+    : fewMany
+    | LABEL '(' constExpression ')'
+                        {
+                            parser->normalizeExpression($3, type_string, true);
+                            $$.setExpr(createExprAttribute(labelAtom, $3.getExpr()), $1);
+                        }
+    ;
+
 fewMany
     : FEW               {   $$.setExpr(createAttribute(fewAtom), $1); }
     | MANY              {   $$.setExpr(createAttribute(manyAtom), $1); }

+ 1 - 0
ecl/hql/hqllex.l

@@ -779,6 +779,7 @@ KEYPATCH            { RETURNSYM(KEYPATCH); }
 KEYUNICODE          { RETURNSYM(KEYUNICODE); }
 LABELED             { RETURNSYM(LABELED); }
 LABELLED            { RETURNSYM(LABELED); }
+LABEL               { RETURNSYM(LABEL); }
 LAST                { RETURNSYM(LAST); }
 LEFT                { RETURNSYM(LEFT); }
 LENGTH              { RETURNSYM(LENGTH); }

+ 1 - 0
ecl/hqlcpp/hqlcpp.cpp

@@ -146,6 +146,7 @@ WorkflowItem::WorkflowItem(IHqlExpression * _function) : wfid(0), function(_func
     assertex(body->getOperator() == no_outofline);
     IHqlExpression * ecl = body->queryChild(0);
     exprs.append(*createValue(no_return_stmt, makeVoidType(), LINK(ecl)));
+    label.append(function->queryId());
 }
 
 IHqlExpression * WorkflowItem::getFunction() const

+ 3 - 1
ecl/hqlcpp/hqlcpp.ipp

@@ -481,19 +481,21 @@ class WorkflowItem : public CInterface
 {
     friend class WorkflowTransformer;
 public:
-    WorkflowItem(unsigned _wfid, node_operator _workflowOp) : wfid(_wfid), workflowOp(_workflowOp) { }
+    WorkflowItem(unsigned _wfid, node_operator _workflowOp, const char * _label) : wfid(_wfid), workflowOp(_workflowOp), label(_label) { }
     WorkflowItem(IHqlExpression * _function);
 
     bool isFunction() const { return function != NULL; }
     IHqlExpression * getFunction() const;
     unsigned queryWfid() const { return wfid; }
     HqlExprArray & queryExprs() { return exprs; }
+    const char * queryGraphLabel() const { return label ? label.str() : nullptr; }
 
 private:
     LinkedHqlExpr function;
     HqlExprArray exprs;
     UnsignedArray dependencies;
     unsigned wfid;
+    StringBuffer label;
     node_operator workflowOp;
 };
 

+ 1 - 11
ecl/hqlcpp/hqlhtcpp.cpp

@@ -7720,14 +7720,6 @@ void HqlCppTranslator::doBuildStmtSetResult(BuildCtx & ctx, IHqlExpression * exp
     else
         value.set(expr->queryChild(0));
 
-    if (matchesConstantValue(seq, ResultSequenceStored) || matchesConstantValue(seq, ResultSequencePersist))
-    {
-        StringBuffer text;
-        text.append("Create ");
-        getStoredDescription(text, seq, name, true);
-        graphLabel.set(text.str());
-    }
-
     if (insideChildQuery(ctx))
     {
         StringBuffer description;
@@ -7804,9 +7796,6 @@ void HqlCppTranslator::doBuildStmtSetResult(BuildCtx & ctx, IHqlExpression * exp
 
     if (cluster)
         popCluster(subctx);
-
-    if (matchesConstantValue(seq, ResultSequenceStored) || matchesConstantValue(seq, ResultSequencePersist))
-        graphLabel.clear();
 }
 
 static bool isFilePersist(IHqlExpression * expr)
@@ -18184,6 +18173,7 @@ void HqlCppTranslator::buildWorkflow(WorkflowArray & workflow)
         WorkflowItem & action = workflow.item(idx);
         HqlExprArray & exprs = action.queryExprs();
         unsigned wfid = action.queryWfid();
+        graphLabel.set(action.queryGraphLabel());
 
         optimizePersists(exprs);
         bool isEmpty = exprs.ordinality() == 0;

+ 90 - 50
ecl/hqlcpp/hqlttcpp.cpp

@@ -153,7 +153,7 @@ public:
     }
 
     void extractGlobal(IHqlExpression * global, ClusterType platform);
-    void extractStoredInfo(IHqlExpression * expr, IHqlExpression * codehash, bool isRoxie, int multiplePersistInstances);
+    void extractStoredInfo(IHqlExpression * expr, const char * id, IHqlExpression * codehash, bool isRoxie, int multiplePersistInstances);
     void checkFew(HqlCppTranslator & translator);
     void splitGlobalDefinition(ITypeInfo * type, IHqlExpression * value, IConstWorkUnit * wu, SharedHqlExpr & setOutput, OwnedHqlExpr * getOutput, bool isRoxie);
     IHqlExpression * getStoredKey();
@@ -161,6 +161,7 @@ public:
     IHqlExpression * queryCluster() const { return cluster; }
     int queryMaxPersistCopies() const { return numPersistInstances; }
     bool queryPersistRefresh() const { return persistRefresh; }
+    const char * queryLabel() const { return label ? label.str() : nullptr; }
 
 protected:
     void doSplitGlobalDefinition(ITypeInfo * type, IHqlExpression * value, IConstWorkUnit * wu, SharedHqlExpr & setOutput, OwnedHqlExpr * getOutput, bool isRoxie);
@@ -186,6 +187,7 @@ protected:
     OwnedHqlExpr extraSetAttr;
     OwnedHqlExpr extraOutputAttr;
     OwnedHqlExpr codehash;
+    StringBuffer label;
     const char * filePrefix;
     const char * storedPrefix;
     int numPersistInstances;
@@ -5294,10 +5296,12 @@ void GlobalAttributeInfo::extractGlobal(IHqlExpression * global, ClusterType pla
     persistOp = no_global;
 }
 
-void GlobalAttributeInfo::extractStoredInfo(IHqlExpression * expr, IHqlExpression * _codehash, bool isRoxie, int multiplePersistInstances)
+void GlobalAttributeInfo::extractStoredInfo(IHqlExpression * expr, const char * id, IHqlExpression * _codehash, bool isRoxie, int multiplePersistInstances)
 {
     node_operator op = expr->getOperator();
     few = expr->hasAttribute(fewAtom) || (isRoxie) || (value->isDictionary() && !expr->hasAttribute(manyAtom));
+
+    getUTF8Value(label, queryAttributeChild(expr, labelAtom, 0), nullptr);
     switch (op)
     {
     case no_stored:
@@ -5340,7 +5344,7 @@ void GlobalAttributeInfo::extractStoredInfo(IHqlExpression * expr, IHqlExpressio
             getStringValue(s, codehash);
             storedName.setown(createConstant(s.str()));
         }
-	persistRefresh = getBoolValue(queryAttributeChild(expr, refreshAtom, 0), true);
+        persistRefresh = getBoolValue(queryAttributeChild(expr, refreshAtom, 0), true);
         break;
     case no_critical:
         setOp = no_setresult;
@@ -5378,6 +5382,26 @@ void GlobalAttributeInfo::extractStoredInfo(IHqlExpression * expr, IHqlExpressio
     default:
         return;
     }
+
+    if (!label)
+    {
+        switch (op)
+        {
+        case no_stored:
+        case no_persist:
+            label.append("Create ");
+            getStoredDescription(label, sequence, storedName, true);
+            break;
+        case no_critical:
+            label.append("CRITICAL(");
+            getStringValue(label, storedName);
+            label.append(")");
+            break;
+        default:
+            label.append(id);
+            break;
+        }
+    }
     persistOp = op;
 }
 
@@ -5779,7 +5803,7 @@ WorkflowTransformer::WorkflowTransformer(IWorkUnit * _wu, HqlCppTranslator & _tr
 
 //-- Helper routines --
 
-IWorkflowItem * WorkflowTransformer::addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, ContingencyData const & conts, IHqlExpression * cluster)
+IWorkflowItem * WorkflowTransformer::addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, ContingencyData const & conts, IHqlExpression * cluster, const char * label)
 {
     Owned<IWorkflowItem> wf(wu->addWorkflowItem(wfid, type, mode, conts.success, conts.failure, conts.recovery, conts.retries, conts.contingencyFor));
     if (cluster)
@@ -5788,6 +5812,8 @@ IWorkflowItem * WorkflowTransformer::addWorkflowToWorkunit(unsigned wfid, WFType
         getStringValue(clusterText, cluster);
         wf->setCluster(clusterText);
     }
+    if (label && *label)
+        wf->setLabel(label);
     ForEachItemIn(idx, dependencies)
         wf->addDependency(dependencies.item(idx));
     return wf.getClear();
@@ -5826,9 +5852,9 @@ void WorkflowTransformer::setWorkflowCritical(IWorkflowItem * wf, char const * c
     wf->setCriticalInfo(criticalName);
 }
 
-WorkflowItem * WorkflowTransformer::createWorkflowItem(IHqlExpression * expr, unsigned wfid, node_operator workflowOp)
+WorkflowItem * WorkflowTransformer::createWorkflowItem(IHqlExpression * expr, unsigned wfid, node_operator workflowOp, const char * label)
 {
-    WorkflowItem * item = new WorkflowItem(wfid, workflowOp);
+    WorkflowItem * item = new WorkflowItem(wfid, workflowOp, label);
     expr->unwindList(item->queryExprs(), no_comma);
     gatherIndirectDependencies(item->dependencies, expr);
     return item;
@@ -5884,8 +5910,9 @@ unsigned WorkflowTransformer::ensureWorkflowAction(IHqlExpression * expr)
     if (isWorkflowAction(expr))
         return (unsigned)getIntValue(expr->queryChild(0));
     unsigned wfid = ++wfidCount;
-    Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(expr), rootCluster);
-    addWorkflowItem(*createWorkflowItem(expr, wfid, no_actionlist));
+    const char * label = str(expr->queryId());
+    Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(expr), rootCluster, label);
+    addWorkflowItem(*createWorkflowItem(expr, wfid, no_actionlist, label));
     return wfid;
 }
 
@@ -5903,7 +5930,7 @@ unsigned WorkflowTransformer::splitValue(IHqlExpression * value)
     info.splitGlobalDefinition(value->queryType(), value, wu, setValue, 0, (translator.getTargetClusterType() == RoxieCluster));
     inheritDependencies(setValue);
     unsigned wfid = ++wfidCount;
-    addWorkflowItem(*createWorkflowItem(setValue, wfid, no_global));
+    addWorkflowItem(*createWorkflowItem(setValue, wfid, no_global, nullptr));
     return wfid;
 }
 
@@ -5952,6 +5979,19 @@ void WorkflowTransformer::extractDependentInputs(UnsignedArray & visited, Depend
 
 IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransformed, IHqlExpression * expr)
 {
+    const char * id = nullptr;
+    ForEachItemInRev(i, activeLocations)
+    {
+        IHqlExpression & next = activeLocations.item(i);
+        if (next.queryBody() != untransformed)
+            break;
+        if (next.queryId())
+        {
+            id = str(next.queryId());
+            break;
+        }
+    }
+
     IHqlExpression * value = expr->queryChild(0);
     GlobalAttributeInfo info("jobtemp::wf", "wf", value);
     info.sequence.setown(getLocalSequenceNumber());
@@ -5979,7 +6019,7 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
         case no_persist:
         case no_checkpoint:
         case no_stored:
-            info.extractStoredInfo(&cur, codehash, isRoxie, multiplePersistInstances);
+            info.extractStoredInfo(&cur, id, codehash, isRoxie, multiplePersistInstances);
 
             OwnedHqlExpr id = info.getStoredKey();
             unsigned match = alreadyProcessed.find(*id);
@@ -6042,7 +6082,7 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
         case no_checkpoint:
         case no_stored:
             {
-                info.extractStoredInfo(&cur, codehash, isRoxie, multiplePersistInstances);
+                info.extractStoredInfo(&cur, id, codehash, isRoxie, multiplePersistInstances);
 
                 OwnedHqlExpr id = info.getStoredKey();
                 alreadyProcessed.append(*id.getClear());
@@ -6052,31 +6092,31 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
             break;
         case no_independent:
         case no_once:
-            info.extractStoredInfo(&cur, codehash, isRoxie, multiplePersistInstances);
+            info.extractStoredInfo(&cur, id, codehash, isRoxie, multiplePersistInstances);
             break;
         case no_success:
             {
                 OwnedHqlExpr successExpr = transformSequentialEtc(cur.queryChild(0));
                 conts.success = splitValue(successExpr);
-                Owned<IWorkflowItem> wf = addWorkflowContingencyToWorkunit(conts.success, WFTypeSuccess, WFModeNormal, queryDirectDependencies(successExpr), NULL, wfid);
-                info.extractStoredInfo(&cur, codehash, isRoxie, multiplePersistInstances);
+                Owned<IWorkflowItem> wf = addWorkflowContingencyToWorkunit(conts.success, WFTypeSuccess, WFModeNormal, queryDirectDependencies(successExpr), NULL, wfid, info.queryLabel());
+                info.extractStoredInfo(&cur, id, codehash, isRoxie, multiplePersistInstances);
                 break;
             }
         case no_failure:
             {
                 OwnedHqlExpr failureExpr = transformSequentialEtc(cur.queryChild(0));
                 conts.failure = splitValue(failureExpr);
-                Owned<IWorkflowItem> wf = addWorkflowContingencyToWorkunit(conts.failure, WFTypeFailure, WFModeNormal, queryDirectDependencies(failureExpr), NULL, wfid);
-                info.extractStoredInfo(&cur, codehash, isRoxie, multiplePersistInstances);
+                Owned<IWorkflowItem> wf = addWorkflowContingencyToWorkunit(conts.failure, WFTypeFailure, WFModeNormal, queryDirectDependencies(failureExpr), NULL, wfid, info.queryLabel());
+                info.extractStoredInfo(&cur, id, codehash, isRoxie, multiplePersistInstances);
                 break;
             }
         case no_recovery:
             {
-            conts.recovery = splitValue(cur.queryChild(0));
-            conts.retries = (unsigned)getIntValue(cur.queryChild(1), 0);
-                Owned<IWorkflowItem> wf = addWorkflowContingencyToWorkunit(conts.recovery, WFTypeRecovery, WFModeNormal, queryDirectDependencies(cur.queryChild(0)), NULL, wfid);
-            info.extractStoredInfo(&cur, codehash, isRoxie, multiplePersistInstances);
-            break;
+                conts.recovery = splitValue(cur.queryChild(0));
+                conts.retries = (unsigned)getIntValue(cur.queryChild(1), 0);
+                Owned<IWorkflowItem> wf = addWorkflowContingencyToWorkunit(conts.recovery, WFTypeRecovery, WFModeNormal, queryDirectDependencies(cur.queryChild(0)), NULL, wfid, info.queryLabel());
+                info.extractStoredInfo(&cur, id, codehash, isRoxie, multiplePersistInstances);
+                break;
             }
         case no_attr:
             assertex(cur.queryName() == _original_Atom);
@@ -6211,10 +6251,10 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
          {
             StringBuffer criticalName;
             info.storedName->queryValue()->getStringValue(criticalName);
-            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeCritical, queryDirectDependencies(setValue), conts, info.queryCluster());
+            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeCritical, queryDirectDependencies(setValue), conts, info.queryCluster(), info.queryLabel());
             setWorkflowCritical(wf, criticalName.str());
 
-            addWorkflowItem(*createWorkflowItem(getValue, wfid, no_none));
+            addWorkflowItem(*createWorkflowItem(getValue, wfid, no_none, info.queryLabel()));
             getValue.setown(createNullExpr(expr->queryType()));
         }
         else if(info.persistOp == no_persist)
@@ -6222,7 +6262,7 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
             StringBuffer persistName;
             info.storedName->queryValue()->getStringValue(persistName);
             unsigned persistWfid = ++wfidCount;
-            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModePersist, queryDirectDependencies(setValue), conts, info.queryCluster());
+            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModePersist, queryDirectDependencies(setValue), conts, info.queryCluster(), info.queryLabel());
             setWorkflowPersist(wf, persistName.str(), persistWfid, info.queryMaxPersistCopies(), info.queryPersistRefresh());
 
             DependenciesUsed dependencies(false);
@@ -6246,10 +6286,10 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
             OwnedHqlExpr check = createValue(no_persist_check, makeVoidType(), checkArgs);
             inheritDependencies(check);
 
-            addWorkflowItem(*createWorkflowItem(check, persistWfid, no_actionlist));
-            addWorkflowItem(*createWorkflowItem(setValue, wfid, no_persist));
+            addWorkflowItem(*createWorkflowItem(check, persistWfid, no_actionlist, nullptr));
+            addWorkflowItem(*createWorkflowItem(setValue, wfid, no_persist, info.queryLabel()));
 
-            Owned<IWorkflowItem> wfPersist = addWorkflowToWorkunit(persistWfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(check), NULL);
+            Owned<IWorkflowItem> wfPersist = addWorkflowToWorkunit(persistWfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(check), nullptr, nullptr);
         }
         else
         {
@@ -6259,8 +6299,8 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
                 inheritDependencies(cluster);
                 setValue.set(cluster);
             }
-            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(setValue), conts, info.queryCluster());
-            addWorkflowItem(*createWorkflowItem(setValue, wfid, info.persistOp));
+            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(setValue), conts, info.queryCluster(), info.queryLabel());
+            addWorkflowItem(*createWorkflowItem(setValue, wfid, info.persistOp, info.queryLabel()));
         }
     }
 
@@ -6268,9 +6308,9 @@ IHqlExpression * WorkflowTransformer::extractWorkflow(IHqlExpression * untransfo
     {
         if (schedWfid == 0)
             schedWfid = ++wfidCount;
-        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(schedWfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(getValue), info.queryCluster());
+        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(schedWfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(getValue), info.queryCluster(), info.queryLabel());
         setWorkflowSchedule(wf, sched);
-        addWorkflowItem(*createWorkflowItem(getValue, schedWfid, no_none));
+        addWorkflowItem(*createWorkflowItem(getValue, schedWfid, no_none, info.queryLabel()));
         getValue.setown(createNullExpr(expr->queryType()));
     }
     else
@@ -6311,8 +6351,8 @@ IHqlExpression * WorkflowTransformer::extractCommonWorkflow(IHqlExpression * exp
     unsigned wfid = ++wfidCount;
 
     s.appendf("AutoWorkflow: Spotted %s ", getOpString(expr->getOperator()));
-    if (expr->queryName())
-        s.append("[").append(expr->queryName()).append("] ");
+    if (expr->queryId())
+        s.append("[").append(expr->queryId()).append("] ");
     s.append(" to common up between workflow items [").append(wfid).append("]");
     DBGLOG("%s", s.str());
     translator.addWorkunitException(SeverityInformation, 0, s.str(), location);
@@ -6327,8 +6367,8 @@ IHqlExpression * WorkflowTransformer::extractCommonWorkflow(IHqlExpression * exp
     info.splitGlobalDefinition(transformed->queryType(), transformed, wu, setValue, &getValue, isRoxie);
     copySetValueDependencies(transformedExtra, setValue);
 
-    Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(setValue), conts, NULL);
-    addWorkflowItem(*createWorkflowItem(setValue, wfid, no_actionlist));
+    Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(setValue), conts, NULL, info.queryLabel());
+    addWorkflowItem(*createWorkflowItem(setValue, wfid, no_actionlist, str(expr->queryId())));
 
     queryBodyExtra(getValue.get())->addDependency(wfid);
     return getValue.getClear();
@@ -6628,7 +6668,7 @@ UnsignedArray const & WorkflowTransformer::queryDirectDependencies(IHqlExpressio
 
 void WorkflowTransformer::cacheWorkflowDependencies(unsigned wfid, UnsignedArray & extra)
 {
-    WorkflowItem * item = new WorkflowItem(wfid, no_actionlist);
+    WorkflowItem * item = new WorkflowItem(wfid, no_actionlist, nullptr);
     ForEachItemIn(i, extra)
     {
         unsigned wfid = extra.item(i);
@@ -6694,7 +6734,7 @@ IHqlExpression * WorkflowTransformer::createCompoundWorkflow(IHqlExpression * ex
         }
 
         unsigned wfid = ++wfidCount;
-        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeSequential, childWfid, rootCluster);
+        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeSequential, childWfid, rootCluster, str(expr->queryId()));
         cacheWorkflowDependencies(wfid, childWfid);
         return createWorkflowAction(wfid);
     }
@@ -6746,7 +6786,7 @@ IHqlExpression * WorkflowTransformer::createSequentialWorkflow(IHqlExpression *
             ensureWorkflowAction(childWfid, nextBranch);
 
         unsigned wfid = ++wfidCount;
-        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeSequential, childWfid, rootCluster);
+        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeSequential, childWfid, rootCluster, str(expr->queryId()));
         cacheWorkflowDependencies(wfid, childWfid);
         return createWorkflowAction(wfid);
     }
@@ -6783,7 +6823,7 @@ IHqlExpression * WorkflowTransformer::createParallelWorkflow(IHqlExpression * ex
         }
 
         unsigned wfid = ++wfidCount;
-        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeParallel, childWfid, rootCluster);
+        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeParallel, childWfid, rootCluster, str(expr->queryId()));
         cacheWorkflowDependencies(wfid, childWfid);
         return createWorkflowAction(wfid);
     }
@@ -6850,9 +6890,9 @@ IHqlExpression * WorkflowTransformer::createIfWorkflow(IHqlExpression * expr)
                 ensureWorkflowAction(dependencies, newFalseExpr);
 
             unsigned wfid = ++wfidCount;
-            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeCondition, dependencies, rootCluster);
+            Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeCondition, dependencies, rootCluster, str(expr->queryId()));
 
-            WorkflowItem * item = new WorkflowItem(wfid, no_if);
+            WorkflowItem * item = new WorkflowItem(wfid, no_if, "IF");
             cloneDependencies(item->dependencies, dependencies);
 
             if (falseExpr)
@@ -6893,17 +6933,17 @@ IHqlExpression * WorkflowTransformer::createWaitWorkflow(IHqlExpression * expr)
 
     unsigned endWaitWfid = ++wfidCount;
     UnsignedArray noDependencies;
-    Owned<IWorkflowItem> wf = addWorkflowToWorkunit(endWaitWfid, WFTypeNormal, WFModeWait, noDependencies, rootCluster);
+    Owned<IWorkflowItem> wf = addWorkflowToWorkunit(endWaitWfid, WFTypeNormal, WFModeWait, noDependencies, rootCluster, str(expr->queryId()));
     setWorkflowSchedule(wf, sched);
     OwnedHqlExpr doNothing = createValue(no_null, makeVoidType());
-    addWorkflowItem(*createWorkflowItem(doNothing, endWaitWfid, no_wait));
+    addWorkflowItem(*createWorkflowItem(doNothing, endWaitWfid, no_wait, "WAIT"));
 
     //Now create a wait entry, with the EndWait as the dependency
     UnsignedArray dependencies;
     dependencies.append(endWaitWfid);
 
     unsigned beginWaitWfid = ++wfidCount;
-    Owned<IWorkflowItem> wfWait = addWorkflowToWorkunit(beginWaitWfid, WFTypeNormal, WFModeBeginWait, dependencies, rootCluster);
+    Owned<IWorkflowItem> wfWait = addWorkflowToWorkunit(beginWaitWfid, WFTypeNormal, WFModeBeginWait, dependencies, rootCluster, str(expr->queryId()));
     cacheWorkflowDependencies(beginWaitWfid, dependencies);
     return createWorkflowAction(beginWaitWfid);
 }
@@ -7080,17 +7120,17 @@ void WorkflowTransformer::transformRoot(const HqlExprArray & in, WorkflowArray &
     {
         //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);
+        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(onceWfid, WFTypeNormal, WFModeOnce, queryDirectDependencies(onceExpr), NULL, "ONCE");
         wf->setScheduledNow();
-        addWorkflowItem(*createWorkflowItem(onceExpr, onceWfid, no_once));
+        addWorkflowItem(*createWorkflowItem(onceExpr, onceWfid, no_once, "ONCE"));
     }
 
     if (trivialStoredExprs.length())
     {
         //By definition they don't have any dependencies, so no need to call inheritDependencies.
         OwnedHqlExpr trivialStoredExpr = createActionList(trivialStoredExprs);
-        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(trivialStoredWfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(trivialStoredExpr), NULL);
-        addWorkflowItem(*createWorkflowItem(trivialStoredExpr, trivialStoredWfid, no_stored));
+        Owned<IWorkflowItem> wf = addWorkflowToWorkunit(trivialStoredWfid, WFTypeNormal, WFModeNormal, queryDirectDependencies(trivialStoredExpr), NULL, nullptr);
+        addWorkflowItem(*createWorkflowItem(trivialStoredExpr, trivialStoredWfid, no_stored, "Trivial STORED"));
     }
 
     if (transformed.ordinality())
@@ -7121,9 +7161,9 @@ void WorkflowTransformer::transformRoot(const HqlExprArray & in, WorkflowArray &
             {
                 wfid = ++wfidCount;
                 ScheduleData sched;
-                Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, dependencies, NULL);
+                Owned<IWorkflowItem> wf = addWorkflowToWorkunit(wfid, WFTypeNormal, WFModeNormal, dependencies, NULL, nullptr);
                 setWorkflowSchedule(wf, sched);
-                addWorkflowItem(*createWorkflowItem(combinedItems, wfid, no_actionlist));
+                addWorkflowItem(*createWorkflowItem(combinedItems, wfid, no_actionlist, nullptr));
             }
             else
                 wfid = ensureWorkflowAction(combinedItems);

+ 5 - 11
ecl/hqlcpp/hqlttcpp.ipp

@@ -459,19 +459,13 @@ public:
 protected:
     virtual ANewTransformInfo * createTransformInfo(IHqlExpression * expr) { return CREATE_NEWTRANSFORMINFO(WorkflowTransformInfo, expr); }
 
-    IWorkflowItem *           addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, IHqlExpression * cluster) 
-    { 
-        UnsignedArray dependencies; 
-        ContingencyData conts; 
-        return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster);
-    }
-    IWorkflowItem *           addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, IHqlExpression * cluster) 
+    IWorkflowItem *           addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, IHqlExpression * cluster, const char * label)
     { 
         ContingencyData conts;
-        return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster);
+        return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster, label);
     }
-    IWorkflowItem *           addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, ContingencyData const & conts, IHqlExpression * cluster);
-    IWorkflowItem *           addWorkflowContingencyToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, IHqlExpression * cluster, unsigned wfidFor) { ContingencyData conts; conts.contingencyFor = wfidFor; return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster); }
+    IWorkflowItem *           addWorkflowToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, ContingencyData const & conts, IHqlExpression * cluster, const char * label);
+    IWorkflowItem *           addWorkflowContingencyToWorkunit(unsigned wfid, WFType type, WFMode mode, UnsignedArray const & dependencies, IHqlExpression * cluster, unsigned wfidFor, const char * label) { ContingencyData conts; conts.contingencyFor = wfidFor; return addWorkflowToWorkunit(wfid, type, mode, dependencies, conts, cluster, label); }
 
     void setWorkflowPersist(IWorkflowItem * wf, char const * persistName, unsigned persistWfid, int  numPersistInstances, bool refresh);
     void setWorkflowSchedule(IWorkflowItem * wf, ScheduleData const & sched);
@@ -505,7 +499,7 @@ protected:
     IHqlExpression *          createWorkflowAction(unsigned wfid);
     unsigned                  ensureWorkflowAction(IHqlExpression * expr);
     void                      ensureWorkflowAction(UnsignedArray & dependencies, IHqlExpression * expr);
-    WorkflowItem *            createWorkflowItem(IHqlExpression * expr, unsigned wfid, node_operator workflowOp);
+    WorkflowItem *            createWorkflowItem(IHqlExpression * expr, unsigned wfid, node_operator workflowOp, const char * label);
     void percolateScheduledIds();
     void percolateScheduledIds(UnsignedArray & visited, const UnsignedArray & dependencies, unsigned rootWfid);
 

+ 1 - 1
ecl/regress/independent1.ecl

@@ -26,5 +26,5 @@ integer2        age := 25;
 
 namesTable := dataset('x',namesRecord,FLAT);
 
-filtered := namesTable(surname[1] in ['0','1','3']) : independent('400way');
+filtered := namesTable(surname[1] in ['0','1','3']) : independent('400way', LABEL('My Filtered code'));
 output(filtered,,'out.d00',overwrite);

+ 1 - 1
ecl/regress/workflow12.ecl

@@ -43,6 +43,6 @@ o2 := output(namesTable2,,'~names',overwrite);
 namesTable := dataset('~names',namesRecord,FLAT);
 
 p1 := namesTable(age <> 0) : success(o1);
-p2 := p1(age <> 10) : success(o1);
+p2 := p1(age <> 10) : success(o1, LABEL('When things go right'));
 
 output(p2);

+ 1 - 1
ecl/regress/workflow13.ecl

@@ -37,7 +37,7 @@ of2 := output(-3) : persist('of2');
 
 ofs := sequential(of1, of2);
 
-o5 := o4 : failure(ofs);
+o5 := o4 : failure(ofs, LABEL('When things go wrong'));
 
 
 o5;

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

@@ -53,7 +53,7 @@ processInput(dataset(rawRecord) inFile, string outFileName) := FUNCTION
     updateIds := OUTPUT(newIds,,newIdFileName);
     extendSuper := Std.File.AddSuperFile(idFileName, newIdFileName);
 
-    result := SEQUENTIAL(InitializeSuperFile, updateIds, extendSuper): CRITICAL('critical_test');
+    result := SEQUENTIAL(InitializeSuperFile, updateIds, extendSuper): CRITICAL('critical_test', LABEL('Special critical section'));
 
     RETURN result;
 END;

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

@@ -44,7 +44,7 @@ recordof(Files.DG_FlatFile) createError := TRANSFORM
     SELF := [];
 END;
 
-o1 := output(LIMIT(Files.DG_FlatFile(DG_firstname=c1), 2, skip)) : independent;
+o1 := output(LIMIT(Files.DG_FlatFile(DG_firstname=c1), 2, skip)) : independent(LABEL('Execute o1'));
 o2 := output(LIMIT(Files.DG_FlatFile(DG_firstname=c2), 2, ONFAIL(createError))) : independent;
 o3 := count(LIMIT(Files.DG_FlatFile(DG_firstname=c3), 2, skip)) : independent;
 o4 := count(LIMIT(Files.DG_FlatFile(DG_firstname=c4), 2, ONFAIL(createError))) : independent;