Commit 816940f6 authored by unknown's avatar unknown

Merge the fix for LP BUG#682683.

parents bcc5d8f2 c8413dba
...@@ -605,6 +605,46 @@ COUNT(t2.f3) f9 ...@@ -605,6 +605,46 @@ COUNT(t2.f3) f9
0 NULL 0 NULL
drop table t1,t2; drop table t1,t2;
# #
# LP BUG#682683 Crash in create_tmp_table called from
# JOIN::init_execution
#
CREATE TABLE t2 (f1 int) ;
INSERT INTO t2 VALUES (1),(2);
CREATE TABLE t1 (f1 int) ;
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
field1
NULL
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
field1
NULL
NULL
INSERT INTO t1 VALUES (1),(2);
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
ERROR 21000: Subquery returns more than 1 row
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2
2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
ERROR 21000: Subquery returns more than 1 row
drop table t1,t2;
#
# LP BUG#680943 Assertion `!table || (!table->read_set || # LP BUG#680943 Assertion `!table || (!table->read_set ||
# bitmap_is_set(table->read_set, field_index))' failed with subquery # bitmap_is_set(table->read_set, field_index))' failed with subquery
# #
......
...@@ -558,6 +558,36 @@ ORDER BY f9; ...@@ -558,6 +558,36 @@ ORDER BY f9;
drop table t1,t2; drop table t1,t2;
--echo #
--echo # LP BUG#682683 Crash in create_tmp_table called from
--echo # JOIN::init_execution
--echo #
CREATE TABLE t2 (f1 int) ;
INSERT INTO t2 VALUES (1),(2);
CREATE TABLE t1 (f1 int) ;
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
INSERT INTO t1 VALUES (1),(2);
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
--error ER_SUBQUERY_NO_1_ROW
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 GROUP BY field1;
EXPLAIN
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
--error ER_SUBQUERY_NO_1_ROW
SELECT (SELECT f1 FROM t1) AS field1 FROM t2 ORDER BY field1;
drop table t1,t2;
--echo # --echo #
--echo # LP BUG#680943 Assertion `!table || (!table->read_set || --echo # LP BUG#680943 Assertion `!table || (!table->read_set ||
--echo # bitmap_is_set(table->read_set, field_index))' failed with subquery --echo # bitmap_is_set(table->read_set, field_index))' failed with subquery
......
...@@ -1402,6 +1402,7 @@ JOIN::optimize() ...@@ -1402,6 +1402,7 @@ JOIN::optimize()
/** /**
Create and initialize objects neeed for the execution of a query plan. Create and initialize objects neeed for the execution of a query plan.
Evaluate constant expressions not evaluated during optimization.
*/ */
int JOIN::init_execution() int JOIN::init_execution()
...@@ -1409,6 +1410,7 @@ int JOIN::init_execution() ...@@ -1409,6 +1410,7 @@ int JOIN::init_execution()
DBUG_ENTER("JOIN::init_execution"); DBUG_ENTER("JOIN::init_execution");
DBUG_ASSERT(optimized); DBUG_ASSERT(optimized);
DBUG_ASSERT(!(select_options & SELECT_DESCRIBE));
initialized= true; initialized= true;
/* Create a tmp table if distinct or if the sort is too complicated */ /* Create a tmp table if distinct or if the sort is too complicated */
...@@ -1839,6 +1841,27 @@ JOIN::exec() ...@@ -1839,6 +1841,27 @@ JOIN::exec()
DBUG_VOID_RETURN; 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) && if ((this->select_lex->options & OPTION_SCHEMA_TABLE) &&
get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC)) get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -8295,13 +8318,16 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, ...@@ -8295,13 +8318,16 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
(join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED && (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
join->outer_join)) join->outer_join))
*simple_order=0; // Must do a temp table to sort *simple_order=0; // Must do a temp table to sort
else if (!(order_tables & not_const_tables) && else if (!(order_tables & not_const_tables))
!order->item[0]->with_subselect)
{ {
/* if (order->item[0]->with_subselect)
Skip constant expressions in the ORDER/GROUP clause, except when there {
is a subquery in the expression. /*
*/ 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())); DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
continue; continue;
} }
......
...@@ -1599,6 +1599,13 @@ class JOIN :public Sql_alloc ...@@ -1599,6 +1599,13 @@ class JOIN :public Sql_alloc
evaluated at optimization time. evaluated at optimization time.
*/ */
Item *exec_const_cond; 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 SQL_SELECT *select; ///<created in optimisation phase
JOIN_TAB *return_tab; ///<used only for outer joins JOIN_TAB *return_tab; ///<used only for outer joins
Item **ref_pointer_array; ///<used pointer reference for this select Item **ref_pointer_array; ///<used pointer reference for this select
...@@ -1762,7 +1769,8 @@ class JOIN :public Sql_alloc ...@@ -1762,7 +1769,8 @@ class JOIN :public Sql_alloc
bool send_row_on_empty_set() bool send_row_on_empty_set()
{ {
return (do_send_rows && tmp_table_param.sum_func_count != 0 && 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 change_result(select_result *result);
bool is_top_level_join() const bool is_top_level_join() const
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment