Browse Source

HPCC-18735 Ensure <groupds>.childds is treated as grouped

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 7 years ago
parent
commit
1a2ad46543

+ 23 - 2
ecl/hql/hqlmeta.cpp

@@ -2070,9 +2070,12 @@ CHqlMetaProperty * querySimpleDatasetMeta(IHqlExpression * expr)
     case no_funcdef:
         return queryMetaProperty(expr->queryChild(0));
     case no_compound:
-    case no_select:
     case no_mapto:
         return queryMetaProperty(expr->queryChild(1));
+    case no_select:
+        if (!isGrouped(expr))
+            return queryMetaProperty(expr->queryChild(1));
+        return nullptr;
     case no_delayedselect:
     case no_libraryselect:
     case no_unboundselect:
@@ -2186,10 +2189,18 @@ void calculateDatasetMeta(CHqlMetaInfo & meta, IHqlExpression * expr)
         extractMeta(meta, dataset);
         break;
     case no_compound:
-    case no_select:
     case no_mapto:
         extractMeta(meta, expr->queryChild(1));
         break;
+    case no_select:
+    {
+        extractMeta(meta, expr->queryChild(1));
+        bool isNew;
+        IHqlExpression * root = querySelectorDataset(expr, isNew);
+        if (isNew && isGrouped(root))
+            meta.grouping.set(queryUnknownSortlist());
+        break;
+    }
     case no_delayedselect:
     case no_libraryselect:
     case no_unboundselect:
@@ -3384,9 +3395,19 @@ ITypeInfo * calculateDatasetType(node_operator op, const HqlExprArray & parms)
     case no_preservemeta:
     case no_keyeddistribute:
     case no_subsort:
+        type.setown(dataset->getType());
+        break;
     case no_select:
+    {
+        IHqlExpression * root = &parms.item(0);
+        bool isNew = hasAttribute(newAtom, parms);
+        if (root->isDatarow() && (root->getOperator() == no_select))
+            root = querySelectorDataset(root, isNew);
         type.setown(dataset->getType());
+        if (isNew && isGrouped(root))
+            type.setown(makeGroupedTableType(type.getClear()));
         break;
+    }
     case no_distribute:
     case no_distributed:
     case no_unordered:

+ 1 - 0
ecl/hqlcpp/hqlhtcpp.cpp

@@ -2155,6 +2155,7 @@ void ActivityInstance::createGraphNode(IPropertyTree * defaultSubGraph, bool alw
             }
 
             IHqlExpression * grouping = queryGrouping(source);
+            assertex((grouping != nullptr) == ::isGrouped(source));
             if (grouping)
                 addAttribute("metaGrouping", getExprECL(grouping, s.clear(), true).str());
 

+ 5 - 1
ecl/hqlcpp/hqlttcpp.cpp

@@ -4293,7 +4293,7 @@ void CompoundSourceTransformer::analyseGatherInfo(IHqlExpression * expr)
             {
                 IHqlExpression * dataset = expr->queryChild(0);
                 CompoundSourceInfo * parentExtra = queryBodyExtra(dataset);
-                if (!parentExtra->isAggregate() && !parentExtra->hasAnyLimit() && parentExtra->isBinary())
+                if (!parentExtra->isAggregate() && !parentExtra->hasAnyLimit() && parentExtra->isBinary() && !isGrouped(dataset))
                 {
                     node_operator newOp = no_none;
                     switch (parentExtra->sourceOp)
@@ -10285,6 +10285,10 @@ IHqlExpression * HqlScopeTagger::createTransformed(IHqlExpression * expr)
                 VStringBuffer msg("dataset expression (%s) assigned to field '%s' with type row", getECL(rhs, exprText), str(lhs->queryChild(1)->queryName()));
                 reportError(CategoryError, msg.str());
             }
+
+            //Ensure datasets assigned to child datasets are not grouped (until grouped child datasets are supported).
+            if (isGrouped(newRhs))
+                newRhs.setown(createDataset(no_group, newRhs.getClear()));
             if (rhs == newRhs)
                 return LINK(expr);
             HqlExprArray children;

+ 41 - 0
testing/regress/ecl/issue18735.ecl

@@ -0,0 +1,41 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2018 HPCC Systems®.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+############################################################################## */
+
+rec1 := RECORD
+  unsigned4 id;
+END;
+
+rec2 := RECORD
+  unsigned c;
+  dataset(rec1) child;
+END;
+
+numRecs := 10000;
+mkchild(unsigned num, unsigned base) := DATASET(num, TRANSFORM(rec1, SELF.id := COUNTER + base));
+ds := DATASET(numRecs, TRANSFORM(rec2, SELF.c := COUNTER, SELF.child := mkchild(COUNTER % 3, COUNTER % 7)));
+
+s := SORT(ds, c);
+gs := GROUP(s, c) : independent;
+ngs := gs.child;
+t := TABLE(ngs, { cnt := COUNT(GROUP) });
+t2 := TABLE(ngs, { sm := SUM(GROUP, id) });
+
+SEQUENTIAL(
+    OUTPUT(TABLE(t, { cnt, num := COUNT(GROUP); }, cnt));
+    OUTPUT(TABLE(t2, { sm, num := COUNT(GROUP); }, sm ));
+    OUTPUT('"Done');
+);

+ 20 - 0
testing/regress/ecl/key/issue18735.xml

@@ -0,0 +1,20 @@
+<Dataset name='Result 1'>
+ <Row><cnt>1</cnt><num>3334</num></Row>
+ <Row><cnt>2</cnt><num>3333</num></Row>
+</Dataset>
+<Dataset name='Result 2'>
+ <Row><sm>15</sm><num>476</num></Row>
+ <Row><sm>9</sm><num>476</num></Row>
+ <Row><sm>6</sm><num>476</num></Row>
+ <Row><sm>3</sm><num>952</num></Row>
+ <Row><sm>13</sm><num>476</num></Row>
+ <Row><sm>7</sm><num>953</num></Row>
+ <Row><sm>4</sm><num>476</num></Row>
+ <Row><sm>1</sm><num>476</num></Row>
+ <Row><sm>11</sm><num>476</num></Row>
+ <Row><sm>5</sm><num>953</num></Row>
+ <Row><sm>2</sm><num>477</num></Row>
+</Dataset>
+<Dataset name='Result 3'>
+ <Row><Result_3>&quot;Done</Result_3></Row>
+</Dataset>