diff --git a/cmd-line-utils/readline/bind.c b/cmd-line-utils/readline/bind.c index fd01049f09f..0e8efc5c636 100644 --- a/cmd-line-utils/readline/bind.c +++ b/cmd-line-utils/readline/bind.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/callback.c b/cmd-line-utils/readline/callback.c index a8f4323c929..737f483eed0 100644 --- a/cmd-line-utils/readline/callback.c +++ b/cmd-line-utils/readline/callback.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include "rlconf.h" diff --git a/cmd-line-utils/readline/complete.c b/cmd-line-utils/readline/complete.c index 693550c9945..749875e0e5e 100644 --- a/cmd-line-utils/readline/complete.c +++ b/cmd-line-utils/readline/complete.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/config_readline.h b/cmd-line-utils/readline/config_readline.h new file mode 100644 index 00000000000..141989ec3c9 --- /dev/null +++ b/cmd-line-utils/readline/config_readline.h @@ -0,0 +1,30 @@ +/* + config-readline.h Maintained by hand. Contains the readline specific + parts from config.h.in in readline 4.3 +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +/* + Ultrix botches type-ahead when switching from canonical to + non-canonical mode, at least through version 4.3 +*/ +#if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix) +# define TERMIOS_MISSING +#endif + +#if defined (STRCOLL_BROKEN) +# undef HAVE_STRCOLL +#endif + +#if defined (__STDC__) && defined (HAVE_STDARG_H) +# define PREFER_STDARG +# define USE_VARARGS +#else +# if defined (HAVE_VARARGS_H) +# define PREFER_VARARGS +# define USE_VARARGS +# endif +#endif diff --git a/cmd-line-utils/readline/display.c b/cmd-line-utils/readline/display.c index f393e7e8516..7c393f1c8a5 100644 --- a/cmd-line-utils/readline/display.c +++ b/cmd-line-utils/readline/display.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/funmap.c b/cmd-line-utils/readline/funmap.c index fe9a1da43d7..53fd22754ab 100644 --- a/cmd-line-utils/readline/funmap.c +++ b/cmd-line-utils/readline/funmap.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #if !defined (BUFSIZ) #include diff --git a/cmd-line-utils/readline/histexpand.c b/cmd-line-utils/readline/histexpand.c index f01d54c5b1d..eed8d5a365e 100644 --- a/cmd-line-utils/readline/histexpand.c +++ b/cmd-line-utils/readline/histexpand.c @@ -22,9 +22,7 @@ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/histfile.c b/cmd-line-utils/readline/histfile.c index 60a91251b7a..77f757eac1d 100644 --- a/cmd-line-utils/readline/histfile.c +++ b/cmd-line-utils/readline/histfile.c @@ -25,9 +25,7 @@ you can call. I think I have done that. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/history.c b/cmd-line-utils/readline/history.c index 4242f33efe1..759ff9e0de9 100644 --- a/cmd-line-utils/readline/history.c +++ b/cmd-line-utils/readline/history.c @@ -25,9 +25,7 @@ you can call. I think I have done that. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/histsearch.c b/cmd-line-utils/readline/histsearch.c index d94fd6cd9c6..ffc97d720db 100644 --- a/cmd-line-utils/readline/histsearch.c +++ b/cmd-line-utils/readline/histsearch.c @@ -22,9 +22,7 @@ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #if defined (HAVE_STDLIB_H) diff --git a/cmd-line-utils/readline/input.c b/cmd-line-utils/readline/input.c index 1442c5ef155..d9c52dfcec8 100644 --- a/cmd-line-utils/readline/input.c +++ b/cmd-line-utils/readline/input.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/isearch.c b/cmd-line-utils/readline/isearch.c index 137842a841f..1de16c6a56c 100644 --- a/cmd-line-utils/readline/isearch.c +++ b/cmd-line-utils/readline/isearch.c @@ -26,9 +26,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/keymaps.c b/cmd-line-utils/readline/keymaps.c index 12506d3aab2..9972d83e4f1 100644 --- a/cmd-line-utils/readline/keymaps.c +++ b/cmd-line-utils/readline/keymaps.c @@ -20,9 +20,7 @@ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #if defined (HAVE_STDLIB_H) # include diff --git a/cmd-line-utils/readline/kill.c b/cmd-line-utils/readline/kill.c index f8c6961bbd3..32a661f076f 100644 --- a/cmd-line-utils/readline/kill.c +++ b/cmd-line-utils/readline/kill.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/macro.c b/cmd-line-utils/readline/macro.c index 7ab4b6ca657..7f5c39f7d86 100644 --- a/cmd-line-utils/readline/macro.c +++ b/cmd-line-utils/readline/macro.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/mbutil.c b/cmd-line-utils/readline/mbutil.c index debad6320ce..3113b7b0538 100644 --- a/cmd-line-utils/readline/mbutil.c +++ b/cmd-line-utils/readline/mbutil.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/misc.c b/cmd-line-utils/readline/misc.c index 94ad433473b..858d09dbe90 100644 --- a/cmd-line-utils/readline/misc.c +++ b/cmd-line-utils/readline/misc.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #if defined (HAVE_UNISTD_H) # include diff --git a/cmd-line-utils/readline/nls.c b/cmd-line-utils/readline/nls.c index 706c8195c10..6555c50c22b 100644 --- a/cmd-line-utils/readline/nls.c +++ b/cmd-line-utils/readline/nls.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/parens.c b/cmd-line-utils/readline/parens.c index 54ef1f3695f..5d4a08a0ce8 100644 --- a/cmd-line-utils/readline/parens.c +++ b/cmd-line-utils/readline/parens.c @@ -23,9 +23,7 @@ #include "rlconf.h" -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/readline.c b/cmd-line-utils/readline/readline.c index 28801f19dfc..2c0bb499b7b 100644 --- a/cmd-line-utils/readline/readline.c +++ b/cmd-line-utils/readline/readline.c @@ -22,9 +22,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include "posixstat.h" diff --git a/cmd-line-utils/readline/rltty.c b/cmd-line-utils/readline/rltty.c index 09702e9e755..9a2cef4b279 100644 --- a/cmd-line-utils/readline/rltty.c +++ b/cmd-line-utils/readline/rltty.c @@ -22,9 +22,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/search.c b/cmd-line-utils/readline/search.c index ac47596a3f8..637534924f1 100644 --- a/cmd-line-utils/readline/search.c +++ b/cmd-line-utils/readline/search.c @@ -22,9 +22,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/shell.c b/cmd-line-utils/readline/shell.c index ad27cc14884..fd6a2816309 100644 --- a/cmd-line-utils/readline/shell.c +++ b/cmd-line-utils/readline/shell.c @@ -22,9 +22,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/signals.c b/cmd-line-utils/readline/signals.c index 0a1468b6b2a..4609598ff98 100644 --- a/cmd-line-utils/readline/signals.c +++ b/cmd-line-utils/readline/signals.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include /* Just for NULL. Yuck. */ #include diff --git a/cmd-line-utils/readline/terminal.c b/cmd-line-utils/readline/terminal.c index 397b10a1d46..a506fa6de09 100644 --- a/cmd-line-utils/readline/terminal.c +++ b/cmd-line-utils/readline/terminal.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include "posixstat.h" diff --git a/cmd-line-utils/readline/text.c b/cmd-line-utils/readline/text.c index 81a468fdbda..d98b266edfe 100644 --- a/cmd-line-utils/readline/text.c +++ b/cmd-line-utils/readline/text.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #if defined (HAVE_UNISTD_H) # include diff --git a/cmd-line-utils/readline/tilde.c b/cmd-line-utils/readline/tilde.c index fab4aab65ad..456a6bcb357 100644 --- a/cmd-line-utils/readline/tilde.c +++ b/cmd-line-utils/readline/tilde.c @@ -19,9 +19,7 @@ along with Readline; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #if defined (HAVE_UNISTD_H) # ifdef _MINIX diff --git a/cmd-line-utils/readline/undo.c b/cmd-line-utils/readline/undo.c index df913195fad..947da3d00d0 100644 --- a/cmd-line-utils/readline/undo.c +++ b/cmd-line-utils/readline/undo.c @@ -22,9 +22,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/util.c b/cmd-line-utils/readline/util.c index 2a6e4e3398a..403b3d544d9 100644 --- a/cmd-line-utils/readline/util.c +++ b/cmd-line-utils/readline/util.c @@ -21,9 +21,7 @@ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include #include diff --git a/cmd-line-utils/readline/vi_mode.c b/cmd-line-utils/readline/vi_mode.c index 01df589f625..e8ad05d866f 100644 --- a/cmd-line-utils/readline/vi_mode.c +++ b/cmd-line-utils/readline/vi_mode.c @@ -31,9 +31,7 @@ #if defined (VI_MODE) -#if defined (HAVE_CONFIG_H) -# include -#endif +#include "config_readline.h" #include diff --git a/cmd-line-utils/readline/xmalloc.c b/cmd-line-utils/readline/xmalloc.c index 8985d340d39..698807addf9 100644 --- a/cmd-line-utils/readline/xmalloc.c +++ b/cmd-line-utils/readline/xmalloc.c @@ -20,9 +20,7 @@ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ #define READLINE_LIBRARY -#if defined (HAVE_CONFIG_H) -#include -#endif +#include "config_readline.h" #include diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result index 1e0b5deaf25..9b851d74a12 100644 --- a/mysql-test/r/type_timestamp.result +++ b/mysql-test/r/type_timestamp.result @@ -436,3 +436,50 @@ t1 CREATE TABLE "t1" ( ) set sql_mode=''; drop table t1; +create table t1 (a int auto_increment primary key, b int, c timestamp); +insert into t1 (a, b, c) values (1, 0, '2001-01-01 01:01:01'), +(2, 0, '2002-02-02 02:02:02'), (3, 0, '2003-03-03 03:03:03'); +select * from t1; +a b c +1 0 2001-01-01 01:01:01 +2 0 2002-02-02 02:02:02 +3 0 2003-03-03 03:03:03 +update t1 set b = 2, c = c where a = 2; +select * from t1; +a b c +1 0 2001-01-01 01:01:01 +2 2 2002-02-02 02:02:02 +3 0 2003-03-03 03:03:03 +insert into t1 (a) values (4); +select * from t1; +a b c +1 0 2001-01-01 01:01:01 +2 2 2002-02-02 02:02:02 +3 0 2003-03-03 03:03:03 +4 NULL 2001-09-09 04:46:59 +update t1 set c = '2004-04-04 04:04:04' where a = 4; +select * from t1; +a b c +1 0 2001-01-01 01:01:01 +2 2 2002-02-02 02:02:02 +3 0 2003-03-03 03:03:03 +4 NULL 2004-04-04 04:04:04 +insert into t1 (a) values (3), (5) on duplicate key update b = 3, c = c; +select * from t1; +a b c +1 0 2001-01-01 01:01:01 +2 2 2002-02-02 02:02:02 +3 3 2003-03-03 03:03:03 +4 NULL 2004-04-04 04:04:04 +5 NULL 2001-09-09 04:46:59 +insert into t1 (a, c) values (4, '2004-04-04 00:00:00'), +(6, '2006-06-06 06:06:06') on duplicate key update b = 4; +select * from t1; +a b c +1 0 2001-01-01 01:01:01 +2 2 2002-02-02 02:02:02 +3 3 2003-03-03 03:03:03 +4 4 2001-09-09 04:46:59 +5 NULL 2001-09-09 04:46:59 +6 NULL 2006-06-06 06:06:06 +drop table t1; diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test index 62e7510405d..01d18afc5af 100644 --- a/mysql-test/t/type_timestamp.test +++ b/mysql-test/t/type_timestamp.test @@ -300,3 +300,24 @@ show create table t1; # restore default mode set sql_mode=''; drop table t1; + +# +# Bug#7806 - insert on duplicate key and auto-update of timestamp +# +create table t1 (a int auto_increment primary key, b int, c timestamp); +insert into t1 (a, b, c) values (1, 0, '2001-01-01 01:01:01'), + (2, 0, '2002-02-02 02:02:02'), (3, 0, '2003-03-03 03:03:03'); +select * from t1; +update t1 set b = 2, c = c where a = 2; +select * from t1; +insert into t1 (a) values (4); +select * from t1; +update t1 set c = '2004-04-04 04:04:04' where a = 4; +select * from t1; +insert into t1 (a) values (3), (5) on duplicate key update b = 3, c = c; +select * from t1; +insert into t1 (a, c) values (4, '2004-04-04 00:00:00'), + (6, '2006-06-06 06:06:06') on duplicate key update b = 4; +select * from t1; +drop table t1; + diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 3b65cc6b195..d12b8d8f2cc 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -43,15 +43,29 @@ static bool check_view_insertability(TABLE_LIST *view, query_id_t query_id); #define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr,MYF(0)) #endif + /* Check if insert fields are correct. - Sets table->timestamp_field_type to TIMESTAMP_NO_AUTO_SET or leaves it - as is, depending on if timestamp should be updated or not. + + SYNOPSIS + check_insert_fields() + thd The current thread. + table The table for insert. + fields The insert fields. + values The insert values. + + NOTE + Clears TIMESTAMP_AUTO_SET_ON_INSERT from table->timestamp_field_type + or leaves it as is, depending on if timestamp should be updated or + not. + + RETURN + 0 OK + -1 Error */ -static int -check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, - List &values, ulong counter, bool check_unique) +static int check_insert_fields(THD *thd, TABLE *table, List &fields, + List &values) { TABLE *table= table_list->table; @@ -87,7 +101,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, return -1; } #endif - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; + (int) table->timestamp_field_type&= ~ (int) TIMESTAMP_AUTO_SET_ON_INSERT; } else { // Part field list @@ -134,7 +148,7 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, } if (table->timestamp_field && // Don't set timestamp if used table->timestamp_field->query_id == thd->query_id) - table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET; + (int) table->timestamp_field_type&= ~ (int) TIMESTAMP_AUTO_SET_ON_INSERT; } // For the values we need select_priv #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -153,6 +167,62 @@ check_insert_fields(THD *thd, TABLE_LIST *table_list, List &fields, } +/* + Check update fields for the timestamp field. + + SYNOPSIS + check_update_fields() + thd The current thread. + insert_table_list The insert table list. + table The table for update. + update_fields The update fields. + + NOTE + If the update fields include the timestamp field, + remove TIMESTAMP_AUTO_SET_ON_UPDATE from table->timestamp_field_type. + + RETURN + 0 OK + -1 Error +*/ + +static int check_update_fields(THD *thd, TABLE *table, + TABLE_LIST *insert_table_list, + List &update_fields) +{ + ulong timestamp_query_id; + LINT_INIT(timestamp_query_id); + + /* + Change the query_id for the timestamp column so that we can + check if this is modified directly. + */ + if (table->timestamp_field) + { + timestamp_query_id= table->timestamp_field->query_id; + table->timestamp_field->query_id= thd->query_id-1; + } + + /* + Check the fields we are going to modify. This will set the query_id + of all used fields to the threads query_id. + */ + if (setup_fields(thd, 0, insert_table_list, update_fields, 1, 0, 0)) + return -1; + + if (table->timestamp_field) + { + /* Don't set timestamp column if this is modified. */ + if (table->timestamp_field->query_id == thd->query_id) + (int) table->timestamp_field_type&= ~ (int) TIMESTAMP_AUTO_SET_ON_UPDATE; + else + table->timestamp_field->query_id= timestamp_query_id; + } + + return 0; +} + + bool mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, List &values_list, @@ -696,6 +766,7 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, TABLE *table, !insert_into_view)) || (values && setup_fields(thd, 0, table_list, *values, 0, 0, 0)) || (duplic == DUP_UPDATE && + (check_update_fields(thd, table, insert_table_list, update_fields) || ((thd->lex->select_lex.no_wrap_view_item= 1, (res= setup_fields(thd, 0, table_list, update_fields, 1, 0, 0)), thd->lex->select_lex.no_wrap_view_item= 0, diff --git a/sql/table.h b/sql/table.h index 270ec313240..d00ac41140e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -73,6 +73,10 @@ typedef struct st_filesort_info /* Values in this enum are used to indicate during which operations value of TIMESTAMP field should be set to current timestamp. + WARNING: The values are used for bit operations. If you change the enum, + you must keep the bitwise relation of the values. For example: + (int) TIMESTAMP_AUTO_SET_ON_BOTH == + (int) TIMESTAMP_AUTO_SET_ON_INSERT | (int) TIMESTAMP_AUTO_SET_ON_UPDATE. */ enum timestamp_auto_set_type {