diff options
author | unknown <gkodinov/kgeorge@magare.gmz> | 2007-03-16 10:50:33 +0200 |
---|---|---|
committer | unknown <gkodinov/kgeorge@magare.gmz> | 2007-03-16 10:50:33 +0200 |
commit | 43b9ff1b21b2d645e5cd52d82878a48b47b01f8d (patch) | |
tree | 08044d9cf7c962f103a3a4f655389bcb2bec96af | |
parent | 1a259b885f0882f136490e13a0b0eaee56442410 (diff) | |
parent | 2e8e78a42cbe49d2e74381c9229d2e93c8df6f0d (diff) | |
download | mariadb-git-43b9ff1b21b2d645e5cd52d82878a48b47b01f8d.tar.gz |
Merge gkodinov@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into magare.gmz:/home/kgeorge/mysql/autopush/B26261-5.0-opt
sql/mysql_priv.h:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
mysql-test/r/insert_update.result:
SCCS merged
mysql-test/t/insert_update.test:
SCCS merged
-rw-r--r-- | mysql-test/r/insert_update.result | 11 | ||||
-rw-r--r-- | mysql-test/t/insert_update.test | 21 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sql_insert.cc | 68 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 2 |
5 files changed, 80 insertions, 25 deletions
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result index b1dee844515..ef0d8ec239e 100644 --- a/mysql-test/r/insert_update.result +++ b/mysql-test/r/insert_update.result @@ -236,6 +236,17 @@ INSERT INTO t2 VALUES (1), (3); INSERT INTO t1 SELECT 1, COUNT(*) FROM t2 ON DUPLICATE KEY UPDATE j= a; ERROR 42S22: Unknown column 'a' in 'field list' DROP TABLE t1,t2; +SET SQL_MODE = 'TRADITIONAL'; +CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL); +INSERT INTO t1 (a) VALUES (1); +ERROR HY000: Field 'b' doesn't have a default value +INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b; +ERROR HY000: Field 'b' doesn't have a default value +INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b; +ERROR HY000: Field 'b' doesn't have a default value +SELECT * FROM t1; +a b +DROP TABLE t1; CREATE TABLE t1 (f1 INT AUTO_INCREMENT PRIMARY KEY, f2 VARCHAR(5) NOT NULL UNIQUE); INSERT t1 (f2) VALUES ('test') ON DUPLICATE KEY UPDATE f1 = LAST_INSERT_ID(f1); diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test index 2ef378aa478..b0de66f7fc6 100644 --- a/mysql-test/t/insert_update.test +++ b/mysql-test/t/insert_update.test @@ -164,6 +164,27 @@ INSERT INTO t1 SELECT 1, COUNT(*) FROM t2 ON DUPLICATE KEY UPDATE j= a; DROP TABLE t1,t2; # +# Bug #26261: Missing default value isn't noticed in +# insert ... on duplicate key update +# +SET SQL_MODE = 'TRADITIONAL'; + +CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL); + +--error 1364 +INSERT INTO t1 (a) VALUES (1); + +--error 1364 +INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b; + +--error 1364 +INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b; + +SELECT * FROM t1; + +DROP TABLE t1; + +# # Bug#27033: 0 as LAST_INSERT_ID() after INSERT .. ON DUPLICATE if rows were # touched but not actually changed. # diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c590429047f..88bd8576965 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -835,7 +835,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 629d1e68d4e..35e724beec8 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -473,10 +473,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 */ @@ -502,7 +507,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++; @@ -581,17 +585,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); @@ -963,6 +959,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: @@ -983,7 +983,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; @@ -1046,10 +1047,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); @@ -2326,7 +2339,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); /* @@ -2388,7 +2401,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; @@ -2499,9 +2523,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 33a57e8bea6..85092f14624 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1070,7 +1070,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; |