Skip to content

Commit b9631e3

Browse files
committed
MDEV-8833 Crash of server on prepared statement with conversion to semi-join
Correct context chain made to allow outer fields pullout.
1 parent ee97274 commit b9631e3

File tree

3 files changed

+81
-4
lines changed

3 files changed

+81
-4
lines changed

mysql-test/r/ps.result

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4072,4 +4072,35 @@ id value
40724072
deallocate prepare stmt;
40734073
SET SESSION sql_mode = @save_sql_mode;
40744074
DROP TABLE t1,t2;
4075-
# End of 10.0 tests
4075+
#
4076+
# MDEV-8833: Crash of server on prepared statement with
4077+
# conversion to semi-join
4078+
#
4079+
CREATE TABLE t1 (column1 INT);
4080+
INSERT INTO t1 VALUES (3),(9);
4081+
CREATE TABLE t2 (column2 INT);
4082+
INSERT INTO t2 VALUES (1),(4);
4083+
CREATE TABLE t3 (column3 INT);
4084+
INSERT INTO t3 VALUES (6),(8);
4085+
CREATE TABLE t4 (column4 INT);
4086+
INSERT INTO t4 VALUES (2),(5);
4087+
PREPARE stmt FROM "SELECT ( SELECT MAX( table1.column1 ) AS field1
4088+
FROM t1 AS table1
4089+
WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS table2 )
4090+
) AS sq
4091+
FROM t3 AS table3, t4 AS table4";
4092+
EXECUTE stmt;
4093+
sq
4094+
NULL
4095+
NULL
4096+
NULL
4097+
NULL
4098+
EXECUTE stmt;
4099+
sq
4100+
NULL
4101+
NULL
4102+
NULL
4103+
NULL
4104+
deallocate prepare stmt;
4105+
drop table t1,t2,t3,t4;
4106+
# End of 5.5 tests

mysql-test/t/ps.test

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3653,5 +3653,32 @@ deallocate prepare stmt;
36533653
SET SESSION sql_mode = @save_sql_mode;
36543654
DROP TABLE t1,t2;
36553655

3656+
--echo #
3657+
--echo # MDEV-8833: Crash of server on prepared statement with
3658+
--echo # conversion to semi-join
3659+
--echo #
3660+
3661+
CREATE TABLE t1 (column1 INT);
3662+
INSERT INTO t1 VALUES (3),(9);
3663+
3664+
CREATE TABLE t2 (column2 INT);
3665+
INSERT INTO t2 VALUES (1),(4);
3666+
3667+
CREATE TABLE t3 (column3 INT);
3668+
INSERT INTO t3 VALUES (6),(8);
3669+
3670+
CREATE TABLE t4 (column4 INT);
3671+
INSERT INTO t4 VALUES (2),(5);
3672+
3673+
PREPARE stmt FROM "SELECT ( SELECT MAX( table1.column1 ) AS field1
3674+
FROM t1 AS table1
3675+
WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS table2 )
3676+
) AS sq
3677+
FROM t3 AS table3, t4 AS table4";
3678+
EXECUTE stmt;
3679+
EXECUTE stmt;
3680+
deallocate prepare stmt;
3681+
drop table t1,t2,t3,t4;
3682+
36563683

3657-
--echo # End of 10.0 tests
3684+
--echo # End of 5.5 tests

sql/item.cc

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,9 +2778,28 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
27782778
if (context)
27792779
{
27802780
Name_resolution_context *ctx= new Name_resolution_context();
2781-
ctx->outer_context= NULL; // We don't build a complete name resolver
2782-
ctx->table_list= NULL; // We rely on first_name_resolution_table instead
2781+
if (context->select_lex == new_parent)
2782+
{
2783+
/*
2784+
This field was pushed in then pulled out
2785+
(for example left part of IN)
2786+
*/
2787+
ctx->outer_context= context->outer_context;
2788+
}
2789+
else if (context->outer_context)
2790+
{
2791+
/* just pull to the upper context */
2792+
ctx->outer_context= context->outer_context->outer_context;
2793+
}
2794+
else
2795+
{
2796+
/* No upper context (merging Derived/VIEW where context chain ends) */
2797+
ctx->outer_context= NULL;
2798+
}
2799+
ctx->table_list= context->first_name_resolution_table;
27832800
ctx->select_lex= new_parent;
2801+
if (context->select_lex == NULL)
2802+
ctx->select_lex= NULL;
27842803
ctx->first_name_resolution_table= context->first_name_resolution_table;
27852804
ctx->last_name_resolution_table= context->last_name_resolution_table;
27862805
ctx->error_processor= context->error_processor;

0 commit comments

Comments
 (0)