summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@magare.gmz>2007-08-28 18:51:03 +0300
committerunknown <gkodinov/kgeorge@magare.gmz>2007-08-28 18:51:03 +0300
commit310afbd4a96baeedc7202a3b2cac7860c76d83e2 (patch)
treea6f10748580275e7b10aa99d7f88d2a5e1f10d02 /sql
parent42aa480b4345aa920e0ff60001b09eb52c9c04c5 (diff)
downloadmariadb-git-310afbd4a96baeedc7202a3b2cac7860c76d83e2.tar.gz
Bug #30377: EXPLAIN loses last_query_cost when used with UNION
Currently the Last_query_cost session status variable shows only the cost of a single flat subselect. For complex queries (with subselects or unions etc) Last_query_cost is not valid as it was showing the cost for the last optimized subselect. Fixed by reseting to zero Last_query_cost when the complete cost of the query cannot be determined. Last_query_cost will be non-zero only for single flat queries. mysql-test/r/status.result: Bug #30377: test case mysql-test/t/status.test: Bug #30377: test case sql/sql_lex.h: Bug #30377: helper function sql/sql_select.cc: Bug #30377: don't assign cost if not on single level statement
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_lex.h22
-rw-r--r--sql/sql_select.cc8
2 files changed, 28 insertions, 2 deletions
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 94015a9fe07..ce56be79744 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1257,6 +1257,28 @@ typedef struct st_lex : public Query_tables_list
void reset_n_backup_query_tables_list(Query_tables_list *backup);
void restore_backup_query_tables_list(Query_tables_list *backup);
+
+ /**
+ @brief check if the statement is a single-level join
+ @return result of the check
+ @retval TRUE The statement doesn't contain subqueries, unions and
+ stored procedure calls.
+ @retval FALSE There are subqueries, UNIONs or stored procedure calls.
+ */
+ bool is_single_level_stmt()
+ {
+ /*
+ This check exploits the fact that the last added to all_select_list is
+ on its top. So select_lex (as the first added) will be at the tail
+ of the list.
+ */
+ if (&select_lex == all_selects_list && !sroutines.records)
+ {
+ DBUG_ASSERT(!all_selects_list->next_select_in_list());
+ return TRUE;
+ }
+ return FALSE;
+ }
} LEX;
struct st_lex_local: public st_lex
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index b7846a7433d..7e9cb4cfbec 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -4369,9 +4369,13 @@ choose_plan(JOIN *join, table_map join_tables)
/*
Store the cost of this query into a user variable
- Don't update last_query_cost for 'show status' command
+ Don't update last_query_cost for 'show status' command.
+ Don't update last_query_cost for statements that are not "flat joins" :
+ i.e. they have subqueries, unions or call stored procedures.
+ TODO: calculate a correct cost for a query with subqueries and UNIONs.
*/
- if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
+ if (join->thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS &&
+ join->thd->lex->is_single_level_stmt())
join->thd->status_var.last_query_cost= join->best_read;
DBUG_RETURN(FALSE);
}