4088 Ole John Aske 2012-11-13 [merge]
Merge 7.1 -> 7.2 (Bug#14709490)
- Also added new (SPJ) testcase developed for this bug.
- Updated some other testcase results as this fix may change
the EXPLAIN of some pushed queries.
added:
mysql-test/suite/ndb/r/ndb_bushy_joins.result
mysql-test/suite/ndb/t/ndb_bushy_joins.cnf
mysql-test/suite/ndb/t/ndb_bushy_joins.test
modified:
mysql-test/suite/ndb/r/ndb_condition_pushdown.result
mysql-test/suite/ndb/r/ndb_join_pushdown_default.result
mysql-test/suite/ndb/t/ndb_join_pushdown.inc
sql/ha_ndbcluster_push.cc
storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp
storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp
4087 magnus.blaudd@stripped 2012-11-12 [merge]
Merge 7.1 -> 7.2
modified:
storage/ndb/compile-cluster
=== added file 'mysql-test/suite/ndb/r/ndb_bushy_joins.result'
=== added file 'mysql-test/suite/ndb/r/ndb_bushy_joins.result'
--- a/mysql-test/suite/ndb/r/ndb_bushy_joins.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_bushy_joins.result 2012-11-13 10:27:06 +0000
@@ -0,0 +1,842 @@
+create table parent(a int primary key, b int, c int, d int) engine=ndb;
+create table eq_child(a int, b int, c int, d int, primary key(a,b)) engine=ndb;
+create table ref_child(a int, b int, c int, d int, primary key(a,b)) engine=ndb;
+alter table parent partition by key(a) partitions 32;
+alter table eq_child partition by key(a) partitions 32;
+alter table ref_child partition by key(a) partitions 32;
+insert into parent values (1,1,1,1);
+insert into parent select a+1, b+1, c+1, d+1 from parent;
+insert into parent select a+1*2, b+1*2, c+1*2, d+1*2 from parent;
+insert into parent select a+1*2*2, b+1*2*2, c+1*2*2, d+1*2*2 from parent;
+insert into parent select a+1*2*2*2, b+1*2*2*2, c+1*2*2*2, d+1*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2, b+1*2*2*2*2, c+1*2*2*2*2, d+1*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2, b+1*2*2*2*2*2, c+1*2*2*2*2*2, d+1*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2, b+1*2*2*2*2*2*2, c+1*2*2*2*2*2*2, d+1*2*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2*2, b+1*2*2*2*2*2*2*2, c+1*2*2*2*2*2*2*2, d+1*2*2*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2*2*2, b+1*2*2*2*2*2*2*2*2, c+1*2*2*2*2*2*2*2*2, d+1*2*2*2*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2*2*2*2, b+1*2*2*2*2*2*2*2*2*2, c+1*2*2*2*2*2*2*2*2*2, d+1*2*2*2*2*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2*2*2*2*2, b+1*2*2*2*2*2*2*2*2*2*2, c+1*2*2*2*2*2*2*2*2*2*2, d+1*2*2*2*2*2*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2*2*2*2*2*2, b+1*2*2*2*2*2*2*2*2*2*2*2, c+1*2*2*2*2*2*2*2*2*2*2*2, d+1*2*2*2*2*2*2*2*2*2*2*2 from parent;
+insert into parent select a+1*2*2*2*2*2*2*2*2*2*2*2*2, b+1*2*2*2*2*2*2*2*2*2*2*2*2, c+1*2*2*2*2*2*2*2*2*2*2*2*2, d+1*2*2*2*2*2*2*2*2*2*2*2*2 from parent;
+select count(*) from parent;
+count(*)
+8192
+insert into eq_child select * from parent;
+insert into ref_child select * from parent;
+update ref_child set a = a-(a%16) where a > 4000;
+analyze table parent, eq_child, ref_child;
+Table Op Msg_type Msg_text
+test.parent analyze status OK
+test.eq_child analyze status OK
+test.ref_child analyze status OK
+set ndb_join_pushdown = on;
+call mtr.add_suppression("starting connect thread");
+===============================
+Run single instance of 'query1'
+===============================
+explain select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent ALL NULL NULL NULL NULL 8192 Parent of 17 pushed join@1
+1 SIMPLE c1 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'parent' in pushed join@1
+1 SIMPLE c2 eq_ref PRIMARY PRIMARY 8 test.c1.a,test.c1.b 1 Child of 'c1' in pushed join@1; Using where
+1 SIMPLE c3 eq_ref PRIMARY PRIMARY 8 test.c2.a,test.c2.a 1 Child of 'c2' in pushed join@1; Using where
+1 SIMPLE c4 eq_ref PRIMARY PRIMARY 8 test.c3.a,test.c1.b 1 Child of 'c3' in pushed join@1; Using where
+1 SIMPLE c5 eq_ref PRIMARY PRIMARY 8 test.c4.a,test.c1.a 1 Child of 'c4' in pushed join@1; Using where
+1 SIMPLE c6 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c5.a 1 Child of 'c5' in pushed join@1; Using where
+1 SIMPLE c7 eq_ref PRIMARY PRIMARY 8 test.c4.a,test.c6.a 1 Child of 'c6' in pushed join@1; Using where
+1 SIMPLE c8 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'c7' in pushed join@1
+1 SIMPLE c9 eq_ref PRIMARY PRIMARY 8 test.c1.b,test.parent.b 1 Child of 'c8' in pushed join@1; Using where
+1 SIMPLE c10 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c7.b 1 Child of 'c9' in pushed join@1; Using where
+1 SIMPLE c11 eq_ref PRIMARY PRIMARY 8 test.c4.a,test.c7.b 1 Child of 'c10' in pushed join@1; Using where
+1 SIMPLE c12 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c1.b 1 Child of 'c11' in pushed join@1; Using where
+1 SIMPLE c13 eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c1.b 1 Child of 'c12' in pushed join@1; Using where
+1 SIMPLE c14 eq_ref PRIMARY PRIMARY 8 test.c5.a,test.c7.b 1 Child of 'c13' in pushed join@1; Using where
+1 SIMPLE c15 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c1.b 1 Child of 'c14' in pushed join@1; Using where
+1 SIMPLE c16 eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c15.b 1 Child of 'c15' in pushed join@1; Using where
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+count(*)
+8192
+===============================
+Run single instance of 'query2'
+===============================
+explain select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent ALL NULL NULL NULL NULL 8192 Parent of 21 pushed join@1
+1 SIMPLE c1 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'parent' in pushed join@1
+1 SIMPLE c5 eq_ref PRIMARY PRIMARY 8 test.c1.c,test.c1.c 1 Child of 'c1' in pushed join@1
+1 SIMPLE c6 eq_ref PRIMARY PRIMARY 8 test.c1.c,test.c1.c 1 Child of 'c5' in pushed join@1
+1 SIMPLE c7 eq_ref PRIMARY PRIMARY 8 test.c1.c,test.c5.b 1 Child of 'c6' in pushed join@1; Using where
+1 SIMPLE c8 eq_ref PRIMARY PRIMARY 8 test.c7.b,test.c1.c 1 Child of 'c7' in pushed join@1; Using where
+1 SIMPLE c2 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'c1' in pushed join@1
+1 SIMPLE c9 eq_ref PRIMARY PRIMARY 8 test.c2.c,test.c2.c 1 Child of 'c2' in pushed join@1
+1 SIMPLE c10 eq_ref PRIMARY PRIMARY 8 test.c2.c,test.c9.b 1 Child of 'c9' in pushed join@1; Using where
+1 SIMPLE c11 eq_ref PRIMARY PRIMARY 8 test.c9.a,test.c9.b 1 Child of 'c10' in pushed join@1; Using where
+1 SIMPLE c12 eq_ref PRIMARY PRIMARY 8 test.c10.b,test.c9.a 1 Child of 'c11' in pushed join@1; Using where
+1 SIMPLE c3 eq_ref PRIMARY PRIMARY 8 test.c1.b,test.c1.b 1 Child of 'c2' in pushed join@1; Using where
+1 SIMPLE c13 eq_ref PRIMARY PRIMARY 8 test.c3.c,test.c3.c 1 Child of 'c3' in pushed join@1
+1 SIMPLE c14 eq_ref PRIMARY PRIMARY 8 test.c13.a,test.c13.b 1 Child of 'c13' in pushed join@1; Using where
+1 SIMPLE c15 eq_ref PRIMARY PRIMARY 8 test.c13.b,test.c3.c 1 Child of 'c14' in pushed join@1; Using where
+1 SIMPLE c16 eq_ref PRIMARY PRIMARY 8 test.c15.a,test.c13.a 1 Child of 'c15' in pushed join@1; Using where
+1 SIMPLE c4 eq_ref PRIMARY PRIMARY 8 test.c1.a,test.parent.b 1 Child of 'c3' in pushed join@1; Using where
+1 SIMPLE c17 eq_ref PRIMARY PRIMARY 8 test.c4.c,test.c4.c 1 Child of 'c4' in pushed join@1
+1 SIMPLE c18 eq_ref PRIMARY PRIMARY 8 test.c4.c,test.c4.c 1 Child of 'c17' in pushed join@1
+1 SIMPLE c19 eq_ref PRIMARY PRIMARY 8 test.c17.a,test.c17.b 1 Child of 'c18' in pushed join@1; Using where
+1 SIMPLE c20 eq_ref PRIMARY PRIMARY 8 test.c19.b,test.c19.a 1 Child of 'c19' in pushed join@1; Using where
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+count(*)
+8192
+===============================
+Run single instance of 'query3'
+===============================
+explain select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join ref_child as c2 on c2.a = parent.b
+join ref_child as c3 on c3.a = parent.b
+join ref_child as c4 on c4.a = parent.b
+join ref_child as c5 on c5.a = parent.b
+join ref_child as c6 on c6.a = parent.b
+join ref_child as c7 on c7.a = parent.b
+join ref_child as c8 on c8.a = parent.b
+join ref_child as c9 on c9.a = parent.b
+join ref_child as c10 on c10.a = parent.b
+join ref_child as c11 on c11.a = parent.b
+join ref_child as c12 on c12.a = parent.b
+join ref_child as c13 on c13.a = parent.b
+join ref_child as c14 on c14.a = parent.b
+join ref_child as c15 on c15.a = parent.b
+join ref_child as c16 on c16.a = parent.b
+where parent.a < 1000
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent range PRIMARY PRIMARY 4 NULL 1104 Parent of 17 pushed join@1; Using where with pushed condition
+1 SIMPLE c1 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c2 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c3 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c4 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c5 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c6 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c7 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c8 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c9 ref PRIMARY PRIMARY 4 test.c1.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c10 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c11 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c12 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c13 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c14 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c15 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c16 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join ref_child as c2 on c2.a = parent.b
+join ref_child as c3 on c3.a = parent.b
+join ref_child as c4 on c4.a = parent.b
+join ref_child as c5 on c5.a = parent.b
+join ref_child as c6 on c6.a = parent.b
+join ref_child as c7 on c7.a = parent.b
+join ref_child as c8 on c8.a = parent.b
+join ref_child as c9 on c9.a = parent.b
+join ref_child as c10 on c10.a = parent.b
+join ref_child as c11 on c11.a = parent.b
+join ref_child as c12 on c12.a = parent.b
+join ref_child as c13 on c13.a = parent.b
+join ref_child as c14 on c14.a = parent.b
+join ref_child as c15 on c15.a = parent.b
+join ref_child as c16 on c16.a = parent.b
+where parent.a < 1000
+;
+count(*)
+999
+===============================
+Run single instance of 'query4'
+===============================
+explain select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+join ref_child as c2 on c2.a = parent.b
+join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+join ref_child as c3 on c3.a = parent.b
+join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+join ref_child as c4 on c4.a = parent.b
+join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+join ref_child as c5 on c5.a = parent.b
+join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+join ref_child as c6 on c6.a = parent.b
+join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+join ref_child as c7 on c7.a = parent.b
+join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+join ref_child as c8 on c8.a = parent.b
+join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+join ref_child as c9 on c9.a = parent.b
+join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+join ref_child as c10 on c10.a = parent.b
+join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+join ref_child as c11 on c11.a = parent.b
+join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+join ref_child as c12 on c12.a = parent.b
+join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+join ref_child as c13 on c13.a = parent.b
+join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+join ref_child as c14 on c14.a = parent.b
+join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+join ref_child as c15 on c15.a = parent.b
+join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+join ref_child as c16 on c16.a = parent.b
+join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+where parent.a < 1000
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent range PRIMARY PRIMARY 4 NULL 1104 Parent of 32 pushed join@1; Using where with pushed condition
+1 SIMPLE c1 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c1eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c1.b 1 Child of 'c1' in pushed join@1
+1 SIMPLE c2 ref PRIMARY PRIMARY 4 test.c1.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c2eq eq_ref PRIMARY PRIMARY 8 test.c2.a,test.c2.b 1 Child of 'c2' in pushed join@1; Using where
+1 SIMPLE c3 ref PRIMARY PRIMARY 4 test.c2.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c3eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c3.b 1 Child of 'c3' in pushed join@1
+1 SIMPLE c4 ref PRIMARY PRIMARY 4 test.c3.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c4eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c4.b 1 Child of 'c4' in pushed join@1
+1 SIMPLE c5 ref PRIMARY PRIMARY 4 test.c4.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c5eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c5.b 1 Child of 'c5' in pushed join@1
+1 SIMPLE c6 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c6eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c6.b 1 Child of 'c6' in pushed join@1
+1 SIMPLE c7 ref PRIMARY PRIMARY 4 test.c5eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c7eq eq_ref PRIMARY PRIMARY 8 test.c6.a,test.c7.b 1 Child of 'c7' in pushed join@1; Using where
+1 SIMPLE c8 ref PRIMARY PRIMARY 4 test.c6eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c8eq eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c8.b 1 Child of 'c8' in pushed join@1; Using where
+1 SIMPLE c9 ref PRIMARY PRIMARY 4 test.c6eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c9eq eq_ref PRIMARY PRIMARY 8 test.c2eq.a,test.c9.b 1 Child of 'c9' in pushed join@1; Using where
+1 SIMPLE c10 ref PRIMARY PRIMARY 4 test.c7.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c10eq eq_ref PRIMARY PRIMARY 8 test.c7eq.a,test.c10.b 1 Child of 'c10' in pushed join@1; Using where
+1 SIMPLE c11 ref PRIMARY PRIMARY 4 test.c7.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c11eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c11.b 1 Child of 'c11' in pushed join@1
+1 SIMPLE c12 ref PRIMARY PRIMARY 4 test.c8eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c12eq eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c12.b 1 Child of 'c12' in pushed join@1; Using where
+1 SIMPLE c13 ref PRIMARY PRIMARY 4 test.c6eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c13eq eq_ref PRIMARY PRIMARY 8 test.c6.a,test.c13.b 1 Child of 'c13' in pushed join@1; Using where
+1 SIMPLE c14 ref PRIMARY PRIMARY 4 test.c5.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c14eq eq_ref PRIMARY PRIMARY 8 test.c5eq.a,test.c14.b 1 Child of 'c14' in pushed join@1; Using where
+1 SIMPLE c15 ref PRIMARY PRIMARY 4 test.c1eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c15eq eq_ref PRIMARY PRIMARY 8 test.c15.a,test.c15.b 1 Child of 'c15' in pushed join@1; Using where
+1 SIMPLE c16 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c16eq eq_ref PRIMARY PRIMARY 8 test.c5.a,test.c16.b 1 Using where
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+join ref_child as c2 on c2.a = parent.b
+join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+join ref_child as c3 on c3.a = parent.b
+join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+join ref_child as c4 on c4.a = parent.b
+join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+join ref_child as c5 on c5.a = parent.b
+join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+join ref_child as c6 on c6.a = parent.b
+join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+join ref_child as c7 on c7.a = parent.b
+join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+join ref_child as c8 on c8.a = parent.b
+join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+join ref_child as c9 on c9.a = parent.b
+join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+join ref_child as c10 on c10.a = parent.b
+join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+join ref_child as c11 on c11.a = parent.b
+join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+join ref_child as c12 on c12.a = parent.b
+join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+join ref_child as c13 on c13.a = parent.b
+join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+join ref_child as c14 on c14.a = parent.b
+join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+join ref_child as c15 on c15.a = parent.b
+join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+join ref_child as c16 on c16.a = parent.b
+join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+where parent.a < 1000
+;
+count(*)
+999
+=================================
+Run multiple 'query1' in parallel
+=================================
+explain select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent ALL NULL NULL NULL NULL 8192 Parent of 17 pushed join@1
+1 SIMPLE c1 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'parent' in pushed join@1
+1 SIMPLE c2 eq_ref PRIMARY PRIMARY 8 test.c1.a,test.c1.b 1 Child of 'c1' in pushed join@1; Using where
+1 SIMPLE c3 eq_ref PRIMARY PRIMARY 8 test.c2.a,test.c2.a 1 Child of 'c2' in pushed join@1; Using where
+1 SIMPLE c4 eq_ref PRIMARY PRIMARY 8 test.c3.a,test.c1.b 1 Child of 'c3' in pushed join@1; Using where
+1 SIMPLE c5 eq_ref PRIMARY PRIMARY 8 test.c4.a,test.c1.a 1 Child of 'c4' in pushed join@1; Using where
+1 SIMPLE c6 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c5.a 1 Child of 'c5' in pushed join@1; Using where
+1 SIMPLE c7 eq_ref PRIMARY PRIMARY 8 test.c4.a,test.c6.a 1 Child of 'c6' in pushed join@1; Using where
+1 SIMPLE c8 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'c7' in pushed join@1
+1 SIMPLE c9 eq_ref PRIMARY PRIMARY 8 test.c1.b,test.parent.b 1 Child of 'c8' in pushed join@1; Using where
+1 SIMPLE c10 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c7.b 1 Child of 'c9' in pushed join@1; Using where
+1 SIMPLE c11 eq_ref PRIMARY PRIMARY 8 test.c4.a,test.c7.b 1 Child of 'c10' in pushed join@1; Using where
+1 SIMPLE c12 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c1.b 1 Child of 'c11' in pushed join@1; Using where
+1 SIMPLE c13 eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c1.b 1 Child of 'c12' in pushed join@1; Using where
+1 SIMPLE c14 eq_ref PRIMARY PRIMARY 8 test.c5.a,test.c7.b 1 Child of 'c13' in pushed join@1; Using where
+1 SIMPLE c15 eq_ref PRIMARY PRIMARY 8 test.c5.b,test.c1.b 1 Child of 'c14' in pushed join@1; Using where
+1 SIMPLE c16 eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c15.b 1 Child of 'c15' in pushed join@1; Using where
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+Await completion or failure
+count(*)
+8192
+count(*)
+8192
+count(*)
+8192
+=================================
+Run multiple 'query2' in parallel
+=================================
+explain select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent ALL NULL NULL NULL NULL 8192 Parent of 21 pushed join@1
+1 SIMPLE c1 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'parent' in pushed join@1
+1 SIMPLE c5 eq_ref PRIMARY PRIMARY 8 test.c1.c,test.c1.c 1 Child of 'c1' in pushed join@1
+1 SIMPLE c6 eq_ref PRIMARY PRIMARY 8 test.c1.c,test.c1.c 1 Child of 'c5' in pushed join@1
+1 SIMPLE c7 eq_ref PRIMARY PRIMARY 8 test.c1.c,test.c5.b 1 Child of 'c6' in pushed join@1; Using where
+1 SIMPLE c8 eq_ref PRIMARY PRIMARY 8 test.c7.b,test.c1.c 1 Child of 'c7' in pushed join@1; Using where
+1 SIMPLE c2 eq_ref PRIMARY PRIMARY 8 test.parent.b,test.parent.b 1 Child of 'c1' in pushed join@1
+1 SIMPLE c9 eq_ref PRIMARY PRIMARY 8 test.c2.c,test.c2.c 1 Child of 'c2' in pushed join@1
+1 SIMPLE c10 eq_ref PRIMARY PRIMARY 8 test.c2.c,test.c9.b 1 Child of 'c9' in pushed join@1; Using where
+1 SIMPLE c11 eq_ref PRIMARY PRIMARY 8 test.c9.a,test.c9.b 1 Child of 'c10' in pushed join@1; Using where
+1 SIMPLE c12 eq_ref PRIMARY PRIMARY 8 test.c10.b,test.c9.a 1 Child of 'c11' in pushed join@1; Using where
+1 SIMPLE c3 eq_ref PRIMARY PRIMARY 8 test.c1.b,test.c1.b 1 Child of 'c2' in pushed join@1; Using where
+1 SIMPLE c13 eq_ref PRIMARY PRIMARY 8 test.c3.c,test.c3.c 1 Child of 'c3' in pushed join@1
+1 SIMPLE c14 eq_ref PRIMARY PRIMARY 8 test.c13.a,test.c13.b 1 Child of 'c13' in pushed join@1; Using where
+1 SIMPLE c15 eq_ref PRIMARY PRIMARY 8 test.c13.b,test.c3.c 1 Child of 'c14' in pushed join@1; Using where
+1 SIMPLE c16 eq_ref PRIMARY PRIMARY 8 test.c15.a,test.c13.a 1 Child of 'c15' in pushed join@1; Using where
+1 SIMPLE c4 eq_ref PRIMARY PRIMARY 8 test.c1.a,test.parent.b 1 Child of 'c3' in pushed join@1; Using where
+1 SIMPLE c17 eq_ref PRIMARY PRIMARY 8 test.c4.c,test.c4.c 1 Child of 'c4' in pushed join@1
+1 SIMPLE c18 eq_ref PRIMARY PRIMARY 8 test.c4.c,test.c4.c 1 Child of 'c17' in pushed join@1
+1 SIMPLE c19 eq_ref PRIMARY PRIMARY 8 test.c17.a,test.c17.b 1 Child of 'c18' in pushed join@1; Using where
+1 SIMPLE c20 eq_ref PRIMARY PRIMARY 8 test.c19.b,test.c19.a 1 Child of 'c19' in pushed join@1; Using where
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+select straight_join count(*) from parent
+join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+Await completion or failure
+count(*)
+8192
+count(*)
+8192
+count(*)
+8192
+=================================
+Run multiple 'query3' in parallel
+=================================
+explain select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join ref_child as c2 on c2.a = parent.b
+join ref_child as c3 on c3.a = parent.b
+join ref_child as c4 on c4.a = parent.b
+join ref_child as c5 on c5.a = parent.b
+join ref_child as c6 on c6.a = parent.b
+join ref_child as c7 on c7.a = parent.b
+join ref_child as c8 on c8.a = parent.b
+join ref_child as c9 on c9.a = parent.b
+join ref_child as c10 on c10.a = parent.b
+join ref_child as c11 on c11.a = parent.b
+join ref_child as c12 on c12.a = parent.b
+join ref_child as c13 on c13.a = parent.b
+join ref_child as c14 on c14.a = parent.b
+join ref_child as c15 on c15.a = parent.b
+join ref_child as c16 on c16.a = parent.b
+where parent.a < 1000
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent range PRIMARY PRIMARY 4 NULL 1104 Parent of 17 pushed join@1; Using where with pushed condition
+1 SIMPLE c1 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c2 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c3 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c4 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c5 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c6 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c7 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c8 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c9 ref PRIMARY PRIMARY 4 test.c1.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c10 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c11 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c12 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c13 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c14 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c15 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c16 ref PRIMARY PRIMARY 4 test.c10.a 54 Child of 'parent' in pushed join@1; Using where
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join ref_child as c2 on c2.a = parent.b
+join ref_child as c3 on c3.a = parent.b
+join ref_child as c4 on c4.a = parent.b
+join ref_child as c5 on c5.a = parent.b
+join ref_child as c6 on c6.a = parent.b
+join ref_child as c7 on c7.a = parent.b
+join ref_child as c8 on c8.a = parent.b
+join ref_child as c9 on c9.a = parent.b
+join ref_child as c10 on c10.a = parent.b
+join ref_child as c11 on c11.a = parent.b
+join ref_child as c12 on c12.a = parent.b
+join ref_child as c13 on c13.a = parent.b
+join ref_child as c14 on c14.a = parent.b
+join ref_child as c15 on c15.a = parent.b
+join ref_child as c16 on c16.a = parent.b
+where parent.a < 1000
+;
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join ref_child as c2 on c2.a = parent.b
+join ref_child as c3 on c3.a = parent.b
+join ref_child as c4 on c4.a = parent.b
+join ref_child as c5 on c5.a = parent.b
+join ref_child as c6 on c6.a = parent.b
+join ref_child as c7 on c7.a = parent.b
+join ref_child as c8 on c8.a = parent.b
+join ref_child as c9 on c9.a = parent.b
+join ref_child as c10 on c10.a = parent.b
+join ref_child as c11 on c11.a = parent.b
+join ref_child as c12 on c12.a = parent.b
+join ref_child as c13 on c13.a = parent.b
+join ref_child as c14 on c14.a = parent.b
+join ref_child as c15 on c15.a = parent.b
+join ref_child as c16 on c16.a = parent.b
+where parent.a < 1000
+;
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join ref_child as c2 on c2.a = parent.b
+join ref_child as c3 on c3.a = parent.b
+join ref_child as c4 on c4.a = parent.b
+join ref_child as c5 on c5.a = parent.b
+join ref_child as c6 on c6.a = parent.b
+join ref_child as c7 on c7.a = parent.b
+join ref_child as c8 on c8.a = parent.b
+join ref_child as c9 on c9.a = parent.b
+join ref_child as c10 on c10.a = parent.b
+join ref_child as c11 on c11.a = parent.b
+join ref_child as c12 on c12.a = parent.b
+join ref_child as c13 on c13.a = parent.b
+join ref_child as c14 on c14.a = parent.b
+join ref_child as c15 on c15.a = parent.b
+join ref_child as c16 on c16.a = parent.b
+where parent.a < 1000
+;
+Await completion or failure
+count(*)
+999
+count(*)
+999
+count(*)
+999
+=================================
+Run multiple 'query4' in parallel
+=================================
+explain select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+join ref_child as c2 on c2.a = parent.b
+join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+join ref_child as c3 on c3.a = parent.b
+join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+join ref_child as c4 on c4.a = parent.b
+join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+join ref_child as c5 on c5.a = parent.b
+join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+join ref_child as c6 on c6.a = parent.b
+join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+join ref_child as c7 on c7.a = parent.b
+join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+join ref_child as c8 on c8.a = parent.b
+join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+join ref_child as c9 on c9.a = parent.b
+join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+join ref_child as c10 on c10.a = parent.b
+join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+join ref_child as c11 on c11.a = parent.b
+join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+join ref_child as c12 on c12.a = parent.b
+join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+join ref_child as c13 on c13.a = parent.b
+join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+join ref_child as c14 on c14.a = parent.b
+join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+join ref_child as c15 on c15.a = parent.b
+join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+join ref_child as c16 on c16.a = parent.b
+join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+where parent.a < 1000
+;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE parent range PRIMARY PRIMARY 4 NULL 1104 Parent of 32 pushed join@1; Using where with pushed condition
+1 SIMPLE c1 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c1eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c1.b 1 Child of 'c1' in pushed join@1
+1 SIMPLE c2 ref PRIMARY PRIMARY 4 test.c1.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c2eq eq_ref PRIMARY PRIMARY 8 test.c2.a,test.c2.b 1 Child of 'c2' in pushed join@1; Using where
+1 SIMPLE c3 ref PRIMARY PRIMARY 4 test.c2.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c3eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c3.b 1 Child of 'c3' in pushed join@1
+1 SIMPLE c4 ref PRIMARY PRIMARY 4 test.c3.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c4eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c4.b 1 Child of 'c4' in pushed join@1
+1 SIMPLE c5 ref PRIMARY PRIMARY 4 test.c4.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c5eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c5.b 1 Child of 'c5' in pushed join@1
+1 SIMPLE c6 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c6eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c6.b 1 Child of 'c6' in pushed join@1
+1 SIMPLE c7 ref PRIMARY PRIMARY 4 test.c5eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c7eq eq_ref PRIMARY PRIMARY 8 test.c6.a,test.c7.b 1 Child of 'c7' in pushed join@1; Using where
+1 SIMPLE c8 ref PRIMARY PRIMARY 4 test.c6eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c8eq eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c8.b 1 Child of 'c8' in pushed join@1; Using where
+1 SIMPLE c9 ref PRIMARY PRIMARY 4 test.c6eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c9eq eq_ref PRIMARY PRIMARY 8 test.c2eq.a,test.c9.b 1 Child of 'c9' in pushed join@1; Using where
+1 SIMPLE c10 ref PRIMARY PRIMARY 4 test.c7.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c10eq eq_ref PRIMARY PRIMARY 8 test.c7eq.a,test.c10.b 1 Child of 'c10' in pushed join@1; Using where
+1 SIMPLE c11 ref PRIMARY PRIMARY 4 test.c7.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c11eq eq_ref PRIMARY PRIMARY 8 test.parent.b,test.c11.b 1 Child of 'c11' in pushed join@1
+1 SIMPLE c12 ref PRIMARY PRIMARY 4 test.c8eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c12eq eq_ref PRIMARY PRIMARY 8 test.c7.a,test.c12.b 1 Child of 'c12' in pushed join@1; Using where
+1 SIMPLE c13 ref PRIMARY PRIMARY 4 test.c6eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c13eq eq_ref PRIMARY PRIMARY 8 test.c6.a,test.c13.b 1 Child of 'c13' in pushed join@1; Using where
+1 SIMPLE c14 ref PRIMARY PRIMARY 4 test.c5.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c14eq eq_ref PRIMARY PRIMARY 8 test.c5eq.a,test.c14.b 1 Child of 'c14' in pushed join@1; Using where
+1 SIMPLE c15 ref PRIMARY PRIMARY 4 test.c1eq.a 54 Child of 'parent' in pushed join@1; Using where
+1 SIMPLE c15eq eq_ref PRIMARY PRIMARY 8 test.c15.a,test.c15.b 1 Child of 'c15' in pushed join@1; Using where
+1 SIMPLE c16 ref PRIMARY PRIMARY 4 test.parent.b 54 Child of 'parent' in pushed join@1
+1 SIMPLE c16eq eq_ref PRIMARY PRIMARY 8 test.c5.a,test.c16.b 1 Using where
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+join ref_child as c2 on c2.a = parent.b
+join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+join ref_child as c3 on c3.a = parent.b
+join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+join ref_child as c4 on c4.a = parent.b
+join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+join ref_child as c5 on c5.a = parent.b
+join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+join ref_child as c6 on c6.a = parent.b
+join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+join ref_child as c7 on c7.a = parent.b
+join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+join ref_child as c8 on c8.a = parent.b
+join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+join ref_child as c9 on c9.a = parent.b
+join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+join ref_child as c10 on c10.a = parent.b
+join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+join ref_child as c11 on c11.a = parent.b
+join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+join ref_child as c12 on c12.a = parent.b
+join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+join ref_child as c13 on c13.a = parent.b
+join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+join ref_child as c14 on c14.a = parent.b
+join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+join ref_child as c15 on c15.a = parent.b
+join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+join ref_child as c16 on c16.a = parent.b
+join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+where parent.a < 1000
+;
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+join ref_child as c2 on c2.a = parent.b
+join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+join ref_child as c3 on c3.a = parent.b
+join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+join ref_child as c4 on c4.a = parent.b
+join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+join ref_child as c5 on c5.a = parent.b
+join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+join ref_child as c6 on c6.a = parent.b
+join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+join ref_child as c7 on c7.a = parent.b
+join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+join ref_child as c8 on c8.a = parent.b
+join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+join ref_child as c9 on c9.a = parent.b
+join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+join ref_child as c10 on c10.a = parent.b
+join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+join ref_child as c11 on c11.a = parent.b
+join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+join ref_child as c12 on c12.a = parent.b
+join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+join ref_child as c13 on c13.a = parent.b
+join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+join ref_child as c14 on c14.a = parent.b
+join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+join ref_child as c15 on c15.a = parent.b
+join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+join ref_child as c16 on c16.a = parent.b
+join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+where parent.a < 1000
+;
+select straight_join count(*) from parent
+join ref_child as c1 on c1.a = parent.b
+join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+join ref_child as c2 on c2.a = parent.b
+join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+join ref_child as c3 on c3.a = parent.b
+join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+join ref_child as c4 on c4.a = parent.b
+join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+join ref_child as c5 on c5.a = parent.b
+join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+join ref_child as c6 on c6.a = parent.b
+join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+join ref_child as c7 on c7.a = parent.b
+join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+join ref_child as c8 on c8.a = parent.b
+join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+join ref_child as c9 on c9.a = parent.b
+join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+join ref_child as c10 on c10.a = parent.b
+join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+join ref_child as c11 on c11.a = parent.b
+join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+join ref_child as c12 on c12.a = parent.b
+join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+join ref_child as c13 on c13.a = parent.b
+join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+join ref_child as c14 on c14.a = parent.b
+join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+join ref_child as c15 on c15.a = parent.b
+join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+join ref_child as c16 on c16.a = parent.b
+join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+where parent.a < 1000
+;
+Await completion or failure
+count(*)
+999
+count(*)
+999
+count(*)
+999
+drop table parent, eq_child, ref_child;
=== modified file 'mysql-test/suite/ndb/r/ndb_condition_pushdown.result'
--- a/mysql-test/suite/ndb/r/ndb_condition_pushdown.result 2012-06-11 10:56:04 +0000
+++ b/mysql-test/suite/ndb/r/ndb_condition_pushdown.result 2012-11-13 10:27:06 +0000
@@ -2233,8 +2233,8 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE tx ALL PRIMARY NULL NULL NULL 2 100.00 Parent of 4 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.tx.a,test.tx.b 1 100.00 Child of 'tx' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.tx.c,test.tx.d 1 100.00 Child of 'tx' in pushed join@1
-1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.tx.d,test.t2.c 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.tx.c,test.tx.d 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.tx.d,test.t2.c 1 100.00 Child of 't3' in pushed join@1
Warnings:
Note 1003 select straight_join `test`.`tx`.`a` AS `a`,`test`.`tx`.`b` AS `b`,`test`.`tx`.`c` AS `c`,`test`.`tx`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c`,`test`.`t4`.`d` AS `d` from `test`.`tx` join `test`.`tx` `t2` join `test`.`tx` `t3` join `test`.`tx` `t4` where ((`test`.`t2`.`b` = `test`.`tx`.`b`) and (`test`.`t2`.`a` = `test`.`tx`.`a`) and (`test`.`t3`.`a` = `test`.`tx`.`c`) and (`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t3`.`b` = `test`.`tx`.`d`) and (`test`.`t4`.`a` = `test`.`tx`.`d`))
explain extended
=== modified file 'mysql-test/suite/ndb/r/ndb_join_pushdown_default.result'
--- a/mysql-test/suite/ndb/r/ndb_join_pushdown_default.result 2012-09-21 07:24:28 +0000
+++ b/mysql-test/suite/ndb/r/ndb_join_pushdown_default.result 2012-11-13 10:27:06 +0000
@@ -167,11 +167,30 @@
select *
from t1
join t1 as t2 on t2.a = t1.b and t2.b = t1.c
+join t1 as t3 on t3.a = t2.a and t3.b = t2.b
+where t1.a = 1 and t1.b = 1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 8 const,const 1 100.00 Parent of 3 pushed join@1
+1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 const,test.t1.c 1 100.00 Child of 't1' in pushed join@1
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 const,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t1`.`b` = 1) and (`test`.`t2`.`a` = 1) and (`test`.`t3`.`a` = 1) and (`test`.`t1`.`a` = 1))
+select *
+from t1
+join t1 as t2 on t2.a = t1.b and t2.b = t1.c
+join t1 as t3 on t3.a = t2.a and t3.b = t2.b
+where t1.a = 1 and t1.b = 1;
+a b c d a b c d a b c d
+1 1 1 1 1 1 1 1 1 1 1 1
+explain extended
+select *
+from t1
+join t1 as t2 on t2.a = t1.b and t2.b = t1.c
join t1 as t3 on t3.a = t2.a and t3.b = t2.b;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))
select *
@@ -200,7 +219,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.a,test.t2.b 1 100.00 Child of 't1' in pushed join@1
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t2.a,test.t2.b 1 100.00 Child of 't2' in pushed join@1
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` left join `test`.`t1` `t3` on(((`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`a` = `test`.`t1`.`b`))) where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`))
select *
@@ -1218,8 +1237,8 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16 100.00 Parent of 4 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t2.c 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t2.c 1 100.00 Child of 't3' in pushed join@1
Warnings:
Note 1003 select straight_join `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c`,`test`.`t4`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` join `test`.`t1` `t4` where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b` = `test`.`t1`.`d`) and (`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t3`.`a` = `test`.`t1`.`c`) and (`test`.`t4`.`a` = `test`.`t1`.`c`))
select straight_join *
@@ -1248,8 +1267,8 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16 100.00 Parent of 4 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.d,test.t2.c 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t1.d,test.t2.c 1 100.00 Child of 't3' in pushed join@1
Warnings:
Note 1003 select straight_join `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c`,`test`.`t4`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` join `test`.`t1` `t4` where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`c`) and (`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`d`) and (`test`.`t4`.`a` = `test`.`t1`.`d`))
select straight_join *
@@ -1332,8 +1351,8 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16 100.00 Parent of 4 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3.a,test.t2.c 1 100.00 Child of 't2' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't2' in pushed join@1
+1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3.a,test.t2.c 1 100.00 Child of 't3' in pushed join@1; Using where
Warnings:
Note 1003 select straight_join `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c`,`test`.`t4`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` join `test`.`t1` `t4` where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b` = `test`.`t1`.`d`) and (`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t3`.`a` = `test`.`t1`.`c`) and (`test`.`t4`.`a` = `test`.`t1`.`c`))
select straight_join *
@@ -1441,8 +1460,8 @@
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16 100.00 Parent of 6 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 100.00 Child of 't1' in pushed join@1
1 SIMPLE t2x eq_ref PRIMARY PRIMARY 8 test.t2.c,test.t2.d 1 100.00 Child of 't2' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3x eq_ref PRIMARY PRIMARY 8 test.t3.a,test.t3.b 1 100.00 Child of 't2x' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t1.d 1 100.00 Child of 't2x' in pushed join@1
+1 SIMPLE t3x eq_ref PRIMARY PRIMARY 8 test.t3.a,test.t3.b 1 100.00 Child of 't3' in pushed join@1; Using where
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3x.c,test.t2x.c 1 100.00 Child of 't3x' in pushed join@1
Warnings:
Note 1003 select straight_join `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2x`.`a` AS `a`,`test`.`t2x`.`b` AS `b`,`test`.`t2x`.`c` AS `c`,`test`.`t2x`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d`,`test`.`t3x`.`a` AS `a`,`test`.`t3x`.`b` AS `b`,`test`.`t3x`.`c` AS `c`,`test`.`t3x`.`d` AS `d`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c`,`test`.`t4`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t2x` join `test`.`t1` `t3` join `test`.`t1` `t3x` join `test`.`t1` `t4` where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t2x`.`b` = `test`.`t2`.`d`) and (`test`.`t2x`.`a` = `test`.`t2`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`d`) and (`test`.`t3x`.`b` = `test`.`t1`.`d`) and (`test`.`t3`.`a` = `test`.`t1`.`c`) and (`test`.`t3x`.`a` = `test`.`t1`.`c`) and (`test`.`t4`.`b` = `test`.`t2x`.`c`) and (`test`.`t4`.`a` = `test`.`t3x`.`c`))
@@ -1458,8 +1477,8 @@
1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 16 100.00 Parent of 6 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a,test.t1.b 1 100.00 Child of 't1' in pushed join@1
1 SIMPLE t2x eq_ref PRIMARY PRIMARY 8 test.t2.c,test.t2.d 1 100.00 Child of 't2' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
-1 SIMPLE t3x eq_ref PRIMARY PRIMARY 8 test.t3.a,test.t1.d 1 100.00 Child of 't2x' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.c,test.t2.b 1 100.00 Child of 't2x' in pushed join@1; Using where
+1 SIMPLE t3x eq_ref PRIMARY PRIMARY 8 test.t3.a,test.t1.d 1 100.00 Child of 't3' in pushed join@1; Using where
1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3x.c,test.t2x.c 1 100.00 Child of 't3x' in pushed join@1
Warnings:
Note 1003 select straight_join `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t2x`.`a` AS `a`,`test`.`t2x`.`b` AS `b`,`test`.`t2x`.`c` AS `c`,`test`.`t2x`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d`,`test`.`t3x`.`a` AS `a`,`test`.`t3x`.`b` AS `b`,`test`.`t3x`.`c` AS `c`,`test`.`t3x`.`d` AS `d`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c`,`test`.`t4`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t2x` join `test`.`t1` `t3` join `test`.`t1` `t3x` join `test`.`t1` `t4` where ((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t2x`.`b` = `test`.`t2`.`d`) and (`test`.`t2x`.`a` = `test`.`t2`.`c`) and (`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t3`.`b` = `test`.`t1`.`b`) and (`test`.`t3x`.`b` = `test`.`t1`.`d`) and (`test`.`t3`.`a` = `test`.`t1`.`c`) and (`test`.`t3x`.`a` = `test`.`t1`.`c`) and (`test`.`t4`.`b` = `test`.`t2x`.`c`) and (`test`.`t4`.`a` = `test`.`t3x`.`c`))
@@ -1730,7 +1749,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`c`,`test`.`t1`.`d`,`test`.`t1`.`a`,`test`.`t1`.`b`
select *
@@ -1763,7 +1782,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`c`,`test`.`t2`.`d`,`test`.`t1`.`a`,`test`.`t1`.`b`
select *
@@ -1795,7 +1814,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 8 NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`a`,`test`.`t1`.`b`
select *
@@ -1827,7 +1846,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`a`,`test`.`t2`.`b`,`test`.`t1`.`a`,`test`.`t1`.`b`
select *
@@ -1859,7 +1878,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 8 NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`a` desc,`test`.`t1`.`b` desc
select *
@@ -1890,7 +1909,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`b`,`test`.`t1`.`a`
select *
@@ -1921,7 +1940,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 8 NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`a`
explain extended
@@ -1933,7 +1952,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t3`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) order by `test`.`t1`.`b`
explain extended
@@ -1945,7 +1964,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 8 NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,count(0) AS `count(*)` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) group by `test`.`t1`.`a`,`test`.`t1`.`b`
select t1.a, t1.b, count(*)
@@ -1976,7 +1995,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 index NULL PRIMARY 8 NULL 16 100.00 Parent of 3 pushed join@1
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,count(0) AS `count(*)` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) group by `test`.`t1`.`a`
select t1.a, count(*)
@@ -1998,7 +2017,7 @@
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 16 100.00 Parent of 3 pushed join@1; Using temporary; Using filesort
1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t1.c 1 100.00 Child of 't1' in pushed join@1
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't1' in pushed join@1; Using where
+1 SIMPLE t3 eq_ref PRIMARY PRIMARY 8 test.t1.b,test.t2.b 1 100.00 Child of 't2' in pushed join@1; Using where
Warnings:
Note 1003 select `test`.`t1`.`b` AS `b`,count(0) AS `count(*)` from `test`.`t1` join `test`.`t1` `t2` join `test`.`t1` `t3` where ((`test`.`t2`.`b` = `test`.`t1`.`c`) and (`test`.`t3`.`b` = `test`.`t1`.`c`) and (`test`.`t2`.`a` = `test`.`t1`.`b`) and (`test`.`t3`.`a` = `test`.`t1`.`b`)) group by `test`.`t1`.`b`
select t1.b, count(*)
@@ -5774,7 +5793,7 @@
LOCAL_TABLE_SCANS_SENT 254
PRUNED_RANGE_SCANS_RECEIVED 27
RANGE_SCANS_RECEIVED 738
-READS_RECEIVED 48
+READS_RECEIVED 49
TABLE_SCANS_RECEIVED 254
drop table spj_counts_at_startup;
drop table spj_counts_at_end;
@@ -5785,9 +5804,9 @@
order by new.variable_name;
variable_name new.variable_value - old.variable_value
NDB_PRUNED_SCAN_COUNT 8
-NDB_PUSHED_QUERIES_DEFINED 411
+NDB_PUSHED_QUERIES_DEFINED 413
NDB_PUSHED_QUERIES_DROPPED 9
-NDB_PUSHED_QUERIES_EXECUTED 541
+NDB_PUSHED_QUERIES_EXECUTED 542
NDB_SORTED_SCAN_COUNT 11
drop table server_counts_at_startup;
set ndb_join_pushdown = @save_ndb_join_pushdown;
=== added file 'mysql-test/suite/ndb/t/ndb_bushy_joins.cnf'
--- a/mysql-test/suite/ndb/t/ndb_bushy_joins.cnf 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_bushy_joins.cnf 2012-11-13 10:27:06 +0000
@@ -0,0 +1,22 @@
+!include suite/ndb/my.cnf
+
+[cluster_config]
+######
+# Increase #LDM threads such that tables
+# can be created with many partitions (> 8)
+# Max: #nodes * #LDM * NoOfFragmentLogParts / NoOfReplicas
+######
+ThreadConfig=ldm={count=4}
+
+######
+# Tune some more configs as test load is
+# expected to really strain the system.
+######
+MaxNoOfConcurrentOperations=250000
+LongMessageBuffer=64M
+TransactionDeadlockDetectionTimeout=30000
+
+[ENV]
+# Need to always use ndbmtd when we want lots of partitions
+# (Avoid mixed 'round robin' use of mt / non-mt)
+MTR_NDBMTD= 1
=== added file 'mysql-test/suite/ndb/t/ndb_bushy_joins.test'
--- a/mysql-test/suite/ndb/t/ndb_bushy_joins.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_bushy_joins.test 2012-11-13 10:27:06 +0000
@@ -0,0 +1,270 @@
+########################################################
+# ndb_bushy_joins.test
+#
+# This test is intended to check system behaviour when SPJ
+# executes large bushy-joins, aka 'star-joins' -> joins with
+# multiple childs being dependent on the same parent.
+#
+# These types of joins has previously caused
+# job buffer overflow as too many requests was
+# sent in parallel from the SPJ block.
+# (bug#14709490)
+########################################################
+
+-- source include/have_ndb.inc
+-- source include/have_multi_ndb.inc
+
+connect (ddl,localhost,root,,test);
+connect (j1,localhost,root,,test);
+connect (j2,localhost,root,,test);
+connect (j3,localhost,root,,test);
+
+connection ddl;
+
+create table parent(a int primary key, b int, c int, d int) engine=ndb;
+create table eq_child(a int, b int, c int, d int, primary key(a,b)) engine=ndb;
+create table ref_child(a int, b int, c int, d int, primary key(a,b)) engine=ndb;
+
+alter table parent partition by key(a) partitions 32;
+alter table eq_child partition by key(a) partitions 32;
+alter table ref_child partition by key(a) partitions 32;
+
+insert into parent values (1,1,1,1);
+
+let $factor = 1;
+let $loops = 13;
+
+# Fill tables with 2^loops rows
+while ($loops)
+{
+ eval insert into parent select a+$factor, b+$factor, c+$factor, d+$factor from parent;
+ let $factor = $factor*2;
+ dec $loops;
+}
+select count(*) from parent;
+
+insert into eq_child select * from parent;
+insert into ref_child select * from parent;
+
+# Cheat statistics: update rows actually not refered in joins below
+# (Cheat required in order to make 'ref-joins' bushy)
+update ref_child set a = a-(a%16) where a > 4000;
+
+analyze table parent, eq_child, ref_child;
+
+let $query1 =
+ select straight_join count(*) from parent
+ join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+ join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+ join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+ join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+ join eq_child as c5 on c5.a = parent.b and c5.b = parent.b
+ join eq_child as c6 on c6.a = parent.b and c6.b = parent.b
+ join eq_child as c7 on c7.a = parent.b and c7.b = parent.b
+ join eq_child as c8 on c8.a = parent.b and c8.b = parent.b
+ join eq_child as c9 on c9.a = parent.b and c9.b = parent.b
+ join eq_child as c10 on c10.a = parent.b and c10.b = parent.b
+ join eq_child as c11 on c11.a = parent.b and c11.b = parent.b
+ join eq_child as c12 on c12.a = parent.b and c12.b = parent.b
+ join eq_child as c13 on c13.a = parent.b and c13.b = parent.b
+ join eq_child as c14 on c14.a = parent.b and c14.b = parent.b
+ join eq_child as c15 on c15.a = parent.b and c15.b = parent.b
+ join eq_child as c16 on c16.a = parent.b and c16.b = parent.b
+;
+
+let $query2 =
+ select straight_join count(*) from parent
+ join eq_child as c1 on c1.a = parent.b and c1.b = parent.b
+ join eq_child as c5 on c5.a = c1.c and c5.b = c1.c
+ join eq_child as c6 on c6.a = c1.c and c6.b = c1.c
+ join eq_child as c7 on c7.a = c1.c and c7.b = c1.c
+ join eq_child as c8 on c8.a = c1.c and c8.b = c1.c
+ join eq_child as c2 on c2.a = parent.b and c2.b = parent.b
+ join eq_child as c9 on c9.a = c2.c and c9.b = c2.c
+ join eq_child as c10 on c10.a = c2.c and c10.b = c2.c
+ join eq_child as c11 on c11.a = c2.c and c11.b = c2.c
+ join eq_child as c12 on c12.a = c2.c and c12.b = c2.c
+ join eq_child as c3 on c3.a = parent.b and c3.b = parent.b
+ join eq_child as c13 on c13.a = c3.c and c13.b = c3.c
+ join eq_child as c14 on c14.a = c3.c and c14.b = c3.c
+ join eq_child as c15 on c15.a = c3.c and c15.b = c3.c
+ join eq_child as c16 on c16.a = c3.c and c16.b = c3.c
+ join eq_child as c4 on c4.a = parent.b and c4.b = parent.b
+ join eq_child as c17 on c17.a = c4.c and c17.b = c4.c
+ join eq_child as c18 on c18.a = c4.c and c18.b = c4.c
+ join eq_child as c19 on c19.a = c4.c and c19.b = c4.c
+ join eq_child as c20 on c20.a = c4.c and c20.b = c4.c
+;
+
+let $query3 =
+ select straight_join count(*) from parent
+ join ref_child as c1 on c1.a = parent.b
+ join ref_child as c2 on c2.a = parent.b
+ join ref_child as c3 on c3.a = parent.b
+ join ref_child as c4 on c4.a = parent.b
+ join ref_child as c5 on c5.a = parent.b
+ join ref_child as c6 on c6.a = parent.b
+ join ref_child as c7 on c7.a = parent.b
+ join ref_child as c8 on c8.a = parent.b
+ join ref_child as c9 on c9.a = parent.b
+ join ref_child as c10 on c10.a = parent.b
+ join ref_child as c11 on c11.a = parent.b
+ join ref_child as c12 on c12.a = parent.b
+ join ref_child as c13 on c13.a = parent.b
+ join ref_child as c14 on c14.a = parent.b
+ join ref_child as c15 on c15.a = parent.b
+ join ref_child as c16 on c16.a = parent.b
+ where parent.a < 1000
+;
+
+let $query4 =
+ select straight_join count(*) from parent
+ join ref_child as c1 on c1.a = parent.b
+ join eq_child as c1eq on c1eq.a = c1.a and c1eq.b = c1.b
+ join ref_child as c2 on c2.a = parent.b
+ join eq_child as c2eq on c2eq.a = c2.a and c2eq.b = c2.b
+ join ref_child as c3 on c3.a = parent.b
+ join eq_child as c3eq on c3eq.a = c3.a and c3eq.b = c3.b
+ join ref_child as c4 on c4.a = parent.b
+ join eq_child as c4eq on c4eq.a = c4.a and c4eq.b = c4.b
+ join ref_child as c5 on c5.a = parent.b
+ join eq_child as c5eq on c5eq.a = c5.a and c5eq.b = c5.b
+ join ref_child as c6 on c6.a = parent.b
+ join eq_child as c6eq on c6eq.a = c6.a and c6eq.b = c6.b
+ join ref_child as c7 on c7.a = parent.b
+ join eq_child as c7eq on c7eq.a = c7.a and c7eq.b = c7.b
+ join ref_child as c8 on c8.a = parent.b
+ join eq_child as c8eq on c8eq.a = c8.a and c8eq.b = c8.b
+ join ref_child as c9 on c9.a = parent.b
+ join eq_child as c9eq on c9eq.a = c9.a and c9eq.b = c9.b
+ join ref_child as c10 on c10.a = parent.b
+ join eq_child as c10eq on c10eq.a = c10.a and c10eq.b = c10.b
+ join ref_child as c11 on c11.a = parent.b
+ join eq_child as c11eq on c11eq.a = c11.a and c11eq.b = c11.b
+ join ref_child as c12 on c12.a = parent.b
+ join eq_child as c12eq on c12eq.a = c12.a and c12eq.b = c12.b
+ join ref_child as c13 on c13.a = parent.b
+ join eq_child as c13eq on c13eq.a = c13.a and c13eq.b = c13.b
+ join ref_child as c14 on c14.a = parent.b
+ join eq_child as c14eq on c14eq.a = c14.a and c14eq.b = c14.b
+ join ref_child as c15 on c15.a = parent.b
+ join eq_child as c15eq on c15eq.a = c15.a and c15eq.b = c15.b
+ join ref_child as c16 on c16.a = parent.b
+ join eq_child as c16eq on c16eq.a = c16.a and c16eq.b = c16.b
+ where parent.a < 1000
+;
+
+connection j1;
+set ndb_join_pushdown = on;
+
+call mtr.add_suppression("starting connect thread");
+
+-- echo ===============================
+-- echo Run single instance of 'query1'
+-- echo ===============================
+eval explain $query1;
+eval $query1;
+
+-- echo ===============================
+-- echo Run single instance of 'query2'
+-- echo ===============================
+eval explain $query2;
+eval $query2;
+
+-- echo ===============================
+-- echo Run single instance of 'query3'
+-- echo ===============================
+eval explain $query3;
+eval $query3;
+
+-- echo ===============================
+-- echo Run single instance of 'query4'
+-- echo ===============================
+eval explain $query4;
+eval $query4;
+
+
+-- echo =================================
+-- echo Run multiple 'query1' in parallel
+-- echo =================================
+let $query = $query1;
+eval explain $query;
+connection j1;
+send_eval $query;
+connection j2;
+send_eval $query;
+connection j3;
+send_eval $query;
+
+-- echo Await completion or failure
+connection j1;
+reap;
+connection j2;
+reap;
+connection j3;
+reap;
+
+-- echo =================================
+-- echo Run multiple 'query2' in parallel
+-- echo =================================
+let $query = $query2;
+eval explain $query;
+connection j1;
+send_eval $query;
+connection j2;
+send_eval $query;
+connection j3;
+send_eval $query;
+
+-- echo Await completion or failure
+connection j1;
+reap;
+connection j2;
+reap;
+connection j3;
+reap;
+
+-- echo =================================
+-- echo Run multiple 'query3' in parallel
+-- echo =================================
+let $query = $query3;
+eval explain $query;
+connection j1;
+send_eval $query;
+connection j2;
+send_eval $query;
+connection j3;
+send_eval $query;
+
+-- echo Await completion or failure
+connection j1;
+reap;
+connection j2;
+reap;
+connection j3;
+reap;
+
+-- echo =================================
+-- echo Run multiple 'query4' in parallel
+-- echo =================================
+let $query = $query4;
+eval explain $query;
+connection j1;
+send_eval $query;
+connection j2;
+send_eval $query;
+connection j3;
+send_eval $query;
+
+-- echo Await completion or failure
+connection j1;
+reap;
+connection j2;
+reap;
+connection j3;
+reap;
+
+
+connection ddl;
+drop table parent, eq_child, ref_child;
+
=== modified file 'mysql-test/suite/ndb/t/ndb_join_pushdown.inc'
--- a/mysql-test/suite/ndb/t/ndb_join_pushdown.inc 2012-09-21 07:24:28 +0000
+++ b/mysql-test/suite/ndb/t/ndb_join_pushdown.inc 2012-11-13 10:27:06 +0000
@@ -109,6 +109,19 @@
select *
from t1
join t1 as t2 on t2.a = t1.b and t2.b = t1.c
+join t1 as t3 on t3.a = t2.a and t3.b = t2.b
+where t1.a = 1 and t1.b = 1;
+--sorted_result
+select *
+from t1
+join t1 as t2 on t2.a = t1.b and t2.b = t1.c
+join t1 as t3 on t3.a = t2.a and t3.b = t2.b
+where t1.a = 1 and t1.b = 1;
+
+explain extended
+select *
+from t1
+join t1 as t2 on t2.a = t1.b and t2.b = t1.c
join t1 as t3 on t3.a = t2.a and t3.b = t2.b;
--sorted_result
select *
=== modified file 'sql/ha_ndbcluster_push.cc'
--- a/sql/ha_ndbcluster_push.cc 2012-06-11 10:56:04 +0000
+++ b/sql/ha_ndbcluster_push.cc 2012-11-13 10:27:06 +0000
@@ -1097,35 +1097,31 @@
DBUG_ASSERT(!parents.contain(tab_no)); // No circular dependency!
/**
- * In order to take advantage of the parallelism in the SPJ block;
+- * In order to take advantage of the parallelism in the SPJ block;
* Initial parent candidate is the first possible among 'parents'.
* Will result in the most 'bushy' query plan (aka: star-join)
*/
parent_no= parents.first_table(root_no);
- if (table.m_fanout*table.m_child_fanout > 1.0 ||
- !ndbcluster_is_lookup_operation(m_plan.get_table_access(tab_no)->get_access_type()))
+ /**
+ * Push optimization for execution of child operations:
+ *
+ * To take advantage of the selectivity of parent operations we
+ * execute any parent operations with fanout <= 1 before this
+ * child operation. By making them depending on parent
+ * operations with high selectivity, child will be eliminated when
+ * the parent returns no matching rows.
+ *
+ * -> Execute child operation after any such parents
+ */
+ for (uint candidate= parent_no+1; candidate<parents.length(); candidate++)
{
- /**
- * This is a index-scan or lookup with scan childs.
- * Push optimization for index-scan execute:
- *
- * These are relative expensive operation which we try to avoid to
- * execute whenever possible. By making them depending on parent
- * operations with high selectivity, they will be eliminated when
- * the parent returns no matching rows.
- *
- * -> Execute index-scan after any such parents
- */
- for (uint candidate= parent_no+1; candidate<parents.length(); candidate++)
+ if (parents.contain(candidate))
{
- if (parents.contain(candidate))
- {
- if (m_tables[candidate].m_fanout > 1.0)
- break;
+ if (m_tables[candidate].m_fanout > 1.0)
+ break;
- parent_no= candidate; // Parent candidate is selective, eval after
- }
+ parent_no= candidate; // Parent candidate is selective, eval after
}
}
=== modified file 'storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp 2012-11-08 12:02:48 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/Dbspj.hpp 2012-11-13 10:27:06 +0000
@@ -112,6 +112,8 @@
struct Request;
struct TreeNode;
struct ScanFragHandle;
+ typedef DataBuffer2<14, LocalArenaPoolImpl> Correlation_list;
+ typedef LocalDataBuffer2<14, LocalArenaPoolImpl> Local_correlation_list;
typedef DataBuffer2<14, LocalArenaPoolImpl> Dependency_map;
typedef LocalDataBuffer2<14, LocalArenaPoolImpl> Local_dependency_map;
typedef DataBuffer2<14, LocalArenaPoolImpl> PatternStore;
@@ -792,6 +794,28 @@
Uint32 m_scanFragReq[ScanFragReq::SignalLength + 2];
};
+ struct DeferredParentOps
+ {
+ /**
+ * m_correlations contains a list of Correlation Values (Uint32)
+ * which identifies parent rows which has been deferred.
+ * m_pos are index into this array, identifying the next parent row
+ * for which to resume operation.
+ */
+ Correlation_list::Head m_correlations;
+ Uint16 m_pos; // Next row operation to resume
+
+ DeferredParentOps() : m_correlations(), m_pos(0) {}
+
+ void init() {
+ m_correlations.init();
+ m_pos = 0;
+ }
+ bool isEmpty() const {
+ return (m_pos == m_correlations.getSize());
+ }
+ };
+
struct TreeNode_cursor_ptr
{
Uint32 nextList;
@@ -809,7 +833,8 @@
TreeNode()
: m_magic(MAGIC), m_state(TN_END),
m_parentPtrI(RNIL), m_requestPtrI(RNIL),
- m_ancestors()
+ m_ancestors(),
+ m_resumeEvents(0), m_resumePtrI(RNIL)
{
}
@@ -818,6 +843,7 @@
m_info(0), m_bits(T_LEAF), m_state(TN_BUILDING),
m_parentPtrI(RNIL), m_requestPtrI(request),
m_ancestors(),
+ m_resumeEvents(0), m_resumePtrI(RNIL),
nextList(RNIL), prevList(RNIL)
{
// m_send.m_ref = 0;
@@ -945,10 +971,27 @@
*/
T_SCAN_REPEATABLE = 0x4000,
+ /**
+ * Exec of a previous REQ must complete before we can proceed.
+ * A ResumeEvent will later resume exec. of this operation
+ */
+ T_EXEC_SEQUENTIAL = 0x8000,
+
// End marker...
T_END = 0
};
+ /**
+ * Describe whether a LQHKEY-REF and/or CONF whould trigger a
+ * exec resume of another TreeNode having T_EXEC_SEQUENTIAL.
+ * (Used as a bitmask)
+ */
+ enum TreeNodeResumeEvents
+ {
+ TN_RESUME_REF = 0x01,
+ TN_RESUME_CONF = 0x02
+ };
+
bool isLeaf() const { return (m_bits & T_LEAF) != 0;}
// table or index this TreeNode operates on, and its schemaVersion
@@ -974,6 +1017,22 @@
*/
RowCollection m_rows;
+ /**
+ * T_EXEC_SEQUENTIAL cause execution of child operations to
+ * be deferred. These operations are queued in the 'struct DeferredParentOps'
+ * Currently only Lookup operation might be deferred.
+ * Could later be extended to also cover index scans.
+ */
+ DeferredParentOps m_deferred;
+
+ /**
+ * Set of TreeNodeResumeEvents, possibly or'ed.
+ * Specify whether a REF or CONF will cause a resume
+ * of the TreeNode referred by 'm_resumePtrI'.
+ */
+ Uint32 m_resumeEvents;
+ Uint32 m_resumePtrI;
+
union
{
LookupData m_lookup_data;
@@ -1251,6 +1310,7 @@
const OpInfo* getOpInfo(Uint32 op);
Uint32 build(Build_context&,Ptr<Request>,SectionReader&,SectionReader&);
Uint32 initRowBuffers(Ptr<Request>);
+ void buildExecPlan(Ptr<Request>, Ptr<TreeNode> node, Ptr<TreeNode> next);
void checkPrepareComplete(Signal*, Ptr<Request>, Uint32 cnt);
void start(Signal*, Ptr<Request>);
void checkBatchComplete(Signal*, Ptr<Request>, Uint32 cnt);
@@ -1259,13 +1319,14 @@
void sendConf(Signal*, Ptr<Request>, bool is_complete);
void complete(Signal*, Ptr<Request>);
void cleanup(Ptr<Request>);
+ void cleanupBatch(Ptr<Request>);
void abort(Signal*, Ptr<Request>, Uint32 errCode);
Uint32 nodeFail(Signal*, Ptr<Request>, NdbNodeBitmask mask);
Uint32 createNode(Build_context&, Ptr<Request>, Ptr<TreeNode> &);
void reportBatchComplete(Signal*, Ptr<Request>, Ptr<TreeNode>);
void releaseScanBuffers(Ptr<Request> requestPtr);
- void releaseRequestBuffers(Ptr<Request> requestPtr, bool reset);
+ void releaseRequestBuffers(Ptr<Request> requestPtr);
void releaseNodeRows(Ptr<Request> requestPtr, Ptr<TreeNode>);
void registerActiveCursor(Ptr<Request>, Ptr<TreeNode>);
void nodeFail_checkRequests(Signal*);
@@ -1368,6 +1429,7 @@
Uint32 lookup_build(Build_context&,Ptr<Request>,
const QueryNode*, const QueryNodeParameters*);
void lookup_start(Signal*, Ptr<Request>, Ptr<TreeNode>);
+ void lookup_resume(Signal*, Ptr<Request>, Ptr<TreeNode>);
void lookup_send(Signal*, Ptr<Request>, Ptr<TreeNode>);
void lookup_execTRANSID_AI(Signal*, Ptr<Request>, Ptr<TreeNode>,
const RowPtr&);
@@ -1375,6 +1437,7 @@
void lookup_execLQHKEYCONF(Signal*, Ptr<Request>, Ptr<TreeNode>);
void lookup_parent_row(Signal*, Ptr<Request>, Ptr<TreeNode>, const RowPtr &);
void lookup_parent_batch_complete(Signal*, Ptr<Request>, Ptr<TreeNode>);
+ void lookup_row(Signal*, Ptr<Request>, Ptr<TreeNode>, const RowPtr &);
void lookup_abort(Signal*, Ptr<Request>, Ptr<TreeNode>);
Uint32 lookup_execNODE_FAILREP(Signal*signal, Ptr<Request>, Ptr<TreeNode>,
NdbNodeBitmask);
=== modified file 'storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2012-11-08 12:02:48 +0000
+++ b/storage/ndb/src/kernel/blocks/dbspj/DbspjMain.cpp 2012-11-13 10:27:06 +0000
@@ -50,7 +50,7 @@
* DEBUG options for different parts od SPJ block
* Comment out those part you don't want DEBUG'ed.
*/
-#define DEBUG(x) ndbout << "DBSPJ: "<< x << endl;
+//#define DEBUG(x) ndbout << "DBSPJ: "<< x << endl;
//#define DEBUG_DICT(x) ndbout << "DBSPJ: "<< x << endl;
//#define DEBUG_LQHKEYREQ
//#define DEBUG_SCAN_FRAGREQ
@@ -1314,7 +1314,35 @@
Uint32
Dbspj::initRowBuffers(Ptr<Request> requestPtr)
{
- Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
+ jam();
+ /**
+ * Execution of scan request requires restrictions
+ * of how lookup-children issues their LQHKEYREQs:
+ * A large scan result with many parallel lookup
+ * siblings can easily flood the job buffers with too many
+ * REQs. So we set up an 'execution plan' for how a
+ * scan request should be executed:
+ *
+ * NOTE: It could make sense to do the same for a lookup Req.
+ * However, CONF/REF for these leafs operations are not
+ * returned to SPJ. Thus, there are no way to know when
+ * the operation has completed, and other operation could
+ * be resumed.
+ *
+ * As a lookup request does not have the same potential for
+ * producing lots of LQHKEYREQs, we believe/hope the risk
+ * of flooding job buffers for a lookup request can be ignored.
+ */
+ if (requestPtr.p->isScan())
+ {
+ jam();
+ Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
+ Ptr<TreeNode> treeRootPtr;
+
+ list.first(treeRootPtr); // treeRootPtr is a scan
+ ndbrequire(!treeRootPtr.isNull());
+ buildExecPlan(requestPtr, treeRootPtr, NullTreeNodePtr);
+ }
/**
* Init ROW_BUFFERS iff Request has to buffer any rows.
@@ -1345,6 +1373,7 @@
requestPtr.p->m_rowBuffer.init(BUFFER_STACK);
}
+ Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
Ptr<TreeNode> treeNodePtr;
for (list.first(treeNodePtr); !treeNodePtr.isNull(); list.next(treeNodePtr))
{
@@ -1372,7 +1401,150 @@
}
return 0;
-}
+} // Dbspj::initRowBuffers
+
+/**
+ * buildExecPlan():
+ * Decides the order/pace in which the different
+ * TreeNodes should be executed.
+ * Currently it is only used to insert sequentialization point in
+ * the execution of bushy lookup-child nodes. (aka star-join).
+ * This is done in order to avoid too many LQHKEYREQ-signals to
+ * be sent which could overflow the job buffers.
+ *
+ * For each branch of TreeNodes starting with a scan, we identify
+ * any 'bushines' among its lookup children. We set up a left -> right
+ * execution order among these such that:
+ * - A child lookup operation can not be REQuested before we
+ * either has executed a TRANSID_AI from the scan parent,
+ * or executed a CONF / REF from another lookup child.
+ * - When a lookup CONF or REF is executed, its TreeNode is
+ * annotated with 'resume' info which decides if/which TreeNode
+ * we should execute next.
+ *
+ * This will maintain a strict 1:1 fanout between incomming rows
+ * being processed, and new row REQuest being produced.
+ * Thus avoiding that large scan result will flood the jobb buffers
+ * with too many lookup requests.
+ *
+ * FUTURE:
+ * For join children where child execution now is T_EXEC_SEQUENTIAL,
+ * it should be relatively simple to extend SPJ to do 'inner join'.
+ * As we at these sequential point knows wheteher the previous
+ * joined children didn't found any matches, we can skip REQuesting
+ * rows from other children having the same parent row.
+ */
+void
+Dbspj::buildExecPlan(Ptr<Request> requestPtr,
+ Ptr<TreeNode> treeNodePtr,
+ Ptr<TreeNode> nextLookup)
+{
+ Uint32 lookupChildren[NDB_SPJ_MAX_TREE_NODES];
+ Uint32 lookupChildCnt = 0;
+
+ /**
+ * Need to iterate lookup childs in reverse order to set up 'next'
+ * operations. As this is not possible throught ConstDataBufferIterator,
+ * store any lookup childs into temp array childPtrI[].
+ * Scan childs are parents of new 'scan -> lookup' branches.
+ */
+ {
+ LocalArenaPoolImpl pool(requestPtr.p->m_arena, m_dependency_map_pool);
+ Local_dependency_map childList(pool, treeNodePtr.p->m_dependent_nodes);
+ Dependency_map::ConstDataBufferIterator it;
+ for (childList.first(it); !it.isNull(); childList.next(it))
+ {
+ jam();
+ Ptr<TreeNode> childPtr;
+ m_treenode_pool.getPtr(childPtr, *it.data);
+
+ if (childPtr.p->m_info == &g_LookupOpInfo)
+ {
+ jam();
+ lookupChildren[lookupChildCnt++] = *it.data;
+ }
+ else
+ {
+ // Build a new plan starting from this scan operation
+ jam();
+ buildExecPlan(requestPtr, childPtr, NullTreeNodePtr);
+ }
+ }
+ }
+
+ /**
+ * Lookup children might have to wait for previous LQHKEYREQs to
+ * complete before they are allowed to send their own requests.
+ * (In order to not overfill jobb buffers)
+ */
+ if (treeNodePtr.p->m_info == &g_LookupOpInfo &&
+ !nextLookup.isNull())
+ {
+ jam();
+ /**
+ * Annotate that:
+ * - 'nextLookup' is not allowed to start immediately.
+ * - 'treeNode' restart 'nextLookup' when it completes
+ */
+ nextLookup.p->m_bits |= TreeNode::T_EXEC_SEQUENTIAL;
+
+ if (lookupChildCnt==0) //'isLeaf() or only scan children
+ {
+ jam();
+ treeNodePtr.p->m_resumeEvents = TreeNode::TN_RESUME_CONF |
+ TreeNode::TN_RESUME_REF;
+ DEBUG("ExecPlan: 'REF/CONF' from node " << treeNodePtr.p->m_node_no
+ << " resumes node " << nextLookup.p->m_node_no);
+ }
+ else
+ {
+ /**
+ * Will REQuest from one of its child lookups if CONF,
+ * so we don't resume another TreeNode in addition.
+ */
+ jam();
+ treeNodePtr.p->m_resumeEvents = TreeNode::TN_RESUME_REF;
+ DEBUG("ExecPlan: 'REF' from node " << treeNodePtr.p->m_node_no
+ << " resumes node " << nextLookup.p->m_node_no);
+ }
+ treeNodePtr.p->m_resumePtrI = nextLookup.i;
+
+ /**
+ * When we T_EXEC_SEQUENTIAL, TreeNode will iterate its
+ * parent rows in order to create new REQ's as previous
+ * are completed (CONF or REF).
+ * - Prepare RowIterator for parent rows
+ * - Buffer rows to be iterated in the parent node
+ */
+ {
+ jam();
+
+ ndbassert(nextLookup.p->m_parentPtrI != RNIL);
+ Ptr<TreeNode> parentPtr;
+ m_treenode_pool.getPtr(parentPtr, nextLookup.p->m_parentPtrI);
+ parentPtr.p->m_bits |= TreeNode::T_ROW_BUFFER
+ | TreeNode::T_ROW_BUFFER_MAP;
+ requestPtr.p->m_bits |= Request::RT_ROW_BUFFERS;
+
+ DEBUG("ExecPlan: rows from node " << parentPtr.p->m_node_no
+ << " are buffered");
+ }
+ }
+
+ /**
+ * Recursively build exec. plan for any lookup child.
+ */
+ for (int i = lookupChildCnt-1; i >= 0; i--)
+ {
+ jam();
+ Ptr<TreeNode> childPtr;
+ m_treenode_pool.getPtr(childPtr, lookupChildren[i]);
+ ndbassert(childPtr.p->m_info == &g_LookupOpInfo);
+
+ buildExecPlan(requestPtr, childPtr, nextLookup);
+ nextLookup = childPtr;
+ }
+} // Dbspj::buildExecPlan
Uint32
Dbspj::createNode(Build_context& ctx, Ptr<Request> requestPtr,
@@ -1547,26 +1719,18 @@
{
jam();
/**
- * request completed
+ * Entire Request completed
*/
cleanup(requestPtr);
}
- else if ((requestPtr.p->m_bits & Request::RT_MULTI_SCAN) != 0)
- {
- jam();
- /**
- * release unneeded buffers as preparation for later SCAN_NEXTREQ
- */
- releaseScanBuffers(requestPtr);
- }
- else if ((requestPtr.p->m_bits & Request::RT_ROW_BUFFERS) != 0)
- {
- jam();
- /**
- * if not multiple scans in request, simply release all pages allocated
- * for row buffers (all rows will be released anyway)
- */
- releaseRequestBuffers(requestPtr, true);
+ else
+ {
+ jam();
+ /**
+ * Cleanup the TreeNode branches getting another
+ * batch of result rows.
+ */
+ cleanupBatch(requestPtr);
}
}
@@ -1699,6 +1863,26 @@
}
void
+Dbspj::registerActiveCursor(Ptr<Request> requestPtr, Ptr<TreeNode> treeNodePtr)
+{
+ Uint32 bit = treeNodePtr.p->m_node_no;
+ ndbrequire(!requestPtr.p->m_active_nodes.get(bit));
+ requestPtr.p->m_active_nodes.set(bit);
+
+ Local_TreeNodeCursor_list list(m_treenode_pool, requestPtr.p->m_cursor_nodes);
+#ifdef VM_TRACE
+ {
+ Ptr<TreeNode> nodePtr;
+ for (list.first(nodePtr); !nodePtr.isNull(); list.next(nodePtr))
+ {
+ ndbrequire(nodePtr.i != treeNodePtr.i);
+ }
+ }
+#endif
+ list.add(treeNodePtr);
+}
+
+void
Dbspj::sendConf(Signal* signal, Ptr<Request> requestPtr, bool is_complete)
{
if (requestPtr.p->isScan())
@@ -1819,26 +2003,64 @@
return 0;
}
+/**
+ * Cleanup resources in preparation for a SCAN_NEXTREQ
+ * requesting a new batch of rows.
+ */
void
-Dbspj::releaseScanBuffers(Ptr<Request> requestPtr)
+Dbspj::cleanupBatch(Ptr<Request> requestPtr)
{
+ /**
+ * Needs to be atleast 1 active otherwise we should have
+ * taken the Request cleanup "path" in batchComplete
+ */
+ ndbassert(requestPtr.p->m_cnt_active >= 1);
+
+ /**
+ * Release any buffered rows for the TreeNode branches
+ * getting new rows.
+ */
+ if ((requestPtr.p->m_bits & Request::RT_ROW_BUFFERS) != 0)
+ {
+ if ((requestPtr.p->m_bits & Request::RT_MULTI_SCAN) != 0)
+ {
+ jam();
+ /**
+ * A MULTI_SCAN may selectively retrieve rows from only
+ * some of the (scan-) branches in the Request.
+ * Selectively release from only these brances.
+ */
+ releaseScanBuffers(requestPtr);
+ }
+ else
+ {
+ jam();
+ /**
+ * if not multiple scans in request, simply release all pages allocated
+ * for row buffers (all rows will be released anyway)
+ */
+ // Root node should be the one and only being active
+ ndbassert(requestPtr.p->m_cnt_active == 1);
+ ndbassert(requestPtr.p->m_active_nodes.get(0));
+ releaseRequestBuffers(requestPtr);
+ }
+ } //RT_ROW_BUFFERS
+
+
Ptr<TreeNode> treeNodePtr;
Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
for (list.first(treeNodePtr); !treeNodePtr.isNull(); list.next(treeNodePtr))
{
/**
- * Release buffered rows for all treeNodes getting more rows
+ * Re-init row buffer structures for those treeNodes getting more rows
* in the following NEXTREQ, including all its childs.
*/
if (requestPtr.p->m_active_nodes.get(treeNodePtr.p->m_node_no) ||
requestPtr.p->m_active_nodes.overlaps(treeNodePtr.p->m_ancestors))
{
- if (treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER)
- {
- jam();
- releaseNodeRows(requestPtr, treeNodePtr);
- }
+ jam();
+ treeNodePtr.p->m_rows.init();
}
/**
@@ -1848,6 +2070,21 @@
if (requestPtr.p->m_active_nodes.overlaps(treeNodePtr.p->m_ancestors))
{
jam();
+ /**
+ * Common TreeNode cleanup:
+ * Release list of deferred operations which may refer
+ * buffered rows released above.
+ */
+ LocalArenaPoolImpl pool(requestPtr.p->m_arena, m_dependency_map_pool);
+ {
+ Local_correlation_list correlations(pool, treeNodePtr.p->m_deferred.m_correlations);
+ correlations.release();
+ }
+ treeNodePtr.p->m_deferred.init();
+
+ /**
+ * TreeNode-type specific cleanup.
+ */
if (treeNodePtr.p->m_info->m_parent_batch_cleanup != 0)
{
jam();
@@ -1856,31 +2093,30 @@
}
}
}
- /**
- * Needs to be atleast 1 active otherwise we should have
- * taken the cleanup "path" in batchComplete
- */
- ndbrequire(requestPtr.p->m_cnt_active >= 1);
}
void
-Dbspj::registerActiveCursor(Ptr<Request> requestPtr, Ptr<TreeNode> treeNodePtr)
+Dbspj::releaseScanBuffers(Ptr<Request> requestPtr)
{
- Uint32 bit = treeNodePtr.p->m_node_no;
- ndbrequire(!requestPtr.p->m_active_nodes.get(bit));
- requestPtr.p->m_active_nodes.set(bit);
+ Ptr<TreeNode> treeNodePtr;
+ Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
- Local_TreeNodeCursor_list list(m_treenode_pool, requestPtr.p->m_cursor_nodes);
-#ifdef VM_TRACE
+ for (list.first(treeNodePtr); !treeNodePtr.isNull(); list.next(treeNodePtr))
{
- Ptr<TreeNode> nodePtr;
- for (list.first(nodePtr); !nodePtr.isNull(); list.next(nodePtr))
+ /**
+ * Release buffered rows for all treeNodes getting more rows
+ * in the following NEXTREQ, including all its childs.
+ */
+ if (requestPtr.p->m_active_nodes.get(treeNodePtr.p->m_node_no) ||
+ requestPtr.p->m_active_nodes.overlaps(treeNodePtr.p->m_ancestors))
{
- ndbrequire(nodePtr.i != treeNodePtr.i);
+ if (treeNodePtr.p->m_bits & TreeNode::T_ROW_BUFFER)
+ {
+ jam();
+ releaseNodeRows(requestPtr, treeNodePtr);
+ }
}
}
-#endif
- list.add(treeNodePtr);
}
void
@@ -1906,7 +2142,6 @@
releaseRow(treeNodePtr.p->m_rows, pos);
cnt ++;
}
- treeNodePtr.p->m_rows.init();
DEBUG("RowIterator: released " << cnt << " rows!");
if (treeNodePtr.p->m_rows.m_type == RowCollection::COLLECTION_MAP)
@@ -1982,7 +2217,7 @@
}
void
-Dbspj::releaseRequestBuffers(Ptr<Request> requestPtr, bool reset)
+Dbspj::releaseRequestBuffers(Ptr<Request> requestPtr)
{
DEBUG("releaseRequestBuffers"
<< ", request: " << requestPtr.i
@@ -2006,17 +2241,6 @@
}
requestPtr.p->m_rowBuffer.reset();
}
-
- if (reset)
- {
- Ptr<TreeNode> nodePtr;
- Local_TreeNode_list list(m_treenode_pool, requestPtr.p->m_nodes);
- for (list.first(nodePtr); !nodePtr.isNull(); list.next(nodePtr))
- {
- jam();
- nodePtr.p->m_rows.init();
- }
- }
}
void
@@ -2226,7 +2450,7 @@
jam();
m_lookup_request_hash.remove(requestPtr, *requestPtr.p);
}
- releaseRequestBuffers(requestPtr, false);
+ releaseRequestBuffers(requestPtr);
ArenaHead ah = requestPtr.p->m_arena;
m_request_pool.release(requestPtr);
m_arenaAllocator.release(ah);
@@ -2253,6 +2477,11 @@
pattern.release();
}
+ {
+ Local_correlation_list correlations(pool, treeNodePtr.p->m_deferred.m_correlations);
+ correlations.release();
+ }
+
if (treeNodePtr.p->m_send.m_keyInfoPtrI != RNIL)
{
jam();
@@ -3612,6 +3841,7 @@
treeNodePtr.p->m_lookup_data.m_outstanding--;
if (treeNodePtr.p->m_bits & TreeNode::T_REPORT_BATCH_COMPLETE
+ && treeNodePtr.p->m_deferred.isEmpty()
&& treeNodePtr.p->m_lookup_data.m_parent_batch_complete
&& treeNodePtr.p->m_lookup_data.m_outstanding == 0)
{
@@ -3726,7 +3956,21 @@
treeNodePtr.p->m_lookup_data.m_outstanding -= cnt;
+ /**
+ * Another TreeNode awaited for completion of this request
+ * before it could resume its operation.
+ */
+ if (treeNodePtr.p->m_resumeEvents & TreeNode::TN_RESUME_REF)
+ {
+ jam();
+ ndbassert(treeNodePtr.p->m_resumePtrI != RNIL);
+ Ptr<TreeNode> resumeTreeNodePtr;
+ m_treenode_pool.getPtr(resumeTreeNodePtr, treeNodePtr.p->m_resumePtrI);
+ lookup_resume(signal, requestPtr, resumeTreeNodePtr);
+ }
+
if (treeNodePtr.p->m_bits & TreeNode::T_REPORT_BATCH_COMPLETE
+ && treeNodePtr.p->m_deferred.isEmpty()
&& treeNodePtr.p->m_lookup_data.m_parent_batch_complete
&& treeNodePtr.p->m_lookup_data.m_outstanding == 0)
{
@@ -3762,7 +4006,21 @@
treeNodePtr.p->m_lookup_data.m_outstanding--;
+ /**
+ * Another TreeNode awaited for completion of this request
+ * before it could resume its operation.
+ */
+ if (treeNodePtr.p->m_resumeEvents & TreeNode::TN_RESUME_CONF)
+ {
+ jam();
+ ndbassert(treeNodePtr.p->m_resumePtrI != RNIL);
+ Ptr<TreeNode> resumeTreeNodePtr;
+ m_treenode_pool.getPtr(resumeTreeNodePtr, treeNodePtr.p->m_resumePtrI);
+ lookup_resume(signal, requestPtr, resumeTreeNodePtr);
+ }
+
if (treeNodePtr.p->m_bits & TreeNode::T_REPORT_BATCH_COMPLETE
+ && treeNodePtr.p->m_deferred.isEmpty()
&& treeNodePtr.p->m_lookup_data.m_parent_batch_complete
&& treeNodePtr.p->m_lookup_data.m_outstanding == 0)
{
@@ -3786,6 +4044,99 @@
{
jam();
+ DEBUG("::lookup_parent_row"
+ << ", node: " << treeNodePtr.p->m_node_no);
+
+ if (treeNodePtr.p->m_bits & TreeNode::T_EXEC_SEQUENTIAL)
+ {
+ jam();
+ DEBUG("T_EXEC_SEQUENTIAL --> exec deferred");
+
+ /**
+ * Append correlation values of deferred parent row operations
+ * to a list / fifo. Upon resume, we will then be able to
+ * relocate all parent rows for which to resume operations.
+ */
+ LocalArenaPoolImpl pool(requestPtr.p->m_arena, m_dependency_map_pool);
+ Local_pattern_store correlations(pool, treeNodePtr.p->m_deferred.m_correlations);
+ if (!correlations.append(&rowRef.m_src_correlation, 1))
+ {
+ jam();
+ abort(signal, requestPtr, DbspjErr::OutOfQueryMemory);
+ return;
+ }
+ return;
+ }
+
+ lookup_row(signal, requestPtr, treeNodePtr, rowRef);
+} // Dbspj::lookup_parent_row()
+
+/**
+ * lookup_resume() is a delayed lookup_parent_row.
+ * It will locate the next parent row now allowed to execute,
+ * and create a child lookup request for that row.
+ */
+void
+Dbspj::lookup_resume(Signal* signal,
+ Ptr<Request> requestPtr,
+ Ptr<TreeNode> treeNodePtr)
+{
+ DEBUG("::lookup_resume"
+ << ", node: " << treeNodePtr.p->m_node_no
+ );
+
+ ndbassert(treeNodePtr.p->m_bits & TreeNode::T_EXEC_SEQUENTIAL);
+ ndbassert(treeNodePtr.p->m_parentPtrI != RNIL);
+ ndbassert(!treeNodePtr.p->m_deferred.isEmpty());
+
+ if (unlikely(requestPtr.p->m_state & Request::RS_ABORTING))
+ {
+ jam();
+ return;
+ }
+
+ Uint32 corrVal;
+ {
+ LocalArenaPoolImpl pool(requestPtr.p->m_arena, m_dependency_map_pool);
+ Local_pattern_store correlations(pool, treeNodePtr.p->m_deferred.m_correlations);
+
+ Local_pattern_store::DataBufferIterator it;
+ const bool valid = correlations.position(it, (Uint32)(treeNodePtr.p->m_deferred.m_pos++));
+ (void)valid; ndbassert(valid);
+ corrVal = *it.data;
+ }
+
+ Ptr<TreeNode> parentPtr;
+ m_treenode_pool.getPtr(parentPtr, treeNodePtr.p->m_parentPtrI);
+
+ // Set up RowPtr & RowRef for this parent row
+ RowPtr row;
+ row.m_src_node_ptrI = parentPtr.i;
+ row.m_src_correlation = corrVal;
+
+ ndbassert(parentPtr.p->m_rows.m_type == RowCollection::COLLECTION_MAP);
+ RowRef ref;
+ parentPtr.p->m_rows.m_map.copyto(ref);
+ const Uint32* const mapptr = get_row_ptr(ref);
+
+ // Relocate parent row from correlation value.
+ const Uint32 rowId = (corrVal & 0xFFFF);
+ parentPtr.p->m_rows.m_map.load(mapptr, rowId, ref);
+
+ const Uint32* const rowptr = get_row_ptr(ref);
+ setupRowPtr(parentPtr.p->m_rows, row, ref, rowptr);
+
+ lookup_row(signal, requestPtr, treeNodePtr, row);
+} // Dbspj::lookup_resume()
+
+void
+Dbspj::lookup_row(Signal* signal,
+ Ptr<Request> requestPtr,
+ Ptr<TreeNode> treeNodePtr,
+ const RowPtr & rowRef)
+{
+ jam();
+
/**
* Here we need to...
* 1) construct a key
@@ -3796,7 +4147,7 @@
const Uint32 tableId = treeNodePtr.p->m_tableOrIndexId;
const Uint32 corrVal = rowRef.m_src_correlation;
- DEBUG("::lookup_parent_row"
+ DEBUG("::lookup_row"
<< ", node: " << treeNodePtr.p->m_node_no);
do
@@ -3853,10 +4204,11 @@
* When the key contains NULL values, an EQ-match is impossible!
* Entire lookup request can therefore be eliminate as it is known
* to be REFused with errorCode = 626 (Row not found).
- * Different handling is required depening of request being a
- * scan or lookup:
+ * Scan request can elliminate these child LQHKEYREQs if REFs
+ * are not needed in order to handle TN_RESUME_REF.
*/
- if (requestPtr.p->isScan())
+ if (requestPtr.p->isScan() &&
+ (treeNodePtr.p->m_resumeEvents & TreeNode::TN_RESUME_REF) == 0)
{
/**
* Scan request: We can simply ignore lookup operation:
@@ -3868,7 +4220,7 @@
releaseSection(ptrI);
return; // Bailout, KEYREQ would have returned KEYREF(626) anyway
}
- else // isLookup()
+ else // isLookup() or 'need TN_RESUME_REF'
{
/**
* Ignored lookup request need a faked KEYREF for the lookup operation.
@@ -4053,7 +4405,9 @@
ndbassert(!treeNodePtr.p->m_lookup_data.m_parent_batch_complete);
treeNodePtr.p->m_lookup_data.m_parent_batch_complete = true;
+
if (treeNodePtr.p->m_bits & TreeNode::T_REPORT_BATCH_COMPLETE
+ && treeNodePtr.p->m_deferred.isEmpty()
&& treeNodePtr.p->m_lookup_data.m_outstanding == 0)
{
jam();
@@ -4679,6 +5033,7 @@
}
}
}
+ ndbassert(treeNodePtr.p->m_resumePtrI == RNIL);
if (treeNodePtr.p->m_scanfrag_data.m_rows_received ==
treeNodePtr.p->m_scanfrag_data.m_rows_expecting)
@@ -6312,6 +6667,7 @@
ScanIndexData& data = treeNodePtr.p->m_scanindex_data;
data.m_rows_received++;
+ ndbassert(treeNodePtr.p->m_resumePtrI == RNIL);
if (data.m_frags_outstanding == 0 &&
data.m_rows_received == data.m_rows_expecting)
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-5.5-cluster-7.2 branch (ole.john.aske:4087 to 4088)Bug#14709490 | Ole John Aske | 14 Nov |