mirror of
https://github.com/MariaDB/server.git
synced 2026-04-30 04:05:32 +02:00
Fix LP bug lp:802979
Analysis: This bug consists of two related problems that are result of too early evaluation of single-row subqueries during the optimization phase of the outer query. Several optimizer code paths try to evaluate single-row subqueries in order to produce a constant and use that constant for further optimzation. When the execution of the subquery peforms destructive changes to the representation of the subquery, and these changes are not anticipated by the subsequent optimization phases of the outer query, we tipically get a crash or failed assert. Specifically, in this bug the inner-most suqbuery with DISTINCT triggers a substitution of the original JOIN object by a single-table JOIN object with a temp table needed to perform the DISTINCT operation (created by JOIN::make_simple_join). This substitution breaks EXPLAIN because: a) in the first example JOIN::cleanup no longer can reach the original table of the innermost subquery, and close all indexes, and b) in this second test query, EXPLAIN attempts to print the name of the internal temp table, and crashes because the temp table has no name (NULL pointer instead). Solution: a) fully disable subquery evaluation during optimization in all cases - both for constant propagation and range optimization, and b) change JOIN::join_free() to perform cleanup irrespective of EXPLAIN or not.
This commit is contained in:
parent
55165f5174
commit
59784abead
10 changed files with 115 additions and 25 deletions
|
|
@ -9620,8 +9620,7 @@ void JOIN::join_free()
|
|||
Optimization: if not EXPLAIN and we are done with the JOIN,
|
||||
free all tables.
|
||||
*/
|
||||
bool full= (!(select_lex->uncacheable) &&
|
||||
!thd->lex->describe);
|
||||
bool full= !(select_lex->uncacheable);
|
||||
bool can_unlock= full;
|
||||
DBUG_ENTER("JOIN::join_free");
|
||||
|
||||
|
|
@ -11472,8 +11471,8 @@ propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
|
|||
{
|
||||
Item_func_eq *func=(Item_func_eq*) cond;
|
||||
Item **args= func->arguments();
|
||||
bool left_const= args[0]->const_item();
|
||||
bool right_const= args[1]->const_item();
|
||||
bool left_const= args[0]->const_item() && !args[0]->is_expensive();
|
||||
bool right_const= args[1]->const_item() && !args[1]->is_expensive();
|
||||
if (!(left_const && right_const) &&
|
||||
args[0]->result_type() == args[1]->result_type())
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue