From d07843efd90a223a3308df73b59675dce30f92b6 Mon Sep 17 00:00:00 2001 From: "dlenev@brandersnatch.localdomain" <> Date: Mon, 20 Jun 2005 16:07:00 +0400 Subject: [PATCH] Fix for bug #11060 "Server crashes on re-execution of prepared INSERT ... SELECT with UNION" (reviewed version). Altough bug manifest itself only starting from 5.0 it is better to apply fix to 4.1 to keep some assumptions true and make code more future-proof. --- mysql-test/r/ps.result | 6 ++++++ mysql-test/t/ps.test | 12 ++++++++++++ sql/sql_insert.cc | 13 ++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index d66114fe44e..ca38f1c75cb 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -557,3 +557,9 @@ id 3 deallocate prepare stmt; drop table t1, t2; +create table t1 (id int); +prepare stmt from "insert into t1 (id) select id from t1 union select id from t1"; +execute stmt; +execute stmt; +deallocate prepare stmt; +drop table t1; diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 96b83a09497..bb1052c7337 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -569,3 +569,15 @@ select t2.id from t2, t1 where (t1.id=1 and t2.t1_id=t1.id); deallocate prepare stmt; drop table t1, t2; + +# +# Bug#11060 "Server crashes on calling stored procedure with INSERT SELECT +# UNION SELECT" aka "Server crashes on re-execution of prepared INSERT ... +# SELECT with UNION". +# +create table t1 (id int); +prepare stmt from "insert into t1 (id) select id from t1 union select id from t1"; +execute stmt; +execute stmt; +deallocate prepare stmt; +drop table t1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 718e6b00ddc..b90de7e93cc 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1578,10 +1578,21 @@ bool delayed_insert::handle_inserts(void) int select_insert::prepare(List &values, SELECT_LEX_UNIT *u) { + int res; + LEX *lex= thd->lex; + SELECT_LEX *lex_current_select_save= lex->current_select; DBUG_ENTER("select_insert::prepare"); unit= u; - if (check_insert_fields(thd, table, *fields, values)) + /* + Since table in which we are going to insert is added to the first + select, LEX::current_select should point to the first select while + we are fixing fields from insert list. + */ + lex->current_select= &lex->select_lex; + res= check_insert_fields(thd, table, *fields, values); + lex->current_select= lex_current_select_save; + if (res) DBUG_RETURN(1); restore_record(table,default_values); // Get empty record