summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/subselect3.result2
-rw-r--r--mysql-test/r/subselect3_jcl6.result2
-rw-r--r--mysql-test/r/view.result2
-rw-r--r--sql/log_event.cc1
-rw-r--r--sql/opt_qpf.cc16
-rw-r--r--sql/opt_qpf.h2
-rw-r--r--sql/sql_lex.cc3
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_select.cc38
-rw-r--r--sql/sql_select.h3
-rw-r--r--sql/sql_union.cc9
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,