[Commits] b9631e3: MDEV-8833 Crash of server on prepared statement with conversion to semi-join

Oleksandr Byelkin sanja at mariadb.com
Fri Sep 2 19:34:37 EEST 2016


revision-id: b9631e310b7cadf8711eef643e432d7e816680b4 (mariadb-5.5.51-6-gb9631e3)
parent(s): ee97274ca7d9ea8d8f00e40476a039c35399ee15
committer: Oleksandr Byelkin
timestamp: 2016-09-02 18:34:37 +0200
message:

MDEV-8833 Crash of server on prepared statement with conversion to semi-join

Correct context chain made to allow outer fields pullout.

---
 mysql-test/r/ps.result | 33 ++++++++++++++++++++++++++++++++-
 mysql-test/t/ps.test   | 29 ++++++++++++++++++++++++++++-
 sql/item.cc            | 23 +++++++++++++++++++++--
 3 files changed, 81 insertions(+), 4 deletions(-)

diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 04a19d3..bb8b76f 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -4072,4 +4072,35 @@ id	value
 deallocate prepare stmt;
 SET SESSION sql_mode = @save_sql_mode;
 DROP TABLE t1,t2;
-# End of 10.0 tests
+#
+# MDEV-8833: Crash of server on prepared statement with
+# conversion to semi-join
+#
+CREATE TABLE t1 (column1 INT);
+INSERT INTO t1 VALUES (3),(9);
+CREATE TABLE t2 (column2 INT);
+INSERT INTO t2 VALUES (1),(4);
+CREATE TABLE t3 (column3 INT);
+INSERT INTO t3 VALUES (6),(8);
+CREATE TABLE t4 (column4 INT);
+INSERT INTO t4 VALUES (2),(5);
+PREPARE stmt FROM "SELECT ( SELECT MAX( table1.column1 ) AS field1 
+FROM t1 AS table1
+WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS table2 ) 
+) AS sq
+FROM t3 AS table3, t4 AS table4";
+EXECUTE stmt;
+sq
+NULL
+NULL
+NULL
+NULL
+EXECUTE stmt;
+sq
+NULL
+NULL
+NULL
+NULL
+deallocate prepare stmt;
+drop table t1,t2,t3,t4;
+# End of 5.5 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 2ed5bb1..1516acca 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3653,5 +3653,32 @@ deallocate prepare stmt;
 SET SESSION sql_mode = @save_sql_mode;
 DROP TABLE t1,t2;
 
+--echo #
+--echo # MDEV-8833: Crash of server on prepared statement with
+--echo # conversion to semi-join
+--echo #
+
+CREATE TABLE t1 (column1 INT);
+INSERT INTO t1 VALUES (3),(9);
+
+CREATE TABLE t2 (column2 INT);
+INSERT INTO t2 VALUES (1),(4);
+
+CREATE TABLE t3 (column3 INT);
+INSERT INTO t3 VALUES (6),(8);
+
+CREATE TABLE t4 (column4 INT);
+INSERT INTO t4 VALUES (2),(5);
+
+PREPARE stmt FROM "SELECT ( SELECT MAX( table1.column1 ) AS field1 
+FROM t1 AS table1
+WHERE table3.column3 IN ( SELECT table2.column2 AS field2 FROM t2 AS table2 ) 
+) AS sq
+FROM t3 AS table3, t4 AS table4";
+EXECUTE stmt;
+EXECUTE stmt;
+deallocate prepare stmt;
+drop table t1,t2,t3,t4;
+
 
---echo # End of 10.0 tests
+--echo # End of 5.5 tests
diff --git a/sql/item.cc b/sql/item.cc
index 5861766..abcf48f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2778,9 +2778,28 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
   if (context)
   {
     Name_resolution_context *ctx= new Name_resolution_context();
-    ctx->outer_context= NULL; // We don't build a complete name resolver
-    ctx->table_list= NULL;    // We rely on first_name_resolution_table instead
+    if (context->select_lex == new_parent)
+    {
+      /*
+        This field was pushed in then pulled out
+        (for example left part of IN)
+      */
+      ctx->outer_context= context->outer_context;
+    }
+    else if (context->outer_context)
+    {
+      /* just pull to the upper context */
+      ctx->outer_context= context->outer_context->outer_context;
+    }
+    else
+    {
+      /* No upper context (merging Derived/VIEW where context chain ends) */
+      ctx->outer_context= NULL;
+    }
+    ctx->table_list= context->first_name_resolution_table;
     ctx->select_lex= new_parent;
+    if (context->select_lex == NULL)
+      ctx->select_lex= NULL;
     ctx->first_name_resolution_table= context->first_name_resolution_table;
     ctx->last_name_resolution_table=  context->last_name_resolution_table;
     ctx->error_processor=             context->error_processor;


More information about the commits mailing list