summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <gkodinov/kgeorge@macbook.gmz>2007-03-16 10:35:39 +0200
committerunknown <gkodinov/kgeorge@macbook.gmz>2007-03-16 10:35:39 +0200
commit2e8e78a42cbe49d2e74381c9229d2e93c8df6f0d (patch)
treebcb1b42fa6a2377ab144ada7be2095e71e0c647e /sql
parent1f93b0c83af4b30b90e3a71eb6f2a663375feebc (diff)
downloadmariadb-git-2e8e78a42cbe49d2e74381c9229d2e93c8df6f0d.tar.gz
Bug #26261:
INSERT uses query_id to verify what fields are mentioned in the fields list of the INSERT command. However the check for that is made after the ON DUPLICATE KEY is processed. This causes all the fields mentioned in ON DUPLICATE KEY to be considered as mentioned in the fields list of INSERT. Moved the check up, right after processing the fields list. mysql-test/r/insert_update.result: Bug #26261: test case mysql-test/t/insert_update.test: Bug #26261: test case sql/mysql_priv.h: Bug #26261: moved the check inside mysql_prepare_insert sql/sql_insert.cc: Bug #26261: move the check inside mysql_prepare_insert before setting up the ON DUPLICATE KEY part sql/sql_prepare.cc: Bug #26261: moved the check inside mysql_prepare_insert
Diffstat (limited to 'sql')
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/sql_insert.cc68
-rw-r--r--sql/sql_prepare.cc2
3 files changed, 48 insertions, 25 deletions
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index f90ea5587fa..e5877e8ed1f 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -823,7 +823,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table,
List<Item> &fields, List_item *values,
List<Item> &update_fields,
List<Item> &update_values, enum_duplicates duplic,
- COND **where, bool select_insert);
+ COND **where, bool select_insert,
+ bool check_fields, bool abort_on_warning);
bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields,
List<List_item> &values, List<Item> &update_fields,
List<Item> &update_values, enum_duplicates flag,
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 332c4c82ba1..dfff70e858e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -451,10 +451,15 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->proc_info="init";
thd->used_tables=0;
values= its++;
+ value_count= values->elements;
if (mysql_prepare_insert(thd, table_list, table, fields, values,
update_fields, update_values, duplic, &unused_conds,
- FALSE))
+ FALSE,
+ (fields.elements || !value_count),
+ !ignore && (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES |
+ MODE_STRICT_ALL_TABLES))))
goto abort;
/* mysql_prepare_insert set table_list->table if it was not set */
@@ -480,7 +485,6 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
- value_count= values->elements;
while ((values= its++))
{
counter++;
@@ -551,17 +555,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
table->file->start_bulk_insert(values_list.elements);
thd->no_trans_update= 0;
- thd->abort_on_warning= (!ignore &&
- (thd->variables.sql_mode &
- (MODE_STRICT_TRANS_TABLES |
- MODE_STRICT_ALL_TABLES)));
-
- if ((fields.elements || !value_count) &&
- check_that_all_fields_are_given_values(thd, table, table_list))
- {
- /* thd->net.report_error is now set, which will abort the next loop */
- error= 1;
- }
+ thd->abort_on_warning= (!ignore && (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES |
+ MODE_STRICT_ALL_TABLES)));
mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic);
@@ -934,6 +930,10 @@ static bool mysql_prepare_insert_check_table(THD *thd, TABLE_LIST *table_list,
be taken from table_list->table)
where Where clause (for insert ... select)
select_insert TRUE if INSERT ... SELECT statement
+ check_fields TRUE if need to check that all INSERT fields are
+ given values.
+ abort_on_warning whether to report if some INSERT field is not
+ assigned as an error (TRUE) or as a warning (FALSE).
TODO (in far future)
In cases of:
@@ -954,7 +954,8 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
TABLE *table, List<Item> &fields, List_item *values,
List<Item> &update_fields, List<Item> &update_values,
enum_duplicates duplic,
- COND **where, bool select_insert)
+ COND **where, bool select_insert,
+ bool check_fields, bool abort_on_warning)
{
SELECT_LEX *select_lex= &thd->lex->select_lex;
Name_resolution_context *context= &select_lex->context;
@@ -1017,10 +1018,22 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list,
table_list->next_local= 0;
context->resolve_in_table_list_only(table_list);
- if (!(res= check_insert_fields(thd, context->table_list, fields, *values,
- !insert_into_view, &map) ||
- setup_fields(thd, 0, *values, 0, 0, 0))
- && duplic == DUP_UPDATE)
+ res= check_insert_fields(thd, context->table_list, fields, *values,
+ !insert_into_view, &map) ||
+ setup_fields(thd, 0, *values, 0, 0, 0);
+
+ if (!res && check_fields)
+ {
+ bool saved_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning= abort_on_warning;
+ res= check_that_all_fields_are_given_values(thd,
+ table ? table :
+ context->table_list->table,
+ context->table_list);
+ thd->abort_on_warning= saved_abort_on_warning;
+ }
+
+ if (!res && duplic == DUP_UPDATE)
{
select_lex->no_wrap_view_item= TRUE;
res= check_update_fields(thd, context->table_list, update_fields, &map);
@@ -2295,7 +2308,7 @@ bool mysql_insert_select_prepare(THD *thd)
lex->query_tables->table, lex->field_list, 0,
lex->update_list, lex->value_list,
lex->duplicates,
- &select_lex->where, TRUE))
+ &select_lex->where, TRUE, FALSE, FALSE))
DBUG_RETURN(TRUE);
/*
@@ -2357,7 +2370,18 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
!insert_into_view, &map) ||
setup_fields(thd, 0, values, 0, 0, 0);
- if (info.handle_duplicates == DUP_UPDATE)
+ if (!res && fields->elements)
+ {
+ bool saved_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning= !info.ignore && (thd->variables.sql_mode &
+ (MODE_STRICT_TRANS_TABLES |
+ MODE_STRICT_ALL_TABLES));
+ res= check_that_all_fields_are_given_values(thd, table_list->table,
+ table_list);
+ thd->abort_on_warning= saved_abort_on_warning;
+ }
+
+ if (info.handle_duplicates == DUP_UPDATE && !res)
{
Name_resolution_context *context= &lex->select_lex.context;
Name_resolution_context_state ctx_state;
@@ -2459,9 +2483,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
(thd->variables.sql_mode &
(MODE_STRICT_TRANS_TABLES |
MODE_STRICT_ALL_TABLES)));
- res= ((fields->elements &&
- check_that_all_fields_are_given_values(thd, table, table_list)) ||
- table_list->prepare_where(thd, 0, TRUE) ||
+ res= (table_list->prepare_where(thd, 0, TRUE) ||
table_list->prepare_check_option(thd));
if (!res)
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index ad2b0be4eb8..8e807ca0ada 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1058,7 +1058,7 @@ static bool mysql_test_insert(Prepared_statement *stmt,
if (mysql_prepare_insert(thd, table_list, table_list->table,
fields, values, update_fields, update_values,
- duplic, &unused_conds, FALSE))
+ duplic, &unused_conds, FALSE, FALSE, FALSE))
goto error;
value_count= values->elements;