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

sanja at mariadb.com sanja at mariadb.com
Tue Nov 10 13:41:29 EET 2015


revision-id: 517e206b8d9855aea64f044b48f740a0df3a48c7 (mariadb-5.5.46-6-g517e206)
parent(s): 7e4da9b370d032db9015adb47ad2ff585aeaea5d
committer: Oleksandr Byelkin
timestamp: 2015-11-10 12:41:26 +0100
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 | 32 ++++++++++++++++++++++++++++++++
 mysql-test/t/ps.test   | 30 ++++++++++++++++++++++++++++++
 sql/item.cc            | 21 +++++++++++++++++++--
 3 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 1438595..a5e9011 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -4052,3 +4052,35 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1;
 ERROR 22003: BIGINT UNSIGNED value is out of range in '(18446744073709551615 + 1)'
 drop table t1;
 # End of 5.3 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 9775a8d..c790e11 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -3633,3 +3633,33 @@ SELECT 1 FROM t1 GROUP BY 0 OR 18446744073709551615+1;
 drop table t1;
 
 --echo # End of 5.3 tests
+
+--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 5.5 tests
diff --git a/sql/item.cc b/sql/item.cc
index 840272c..e864e2c 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -2772,8 +2772,25 @@ 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;
     ctx->first_name_resolution_table= context->first_name_resolution_table;
     ctx->last_name_resolution_table=  context->last_name_resolution_table;


More information about the commits mailing list