Просмотр исходного кода

Support LIMIT on a join converted to an all join

- Fixes bugzilla #95217

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday 13 лет назад
Родитель
Сommit
eaaba166e2
2 измененных файлов с 42 добавлено и 1 удалено
  1. 11 1
      ecl/hqlcpp/hqlhtcpp.cpp
  2. 31 0
      ecl/regress/limitalljoin.ecl

+ 11 - 1
ecl/hqlcpp/hqlhtcpp.cpp

@@ -11123,6 +11123,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityJoinOrDenormalize(BuildCtx & c
     }
     extendConditionOwn(match, no_and, fuzzy.getClear());
 
+    LinkedHqlExpr rhs = dataset2;
     if (isAllJoin)
     {
         if (leftSorts.ordinality() && allowAllToLookupConvert)
@@ -11137,6 +11138,15 @@ ABoundActivity * HqlCppTranslator::doBuildActivityJoinOrDenormalize(BuildCtx & c
     {
         if (expr->hasProperty(_conditionFolded_Atom))
         {
+            //LIMIT on an ALL join is equivalent to applying a limit to the rhs of the join (since all will hard match).
+            //This could be transformed early, but uncommon enough to not be too concerned.
+            if (rowlimit)
+            {
+                HqlExprArray args;
+                args.append(*LINK(rhs));
+                unwindChildren(args, rowlimit);
+                rhs.setown(createDataset(no_limit, args));
+            }
             isAllJoin = true;
             WARNING(HQLWRN_JoinConditionFoldedNowAll);
         }
@@ -11152,7 +11162,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityJoinOrDenormalize(BuildCtx & c
     Owned<ABoundActivity> boundDataset1 = buildCachedActivity(ctx, dataset1);
     Owned<ABoundActivity> boundDataset2;
     if (!joinToSelf)
-        boundDataset2.setown(buildCachedActivity(ctx, dataset2));
+        boundDataset2.setown(buildCachedActivity(ctx, rhs));
 
     const char * argName;
     ThorActivityKind kind;

+ 31 - 0
ecl/regress/limitalljoin.ecl

@@ -0,0 +1,31 @@
+/*##############################################################################
+
+    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/>.
+############################################################################## */
+
+layout := {
+    string id,
+};
+
+ds1 := dataset([{'a'}], layout);
+ds2 := dataset([{'a'},{'a'}], layout);
+
+dsjoin := join(ds1, ds2,
+               left.id = right.id,
+               transform(left),
+               limit(1, skip));
+
+output(dsjoin);