Forráskód Böngészése

HPCC-8856 Fix problems with inactive selectors

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 12 éve
szülő
commit
a2f7ad169a
4 módosított fájl, 26 hozzáadás és 3 törlés
  1. 5 3
      ecl/hql/hqlexpr.cpp
  2. 4 0
      ecl/hql/hqlutil.cpp
  3. 16 0
      ecl/hqlcpp/hqlttcpp.cpp
  4. 1 0
      ecl/hqlcpp/hqlttcpp.ipp

+ 5 - 3
ecl/hql/hqlexpr.cpp

@@ -15070,7 +15070,9 @@ unsigned firstPayloadField(IHqlExpression * record, unsigned cnt)
 IHqlExpression * createSelector(node_operator op, IHqlExpression * ds, IHqlExpression * seq)
 {
 //  OwnedHqlExpr record = getUnadornedExpr(ds->queryRecord());
-    IHqlExpression * record = ds->queryRecord()->queryBody();
+    IHqlExpression * dsRecord = ds->queryRecord();
+    assertex(dsRecord);
+    IHqlExpression * record = dsRecord->queryBody();
 
     switch (op)
     {
@@ -15078,11 +15080,11 @@ IHqlExpression * createSelector(node_operator op, IHqlExpression * ds, IHqlExpre
     case no_right:
     case no_top:
         assertex(seq && seq->isAttribute());
-        return createRow(op, LINK(record->queryBody()), LINK(seq));
+        return createRow(op, LINK(record), LINK(seq));
     case no_self:
         {
             //seq is set when generating code unique target selectors
-            return createRow(op, LINK(record->queryBody()), LINK(seq));
+            return createRow(op, LINK(record), LINK(seq));
         }
     case no_none:
         return LINK(ds);

+ 4 - 0
ecl/hql/hqlutil.cpp

@@ -4564,6 +4564,10 @@ static bool splitDatasetAttribute(SharedHqlExpr & dataset, SharedHqlExpr & attri
     node_operator leftOp = left->getOperator();
     if ((leftOp !=no_select) || expr->hasProperty(newAtom))
     {
+        //If this is a selection from an inscope dataset then this must not be assumed to be an input dataset.
+        if (expr->isDataset() && !expr->hasProperty(newAtom))
+            return false;
+
         IHqlExpression * lhs = LINK(left);
         IHqlExpression * field = expr->queryChild(1);
         if (lhs->isDataset()) lhs = createRow(no_activerow, lhs);

+ 16 - 0
ecl/hqlcpp/hqlttcpp.cpp

@@ -11129,6 +11129,14 @@ static void gatherPotentialSelectors(HqlExprArray & args, IHqlExpression * expr)
 }
 
 
+IHqlExpression * HqlTreeNormalizer::transformChildrenNoAnnotations(IHqlExpression * expr)
+{
+    HqlExprArray args;
+    ForEachChild(i, expr)
+        args.append(*transform(expr->queryChild(i)->queryBody()));
+    return completeTransform(expr, args);
+}
+
 //The following symbol removal code works, but I'm not sure I want to do it at the moment because of the changes to the HOLe queries
 //Remove as many named symbols as we can - try and keep for datasets and statements so can go in the tree.
 IHqlExpression * HqlTreeNormalizer::createTransformed(IHqlExpression * expr)
@@ -11904,6 +11912,14 @@ IHqlExpression * HqlTreeNormalizer::createTransformedBody(IHqlExpression * expr)
                 }
             }
 #endif
+
+            //If a named symbol is used as an argument to maxlength you can end up with a situation
+            //where records are identical except for that named symbol.
+            //If f(a + b) is then optimized to b this can lead to incompatible selectors, since
+            //a and b are "compatible", but not identical.
+            //This then causes chaos, so strip them as a precaution... but it is only a partial solution.
+            if (name == maxLengthAtom)
+                return transformChildrenNoAnnotations(expr);
             break;
         }
 

+ 1 - 0
ecl/hqlcpp/hqlttcpp.ipp

@@ -1167,6 +1167,7 @@ protected:
     IHqlExpression * validateKeyedJoin(IHqlExpression * expr);
 
 protected:
+    IHqlExpression * transformChildrenNoAnnotations(IHqlExpression * expr);
     IHqlExpression * makeRecursiveName(_ATOM searchModule, _ATOM searchName);
     HqlTreeNormalizerInfo * queryCommonExtra(IHqlExpression * expr);
     IHqlExpression * transformSimpleConst(IHqlExpression * expr)