Quellcode durchsuchen

HPCC-10643 Don't generate HASH and SMART joins inside child queries

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday vor 11 Jahren
Ursprung
Commit
aa79b3dbec

+ 9 - 0
ecl/hqlcpp/hqlhtcpp.cpp

@@ -11648,6 +11648,15 @@ ABoundActivity * HqlCppTranslator::doBuildActivityJoinOrDenormalize(BuildCtx & c
     if (expr->hasAttribute(groupedAtom) && targetThor())
         WARNING(HQLWRN_GroupedJoinIsLookupJoin);
 
+    //Hash and smart joins are not valid inside child queries - convert to a normal join.
+    //The flags should already have been stripped if targetting hthor/roxie
+    if (insideChildQuery(ctx) && (isHashJoin || isSmartJoin))
+    {
+        assertex(targetThor());
+        isHashJoin = false;
+        isSmartJoin = false;
+    }
+
     if ((op == no_denormalize || op == no_denormalizegroup) && targetThor() && options.checkThorRestrictions)
     {
         if (isHashJoin)

+ 10 - 6
ecl/hqlcpp/hqlttcpp.cpp

@@ -2718,16 +2718,20 @@ IHqlExpression * ThorHqlTransformer::normalizeJoinOrDenormalize(IHqlExpression *
 
     bool hasLocal = isLocalActivity(expr);
     bool alwaysLocal = !translator.targetThor();
+    if (alwaysLocal)
+    {
+        if (expr->hasAttribute(hashAtom))
+            return removeAttribute(expr, hashAtom);
+        //Hthor and roxie don't currently support smart joins since the normal join requires the input to be sorted
+        if (expr->hasAttribute(smartAtom))
+            return removeAttribute(expr, smartAtom);
+    }
+
     bool isLocal = hasLocal || alwaysLocal;
     //hash,local doesn't make sense (hash is only used for distribution) => remove hash
     //but also prevent it being converted to a lookup join??
     if (isLocal && expr->hasAttribute(hashAtom))
-    {
-        HqlExprArray args;
-        unwindChildren(args, expr);
-        removeAttribute(args, hashAtom);
-        return expr->clone(args);
-    }
+        return removeAttribute(expr, hashAtom);
 
     //Check to see if this join should be done as a keyed join...
     if (!expr->hasAttribute(lookupAtom) && !expr->hasAttribute(smartAtom) && !expr->hasAttribute(allAtom))

+ 58 - 0
ecl/regress/issue10643a.ecl

@@ -0,0 +1,58 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 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.
+############################################################################## */
+
+subrec1 := record
+    string1 a;
+    string1 b;
+end;
+
+subrec2 := record
+    string1 c;
+    string1 d;
+end;
+
+rec1 := record
+    integer seq;
+    integer foobar;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+rec2 := record
+    integer seq;
+    string5 foo;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+df := dataset([{'a','b'},{'c','d'}],subrec1);
+dfb := dataset([{'e','f'},{'h','i'}],subrec1);
+df2 := dataset([{'1','2'},{'3','4'}],subrec2);
+df2b := dataset([{'5','6'}],subrec2);
+
+myrecs1 := nofold(dataset([{1,2,df,df2}],rec1));
+myrecs2 := nofold(dataset([{1,'foo',dfb,df2b}],rec2));
+
+rec1 jn(myrecs1 L, myrecs2 R) := transform
+    self.s1 := JOIN(L.s1, R.s1, LEFT=RIGHT, HASH);
+    self.s2 := JOIN(L.s2, R.s2, LEFT=RIGHT, SMART);
+    self := L;
+end;
+
+outf := join(myrecs1,myrecs2,left.seq = right.seq,jn(LEFT,RIGHT));
+
+output(outf);

+ 58 - 0
ecl/regress/issue10643b.ecl

@@ -0,0 +1,58 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 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.
+############################################################################## */
+
+subrec1 := record
+    string1 a;
+    string1 b;
+end;
+
+subrec2 := record
+    string1 c;
+    string1 d;
+end;
+
+rec1 := record
+    integer seq;
+    integer foobar;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+rec2 := record
+    integer seq;
+    string5 foo;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+df := dataset([{'a','b'},{'c','d'}],subrec1);
+dfb := dataset([{'e','f'},{'h','i'}],subrec1);
+df2 := dataset([{'1','2'},{'3','4'}],subrec2);
+df2b := dataset([{'5','6'}],subrec2);
+
+myrecs1 := nofold(dataset([{1,2,df,df2}],rec1));
+myrecs2 := nofold(dataset([{1,'foo',dfb,df2b}],rec2));
+
+rec1 jn(DATASET(rec1) ds) := FUNCTION
+    j1 := JOIN(ds(seq >= 0), ds(seq > 0), LEFT.seq=RIGHT.seq, HASH);
+    j2 := JOIN(j1(seq >= 0), j1(seq > 0), LEFT.seq=RIGHT.seq, SMART);
+    RETURN j2;
+end;
+
+outf := LOOP(myrecs1,5,jn(ROWS(LEFT)));
+
+output(outf);

+ 60 - 0
ecl/regress/issue10643c.ecl

@@ -0,0 +1,60 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 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.
+############################################################################## */
+
+#option ('targetClusterType', 'hthor');
+
+subrec1 := record
+    string1 a;
+    string1 b;
+end;
+
+subrec2 := record
+    string1 c;
+    string1 d;
+end;
+
+rec1 := record
+    integer seq;
+    integer foobar;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+rec2 := record
+    integer seq;
+    string5 foo;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+df := dataset([{'a','b'},{'c','d'}],subrec1);
+dfb := dataset([{'e','f'},{'h','i'}],subrec1);
+df2 := dataset([{'1','2'},{'3','4'}],subrec2);
+df2b := dataset([{'5','6'}],subrec2);
+
+myrecs1 := nofold(dataset([{1,2,df,df2}],rec1));
+myrecs2 := nofold(dataset([{1,'foo',dfb,df2b}],rec2));
+
+rec1 jn(myrecs1 L, myrecs2 R) := transform
+    self.s1 := JOIN(L.s1, R.s1, LEFT=RIGHT, HASH);
+    self.s2 := JOIN(L.s2, R.s2, LEFT=RIGHT, SMART);
+    self := L;
+end;
+
+outf := join(myrecs1,myrecs2,left.seq = right.seq,jn(LEFT,RIGHT));
+
+output(outf);

+ 60 - 0
ecl/regress/issue10643d.ecl

@@ -0,0 +1,60 @@
+/*##############################################################################
+
+    HPCC SYSTEMS software Copyright (C) 2012 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.
+############################################################################## */
+
+#option ('targetClusterType', 'hthor');
+
+subrec1 := record
+    string1 a;
+    string1 b;
+end;
+
+subrec2 := record
+    string1 c;
+    string1 d;
+end;
+
+rec1 := record
+    integer seq;
+    integer foobar;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+rec2 := record
+    integer seq;
+    string5 foo;
+    dataset(subrec1) s1;
+    dataset(subrec2) s2;
+end;
+
+df := dataset([{'a','b'},{'c','d'}],subrec1);
+dfb := dataset([{'e','f'},{'h','i'}],subrec1);
+df2 := dataset([{'1','2'},{'3','4'}],subrec2);
+df2b := dataset([{'5','6'}],subrec2);
+
+myrecs1 := nofold(dataset([{1,2,df,df2}],rec1));
+myrecs2 := nofold(dataset([{1,'foo',dfb,df2b}],rec2));
+
+rec1 jn(DATASET(rec1) ds) := FUNCTION
+    j1 := JOIN(ds(seq >= 0), ds(seq > 0), LEFT.seq=RIGHT.seq, HASH);
+    j2 := JOIN(j1(seq >= 0), j1(seq > 0), LEFT.seq=RIGHT.seq, SMART);
+    RETURN j2;
+end;
+
+outf := LOOP(myrecs1,5,jn(ROWS(LEFT)));
+
+output(outf);