1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fix LP BUG#682683

Analysis:
The fix for LP BUG#680846 avoids evaluation of constant expressions
with subqueries in the GROUP/ORDER clauses in the procedure
remove_const(). The purpose of remove_const is to remove constant
expressions in the GROUP/ORDER clauses.
  
In order delay until execution the evaluation of such subqueries,
they were not removed in the GROUP/ORDER clause. As a result temp
table creation during execution attempted to create a column in the
temp table for each constant GROUP/ORDER expression. However, the
logic in create_tmp_table is to not create temp table columns for
constant items. The crash was due to a group Item without a
corresponding column in the temp table for GROUP BY.
  
Solution:
The patch adds back removal of constant expressions with subqueries.
In order for such expressions to be evaluated, so that the server can
ensure that such subquries return 1 row, the evaluation of these
expressions is delayed until execution.
This commit is contained in:
unknown
2010-12-02 21:54:40 +02:00
parent 1b3336dc30
commit 620aea4fde
4 changed files with 111 additions and 7 deletions

View File

@ -1402,6 +1402,7 @@ setup_subq_exit:
/**
Create and initialize objects neeed for the execution of a query plan.
Evaluate constant expressions not evaluated during optimization.
*/
int JOIN::init_execution()
@ -1409,6 +1410,7 @@ int JOIN::init_execution()
DBUG_ENTER("JOIN::init_execution");
DBUG_ASSERT(optimized);
DBUG_ASSERT(!(select_options & SELECT_DESCRIBE));
initialized= true;
/* Create a tmp table if distinct or if the sort is too complicated */
@ -1839,6 +1841,27 @@ JOIN::exec()
DBUG_VOID_RETURN;
}
/*
Evaluate all constant expressions with subqueries in the ORDER/GROUP clauses
to make sure that all subqueries return a single row. The evaluation itself
will trigger an error if that is not the case.
*/
if (exec_const_order_group_cond.elements &&
!(select_options & SELECT_DESCRIBE))
{
List_iterator_fast<Item> const_item_it(exec_const_order_group_cond);
Item *cur_const_item;
while ((cur_const_item= const_item_it++))
{
cur_const_item->val_str(&cur_const_item->str_value);
if (thd->is_error())
{
error= thd->is_error();
DBUG_VOID_RETURN;
}
}
}
if ((this->select_lex->options & OPTION_SCHEMA_TABLE) &&
get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
DBUG_VOID_RETURN;
@ -8279,13 +8302,16 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
(join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
join->outer_join))
*simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables) &&
!order->item[0]->with_subselect)
else if (!(order_tables & not_const_tables))
{
/*
Skip constant expressions in the ORDER/GROUP clause, except when there
is a subquery in the expression.
*/
if (order->item[0]->with_subselect)
{
/*
Delay the evaluation of constant ORDER and/or GROUP expressions that
contain subqueries until the execution phase.
*/
join->exec_const_order_group_cond.push_back(order->item[0]);
}
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue;
}