diff options
author | unknown <timour@askmonty.org> | 2010-12-10 13:10:11 +0200 |
---|---|---|
committer | unknown <timour@askmonty.org> | 2010-12-10 13:10:11 +0200 |
commit | fd24b33b578eecb1046414cb4406f6986c95611e (patch) | |
tree | d90a72ede847b061e322da0f21ff1cbae5ac8dfb /sql | |
parent | be95cde85991f4d4149d6532801720e583257642 (diff) | |
parent | 620aea4fde7d40f3870bebdcfd66d2b0b556db2f (diff) | |
download | mariadb-git-fd24b33b578eecb1046414cb4406f6986c95611e.tar.gz |
Merge the fix for LP BUG#682683.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_select.cc | 38 | ||||
-rw-r--r-- | sql/sql_select.h | 10 |
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 |