From: Ole John Aske Date: May 2 2011 1:44pm Subject: bzr commit into mysql-5.1-telco-7.0-spj-scan-vs-scan branch (ole.john.aske:3487) List-Archive: http://lists.mysql.com/commits/136527 Message-Id: <20110502134443.96D84222@fimafeng09.norway.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============1629841108570938634==" --===============1629841108570938634== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///net/fimafeng09/export/home/tmp/oleja/mysql/mysql-5.1-telco-7.0-spj-scan-scan/ based on revid:jonas@stripped 3487 Ole John Aske 2011-05-02 SPJ: Fixed a regression introduced with recent refactoring of ha_ndbcluster_push.cc: As we now allow dependencies between (grand-)parents to be added such that all the dependent parents become (artificial) dependent on each other, we may also implicit introduce dependencies on outer joined tables. This is incorrect as it is only inner joined tables which can sequentially linked wo/ changing the sematics in the SQL statement. @ sql/abstract_query_plan.cc Removed a double ';;' terminating a line. modified: mysql-test/suite/ndb/r/ndb_join_pushdown.result mysql-test/suite/ndb/t/ndb_join_pushdown.test sql/abstract_query_plan.cc sql/ha_ndbcluster_push.cc === modified file 'mysql-test/suite/ndb/r/ndb_join_pushdown.result' --- a/mysql-test/suite/ndb/r/ndb_join_pushdown.result 2011-04-27 07:42:18 +0000 +++ b/mysql-test/suite/ndb/r/ndb_join_pushdown.result 2011-05-02 13:44:39 +0000 @@ -1434,6 +1434,92 @@ id select_type table type possible_keys 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`)) +explain extended +select straight_join * +from t1 +left join t1 as t2 on t2.a = t1.a and t2.b = t1.b +join t1 as t3 on t3.a = t1.c and t3.b = t1.d +left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; +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.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.c,test.t2.c 1 100.00 +Warnings: +Note 1644 Can't push table 't4' as child of 't1', dependencies on outer joined grandparents not implemented +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` left join `test`.`t1` `t2` on(((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`))) join `test`.`t1` `t3` left join `test`.`t1` `t4` on(((`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t4`.`a` = `test`.`t3`.`c`))) where ((`test`.`t3`.`b` = `test`.`t1`.`d`) and (`test`.`t3`.`a` = `test`.`t1`.`c`)) +explain extended +select straight_join * +from t1 +join t1 as t2 on t2.a = t1.a and t2.b = t1.b +left join t1 as t3 on t3.a = t1.c and t3.b = t1.d +left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; +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 't2' in pushed join@1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3.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` left join `test`.`t1` `t3` on(((`test`.`t3`.`b` = `test`.`t1`.`d`) and (`test`.`t3`.`a` = `test`.`t1`.`c`))) left join `test`.`t1` `t4` on(((`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t4`.`a` = `test`.`t3`.`c`))) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`)) +explain extended +select straight_join * +from t1 +left join t1 as t2 on t2.a = t1.a and t2.b = t1.b +join t1 as t3 on t3.a = t1.a +left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; +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 3 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 ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Child of 't1' in pushed join@1 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3.c,test.t2.c 1 100.00 +Warnings: +Note 1644 Can't push table 't4' as child of 't1', dependencies on outer joined grandparents not implemented +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` left join `test`.`t1` `t2` on(((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`))) join `test`.`t1` `t3` left join `test`.`t1` `t4` on(((`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t4`.`a` = `test`.`t3`.`c`))) where (`test`.`t3`.`a` = `test`.`t1`.`a`) +explain extended +select straight_join * +from t1 +join t1 as t2 on t2.a = t1.a and t2.b = t1.b +left join t1 as t3 on t3.a = t1.a +left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; +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 2 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 ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 Parent of 2 pushed join@2 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 8 test.t3.c,test.t2.c 1 100.00 Child of 't3' in pushed join@2 +Warnings: +Note 1644 Can't push table 't3' as child of 't1', outer join with scan-ancestor 't1' not implemented +Note 1644 Can't push table 't4' as child of 't1', column 't3.c' is outside scope of pushable join +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` left join `test`.`t1` `t3` on(((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`))) left join `test`.`t1` `t4` on(((`test`.`t4`.`b` = `test`.`t2`.`c`) and (`test`.`t4`.`a` = `test`.`t3`.`c`))) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`)) +explain extended +select straight_join * +from t1 +left join t1 as t2 on t2.a = t1.a and t2.b = t1.b +join t1 as t3 on t3.a = t1.a +left join t1 as t4 on t4.a = t3.c; +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 3 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 ref PRIMARY PRIMARY 4 test.t1.a 1 100.00 Child of 't1' in pushed join@1 +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.c 1 100.00 +Warnings: +Note 1644 Can't push table 't4' as child of 't1', outer join with scan-ancestor 't3' not implemented +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` left join `test`.`t1` `t2` on(((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`))) join `test`.`t1` `t3` left join `test`.`t1` `t4` on((`test`.`t4`.`a` = `test`.`t3`.`c`)) where (`test`.`t3`.`a` = `test`.`t1`.`a`) +explain extended +select straight_join * +from t1 +join t1 as t2 on t2.a = t1.a and t2.b = t1.b +left join t1 as t3 on t3.a = t1.a +left join t1 as t4 on t4.a = t3.c; +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 2 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 ref PRIMARY PRIMARY 4 test.t2.a 1 100.00 +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.c 1 100.00 +Warnings: +Note 1644 Can't push table 't3' as child of 't1', outer join with scan-ancestor 't1' not implemented +Note 1644 Can't push table 't4' as child of 't1', column 't3.c' is outside scope of pushable join +Note 1644 Can't push table 't4' as child of 't3', outer join with scan-ancestor 't3' not implemented +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` left join `test`.`t1` `t3` on(((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`a` = `test`.`t1`.`a`))) left join `test`.`t1` `t4` on((`test`.`t4`.`a` = `test`.`t3`.`c`)) where ((`test`.`t2`.`b` = `test`.`t1`.`b`) and (`test`.`t2`.`a` = `test`.`t1`.`a`)) set ndb_join_pushdown=true; explain extended select * from t1 x, t1 y, t1 z, t1 where @@ -4998,13 +5084,13 @@ LOCAL+REMOTE READS_SENT drop table spj_counts_at_startup; drop table spj_counts_at_end; scan_count -2530 +2536 pruned_scan_count 8 sorted_scan_count 9 pushed_queries_defined -366 +373 pushed_queries_dropped 11 pushed_queries_executed === modified file 'mysql-test/suite/ndb/t/ndb_join_pushdown.test' --- a/mysql-test/suite/ndb/t/ndb_join_pushdown.test 2011-04-27 07:42:18 +0000 +++ b/mysql-test/suite/ndb/t/ndb_join_pushdown.test 2011-05-02 13:44:39 +0000 @@ -659,6 +659,50 @@ from t1 join t1 as t3x on t3x.a = t1.c and t3x.b = t1.d join t1 as t4 on t4.a = t3x.c and t4.b = t2x.c; +## It should not be possible to force grandparent dependencies +## via a previously outer joined table: +explain extended +select straight_join * +from t1 + left join t1 as t2 on t2.a = t1.a and t2.b = t1.b + join t1 as t3 on t3.a = t1.c and t3.b = t1.d + left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; + +explain extended +select straight_join * +from t1 + join t1 as t2 on t2.a = t1.a and t2.b = t1.b + left join t1 as t3 on t3.a = t1.c and t3.b = t1.d + left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; + +explain extended +select straight_join * +from t1 + left join t1 as t2 on t2.a = t1.a and t2.b = t1.b + join t1 as t3 on t3.a = t1.a + left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; + +explain extended +select straight_join * +from t1 + join t1 as t2 on t2.a = t1.a and t2.b = t1.b + left join t1 as t3 on t3.a = t1.a + left join t1 as t4 on t4.a = t3.c and t4.b = t2.c; + +explain extended +select straight_join * +from t1 + left join t1 as t2 on t2.a = t1.a and t2.b = t1.b + join t1 as t3 on t3.a = t1.a + left join t1 as t4 on t4.a = t3.c; + +explain extended +select straight_join * +from t1 + join t1 as t2 on t2.a = t1.a and t2.b = t1.b + left join t1 as t3 on t3.a = t1.a + left join t1 as t4 on t4.a = t3.c; + # Test a combination of pushed table scan (x, y) # & pushed EQ-bound (indexScan) (z, t1) === modified file 'sql/abstract_query_plan.cc' --- a/sql/abstract_query_plan.cc 2011-01-04 14:50:54 +0000 +++ b/sql/abstract_query_plan.cc 2011-05-02 13:44:39 +0000 @@ -167,7 +167,7 @@ namespace AQP } const TABLE_LIST* const child_embedding= - get_join_tab()->table->pos_in_table_list->embedding;; + get_join_tab()->table->pos_in_table_list->embedding; if (child_embedding == NULL) { === modified file 'sql/ha_ndbcluster_push.cc' --- a/sql/ha_ndbcluster_push.cc 2011-04-27 09:06:08 +0000 +++ b/sql/ha_ndbcluster_push.cc 2011-05-02 13:44:39 +0000 @@ -644,6 +644,36 @@ ndb_pushed_builder_ctx::is_pushable_as_c } } // scan operation + /** + * In order to allow multiple parents refs to be made grandparent referrences, + * none of the grandparents should be outer joins. + */ + ndb_table_access_map grandparents(depend_parents); + grandparents.clear_bit(root_no); + uint ancestor_no= root_no+1; + while (!grandparents.is_clear_all()) + { + if (grandparents.contain(ancestor_no)) + { + grandparents.clear_bit(ancestor_no); + if (grandparents.is_clear_all()) + break; // done + + const AQP::Table_access* const ancestor= + m_plan.get_table_access(ancestor_no); + + if (ancestor->get_join_type(m_join_root) == AQP::JT_OUTER_JOIN) + { + EXPLAIN_NO_PUSH("Can't push table '%s' as child of '%s', " + "dependencies on outer joined grandparents not implemented", + table->get_table()->alias, + m_join_root->get_table()->alias); + DBUG_RETURN(false); + } + } + ancestor_no++; + } + DBUG_ASSERT(m_join_scope.contain(common_parents)); DBUG_ASSERT(m_join_scope.contain(extend_parents)); DBUG_ASSERT(extend_parents.is_clear_all() || @@ -865,8 +895,7 @@ ndb_pushed_builder_ctx::optimize_query_p */ if (!table.m_depend_parents.is_clear_all()) { - ndb_table_access_map const &dependency - = table.m_depend_parents; + ndb_table_access_map const &dependency= table.m_depend_parents; DBUG_ASSERT(!dependency.contain(tab_no)); // Circular dependency! uint depends_on_parent= dependency.last_table(tab_no-1); @@ -876,6 +905,8 @@ ndb_pushed_builder_ctx::optimize_query_p if (table.m_extend_parents.is_overlapping(dependency_mask)) { table.m_extend_parents.subtract(dependency_mask); + DBUG_ASSERT(table.m_extend_parents.contain(depends_on_parent) || + m_plan.get_table_access(depends_on_parent)->get_join_type(m_join_root) == AQP::JT_INNER_JOIN); table.m_extend_parents.add(depends_on_parent); } if (table.m_common_parents.is_overlapping(dependency_mask)) @@ -886,7 +917,7 @@ ndb_pushed_builder_ctx::optimize_query_p /** * Select set to choose parent from, prefer a 'common' - * parent of available. + * parent if available. */ uint parent_no; ndb_table_access_map const &parents= @@ -1204,7 +1235,7 @@ ndb_pushed_builder_ctx::build_query() if (table->get_join_type(parent) == AQP::JT_INNER_JOIN) { options.setMatchType(NdbQueryOptions::MatchNonNull); - } + } } const NdbQueryOperationDef* query_op= NULL; --===============1629841108570938634== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/ole.john.aske@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: ole.john.aske@stripped\ # 7u9xtk23w6i5flfa # target_branch: file:///net/fimafeng09/export/home/tmp/oleja/mysql\ # /mysql-5.1-telco-7.0-spj-scan-scan/ # testament_sha1: 691c58036abdea255ee196ea7ff01a3ceb4283b1 # timestamp: 2011-05-02 15:44:43 +0200 # source_branch: bzr+ssh://oaske@stripped/bzrroot/server\ # /mysql-5.1-telco-7.0/ # base_revision_id: jonas@stripped # # Begin bundle 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 --===============1629841108570938634==--