summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <timour@askmonty.org>2010-12-10 13:10:11 +0200
committerunknown <timour@askmonty.org>2010-12-10 13:10:11 +0200
commitfd24b33b578eecb1046414cb4406f6986c95611e (patch)
treed90a72ede847b061e322da0f21ff1cbae5ac8dfb /sql
parentbe95cde85991f4d4149d6532801720e583257642 (diff)
parent620aea4fde7d40f3870bebdcfd66d2b0b556db2f (diff)
downloadmariadb-git-fd24b33b578eecb1046414cb4406f6986c95611e.tar.gz
Merge the fix for LP BUG#682683.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_select.cc38
-rw-r--r--sql/sql_select.h10
2 files changed, 41 insertions, 7 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index be0e48f30d4..b5fdcb9b6b5 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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;
@@ -8295,13 +8318,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;
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 9d57a41426d..9be3b7c3ffe 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -1599,6 +1599,13 @@ public:
evaluated at optimization time.
*/
Item *exec_const_cond;
+ /*
+ Constant ORDER and/or GROUP expressions that contain subqueries. Such
+ expressions need to evaluated to verify that the subquery indeed
+ returns a single row. The evaluation of such expressions is delayed
+ until query execution.
+ */
+ List<Item> exec_const_order_group_cond;
SQL_SELECT *select; ///<created in optimisation phase
JOIN_TAB *return_tab; ///<used only for outer joins
Item **ref_pointer_array; ///<used pointer reference for this select
@@ -1762,7 +1769,8 @@ public:
bool send_row_on_empty_set()
{
return (do_send_rows && tmp_table_param.sum_func_count != 0 &&
- !group_list && having_value != Item::COND_FALSE);
+ !(group_list || group_optimized_away) &&
+ having_value != Item::COND_FALSE);
}
bool change_result(select_result *result);
bool is_top_level_join() const