소스 검색

HPCC-10283 Ensure GLOBAL(,OPT) is processed correctly inside a library

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 11 년 전
부모
커밋
ce90e01170
4개의 변경된 파일87개의 추가작업 그리고 6개의 파일을 삭제
  1. 5 1
      ecl/hql/hqlthql.cpp
  2. 2 0
      ecl/hqlcpp/hqlresource.cpp
  3. 64 5
      ecl/hqlcpp/hqlttcpp.cpp
  4. 16 0
      ecl/hqlcpp/hqlttcpp.ipp

+ 5 - 1
ecl/hql/hqlthql.cpp

@@ -726,7 +726,7 @@ void HqltHql::toECL(IHqlExpression *expr, StringBuffer &s, bool paren, bool inTy
         {
             if (expr->isDataset())
             {
-                IHqlExpression * group = queryGroupInfo(expr);
+                IHqlExpression * group = queryGrouping(expr);
                 if (group)
                     getExprECL(group, s.append("G(")).append(")");
                 IHqlExpression * distrib = queryDistribution(expr);
@@ -763,6 +763,10 @@ void HqltHql::toECL(IHqlExpression *expr, StringBuffer &s, bool paren, bool inTy
     #endif
             }
         }
+        else if (!expr->isIndependentOfScope())
+        {
+            s.append("[[!]]");
+        }
 #endif
 #ifdef SHOW_DSRECORD
         if (expr->isDataset() || expr->isTransform())

+ 2 - 0
ecl/hqlcpp/hqlresource.cpp

@@ -2269,6 +2269,8 @@ protected:
             return;
         case no_globalscope:
         case no_evalonce:
+            if (expr->hasAttribute(optAtom) && !expr->isIndependentOfScope())
+                break;
             if (expr->isDataset() || expr->isDatarow() || expr->isDictionary())
                 noteDataset(expr, expr->queryChild(0), true);
             else

+ 64 - 5
ecl/hqlcpp/hqlttcpp.cpp

@@ -7342,14 +7342,17 @@ IHqlExpression * ExplicitGlobalTransformer::createTransformed(IHqlExpression * e
         //fall through
     case no_globalscope:
         {
+            IHqlExpression * value = transformed->queryChild(0);
+            if (expr->hasAttribute(optAtom))
+            {
+                if (!isIndependentOfScope(value))
+                    return LINK(value);
+            }
+
             if (!expr->hasAttribute(localAtom) || isUsedUnconditionally(expr))
             {
-                IHqlExpression * value = transformed->queryChild(0);
                 if (!isIndependentOfScope(value))
                 {
-                    if (expr->hasAttribute(optAtom))
-                        return LINK(transformed->queryChild(0));
-
                     IHqlExpression * symbol = queryActiveSymbol();
                     StringBuffer s;
                     if (symbol && symbol->queryBody() == expr)
@@ -7404,6 +7407,49 @@ IHqlExpression * ExplicitGlobalTransformer::createTransformed(IHqlExpression * e
     return transformed.getClear();
 }
 
+static HqlTransformerInfo optGlobalTransformerInfo("OptGlobalTransformer");
+OptGlobalTransformer::OptGlobalTransformer() : NewHqlTransformer(optGlobalTransformerInfo)
+{
+    seenOptGlobal = false;
+}
+
+void OptGlobalTransformer::analyseExpr(IHqlExpression * expr)
+{
+    if (alreadyVisited(expr))
+        return;
+
+    node_operator op = expr->getOperator();
+    switch (op)
+    {
+    case no_globalscope:
+        if (expr->hasAttribute(optAtom))
+            seenOptGlobal = true;
+        break;
+    }
+    NewHqlTransformer::analyseExpr(expr);
+}
+
+IHqlExpression * OptGlobalTransformer::createTransformed(IHqlExpression * expr)
+{
+    OwnedHqlExpr transformed = NewHqlTransformer::createTransformed(expr);
+    node_operator op = transformed->getOperator();
+    switch (op)
+    {
+    case no_globalscope:
+        {
+            if (transformed->hasAttribute(optAtom))
+            {
+                IHqlExpression * value = transformed->queryChild(0);
+                if (!isIndependentOfScope(value))
+                    return LINK(value);
+                return removeAttribute(transformed, optAtom);
+            }
+            break;
+        }
+    }
+    return transformed.getClear();
+}
+
 //------------------------------------------------------------------------
 
 static HqlTransformerInfo scopeIndependentActionCheckerInfo("ScopeIndependentActionChecker");
@@ -7686,8 +7732,21 @@ void migrateExprToNaturalLevel(WorkflowItem & cur, IWorkUnit * wu, HqlCppTransla
             transformer.transformRoot(exprs, results);
             replaceArray(exprs, results);
         }
-        translator.checkNormalized(exprs);
     }
+    else
+    {
+        OptGlobalTransformer transformer;
+
+        transformer.analyseArray(exprs, 0);
+        if (transformer.needToTransform())
+        {
+            HqlExprArray results;
+            transformer.transformRoot(exprs, results);
+            replaceArray(exprs, results);
+        }
+    }
+
+    translator.checkNormalized(exprs);
 
     translator.traceExpressions("m1", exprs);
 

+ 16 - 0
ecl/hqlcpp/hqlttcpp.ipp

@@ -582,6 +582,22 @@ private:
     bool isRoxie;
 };
 
+class OptGlobalTransformer : public NewHqlTransformer
+{
+public:
+    OptGlobalTransformer();
+
+    inline bool needToTransform() const { return seenOptGlobal; }
+
+protected:
+    virtual IHqlExpression * createTransformed(IHqlExpression * expr);
+
+    virtual void analyseExpr(IHqlExpression * expr);
+
+private:
+    bool seenOptGlobal;
+};
+
 class ScalarGlobalExtra : public HoistingTransformInfo
 {
 public: