瀏覽代碼

gh-518 Finish implementation of WHEN

Ensure that WHEN doesn't prevent the implicit field projection, add
better support for WHEN as a side-effect of an action.

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 13 年之前
父節點
當前提交
c762d543f5

+ 2 - 1
common/commonext/commonext.cpp

@@ -193,12 +193,13 @@ MODULE_INIT(INIT_PRIORITY_STANDARD)
     kindArray[TAKindexgroupcount] = "indexgroupcount";
     kindArray[TAKhashdistributemerge] = "hashdistributemerge";
     kindArray[TAKselfjoinlight] = "selfjoinlight";
-    kindArray[TAKwhen] = "when";
+    kindArray[TAKwhen_dataset] = "when_dataset";
     kindArray[TAKhttp_rowdataset] = "http";
     kindArray[TAKstreamediterator] = "streamediterator";
     kindArray[TAKexternalsource] = "externalsource";
     kindArray[TAKexternalsink] = "externalsink";
     kindArray[TAKexternalprocess] = "externalprocess";
+    kindArray[TAKwhen_action] = "when_action";
 
 //Non standard
     kindArray[TAKcountindex] = "countindex";

+ 3 - 1
common/thorhelper/thorcommon.cpp

@@ -780,12 +780,13 @@ extern const char * getActivityText(ThorActivityKind kind)
     case TAKindexgroupexists:   return "Index Grouped Exists";
     case TAKhashdistributemerge:    return "Distribute Merge";
     case TAKselfjoinlight:          return "Lightweight Self Join";
-    case TAKwhen:                   return "When";
+    case TAKwhen_dataset:           return "When";
     case TAKhttp_rowdataset:        return "HTTP dataset";
     case TAKstreamediterator:       return "Streamed Dataset";
     case TAKexternalsource:         return "User Source";
     case TAKexternalsink:           return "User Output";
     case TAKexternalprocess:        return "User Proceess";
+    case TAKwhen_action:            return "When";
     }
     throwUnexpected();
 }
@@ -865,6 +866,7 @@ extern bool isActivitySink(ThorActivityKind kind)
     case TAKifaction:
     case TAKparallel:
     case TAKsequential:
+    case TAKwhen_action:
         return true;
     }
     return false;

+ 1 - 1
ecl/eclagent/eclgraph.cpp

@@ -206,7 +206,7 @@ static IHThorActivity * createActivity(IAgentContext & agent, unsigned activityI
     case TAKparallel:
     case TAKemptyaction:
     case TAKifaction:
-    case TAKwhen:
+    case TAKwhen_dataset:
         return createDummyActivity(agent, activityId, subgraphId, arg, kind);
     case TAKhashdedup:
         return createHashDedupActivity(agent, activityId, subgraphId, (IHThorHashDedupArg &)arg, kind);

+ 6 - 2
ecl/hql/hqlgram.y

@@ -2569,9 +2569,13 @@ failAction
                             Owned<ITypeInfo> retType = $1.getType();
                             $$.setExpr(parser->leaveLamdaExpression($5), $7);
                         }
-    | WHEN '(' action ',' action ')'
+    | WHEN '(' action ',' action sideEffectOptions ')'
                         {
-                            $$.setExpr(createCompound($5.getExpr(), $3.getExpr()), $1);
+                            OwnedHqlExpr options = $6.getExpr();
+                            if (options)
+                                $$.setExpr(createValueF(no_executewhen, makeVoidType(), $3.getExpr(), $5.getExpr(), options.getClear(), NULL), $1);
+                            else
+                                $$.setExpr(createCompound($5.getExpr(), $3.getExpr()), $1);
                         }
     ;
 

+ 1 - 1
ecl/hqlcpp/hqlcpp.ipp

@@ -1568,7 +1568,7 @@ public:
     ABoundActivity * doBuildActivityDistribution(BuildCtx & ctx, IHqlExpression * expr, bool isRoot);
     ABoundActivity * doBuildActivitySectionInput(BuildCtx & ctx, IHqlExpression * expr);
     ABoundActivity * doBuildActivityEnth(BuildCtx & ctx, IHqlExpression * expr);
-    ABoundActivity * doBuildActivityExecuteWhen(BuildCtx & ctx, IHqlExpression * expr);
+    ABoundActivity * doBuildActivityExecuteWhen(BuildCtx & ctx, IHqlExpression * expr, bool isRoot);
     ABoundActivity * doBuildActivityForceLocal(BuildCtx & ctx, IHqlExpression * expr);
     ABoundActivity * doBuildActivityFetch(BuildCtx & ctx, IHqlExpression * expr);
     ABoundActivity * doBuildActivityFilter(BuildCtx & ctx, IHqlExpression * expr);

+ 5 - 4
ecl/hqlcpp/hqlhtcpp.cpp

