Procházet zdrojové kódy

HPCC-7942 Fix problem with LIMIT(0) on an JOIN(,ALL)

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday před 12 roky
rodič
revize
8d1e5df561

+ 22 - 2
ecl/hqlcpp/hqlhtcpp.cpp

@@ -11153,8 +11153,28 @@ ABoundActivity * HqlCppTranslator::doBuildActivityJoinOrDenormalize(BuildCtx & c
             {
                 HqlExprArray args;
                 args.append(*LINK(rhs));
-                unwindChildren(args, rowlimit);
-                rhs.setown(createDataset(no_limit, args));
+
+                //A LIMIT on a join means no limit, whilst a LIMIT(ds, 0) limits to no records.
+                //So avoid adding a zero limit (if constant), or ensure 0 is mapped to a maximal value.
+                LinkedHqlExpr count = rowlimit->queryChild(0);
+                if (count->queryValue())
+                {
+                    if (isZero(count))
+                        count.clear();
+                }
+                else
+                {
+                    OwnedHqlExpr zero = createConstant(count->queryType()->castFrom(false, I64C(0)));
+                    OwnedHqlExpr all = createConstant(count->queryType()->castFrom(false, I64C(-1)));
+                    OwnedHqlExpr ne = createBoolExpr(no_ne, LINK(count), zero.getClear());
+                    count.setown(createValue(no_if, count->getType(), LINK(ne), LINK(count), LINK(all)));
+                }
+                if (count)
+                {
+                    args.append(*LINK(count));
+                    unwindChildren(args, rowlimit, 1);
+                    rhs.setown(createDataset(no_limit, args));
+                }
             }
             isAllJoin = true;
             WARNING(HQLWRN_JoinConditionFoldedNowAll);

+ 45 - 0
ecl/regress/issue7942.ecl

@@ -0,0 +1,45 @@
+/*##############################################################################
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+############################################################################## */
+
+outrec := record
+    integer id;
+    string20 desc;
+end;
+
+aData := DATASET([{1234}],{ integer id});
+bData := DATASET([{1234,'BigRed'}],outrec);
+
+outrec xform(aData l, bData r) := transform
+    self.id := l.id;
+    self.desc := if (r.desc <> '', r.desc, '');
+end;
+
+zero := 0 : stored('zero');
+one := 1 : stored('one');
+
+abData1 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(0));
+abData2 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(2));
+abData3 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(one));
+abData4 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(zero));
+
+sequential(
+output(abData1);                                                         
+output(abData2);
+output(abData3);
+output(abData4);
+);                                                         

+ 45 - 0
testing/ecl/issue7942.ecl

@@ -0,0 +1,45 @@
+/*##############################################################################
+
+    Copyright (C) 2011 HPCC Systems.
+
+    All rights reserved. This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU Affero General Public License as
+    published by the Free Software Foundation, either version 3 of the
+    License, or (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU Affero General Public License for more details.
+
+    You should have received a copy of the GNU Affero General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+############################################################################## */
+
+outrec := record
+    integer id;
+    string20 desc;
+end;
+
+aData := DATASET([{1234}],{ integer id});
+bData := DATASET([{1234,'BigRed'}],outrec);
+
+outrec xform(aData l, bData r) := transform
+    self.id := l.id;
+    self.desc := if (r.desc <> '', r.desc, '');
+end;
+
+zero := 0 : stored('zero');
+one := 1 : stored('one');
+
+abData1 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(0));
+abData2 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(2));
+abData3 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(one));
+abData4 := join(aData, bData,left.id = right.id, xform(LEFT,RIGHT), left outer, KEEP(1), LIMIT(zero));
+
+sequential(
+output(abData1);                                                         
+output(abData2);
+output(abData3);
+output(abData4);
+);                                                         

+ 12 - 0
testing/ecl/key/issue7942.xml

@@ -0,0 +1,12 @@
+<Dataset name='Result 1'>
+ <Row><id>1234</id><desc>BigRed              </desc></Row>
+</Dataset>
+<Dataset name='Result 2'>
+ <Row><id>1234</id><desc>BigRed              </desc></Row>
+</Dataset>
+<Dataset name='Result 3'>
+ <Row><id>1234</id><desc>BigRed              </desc></Row>
+</Dataset>
+<Dataset name='Result 4'>
+ <Row><id>1234</id><desc>BigRed              </desc></Row>
+</Dataset>