Commit 3ec4296e authored by Igor Babaev's avatar Igor Babaev

Fixed bug mdev-5410.

The fix for bug #27937 was incomplete: it did not handle correctly the queries
containing UNION with global ORDER BY in subselects.
parent fde2777b
...@@ -3284,4 +3284,27 @@ Handler_read_rnd_deleted 0 ...@@ -3284,4 +3284,27 @@ Handler_read_rnd_deleted 0
Handler_read_rnd_next 0 Handler_read_rnd_next 0
deallocate prepare st; deallocate prepare st;
drop table t1; drop table t1;
#
# Bug mdev-5410: crash at the execution of PS with subselect
# formed by UNION with global ORDER BY
#
CREATE TABLE t1 (a int DEFAULT NULL);
INSERT INTO t1 VALUES (2), (4);
CREATE TABLE t2 (b int DEFAULT NULL);
INSERT INTO t2 VALUES (1), (3);
PREPARE stmt FROM "
SELECT c1 FROM (SELECT (SELECT a FROM t1 WHERE t1.a <= t2.b
UNION ALL
SELECT a FROM t1 WHERE t1.a+3<= t2.b
ORDER BY a DESC) AS c1 FROM t2) t3;
";
EXECUTE stmt;
c1
NULL
2
EXECUTE stmt;
c1
NULL
2
DROP TABLE t1,t2;
# End of 5.3 tests # End of 5.3 tests
...@@ -3308,4 +3308,26 @@ show status like '%Handler_read%'; ...@@ -3308,4 +3308,26 @@ show status like '%Handler_read%';
deallocate prepare st; deallocate prepare st;
drop table t1; drop table t1;
--echo #
--echo # Bug mdev-5410: crash at the execution of PS with subselect
--echo # formed by UNION with global ORDER BY
--echo #
CREATE TABLE t1 (a int DEFAULT NULL);
INSERT INTO t1 VALUES (2), (4);
CREATE TABLE t2 (b int DEFAULT NULL);
INSERT INTO t2 VALUES (1), (3);
PREPARE stmt FROM "
SELECT c1 FROM (SELECT (SELECT a FROM t1 WHERE t1.a <= t2.b
UNION ALL
SELECT a FROM t1 WHERE t1.a+3<= t2.b
ORDER BY a DESC) AS c1 FROM t2) t3;
";
EXECUTE stmt;
EXECUTE stmt;
DROP TABLE t1,t2;
--echo # End of 5.3 tests --echo # End of 5.3 tests
...@@ -584,7 +584,7 @@ public: ...@@ -584,7 +584,7 @@ public:
void print(String *str, enum_query_type query_type); void print(String *str, enum_query_type query_type);
bool add_fake_select_lex(THD *thd); bool add_fake_select_lex(THD *thd);
void init_prepare_fake_select_lex(THD *thd); void init_prepare_fake_select_lex(THD *thd, bool first_execution);
inline bool is_prepared() { return prepared; } inline bool is_prepared() { return prepared; }
bool change_result(select_result_interceptor *result, bool change_result(select_result_interceptor *result,
select_result_interceptor *old_result); select_result_interceptor *old_result);
......
...@@ -184,13 +184,15 @@ void select_union::cleanup() ...@@ -184,13 +184,15 @@ void select_union::cleanup()
SYNOPSIS SYNOPSIS
st_select_lex_unit::init_prepare_fake_select_lex() st_select_lex_unit::init_prepare_fake_select_lex()
thd - thread handler thd - thread handler
first_execution - TRUE at the first execution of the union
RETURN RETURN
options of SELECT options of SELECT
*/ */
void void
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg,
bool first_execution)
{ {
thd_arg->lex->current_select= fake_select_lex; thd_arg->lex->current_select= fake_select_lex;
fake_select_lex->table_list.link_in_list(&result_table_list, fake_select_lex->table_list.link_in_list(&result_table_list,
...@@ -198,7 +200,13 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg) ...@@ -198,7 +200,13 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd_arg)
fake_select_lex->context.table_list= fake_select_lex->context.table_list=
fake_select_lex->context.first_name_resolution_table= fake_select_lex->context.first_name_resolution_table=
fake_select_lex->get_table_list(); fake_select_lex->get_table_list();
if (!fake_select_lex->first_execution) /*
The flag fake_select_lex->first_execution indicates whether this is
called at the first execution of the statement, while first_execution
shows whether this is called at the first execution of the union that
may form just a subselect.
*/
if (!fake_select_lex->first_execution && first_execution)
{ {
for (ORDER *order= global_parameters->order_list.first; for (ORDER *order= global_parameters->order_list.first;
order; order;
...@@ -472,7 +480,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -472,7 +480,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{ {
/* Validate the global parameters of this union */ /* Validate the global parameters of this union */
init_prepare_fake_select_lex(thd); init_prepare_fake_select_lex(thd, TRUE);
/* Should be done only once (the only item_list per statement) */ /* Should be done only once (the only item_list per statement) */
DBUG_ASSERT(fake_select_lex->join == 0); DBUG_ASSERT(fake_select_lex->join == 0);
if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options, if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options,
...@@ -612,6 +620,7 @@ bool st_select_lex_unit::exec() ...@@ -612,6 +620,7 @@ bool st_select_lex_unit::exec()
SELECT_LEX *select_cursor=first_select(); SELECT_LEX *select_cursor=first_select();
ulonglong add_rows=0; ulonglong add_rows=0;
ha_rows examined_rows= 0; ha_rows examined_rows= 0;
bool first_execution= !executed;
DBUG_ENTER("st_select_lex_unit::exec"); DBUG_ENTER("st_select_lex_unit::exec");
if (executed && !uncacheable && !describe) if (executed && !uncacheable && !describe)
...@@ -714,7 +723,7 @@ bool st_select_lex_unit::exec() ...@@ -714,7 +723,7 @@ bool st_select_lex_unit::exec()
if (!thd->is_fatal_error) // Check if EOM if (!thd->is_fatal_error) // Check if EOM
{ {
set_limit(global_parameters); set_limit(global_parameters);
init_prepare_fake_select_lex(thd); init_prepare_fake_select_lex(thd, first_execution);
JOIN *join= fake_select_lex->join; JOIN *join= fake_select_lex->join;
if (!join) if (!join)
{ {
......
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