@@ -6259,7 +6259,7 @@ ABoundActivity * HqlCppTranslator::buildActivity(BuildCtx & ctx, IHqlExpression
                 result = doBuildActivityCallSideEffect(ctx, expr);
                 break;
             case no_executewhen:
-                result = doBuildActivityExecuteWhen(ctx, expr);
+                result = doBuildActivityExecuteWhen(ctx, expr, isRoot);
                 break;
             case no_thor:
                 UNIMPLEMENTED;
@@ -14455,7 +14455,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityCallSideEffect(BuildCtx & ctx,
 
 //---------------------------------------------------------------------------
 
-ABoundActivity * HqlCppTranslator::doBuildActivityExecuteWhen(BuildCtx & ctx, IHqlExpression * expr)
+ABoundActivity * HqlCppTranslator::doBuildActivityExecuteWhen(BuildCtx & ctx, IHqlExpression * expr, bool isRoot)
 {
     Owned<ABoundActivity> boundDataset = buildCachedActivity(ctx, expr->queryChild(0));
     Owned<ABoundActivity> associatedActivity = buildCachedActivity(ctx, expr->queryChild(1));
@@ -14486,11 +14486,12 @@ ABoundActivity * HqlCppTranslator::doBuildActivityExecuteWhen(BuildCtx & ctx, IH
     }
 
     bool useImplementationClass = options.minimizeActivityClasses;
-    Owned<ActivityInstance> instance = new ActivityInstance(*this, ctx, TAKwhen, expr, "WhenAction");
+    ThorActivityKind kind = (expr->isAction() ? TAKwhen_action : TAKwhen_dataset);
+    Owned<ActivityInstance> instance = new ActivityInstance(*this, ctx, kind, expr, "WhenAction");
     if (useImplementationClass)
         instance->setImplementationClass(newWhenActionArgAtom);
 
-    buildActivityFramework(instance);
+    buildActivityFramework(instance, isRoot);
 
     buildInstancePrefix(instance);
     buildInstanceSuffix(instance);

+ 15 - 0
ecl/hqlcpp/hqliproj.cpp

@@ -904,6 +904,17 @@ void ImplicitProjectTransformer::analyseExpr(IHqlExpression * expr)
             assertex(extra->activityKind() == NonActivity);
             Parent::analyseExpr(expr);
             break;
+        case no_executewhen:
+            if (expr->isDataset())
+            {
+                assertex(extra->activityKind() == SimpleActivity);
+                Parent::analyseExpr(expr);
+                connect(expr->queryChild(0), expr);
+                break;
+            }
+            assertex(extra->activityKind() == NonActivity);
+            Parent::analyseExpr(expr);
+            break;
         case no_subgraph:
             assertex(extra->activityKind() == NonActivity);
             Parent::analyseExpr(expr);
@@ -1392,6 +1403,10 @@ ProjectExprKind ImplicitProjectTransformer::getProjectExprKind(IHqlExpression *
         if (expr->isDatarow())
             return ComplexNonActivity;
         return NonActivity;
+    case no_executewhen:
+        if (expr->isDataset() || expr->isDatarow())
+            return SimpleActivity;
+        return NonActivity;
     case no_subgraph:
     case no_libraryscopeinstance:
         return NonActivity;

+ 1 - 1
roxie/ccd/ccdquery.cpp

@@ -533,7 +533,7 @@ protected:
             return createRoxieServerNonEmptyActivityFactory(id, subgraphId, *this, helperFactory, kind);
         case TAKprefetchproject:
             return createRoxieServerPrefetchProjectActivityFactory(id, subgraphId, *this, helperFactory, kind);
-        case TAKwhen:
+        case TAKwhen_dataset:
             return createRoxieServerWhenActivityFactory(id, subgraphId, *this, helperFactory, kind);
 
         // These are not required in Roxie for the time being - code generator should trap them

+ 2 - 2
rtl/include/eclhelper.hpp

@@ -800,8 +800,8 @@ enum ThorActivityKind
     TAKcreaterowcatch,
     TAKsectioninput,
     TAKcaseaction,
-    TAKwhen,
-    TAKunused1,
+    TAKwhen_dataset,
+    TAKwhen_action,
     TAKunsued2,
     TAKindexgroupexists,
     TAKindexgroupcount,

+ 2 - 1
thorlcr/graph/thgraph.cpp

@@ -981,7 +981,8 @@ bool isGlobalActivity(CGraphElementBase &container)
         case TAKtopn:
         case TAKprocess:
         case TAKchildcount:
-        case TAKwhen:
+        case TAKwhen_dataset:
+        case TAKwhen_action:
             if (!container.queryLocalOrGrouped())
                 return true;
             break;

+ 1 - 1
thorlcr/master/thactivitymaster.cpp

@@ -365,7 +365,7 @@ public:
             case TAKcase:           // gen. time.
             case TAKif:
                 throwUnexpected();
-            case TAKwhen:
+            case TAKwhen_dataset:
                 ret = createWhenActivityMaster(this);
                 break;
             case TAKifaction:

+ 1 - 1
thorlcr/slave/slave.cpp

@@ -599,7 +599,7 @@ public:
             case TAKif:
                 throwUnexpected();
                 break;
-            case TAKwhen:
+            case TAKwhen_dataset:
                 ret = createWhenSlave(this);
                 break;
             case TAKworkunitread: