summaryrefslogtreecommitdiff
path: root/sql/sql_insert.cc
diff options
context:
space:
mode:
authorunknown <acurtis@xiphis.org>2005-08-07 03:16:15 +0100
committerunknown <acurtis@xiphis.org>2005-08-07 03:16:15 +0100
commitfdb4d307ab8c7639ced6e08c61528bfe81823fae (patch)
tree58a1759c94967db7d8ef575fe9f3af0cec92c74a /sql/sql_insert.cc
parent75c06af27784e6fa6ba23f4cd6803bc7574f8253 (diff)
downloadmariadb-git-fdb4d307ab8c7639ced6e08c61528bfe81823fae.tar.gz
Bug#10109
"INSERT .. SELECT ... ON DUPLICATE KEY UPDATE fails" Ensure that check_insert_fields() is only called once when doing an INSERT..SELECT mysql-test/r/insert_update.result: Test for bug 10109 mysql-test/t/insert_update.test: Test for bug 10109 sql/sql_class.h: select_insert needs more state sql/sql_insert.cc: ensure that check_insert_fields() is only called once when doing an INSERT...SELECT sql/sql_parse.cc: more args for select_insert constructor
Diffstat (limited to 'sql/sql_insert.cc')
-rw-r--r--sql/sql_insert.cc36
1 files changed, 25 insertions, 11 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 7d613ad6fbf..8c6fed26f8e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -543,18 +543,22 @@ int mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
if (!table->insert_values)
DBUG_RETURN(-1);
}
- if ((values && check_insert_fields(thd, table, fields, *values)) ||
- setup_tables(insert_table_list) ||
- (values && setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0)) ||
- (duplic == DUP_UPDATE &&
- (check_update_fields(thd, table, insert_table_list, update_fields) ||
- setup_fields(thd, 0, dup_table_list, update_values, 1, 0, 0))))
+ if (setup_tables(insert_table_list))
DBUG_RETURN(-1);
- if (values && find_real_table_in_list(table_list->next, table_list->db,
- table_list->real_name))
+ if (values)
{
- my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
- DBUG_RETURN(-1);
+ if (check_insert_fields(thd, table, fields, *values) ||
+ setup_fields(thd, 0, insert_table_list, *values, 0, 0, 0) ||
+ (duplic == DUP_UPDATE &&
+ (check_update_fields(thd, table, insert_table_list, update_fields) ||
+ setup_fields(thd, 0, dup_table_list, update_values, 1, 0, 0))))
+ DBUG_RETURN(-1);
+ if (find_real_table_in_list(table_list->next, table_list->db,
+ table_list->real_name))
+ {
+ my_error(ER_UPDATE_TABLE_USED, MYF(0), table_list->real_name);
+ DBUG_RETURN(-1);
+ }
}
if (duplic == DUP_UPDATE || duplic == DUP_REPLACE)
table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY);
@@ -1601,6 +1605,7 @@ 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;
+ bool lex_select_no_error= lex->select_lex.no_error;
DBUG_ENTER("select_insert::prepare");
unit= u;
@@ -1608,10 +1613,19 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
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.
+ Since these checks may cause the query to fail, we don't want the
+ error messages to be converted into warnings, must force no_error=0
*/
lex->current_select= &lex->select_lex;
- res= check_insert_fields(thd, table, *fields, values);
+ lex->select_lex.no_error= 0;
+ res=
+ check_insert_fields(thd, table, *fields, values) ||
+ setup_fields(thd, 0, insert_table_list, values, 0, 0, 0) ||
+ (info.handle_duplicates == DUP_UPDATE &&
+ (check_update_fields(thd, table, insert_table_list, *info.update_fields) ||
+ setup_fields(thd, 0, dup_table_list, *info.update_values, 1, 0, 0)));
lex->current_select= lex_current_select_save;
+ lex->select_lex.no_error= lex_select_no_error;
if (res)
DBUG_RETURN(1);