Browse Source

HPCC-19918 Fix problem with LOOP conditions being corrupted

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 7 years ago
parent
commit
420c03b6f0
3 changed files with 61 additions and 8 deletions
  1. 16 8
      ecl/hqlcpp/hqlttcpp.cpp
  2. 12 0
      testing/regress/ecl/key/loopagain2.xml
  3. 33 0
      testing/regress/ecl/loopagain2.ecl

+ 16 - 8
ecl/hqlcpp/hqlttcpp.cpp

@@ -13448,19 +13448,27 @@ IHqlExpression * HqlTreeNormalizer::createTransformedBody(IHqlExpression * expr)
                 OwnedHqlExpr left = createSelector(no_left, dataset, selSeq);
                 OwnedHqlExpr rowsExpr = createDataset(no_rows, LINK(left), LINK(rowsid));
                 OwnedHqlExpr initialLoopDataset = LINK(dataset);
-                if (filter)
-                {
-                    //If there is a loop filter then the global condition is applied to dataset filtered by that.
-                    OwnedHqlExpr mappedFilter = replaceSelector(filter, left, dataset);
-                    initialLoopDataset.setown(createDataset(no_filter, initialLoopDataset.getClear(), LINK(mappedFilter)));
-                }
-                OwnedHqlExpr firstCond = quickFullReplaceExpression(loopCond, rowsExpr, initialLoopDataset);
+                LinkedHqlExpr mappedFilter = filter;
+                LinkedHqlExpr mappedCond = loopCond;
                 if (counter)
                 {
                     //Whether to evaluate the 1st time round the loop requires COUNTER=1
+                    //Replace before the input dataset is substituted, otherwise it can change other loops
                     OwnedHqlExpr one = createConstant(createIntValue(1, counter->getType()));
-                    firstCond.setown(quickFullReplaceExpression(firstCond, counter, one));
+                    if (mappedFilter)
+                        mappedFilter.setown(quickFullReplaceExpression(mappedFilter, counter, one));
+                    if (mappedCond)
+                        mappedCond.setown(quickFullReplaceExpression(mappedCond, counter, one));
+                }
+
+                if (mappedFilter)
+                {
+                    //If there is a loop filter then the global condition is applied to dataset filtered by that.
+                    mappedFilter.setown(replaceSelector(mappedFilter, left, dataset));
+                    initialLoopDataset.setown(createDataset(no_filter, initialLoopDataset.getClear(), LINK(mappedFilter)));
                 }
+
+                OwnedHqlExpr firstCond = quickFullReplaceExpression(mappedCond, rowsExpr, initialLoopDataset);
                 return appendOwnedOperand(transformed, createExprAttribute(loopFirstAtom, firstCond.getClear()));
             }
             return transformed.getClear();

+ 12 - 0
testing/regress/ecl/key/loopagain2.xml

@@ -0,0 +1,12 @@
+<Dataset name='Result 1'>
+ <Row><i>91</i></Row>
+ <Row><i>92</i></Row>
+ <Row><i>93</i></Row>
+ <Row><i>94</i></Row>
+ <Row><i>95</i></Row>
+ <Row><i>96</i></Row>
+ <Row><i>97</i></Row>
+ <Row><i>98</i></Row>
+ <Row><i>99</i></Row>
+ <Row><i>100</i></Row>
+</Dataset>

+ 33 - 0
testing/regress/ecl/loopagain2.ecl

@@ -0,0 +1,33 @@
+/*##############################################################################
+
+    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.
+############################################################################## */
+
+r := record
+  integer i;
+end;
+
+r t(integer c) := transform
+  SELF.i := c;
+end;
+
+ds1 := NOCOMBINE(dataset(10, t(COUNTER), distributed));
+
+loopbody(dataset(r) infile, UNSIGNED c) := PROJECT(infile, TRANSFORM(r, SELF.i := LEFT.i + c));
+
+f(dataset(r) infile) := LOOP(infile, exists(rows(left)) AND COUNTER < 10, loopbody(rows(left), COUNTER));
+
+x := f(ds1);
+output(f(x));