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.
This commit is contained in:
parent
fde2777b27
commit
3ec4296ec4
@ -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%';
|
|||||||
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:
|
|||||||
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()
|
|||||||
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)
|
|||||||
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,
|
|||||||
{
|
{
|
||||||
/* 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()
|
|||||||
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()
|
|||||||
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)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user