diff options
-rw-r--r-- | mysql-test/r/subselect3.result | 2 | ||||
-rw-r--r-- | mysql-test/r/subselect3_jcl6.result | 2 | ||||
-rw-r--r-- | mysql-test/r/view.result | 2 | ||||
-rw-r--r-- | sql/log_event.cc | 1 | ||||
-rw-r--r-- | sql/opt_qpf.cc | 16 | ||||
-rw-r--r-- | sql/opt_qpf.h | 2 | ||||
-rw-r--r-- | sql/sql_lex.cc | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 8 | ||||
-rw-r--r-- | sql/sql_select.cc | 38 | ||||
-rw-r--r-- | sql/sql_select.h | 3 | ||||
-rw-r--r-- | sql/sql_union.cc | 9 |
11 files changed, 68 insertions, 18 deletions
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result index 1a33fb0c6a3..24d9f0de35a 100644 --- a/mysql-test/r/subselect3.result +++ b/mysql-test/r/subselect3.result @@ -1031,7 +1031,7 @@ update t22 set c = '2005-12-08 15:58:27' where a = 255; explain select t21.* from t21,t22 where t21.a = t22.a and t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort; Start temporary +1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Start temporary; Using temporary; Using filesort 1 PRIMARY t12 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t22 ALL NULL NULL NULL NULL 26 Using where; End temporary; Using join buffer (flat, BNL join) 1 PRIMARY t21 ALL NULL NULL NULL NULL 26 Using where; Using join buffer (flat, BNL join) diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result index 5bae1453a5e..19d3d25148f 100644 --- a/mysql-test/r/subselect3_jcl6.result +++ b/mysql-test/r/subselect3_jcl6.result @@ -1041,7 +1041,7 @@ update t22 set c = '2005-12-08 15:58:27' where a = 255; explain select t21.* from t21,t22 where t21.a = t22.a and t22.a in (select t12.a from t11, t12 where t11.a in(255,256) and t11.a = t12.a and t11.c is null) and t22.c is null order by t21.a; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Using temporary; Using filesort; Start temporary +1 PRIMARY t11 ALL NULL NULL NULL NULL 8 Using where; Start temporary; Using temporary; Using filesort 1 PRIMARY t12 hash_ALL NULL #hash#$hj 4 test.t11.a 8 Using where; Using join buffer (flat, BNLH join) 1 PRIMARY t22 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; End temporary; Using join buffer (incremental, BNLH join) 1 PRIMARY t21 hash_ALL NULL #hash#$hj 4 test.t11.a 26 Using where; Using join buffer (incremental, BNLH join) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index bc286c36655..7fc2fa72805 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3584,7 +3584,7 @@ View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` FORCE INDEX (PRIMARY) FORCE INDEX (`b`) order by `t1`.`a` latin1 latin1_swedish_ci EXPLAIN SELECT * FROM v1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 15 +1 SIMPLE t1 index NULL PRIMARY 4 NULL 15 CREATE VIEW v2 AS SELECT * FROM t1 USE KEY () ORDER BY a; SHOW CREATE VIEW v2; View Create View character_set_client collation_connection diff --git a/sql/log_event.cc b/sql/log_event.cc index f4e34dd9224..a89806fa708 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -9041,6 +9041,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) call might reset the value of current_stmt_binlog_format, so we need to do any changes to that value after this function. */ + delete_qpf_query(thd->lex); lex_start(thd); mysql_reset_thd_for_next_command(thd, 0); /* diff --git a/sql/opt_qpf.cc b/sql/opt_qpf.cc index 309e24471eb..37a01a4f832 100644 --- a/sql/opt_qpf.cc +++ b/sql/opt_qpf.cc @@ -13,6 +13,7 @@ QPF_query::QPF_query() { upd_del_plan= NULL; + operations= 0; //memset(&unions, 0, sizeof(unions)); //memset(&selects, 0, sizeof(selects)); } @@ -51,15 +52,18 @@ QPF_select *QPF_query::get_select(uint select_id) void QPF_query::add_node(QPF_node *node) { + operations++; if (node->get_type() == QPF_node::QPF_UNION) { QPF_union *u= (QPF_union*)node; uint select_id= u->get_select_id(); - DBUG_ASSERT(!get_union(select_id)); - if (unions.elements() <= select_id) unions.resize(max(select_id+1, unions.elements()*2), NULL); + QPF_union *old_node; + if ((old_node= get_union(select_id))) + delete old_node; + unions.at(select_id)= u; } else @@ -73,10 +77,14 @@ void QPF_query::add_node(QPF_node *node) else { uint select_id= sel->select_id; - DBUG_ASSERT(!get_select(select_id)); - + QPF_select *old_node; + //DBUG_ASSERT(!get_select(select_id)); if (selects.elements() <= select_id) selects.resize(max(select_id+1, selects.elements()*2), NULL); + + if ((old_node= get_select(select_id))) + delete old_node; + selects.at(select_id)= sel; } } diff --git a/sql/opt_qpf.h b/sql/opt_qpf.h index 1944f79254d..35afcde10df 100644 --- a/sql/opt_qpf.h +++ b/sql/opt_qpf.h @@ -223,6 +223,8 @@ private: Dynamic_array<QPF_select*> selects; //QPF_union *unions[MAX_TABLES]; //QPF_select *selects[MAX_TABLES]; + + longlong operations; }; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c453a599dce..2e4eaf5b721 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2552,7 +2552,8 @@ void Query_tables_list::destroy_query_tables_list() */ LEX::LEX() - :result(0), option_type(OPT_DEFAULT), is_lex_started(0), + : query_plan_footprint(NULL), + result(0), option_type(OPT_DEFAULT), is_lex_started(0), limit_rows_examined_cnt(ULONGLONG_MAX) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 6f2f7eaca20..9e477e62e19 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4750,8 +4750,14 @@ finish: ha_maria::implicit_commit(thd, FALSE); #endif } - lex->unit.cleanup(); + //psergey-todo: print EXPLAIN here? After the above JOIN::cleanup calls? + // how do we print EXPLAIN extended, then? + if (lex->describe) + { + DBUG_ASSERT(lex->query_plan_footprint); + ///.. + } /* Free tables */ thd_proc_info(thd, "closing tables"); close_thread_tables(thd); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5e20d2faf24..5a5928f9b73 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2347,6 +2347,36 @@ void JOIN::exec() exec_inner(); + if (!exec_qpf_saved) + { + if (select_lex->select_number != UINT_MAX && + select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ && + have_query_plan != QEP_NOT_PRESENT_YET && + have_query_plan != QEP_DELETED && // this happens when there was no QEP ever, but then + //cleanup() is called multiple times + + thd->lex->query_plan_footprint //&& // for "SET" command in SPs. + /*!thd->lex->query_plan_footprint->get_select(select_lex->select_number)*/) + { + const char *message= NULL; + + if (!table_count || !tables_list || zero_result_cause) + { + /* It's a degenerate join */ + message= zero_result_cause ? zero_result_cause : "No tables used"; + } + + save_qpf(thd->lex->query_plan_footprint, + need_tmp, // need_tmp_table + // !skip_sort_order && !no_order && + // (order || group_list), // bool need_order + order != 0 && !skip_sort_order, + select_distinct, // bool distinct + message); // message + } + exec_qpf_saved= true; + } + DBUG_EXECUTE_IF("show_explain_probe_join_exec_end", if (dbug_user_var_equals_int(thd, "show_explain_probe_select_id", @@ -11151,7 +11181,7 @@ void JOIN::cleanup(bool full) if (full) { - // + /* Save it again */ #if 0 if (select_lex->select_number != UINT_MAX && select_lex->select_number != INT_MAX /* this is not a UNION's "fake select */ && @@ -11159,8 +11189,8 @@ void JOIN::cleanup(bool full) have_query_plan != QEP_DELETED && // this happens when there was no QEP ever, but then //cleanup() is called multiple times - thd->lex->query_plan_footprint && // for "SET" command in SPs. - !thd->lex->query_plan_footprint->get_select(select_lex->select_number)) + thd->lex->query_plan_footprint //&& // for "SET" command in SPs. + /*!thd->lex->query_plan_footprint->get_select(select_lex->select_number)*/) { const char *message= NULL; @@ -11178,8 +11208,6 @@ void JOIN::cleanup(bool full) message); // message } #endif - // - have_query_plan= QEP_DELETED; //psergey: this is a problem! } diff --git a/sql/sql_select.h b/sql/sql_select.h index 6d4dfed479e..b394ee40276 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1336,7 +1336,10 @@ public: pre_sort_join_tab= NULL; emb_sjm_nest= NULL; sjm_lookup_tables= 0; + + exec_qpf_saved= false; } + bool exec_qpf_saved; int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, COND *conds, uint og_num, ORDER *order, ORDER *group, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index b77b0669b50..e4a9c7630e6 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -617,6 +617,7 @@ bool st_select_lex_unit::exec() ulonglong add_rows=0; ha_rows examined_rows= 0; DBUG_ENTER("st_select_lex_unit::exec"); + bool was_executed= executed; if (executed && !uncacheable && !describe) DBUG_RETURN(FALSE); @@ -626,8 +627,8 @@ bool st_select_lex_unit::exec() saved_error= optimize(); - - save_union_qpf(thd->lex->query_plan_footprint); + if (!was_executed && thd->lex->query_plan_footprint) + save_union_qpf(thd->lex->query_plan_footprint); if (uncacheable || !item || !item->assigned() || describe) { @@ -776,8 +777,8 @@ bool st_select_lex_unit::exec() if (!fake_select_lex->ref_pointer_array) fake_select_lex->n_child_sum_items+= global_parameters->n_sum_items; - - save_union_qpf_part2(thd->lex->query_plan_footprint); + if (!was_executed && thd->lex->query_plan_footprint) + save_union_qpf_part2(thd->lex->query_plan_footprint); saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array, &result_table_list, |