diff options
author | unknown <dlenev@brandersnatch.localdomain> | 2005-06-20 16:07:00 +0400 |
---|---|---|
committer | unknown <dlenev@brandersnatch.localdomain> | 2005-06-20 16:07:00 +0400 |
commit | 78e6794b63bdacaf260397ee70d098ba7afb85d5 (patch) | |
tree | 9663c3b1decfcf7a324d7b1a05ff5a7c1117247a /sql/sql_insert.cc | |
parent | c7a681ff94d3f39360a53d940398931dd55aad66 (diff) | |
download | mariadb-git-78e6794b63bdacaf260397ee70d098ba7afb85d5.tar.gz |
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:
Added test case for bug #11060 "Server crashes on re-execution of
prepared INSERT ... SELECT with UNION".
mysql-test/t/ps.test:
Added test case for bug #11060 "Server crashes on re-execution of
prepared INSERT ... SELECT with UNION".
sql/sql_insert.cc:
select_insert::prepare():
Item::fix_fields() methods operate assuming that LEX::current_select
points to the select to which current item belongs. Thus
during check_insert_fields() routine execution LEX::current_select
should point ot the first select in query since this is the
select with which items in insert list is associated.
But if we have INSERT SELECT UNION SELECT type of query
LEX::current_select will point to the fake_select_lex instead
since select_insert::prepare() is called during processing of JOIN
which corresponds to this select_lex.
So we have set LEX::current_select before calling check_insert_fields()
and restore it afterwards.
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r-- | sql/sql_insert.cc | 13 |
1 files changed, 12 insertions, 1 deletions
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<Item> &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 |