summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mysql_com.h2
-rw-r--r--mysql-test/include/function_defaults.inc1166
-rw-r--r--mysql-test/include/function_defaults_notembedded.inc94
-rw-r--r--mysql-test/r/create.result4
-rw-r--r--mysql-test/r/function_defaults.result3067
-rw-r--r--mysql-test/r/function_defaults_notembedded.result171
-rw-r--r--mysql-test/r/log_slow.result2
-rw-r--r--mysql-test/r/log_tables.result16
-rw-r--r--mysql-test/r/mysqldump.result4
-rw-r--r--mysql-test/r/system_mysql_db.result4
-rw-r--r--mysql-test/r/system_mysql_db_fix40123.result4
-rw-r--r--mysql-test/r/system_mysql_db_fix50030.result4
-rw-r--r--mysql-test/r/system_mysql_db_fix50117.result4
-rw-r--r--mysql-test/r/type_timestamp.result10
-rw-r--r--mysql-test/r/type_timestamp_hires.result8
-rw-r--r--mysql-test/std_data/onerow.xml13
-rw-r--r--mysql-test/suite/funcs_1/r/is_columns_mysql.result4
-rw-r--r--mysql-test/suite/rpl/r/rpl_function_defaults.result132
-rw-r--r--mysql-test/suite/rpl/t/rpl_function_defaults.test93
-rw-r--r--mysql-test/t/create.test4
-rw-r--r--mysql-test/t/function_defaults.test23
-rw-r--r--mysql-test/t/function_defaults_notembedded.test18
-rw-r--r--mysql-test/t/type_timestamp.test11
-rw-r--r--sql/event_db_repository.cc5
-rw-r--r--sql/field.cc157
-rw-r--r--sql/field.h72
-rw-r--r--sql/ha_ndbcluster.cc7
-rw-r--r--sql/ha_partition.cc22
-rw-r--r--sql/log_event.cc19
-rw-r--r--sql/log_event_old.cc36
-rw-r--r--sql/sp.cc1
-rw-r--r--sql/sp_head.cc4
-rw-r--r--sql/sql_base.cc47
-rw-r--r--sql/sql_base.h11
-rw-r--r--sql/sql_class.h10
-rw-r--r--sql/sql_expression_cache.cc2
-rw-r--r--sql/sql_insert.cc142
-rw-r--r--sql/sql_load.cc49
-rw-r--r--sql/sql_parse.cc25
-rw-r--r--sql/sql_partition.cc3
-rw-r--r--sql/sql_select.cc2
-rw-r--r--sql/sql_show.cc61
-rw-r--r--sql/sql_string.cc18
-rw-r--r--sql/sql_string.h1
-rw-r--r--sql/sql_table.cc89
-rw-r--r--sql/sql_table.h4
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_update.cc46
-rw-r--r--sql/sql_yacc.yy8
-rw-r--r--sql/table.cc129
-rw-r--r--sql/table.h41
-rw-r--r--storage/archive/ha_archive.cc2
-rw-r--r--storage/csv/ha_tina.cc6
-rw-r--r--storage/federated/ha_federated.cc2
-rw-r--r--storage/federatedx/ha_federatedx.cc2
-rw-r--r--storage/heap/ha_heap.cc4
-rw-r--r--storage/innobase/handler/ha_innodb.cc6
-rw-r--r--storage/maria/ha_maria.cc6
-rw-r--r--storage/myisam/ha_myisam.cc6
-rw-r--r--storage/myisammrg/ha_myisammrg.cc4
-rw-r--r--storage/xtradb/handler/ha_innodb.cc6
61 files changed, 5375 insertions, 540 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 0988d20f97f..80ce1b4b014 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -128,6 +128,8 @@ enum enum_server_command
reserved by MySQL Cluster */
#define FIELD_FLAGS_COLUMN_FORMAT 24 /* Field column format, bit 24-25,
reserved by MySQL Cluster */
+#define HAS_EXPLICIT_DEFAULT (1 << 26) /* An INSERT/UPDATE operation supplied
+ an explicit default value */
#define REFRESH_GRANT 1 /* Refresh grant tables */
#define REFRESH_LOG 2 /* Start on new log file */
diff --git a/mysql-test/include/function_defaults.inc b/mysql-test/include/function_defaults.inc
new file mode 100644
index 00000000000..e588c82df1b
--- /dev/null
+++ b/mysql-test/include/function_defaults.inc
@@ -0,0 +1,1166 @@
+SET TIME_ZONE = "+00:00";
+
+--echo #
+--echo # Test of errors for column data types that dont support function
+--echo # defaults.
+--echo #
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a BIT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a TINYINT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a SMALLINT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a MEDIUMINT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a INT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a BIGINT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a FLOAT DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a DECIMAL DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a DATE DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a TIME DEFAULT $current_timestamp );
+--error ER_INVALID_DEFAULT
+eval CREATE TABLE t1( a YEAR DEFAULT $current_timestamp );
+
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a BIT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a TINYINT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a SMALLINT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a MEDIUMINT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a INT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a BIGINT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a FLOAT ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a DECIMAL ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a DATE ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a TIME ON UPDATE $current_timestamp );
+--error ER_INVALID_ON_UPDATE
+eval CREATE TABLE t1( a YEAR ON UPDATE $current_timestamp );
+
+--echo #
+--echo # Test that the default clause behaves like NOW() regarding time zones.
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $timestamp NOT NULL DEFAULT $current_timestamp,
+ c $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ d $timestamp NULL,
+ e $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ f $datetime DEFAULT $current_timestamp,
+ g $datetime ON UPDATE $current_timestamp,
+ h $datetime
+);
+
+--echo # 2011-09-27 14:11:08 UTC
+SET TIMESTAMP = 1317132668.654321;
+SET @old_time_zone = @@TIME_ZONE;
+SET TIME_ZONE = "+05:00";
+
+eval INSERT INTO t1( d, h ) VALUES ( $now, $now );
+SELECT * FROM t1;
+
+--echo # 1989-05-13 01:02:03
+SET TIMESTAMP = 611017323.543212;
+eval UPDATE t1 SET d = $now, h = $now;
+SELECT * FROM t1;
+
+SET TIME_ZONE = @old_time_zone;
+DROP TABLE t1;
+
+--echo #
+--echo # Test of several TIMESTAMP columns with different function defaults.
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $timestamp NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ e $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ f INT
+);
+
+--echo # 2011-04-19 07:22:02 UTC
+SET TIMESTAMP = 1303197722.534231;
+
+INSERT INTO t1 ( f ) VALUES (1);
+SELECT * FROM t1;
+
+--echo # 2011-04-19 07:23:18 UTC
+SET TIMESTAMP = 1303197798.132435;
+
+UPDATE t1 SET f = 2;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of inserted values out of order.
+--echo #
+eval CREATE TABLE t1 (
+ a INT,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $timestamp NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ e $timestamp NULL,
+ f $datetime,
+ g $datetime DEFAULT $current_timestamp,
+ h $datetime ON UPDATE $current_timestamp,
+ i $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ j INT
+);
+
+--echo # 2011-04-19 07:22:02 UTC
+SET TIMESTAMP = 1303197722.534231;
+
+INSERT INTO t1 ( j, a ) VALUES ( 1, 1 );
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of ON DUPLICATE KEY UPDATE
+--echo #
+eval CREATE TABLE t1 (
+ a INT PRIMARY KEY,
+ b INT,
+ c $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ d $timestamp NOT NULL DEFAULT $current_timestamp,
+ e $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ f $timestamp NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+ g $timestamp NULL,
+ h $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ i $datetime DEFAULT $current_timestamp,
+ j $datetime ON UPDATE $current_timestamp,
+ k $datetime NULL,
+ l $datetime DEFAULT '1986-09-27 03:00:00.098765'
+);
+
+--echo # 1977-12-21 23:00:00 UTC
+SET TIMESTAMP = 251593200.192837;
+INSERT INTO t1(a) VALUES (1) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+
+--echo # 1975-05-21 23:00:00 UTC
+SET TIMESTAMP = 169945200.918273;
+INSERT INTO t1(a) VALUES (1) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+
+--echo # 1973-08-14 09:11:22 UTC
+SET TIMESTAMP = 114167482.534231;
+INSERT INTO t1(a) VALUES (2) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, c $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp );
+
+--echo # 2011-04-19 07:23:18 UTC
+SET TIMESTAMP = 1303197798.945156;
+
+INSERT INTO t1 VALUES
+ (1, 0, '2001-01-01 01:01:01.111111'),
+ (2, 0, '2002-02-02 02:02:02.222222'),
+ (3, 0, '2003-03-03 03:03:03.333333');
+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.444444' 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.444444'),
+ (6, '2006-06-06 06:06:06.666666')
+ON DUPLICATE KEY UPDATE b = 4;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+
+--echo #
+--echo # Test of REPLACE INTO executed as UPDATE.
+--echo #
+eval CREATE TABLE t1 (
+ a INT PRIMARY KEY,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ d $timestamp NOT NULL DEFAULT $current_timestamp,
+ e $datetime DEFAULT $current_timestamp,
+ f $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ g $datetime ON UPDATE $current_timestamp,
+ h $timestamp NULL,
+ i $datetime
+);
+
+--echo # 1970-09-21 09:11:12 UTC
+SET TIMESTAMP = 22756272.163584;
+
+REPLACE INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+
+--echo # 1970-11-10 14:16:17 UTC
+SET TIMESTAMP = 27094577.852954;
+
+
+REPLACE INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+
+--echo #
+--echo # Test of insertion of NULL, DEFAULT and an empty row for DEFAULT
+--echo # CURRENT_TIMESTAMP.
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $datetime DEFAULT $current_timestamp,
+ c INT
+);
+
+--echo # 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.163578;
+
+INSERT INTO t1 VALUES (NULL, NULL, 1), (DEFAULT, DEFAULT, 2);
+INSERT INTO t1 ( a, b, c ) VALUES (NULL, NULL, 3), (DEFAULT, DEFAULT, 4);
+SELECT * FROM t1;
+
+SET TIME_ZONE = "+03:00";
+SELECT * FROM t1;
+SET TIME_ZONE = "+00:00";
+
+DROP TABLE t1;
+
+--echo # 2011-04-20 07:05:39 UTC
+SET TIMESTAMP = 1303283139.195624;
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT '2010-10-11 12:34:56' ON UPDATE $current_timestamp,
+ b $datetime DEFAULT '2010-10-11 12:34:56'
+);
+
+INSERT INTO t1 VALUES (NULL, NULL), (DEFAULT, DEFAULT);
+INSERT INTO t1 ( a, b ) VALUES (NULL, NULL), (DEFAULT, DEFAULT);
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo # 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.136952;
+
+eval CREATE TABLE t1 (
+a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+b $timestamp NOT NULL DEFAULT $current_timestamp,
+c $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+d $timestamp NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+e $timestamp NULL,
+f $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+g $datetime DEFAULT $current_timestamp,
+h $datetime ON UPDATE $current_timestamp,
+i $datetime NULL,
+j $datetime DEFAULT '1986-09-27 03:00:00.098765'
+);
+
+INSERT INTO t1 VALUES ();
+
+INSERT INTO t1 SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of multiple-table UPDATE for DEFAULT CURRENT_TIMESTAMP
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $datetime DEFAULT $current_timestamp,
+ c INT
+);
+
+INSERT INTO t1 ( c ) VALUES (1);
+SELECT * FROM t1;
+
+--echo # 2011-04-20 17:06:13 UTC
+SET TIMESTAMP = 1303311973.163587;
+
+UPDATE t1 t11, t1 t12 SET t11.c = 1;
+SELECT * FROM t1;
+
+UPDATE t1 t11, t1 t12 SET t11.c = 2;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp,
+ b $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ c $datetime DEFAULT $current_timestamp,
+ d $datetime ON UPDATE $current_timestamp,
+ e INT
+);
+
+eval CREATE TABLE t2 (
+ f INT,
+ g $datetime ON UPDATE $current_timestamp,
+ h $datetime DEFAULT $current_timestamp,
+ i $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ j $timestamp NOT NULL DEFAULT $current_timestamp
+);
+
+--echo # 1995-03-11 00:02:03 UTC
+SET TIMESTAMP = 794880123.195676;
+
+INSERT INTO t1 ( e ) VALUES ( 1 ), ( 2 );
+
+INSERT INTO t2 ( f ) VALUES ( 1 ), ( 2 );
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+--echo # 1980-12-13 02:02:01 UTC
+SET TIMESTAMP = 345520921.196755;
+
+UPDATE t1, t2 SET t1.e = 3, t2.f = 4;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Test of multiple table update with temporary table and on the fly.
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ b $datetime ON UPDATE $current_timestamp,
+ c INT,
+ d INT
+);
+
+eval CREATE TABLE t2 (
+ a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ b $datetime ON UPDATE $current_timestamp,
+ c INT KEY,
+ d INT
+);
+
+INSERT INTO t1 ( c ) VALUES (1), (2);
+INSERT INTO t2 ( c ) VALUES (1), (2);
+
+--echo # Test of multiple table update done on the fly
+--echo # 2011-04-20 15:06:13 UTC
+SET TIMESTAMP = 1303311973.194685;
+UPDATE t1 JOIN t2 USING ( c ) SET t2.d = 1;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+--echo # Test of multiple table update done with temporary table.
+--echo # 1979-01-15 03:02:01
+SET TIMESTAMP = 285213721.134679;
+UPDATE t1 JOIN t2 USING ( c ) SET t1.d = 1;
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+
+--echo #
+--echo # Test of ON UPDATE CURRENT_TIMESTAMP.
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ b $datetime ON UPDATE $current_timestamp,
+ c INT
+);
+
+--echo # 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.794613;
+
+INSERT INTO t1 ( c ) VALUES ( 1 );
+SELECT * FROM t1;
+
+UPDATE t1 SET c = 1;
+SELECT * FROM t1;
+
+UPDATE t1 SET c = 2;
+SELECT * FROM t1;
+
+--echo #
+--echo # Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
+--echo #
+--echo # 2011-04-20 15:06:13 UTC
+SET TIMESTAMP = 1303311973.534231;
+
+UPDATE t1 t11, t1 t12 SET t11.c = 2;
+SELECT * FROM t1;
+
+UPDATE t1 t11, t1 t12 SET t11.c = 3;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of a multiple-table update where only one table is updated and
+--echo # the updated table has a primary key.
+--echo #
+eval CREATE TABLE t1 ( a INT, b INT, PRIMARY KEY (a) );
+INSERT INTO t1 VALUES (1, 1),(2, 2),(3, 3),(4, 4);
+
+eval CREATE TABLE t2 ( a INT, b INT );
+INSERT INTO t2 VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5);
+
+UPDATE t1, t2 SET t1.b = 100 WHERE t1.a = t2.a;
+
+SELECT * FROM t1;
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Test of ALTER TABLE, reordering columns.
+--echo #
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp, b INT );eval ALTER TABLE t1 MODIFY a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp AFTER b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp, c $timestamp NULL );eval ALTER TABLE t1 MODIFY b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp FIRST;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a INT, b $timestamp NULL );eval ALTER TABLE t1 MODIFY b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp FIRST;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp, b $timestamp NULL );eval ALTER TABLE t1 MODIFY a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp, b $timestamp NULL );eval ALTER TABLE t1 MODIFY a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $now, b INT, c $timestamp NULL );
+SHOW CREATE TABLE t1;eval ALTER TABLE t1 MODIFY a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp AFTER b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $now, b INT, c $timestamp NULL );eval ALTER TABLE t1 MODIFY c $timestamp NULL FIRST;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $now ON UPDATE $current_timestamp, b INT, c $timestamp NULL );
+SHOW CREATE TABLE t1;eval ALTER TABLE t1 MODIFY a $timestamp NOT NULL DEFAULT $now ON UPDATE $current_timestamp AFTER b;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $now ON UPDATE $current_timestamp, b INT, c $timestamp NULL );eval ALTER TABLE t1 MODIFY c $timestamp NULL FIRST;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # Test of ALTER TABLE, adding columns.
+--echo #
+eval CREATE TABLE t1 ( a INT );
+eval ALTER TABLE t1 ADD COLUMN b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo #
+--echo # Test of INSERT SELECT.
+--echo #
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ d $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp
+);
+
+eval CREATE TABLE t2 (
+ placeholder1 INT,
+ placeholder2 INT,
+ placeholder3 INT,
+ placeholder4 INT,
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ c $datetime,
+ d $datetime
+);
+
+--echo # 1977-08-16 15:30:01 UTC
+SET TIMESTAMP = 240589801.654312;
+
+INSERT INTO t2 (a, b, c, d) VALUES (
+ '1977-08-16 15:30:01.123456',
+ '1977-08-16 15:30:01.234567',
+ '1977-08-16 15:30:01.345678',
+ '1977-08-16 15:30:01.456789'
+);
+
+--echo # 1986-09-27 01:00:00 UTC
+SET TIMESTAMP = 528166800.132435;
+
+INSERT INTO t1 ( a, c ) SELECT a, c FROM t2;
+
+SELECT * FROM t1;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Test of CREATE TABLE SELECT.
+--echo #
+--echo # We test that the columns of the source table are not used to determine
+--echo # function defaults for the receiving table.
+--echo #
+
+--echo # 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.657898;
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $timestamp NOT NULL DEFAULT $current_timestamp,
+ c $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ d $timestamp NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+ e $timestamp NULL,
+ f $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ g $datetime DEFAULT $current_timestamp,
+ h $datetime ON UPDATE $current_timestamp,
+ i $datetime NULL,
+ j $datetime DEFAULT '1986-09-27 03:00:00.098765'
+);
+
+INSERT INTO t1 VALUES ();
+
+--echo # 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.164937;
+
+eval CREATE TABLE t2 SELECT a FROM t1; SHOW CREATE TABLE t2; SELECT * FROM t2;
+eval CREATE TABLE t3 SELECT b FROM t1; SHOW CREATE TABLE t3; SELECT * FROM t3;
+eval CREATE TABLE t4 SELECT c FROM t1; SHOW CREATE TABLE t4; SELECT * FROM t4;
+eval CREATE TABLE t5 SELECT d FROM t1; SHOW CREATE TABLE t5; SELECT * FROM t5;
+eval CREATE TABLE t6 SELECT e FROM t1; SHOW CREATE TABLE t6; SELECT * FROM t6;
+eval CREATE TABLE t7 SELECT f FROM t1; SHOW CREATE TABLE t7; SELECT * FROM t7;
+eval CREATE TABLE t8 SELECT g FROM t1; SHOW CREATE TABLE t8; SELECT * FROM t8;
+eval CREATE TABLE t9 SELECT h FROM t1; SHOW CREATE TABLE t9; SELECT * FROM t9;
+eval CREATE TABLE t10 SELECT i FROM t1; SHOW CREATE TABLE t10; SELECT * FROM t10;
+eval CREATE TABLE t11 SELECT j FROM t1; SHOW CREATE TABLE t11; SELECT * FROM t11;
+
+eval CREATE TABLE t12 (
+ k $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ l $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ m $timestamp NOT NULL DEFAULT $current_timestamp,
+ n $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ o $timestamp NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+ p $timestamp NULL,
+ q $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ r $datetime DEFAULT $current_timestamp,
+ s $datetime ON UPDATE $current_timestamp,
+ t $datetime NULL,
+ u $datetime DEFAULT '1986-09-27 03:00:00.098765'
+)
+SELECT * FROM t1;
+
+SHOW CREATE TABLE t12;
+
+DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12;
+
+--echo # 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.164953;
+eval CREATE TABLE t1 (
+ a $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $datetime DEFAULT $current_timestamp,
+ c $datetime ON UPDATE $current_timestamp,
+ d $datetime NULL,
+ e $datetime DEFAULT '1986-09-27 03:00:00.098765'
+);
+
+INSERT INTO t1 VALUES ();
+
+--echo # 1971-01-31 20:13:57 UTC
+SET TIMESTAMP = 34200837.915736;
+
+eval CREATE TABLE t2 SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+SELECT * FROM t2;
+
+eval CREATE TABLE t3 SELECT b FROM t1;
+SHOW CREATE TABLE t3;
+SELECT * FROM t3;
+
+eval CREATE TABLE t4 SELECT c FROM t1;
+SHOW CREATE TABLE t4;
+SELECT * FROM t4;
+
+eval CREATE TABLE t5 SELECT d FROM t1;
+SHOW CREATE TABLE t5;
+SELECT * FROM t5;
+
+eval CREATE TABLE t6 SELECT e FROM t1;
+SHOW CREATE TABLE t6;
+SELECT * FROM t6;
+
+DROP TABLE t1, t2, t3, t4, t5, t6;
+
+--echo #
+--echo # Test of a CREATE TABLE SELECT that also declared columns. In this case
+--echo # the function default should be de-activated during the execution of the
+--echo # CREATE TABLE statement.
+--echo #
+--echo # 1970-01-01 03:16:40
+SET TIMESTAMP = 1000.987654;
+eval CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES ( 1 ), ( 2 );
+
+eval CREATE TABLE t2 ( b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp) SELECT a FROM t1;
+
+SHOW CREATE TABLE t2;
+SET TIMESTAMP = 2000.876543;
+INSERT INTO t2( a ) VALUES ( 3 );
+SELECT * FROM t2;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Test of updating a view.
+--echo #
+eval CREATE TABLE t1 ( a INT, b $datetime DEFAULT $current_timestamp );
+eval CREATE TABLE t2 ( a INT, b $datetime ON UPDATE $current_timestamp );
+
+eval CREATE VIEW v1 AS SELECT * FROM t1;
+SHOW CREATE VIEW v1;
+
+eval CREATE VIEW v2 AS SELECT * FROM t2;
+SHOW CREATE VIEW v2;
+
+--echo # 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.348564;
+
+INSERT INTO v1 ( a ) VALUES ( 1 );
+INSERT INTO v2 ( a ) VALUES ( 1 );
+
+SELECT * FROM t1;
+SELECT * FROM v1;
+
+SELECT * FROM t2;
+SELECT * FROM v2;
+
+--echo # 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.567332;
+UPDATE v1 SET a = 2;
+UPDATE v2 SET a = 2;
+
+SELECT * FROM t1;
+SELECT * FROM v1;
+
+SELECT * FROM t2;
+SELECT * FROM v2;
+
+DROP VIEW v1, v2;
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Test with stored procedures.
+--echo #
+eval CREATE TABLE t1 (
+ a INT,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $timestamp NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ e $timestamp NULL,
+ f $datetime DEFAULT $current_timestamp,
+ g $datetime ON UPDATE $current_timestamp
+);
+CREATE PROCEDURE p1() INSERT INTO test.t1( a ) VALUES ( 1 );
+CREATE PROCEDURE p2() UPDATE t1 SET a = 2 WHERE a = 1;
+
+--echo # 1971-01-31 20:13:57 UTC
+SET TIMESTAMP = 34200837.876544;
+CALL p1();
+SELECT * FROM t1;
+
+--echo # 1970-04-11 21:13:57 UTC
+SET TIMESTAMP = 8712837.143546;
+CALL p2();
+SELECT * FROM t1;
+
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+
+--echo #
+--echo # Test with triggers.
+--echo #
+eval CREATE TABLE t1 (
+ a INT,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $timestamp NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ e $timestamp NULL,
+ f $datetime,
+ g $datetime DEFAULT $current_timestamp,
+ h $datetime ON UPDATE $current_timestamp,
+ i $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp
+);
+
+eval CREATE TABLE t2 ( a INT );
+
+DELIMITER |;
+eval CREATE TRIGGER t2_trg BEFORE INSERT ON t2 FOR EACH ROW
+BEGIN
+ INSERT INTO t1 ( a ) VALUES ( 1 );
+END|
+DELIMITER ;|
+
+--echo # 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.978675;
+
+INSERT INTO t2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+
+DROP TRIGGER t2_trg;
+
+DELIMITER |;
+eval CREATE TRIGGER t2_trg BEFORE INSERT ON t2 FOR EACH ROW
+BEGIN
+ UPDATE t1 SET a = 2;
+END|
+DELIMITER ;|
+
+--echo # 1970-04-11 21:13:57 UTC
+SET TIMESTAMP = 8712837.456789;
+
+INSERT INTO t2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Test where the assignment target is not a column.
+--echo #
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp );
+eval CREATE TABLE t2 ( a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp );
+eval CREATE TABLE t3 ( a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp );
+eval CREATE TABLE t4 ( a $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp );
+
+eval CREATE VIEW v1 AS SELECT a COLLATE latin1_german1_ci AS b FROM t1;
+eval CREATE VIEW v2 ( b ) AS SELECT a COLLATE latin1_german1_ci FROM t2;
+eval CREATE VIEW v3 AS SELECT a COLLATE latin1_german1_ci AS b FROM t3;
+eval CREATE VIEW v4 ( b ) AS SELECT a COLLATE latin1_german1_ci FROM t4;
+
+INSERT INTO v1 ( b ) VALUES ( '2007-10-24 00:03:34.010203' );
+SELECT a FROM t1;
+
+INSERT INTO v2 ( b ) VALUES ( '2007-10-24 00:03:34.010203' );
+SELECT a FROM t2;
+
+INSERT INTO t3 VALUES ();
+UPDATE v3 SET b = '2007-10-24 00:03:34.010203';
+SELECT a FROM t3;
+
+INSERT INTO t4 VALUES ();
+UPDATE v4 SET b = '2007-10-24 00:03:34.010203';
+SELECT a FROM t4;
+
+DROP VIEW v1, v2, v3, v4;
+DROP TABLE t1, t2, t3, t4;
+
+--echo #
+--echo # Test of LOAD DATA/XML INFILE
+--echo # This tests behavior of function defaults for TIMESTAMP and DATETIME
+--echo # columns. during LOAD ... INFILE.
+--echo # As can be seen here, a TIMESTAMP column with only ON UPDATE
+--echo # CURRENT_TIMESTAMP will still have CURRENT_TIMESTAMP inserted on LOAD
+--echo # ... INFILE if the value is missing. For DATETIME columns a NULL value
+--echo # is inserted instead.
+--echo #
+
+eval CREATE TABLE t1 (
+ a INT,
+ b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ c $timestamp NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ e $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ f $datetime,
+ g $datetime DEFAULT $current_timestamp,
+ h $datetime ON UPDATE $current_timestamp,
+ i $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp
+);
+
+eval CREATE TABLE t2 (
+ a $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ b $timestamp NOT NULL DEFAULT $current_timestamp,
+ c $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $current_timestamp,
+ d $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ e $datetime NOT NULL,
+ f $datetime NOT NULL DEFAULT '1977-01-02 12:13:14',
+ g $datetime DEFAULT $current_timestamp NOT NULL,
+ h $datetime ON UPDATE $current_timestamp NOT NULL,
+ i $datetime DEFAULT $current_timestamp ON UPDATE $current_timestamp NOT NULL
+);
+
+SELECT 1 INTO OUTFILE 't3.dat' FROM dual;
+
+SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+INTO OUTFILE 't4.dat'
+FROM dual;
+
+SELECT 1, 2 INTO OUTFILE 't5.dat' FROM dual;
+
+--echo # Mon Aug 1 15:11:19 2011 UTC
+SET TIMESTAMP = 1312211479.918273;
+
+LOAD DATA INFILE 't3.dat' INTO TABLE t1;
+--query_vertical SELECT * FROM t1
+
+LOAD DATA INFILE 't4.dat' INTO TABLE t2;
+SELECT a FROM t2;
+SELECT b FROM t2;
+SELECT c FROM t2;
+SELECT d FROM t2;
+--echo # As shown here, supplying a NULL value to a non-nullable
+--echo # column with no default value results in the zero date.
+SELECT e FROM t2;
+--echo # As shown here, supplying a NULL value to a non-nullable column with a
+--echo # default value results in the zero date.
+SELECT f FROM t2;
+--echo # As shown here, supplying a NULL value to a non-nullable column with a
+--echo # default function results in the zero date.
+SELECT g FROM t2;
+--echo # As shown here, supplying a NULL value to a non-nullable DATETIME ON
+--echo # UPDATE CURRENT_TIMESTAMP column with no default value results in the
+--echo # zero date.
+SELECT h FROM t2;
+SELECT i FROM t2;
+
+DELETE FROM t1;
+DELETE FROM t2;
+
+--echo # Read t3 file into t1
+--echo # The syntax will cause a different code path to be taken
+--echo # (read_fixed_length()) than under the LOAD ... INTO TABLE t1 command
+--echo # above. The code in this path is copy-pasted code from the path taken
+--echo # under the syntax used in the previous LOAD command.
+LOAD DATA INFILE 't3.dat' INTO TABLE t1
+FIELDS TERMINATED BY '' ENCLOSED BY '';
+
+SELECT b FROM t1;
+SELECT c FROM t1;
+SELECT d FROM t1;
+SELECT e FROM t1;
+--echo # Yes, a missing field cannot be NULL using this syntax, so it will
+--echo # zero date instead. Says a comment in read_fixed_length() : "No fields
+--echo # specified in fields_vars list can be NULL in this format."
+--echo # It appears to be by design. This is inconsistent with LOAD DATA INFILE
+--echo # syntax in previous test.
+SELECT f FROM t1;
+SELECT g FROM t1;
+--echo # See comment above "SELECT f FROM f1".
+SELECT h FROM t1;
+SELECT i FROM t1;
+DELETE FROM t1;
+
+LOAD DATA INFILE 't5.dat' INTO TABLE t1 ( a, @dummy );
+SELECT * FROM t1;
+SELECT @dummy;
+DELETE FROM t1;
+
+LOAD DATA INFILE 't3.dat' INTO TABLE t1 ( a ) SET c = '2005-06-06 08:09:10';
+SELECT * FROM t1;
+DELETE FROM t1;
+
+LOAD DATA INFILE 't3.dat' INTO TABLE t1 ( a ) SET g = '2005-06-06 08:09:10';
+SELECT * FROM t1;
+DELETE FROM t1;
+
+--echo # Load a static XML file
+LOAD XML INFILE '../../std_data/onerow.xml' INTO TABLE t1
+ROWS IDENTIFIED BY '<row>';
+
+--echo Missing tags are treated as NULL
+--query_vertical SELECT * FROM t1
+
+DROP TABLE t1, t2;
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+remove_file $MYSQLD_DATADIR/test/t3.dat;
+remove_file $MYSQLD_DATADIR/test/t4.dat;
+remove_file $MYSQLD_DATADIR/test/t5.dat;
+
+
+--echo #
+--echo # Similar LOAD DATA tests in another form
+--echo #
+--echo # All of this test portion has been run on a pre-WL5874 trunk
+--echo # (except that like_b and like_c didn't exist) and all result
+--echo # differences are a bug.
+--echo # Regarding like_b its definition is the same as b's except
+--echo # that the constant default is replaced with a function
+--echo # default. Our expectation is that like_b would behave
+--echo # like b: if b is set to NULL, or set to 0000-00-00, or set to
+--echo # its default, then the same should apply to like_b. Same for
+--echo # like_c vs c.
+
+--echo # Mon Aug 1 15:11:19 2011 UTC
+SET TIMESTAMP = 1312211479.089786;
+
+SELECT 1 INTO OUTFILE "file1.dat" FROM dual;
+SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+ INTO OUTFILE "file2.dat" FROM dual;
+
+--echo # Too short row
+
+eval
+CREATE TABLE t1 (
+ dummy INT,
+ a $datetime NULL DEFAULT NULL,
+ b $datetime NULL DEFAULT "2011-11-18",
+ like_b $datetime NULL DEFAULT $current_timestamp,
+ c $datetime NOT NULL DEFAULT "2011-11-18",
+ like_c $datetime NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NULL DEFAULT "2011-05-03" ON UPDATE $current_timestamp,
+ e $timestamp NOT NULL DEFAULT "2011-05-03",
+ f $timestamp NOT NULL DEFAULT $current_timestamp,
+ g $timestamp NULL DEFAULT NULL,
+ h INT NULL,
+ i INT NOT NULL DEFAULT 42
+);
+
+--echo # There is no promotion
+SHOW CREATE TABLE t1;
+
+LOAD DATA INFILE "file1.dat" INTO table t1;
+
+--echo # It is strange that "like_b" gets NULL when "b" gets 0. But
+--echo # this is consistent with how "a" gets NULL when "b" gets 0,
+--echo # with how "g" gets NULL when "d" gets 0, and with how "h" gets
+--echo # NULL when "i" gets 0. Looks like "DEFAULT
+--echo # <non-NULL-constant>" is changed to 0, whereas DEFAULT NULL
+--echo # and DEFAULT NOW are changed to NULL.
+--query_vertical SELECT * FROM t1
+delete from t1;
+
+alter table t1
+modify f TIMESTAMP NULL default CURRENT_TIMESTAMP;
+
+--echo # There is no promotion
+SHOW CREATE TABLE t1;
+
+LOAD DATA INFILE "file1.dat" INTO table t1;
+
+--query_vertical SELECT * FROM t1
+delete from t1;
+
+drop table t1;
+
+--echo # Conclusion derived from trunk's results:
+--echo # DATETIME DEFAULT <non-NULL-constant> (b,c) gets 0000-00-00,
+--echo # DATETIME DEFAULT NULL (a) gets NULL,
+--echo # TIMESTAMP NULL DEFAULT <non-NULL-constant> (d) gets 0000-00-00,
+--echo # TIMESTAMP NULL DEFAULT NULL (g) gets NULL,
+--echo # TIMESTAMP NULL DEFAULT NOW (f after ALTER) gets NULL,
+--echo # TIMESTAMP NOT NULL (f before ALTER, e) gets NOW.
+
+--echo ### Loading NULL ###
+
+eval
+CREATE TABLE t1 (
+ dummy INT,
+ a $datetime NULL DEFAULT NULL,
+ b $datetime NULL DEFAULT "2011-11-18",
+ like_b $datetime NULL DEFAULT $current_timestamp,
+ c $datetime NOT NULL DEFAULT "2011-11-18",
+ like_c $datetime NOT NULL DEFAULT $current_timestamp,
+ d $timestamp NULL DEFAULT "2011-05-03" ON UPDATE $current_timestamp,
+ e $timestamp NOT NULL DEFAULT "2011-05-03",
+ f $timestamp NOT NULL DEFAULT $current_timestamp,
+ g $timestamp NULL DEFAULT NULL,
+ h INT NULL,
+ i INT NOT NULL DEFAULT 42
+);
+
+--echo # There is no promotion
+SHOW CREATE TABLE t1;
+
+LOAD DATA INFILE "file2.dat" INTO table t1;
+
+--query_vertical SELECT * FROM t1
+delete from t1;
+
+alter table t1
+modify f TIMESTAMP NULL default CURRENT_TIMESTAMP;
+
+--echo # There is no promotion
+SHOW CREATE TABLE t1;
+
+LOAD DATA INFILE "file2.dat" INTO table t1;
+
+--query_vertical SELECT * FROM t1
+delete from t1;
+
+--echo # Conclusion derived from trunk's results:
+--echo # DATETIME NULL (a,b) gets NULL,
+--echo # DATETIME NOT NULL (c) gets 0000-00-00,
+--echo # TIMESTAMP NULL (d,f,g) gets NULL,
+--echo # TIMESTAMP NOT NULL (e) gets NOW.
+
+drop table t1;
+remove_file $MYSQLD_DATADIR/test/file1.dat;
+remove_file $MYSQLD_DATADIR/test/file2.dat;
+
+--echo #
+--echo # Test of updatable views with check options. The option can be violated
+--echo # using ON UPDATE updates which is very strange as this offers a loophole
+--echo # in this integrity check.
+--echo #
+SET TIME_ZONE = "+03:00";
+--echo # 1970-01-01 03:16:40
+SET TIMESTAMP = 1000.123456;
+
+eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp) ENGINE = INNODB;
+
+SHOW CREATE TABLE t1;
+
+INSERT INTO t1 ( a ) VALUES ( 1 );
+
+SELECT * FROM t1;
+
+eval CREATE VIEW v1 AS SELECT * FROM t1 WHERE b <= '1970-01-01 03:16:40.123456'
+WITH CHECK OPTION;
+
+SELECT * FROM v1;
+
+--echo # 1970-01-01 03:33:20
+SET TIMESTAMP = 2000.000234;
+
+--error ER_VIEW_CHECK_FAILED
+UPDATE v1 SET a = 2;
+SELECT * FROM t1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT '1973-08-14 09:11:22.089786' ON UPDATE $current_timestamp,
+ c INT KEY
+);
+--echo # 1973-08-14 09:11:22 UTC
+SET TIMESTAMP = 114167482.534231;
+INSERT INTO t1 ( c ) VALUES ( 1 );
+
+eval CREATE VIEW v1 AS
+SELECT *
+FROM t1
+WHERE a >= '1973-08-14 09:11:22'
+WITH LOCAL CHECK OPTION;
+
+SELECT * FROM v1;
+
+SET TIMESTAMP = 1.126789;
+
+--error ER_VIEW_CHECK_FAILED
+INSERT INTO v1 ( c ) VALUES ( 1 ) ON DUPLICATE KEY UPDATE c = 2;
+
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+--echo #
+--echo # Bug 13095459 - MULTI-TABLE UPDATE MODIFIES A ROW TWICE
+--echo #
+eval CREATE TABLE t1 (
+ a INT,
+ b INT,
+ ts $timestamp NOT NULL DEFAULT $current_timestamp ON UPDATE $current_timestamp,
+ PRIMARY KEY ( a, ts )
+) ENGINE = INNODB;
+INSERT INTO t1( a, b, ts ) VALUES ( 1, 0, '2000-09-28 17:44:34' );
+
+eval CREATE TABLE t2 ( a INT ) ENGINE = INNODB;
+INSERT INTO t2 VALUES ( 1 );
+
+UPDATE t1 STRAIGHT_JOIN t2
+SET t1.b = t1.b + 1
+WHERE t1.a = 1 AND t1.ts >= '2000-09-28 00:00:00';
+
+SELECT b FROM t1;
+
+DROP TABLE t1, t2;
+
+--echo #
+--echo # Bug#11745578: 17392: ALTER TABLE ADD COLUMN TIMESTAMP DEFAULT
+--echo # CURRENT_TIMESTAMP INSERTS ZERO
+--echo #
+SET timestamp = 1000;
+
+CREATE TABLE t1 ( b INT );
+INSERT INTO t1 VALUES (1);
+
+eval ALTER TABLE t1 ADD COLUMN a6 $datetime DEFAULT $now ON UPDATE $now FIRST;
+eval ALTER TABLE t1 ADD COLUMN a5 $datetime DEFAULT $now FIRST;
+eval ALTER TABLE t1 ADD COLUMN a4 $datetime ON UPDATE $now FIRST;
+
+eval ALTER TABLE t1 ADD COLUMN a3 $timestamp NOT NULL DEFAULT $now ON UPDATE $now FIRST;
+eval ALTER TABLE t1 ADD COLUMN a2 $timestamp NOT NULL DEFAULT $now FIRST;
+eval ALTER TABLE t1 ADD COLUMN a1 $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $now FIRST;
+
+eval ALTER TABLE t1 ADD COLUMN c1 $timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE $now AFTER b;
+eval ALTER TABLE t1 ADD COLUMN c2 $timestamp NOT NULL DEFAULT $now AFTER c1;
+eval ALTER TABLE t1 ADD COLUMN c3 $timestamp NOT NULL DEFAULT $now ON UPDATE $now AFTER c2;
+
+eval ALTER TABLE t1 ADD COLUMN c4 $datetime ON UPDATE $now AFTER c3;
+eval ALTER TABLE t1 ADD COLUMN c5 $datetime DEFAULT $now AFTER c4;
+eval ALTER TABLE t1 ADD COLUMN c6 $datetime DEFAULT $now ON UPDATE $now AFTER c5;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+
+eval CREATE TABLE t1 ( a $timestamp NOT NULL DEFAULT $now ON UPDATE $current_timestamp, b $datetime DEFAULT $now );
+INSERT INTO t1 VALUES ();
+
+SET timestamp = 1000000000;
+
+ALTER TABLE t1 MODIFY COLUMN a TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3);
+ALTER TABLE t1 MODIFY COLUMN b DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3);
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+
+eval CREATE TABLE t1 (
+ a $timestamp NOT NULL DEFAULT '1999-12-01 11:22:33' ON UPDATE $current_timestamp,
+ b $datetime DEFAULT '1999-12-01 11:22:33'
+);
+INSERT INTO t1 VALUES ();
+
+eval ALTER TABLE t1 MODIFY COLUMN a $timestamp DEFAULT $now;
+eval ALTER TABLE t1 MODIFY COLUMN b $datetime DEFAULT $now;
+INSERT INTO t1 VALUES ();
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/include/function_defaults_notembedded.inc b/mysql-test/include/function_defaults_notembedded.inc
new file mode 100644
index 00000000000..d9708c13da5
--- /dev/null
+++ b/mysql-test/include/function_defaults_notembedded.inc
@@ -0,0 +1,94 @@
+SET TIME_ZONE = "+00:00";
+
+--echo #
+--echo # Test of INSERT DELAYED ... SET ...
+--echo #
+
+--echo # 2011-04-19 08:02:40 UTC
+SET TIMESTAMP = 1303200160.123456;
+
+eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
+
+INSERT DELAYED INTO t1 SET a = 1;
+FLUSH TABLE t1;
+
+SELECT * FROM t1;
+SELECT * FROM t1 WHERE b = 0;
+
+INSERT DELAYED INTO t1 SET a = 2, b = '1980-01-02 10:20:30.405060';
+FLUSH TABLE t1;
+
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of INSERT DELAYED ... VALUES ...
+--echo #
+
+--echo # 2011-04-19 08:04:01 UTC
+SET TIMESTAMP = 1303200241.234567;
+
+eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
+
+INSERT DELAYED INTO t1 ( a ) VALUES (1);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+
+INSERT DELAYED INTO t1 VALUES (2, '1977-12-19 12:34:56.789123');
+FLUSH TABLE t1;
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of a delayed insert handler servicing two insert operations
+--echo # with different sets of active defaults.
+--echo #
+eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
+
+--connect(con1, localhost, root,,)
+--echo # 2011-04-19 08:04:01 UTC
+SET TIMESTAMP = 1303200241.345678;
+SET debug_sync = 'before_write_delayed SIGNAL parked WAIT_FOR go';
+--send INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3)
+
+--connection default
+SET debug_sync = 'now WAIT_FOR parked';
+
+--connect(con2, localhost, root,,)
+--echo # 2011-04-19 08:04:01 UTC
+SET TIME_ZONE="+03:00";
+SET TIMESTAMP = 1303200241.456789;
+--send INSERT DELAYED INTO t1 ( a, b ) VALUES (4, '1977-12-19 12:34:56.789123'), (5, '1977-12-19 12:34:57.891234'), (6, '1977-12-19 12:34:58.912345')
+
+--connection default
+SET debug_sync = 'now SIGNAL go';
+
+--let $wait_condition= SELECT COUNT(*) = 6 FROM t1
+--source include/wait_condition.inc
+
+--sorted_result
+SELECT * FROM t1;
+
+--disconnect con1
+--disconnect con2
+
+DROP TABLE t1;
+
+--echo #
+--echo # Test of early activation of function defaults.
+--echo #
+
+eval CREATE TABLE t1 ( a INT, b $timestamp NOT NULL DEFAULT CURRENT_$timestamp ON UPDATE CURRENT_$timestamp);
+
+SET TIMESTAMP = 1317235172.987654; # 2011-09-28 18:39:32 UTC
+INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
+
+SET TIMESTAMP = 385503754.876543; # 1982-03-20 20:22:34 UTC
+INSERT DELAYED INTO t1 ( a ) VALUES (4), (5), (6);
+
+FLUSH TABLE t1;
+SELECT * FROM t1;
+
+DROP TABLE t1;
diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index ba52959be84..7102968a8d7 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -55,9 +55,9 @@ ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` int);
ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long
create table t1 (a datetime default now());
-ERROR 42000: Invalid default value for 'a'
+drop table t1;
create table t1 (a datetime on update now());
-ERROR HY000: Invalid ON UPDATE clause for 'a' column
+drop table t1;
create table t1 (a int default 100 auto_increment);
ERROR 42000: Invalid default value for 'a'
create table t1 (a tinyint default 1000);
diff --git a/mysql-test/r/function_defaults.result b/mysql-test/r/function_defaults.result
new file mode 100644
index 00000000000..27b9ee0a323
--- /dev/null
+++ b/mysql-test/r/function_defaults.result
@@ -0,0 +1,3067 @@
+#
+# Test of function defaults for any server, including embedded.
+#
+#
+# Function defaults run 1. No microsecond precision.
+#
+SET TIME_ZONE = "+00:00";
+#
+# Test of errors for column data types that dont support function
+# defaults.
+#
+CREATE TABLE t1( a BIT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a TINYINT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a SMALLINT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a MEDIUMINT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a INT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a BIGINT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a FLOAT DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a DECIMAL DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a DATE DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a TIME DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a YEAR DEFAULT CURRENT_TIMESTAMP );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a BIT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a TINYINT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a SMALLINT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a MEDIUMINT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a INT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a BIGINT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a FLOAT ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a DECIMAL ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a DATE ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a TIME ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a YEAR ON UPDATE CURRENT_TIMESTAMP );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+#
+# Test that the default clause behaves like NOW() regarding time zones.
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+d TIMESTAMP NULL,
+e DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+f DATETIME DEFAULT CURRENT_TIMESTAMP,
+g DATETIME ON UPDATE CURRENT_TIMESTAMP,
+h DATETIME
+);
+# 2011-09-27 14:11:08 UTC
+SET TIMESTAMP = 1317132668.654321;
+SET @old_time_zone = @@TIME_ZONE;
+SET TIME_ZONE = "+05:00";
+INSERT INTO t1( d, h ) VALUES ( NOW(), NOW() );
+SELECT * FROM t1;
+a b c d e f g h
+2011-09-27 19:11:08 2011-09-27 19:11:08 0000-00-00 00:00:00 2011-09-27 19:11:08 2011-09-27 19:11:08 2011-09-27 19:11:08 NULL 2011-09-27 19:11:08
+# 1989-05-13 01:02:03
+SET TIMESTAMP = 611017323.543212;
+UPDATE t1 SET d = NOW(), h = NOW();
+SELECT * FROM t1;
+a b c d e f g h
+1989-05-13 04:02:03 2011-09-27 19:11:08 1989-05-13 04:02:03 1989-05-13 04:02:03 1989-05-13 04:02:03 2011-09-27 19:11:08 1989-05-13 04:02:03 1989-05-13 04:02:03
+SET TIME_ZONE = @old_time_zone;
+DROP TABLE t1;
+#
+# Test of several TIMESTAMP columns with different function defaults.
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+f INT
+);
+# 2011-04-19 07:22:02 UTC
+SET TIMESTAMP = 1303197722.534231;
+INSERT INTO t1 ( f ) VALUES (1);
+SELECT * FROM t1;
+a b c d e f
+2011-04-19 07:22:02 2011-04-19 07:22:02 2011-04-19 07:22:02 0000-00-00 00:00:00 0000-00-00 00:00:00 1
+# 2011-04-19 07:23:18 UTC
+SET TIMESTAMP = 1303197798.132435;
+UPDATE t1 SET f = 2;
+SELECT * FROM t1;
+a b c d e f
+2011-04-19 07:23:18 2011-04-19 07:23:18 2011-04-19 07:22:02 2011-04-19 07:23:18 2011-04-19 07:23:18 2
+DROP TABLE t1;
+#
+# Test of inserted values out of order.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NULL,
+f DATETIME,
+g DATETIME DEFAULT CURRENT_TIMESTAMP,
+h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+j INT
+);
+# 2011-04-19 07:22:02 UTC
+SET TIMESTAMP = 1303197722.534231;
+INSERT INTO t1 ( j, a ) VALUES ( 1, 1 );
+SELECT * FROM t1;
+a b c d e f g h i j
+1 2011-04-19 07:22:02 2011-04-19 07:22:02 0000-00-00 00:00:00 NULL NULL 2011-04-19 07:22:02 NULL 2011-04-19 07:22:02 1
+DROP TABLE t1;
+#
+# Test of ON DUPLICATE KEY UPDATE
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY,
+b INT,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+e TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+f TIMESTAMP NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+g TIMESTAMP NULL,
+h DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME DEFAULT CURRENT_TIMESTAMP,
+j DATETIME ON UPDATE CURRENT_TIMESTAMP,
+k DATETIME NULL,
+l DATETIME DEFAULT '1986-09-27 03:00:00.098765'
+);
+# 1977-12-21 23:00:00 UTC
+SET TIMESTAMP = 251593200.192837;
+INSERT INTO t1(a) VALUES (1) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+a b c d e f g h i j k l
+1 NULL 1977-12-21 23:00:00 1977-12-21 23:00:00 0000-00-00 00:00:00 1986-09-27 03:00:00 NULL 1977-12-21 23:00:00 1977-12-21 23:00:00 NULL NULL 1986-09-27 03:00:00
+# 1975-05-21 23:00:00 UTC
+SET TIMESTAMP = 169945200.918273;
+INSERT INTO t1(a) VALUES (1) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+a b c d e f g h i j k l
+1 2 1975-05-21 23:00:00 1977-12-21 23:00:00 1975-05-21 23:00:00 1986-09-27 03:00:00 NULL 1975-05-21 23:00:00 1977-12-21 23:00:00 1975-05-21 23:00:00 NULL 1986-09-27 03:00:00
+# 1973-08-14 09:11:22 UTC
+SET TIMESTAMP = 114167482.534231;
+INSERT INTO t1(a) VALUES (2) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+a b c d e f g h i j k l
+1 2 1975-05-21 23:00:00 1977-12-21 23:00:00 1975-05-21 23:00:00 1986-09-27 03:00:00 NULL 1975-05-21 23:00:00 1977-12-21 23:00:00 1975-05-21 23:00:00 NULL 1986-09-27 03:00:00
+2 NULL 1973-08-14 09:11:22 1973-08-14 09:11:22 0000-00-00 00:00:00 1986-09-27 03:00:00 NULL 1973-08-14 09:11:22 1973-08-14 09:11:22 NULL NULL 1986-09-27 03:00:00
+DROP TABLE t1;
+CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
+# 2011-04-19 07:23:18 UTC
+SET TIMESTAMP = 1303197798.945156;
+INSERT INTO t1 VALUES
+(1, 0, '2001-01-01 01:01:01.111111'),
+(2, 0, '2002-02-02 02:02:02.222222'),
+(3, 0, '2003-03-03 03:03:03.333333');
+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 2011-04-19 07:23:18
+UPDATE t1 SET c = '2004-04-04 04:04:04.444444' 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 2011-04-19 07:23:18
+INSERT INTO t1 (a, c) VALUES
+(4, '2004-04-04 00:00:00.444444'),
+(6, '2006-06-06 06:06:06.666666')
+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 2011-04-19 07:23:18
+5 NULL 2011-04-19 07:23:18
+6 NULL 2006-06-06 06:06:06
+DROP TABLE t1;
+#
+# Test of REPLACE INTO executed as UPDATE.
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+e DATETIME DEFAULT CURRENT_TIMESTAMP,
+f TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+g DATETIME ON UPDATE CURRENT_TIMESTAMP,
+h TIMESTAMP NULL,
+i DATETIME
+);
+# 1970-09-21 09:11:12 UTC
+SET TIMESTAMP = 22756272.163584;
+REPLACE INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+1 1970-09-21 09:11:12 1970-09-21 09:11:12 1970-09-21 09:11:12 1970-09-21 09:11:12 0000-00-00 00:00:00 NULL NULL NULL
+# 1970-11-10 14:16:17 UTC
+SET TIMESTAMP = 27094577.852954;
+REPLACE INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+1 1970-11-10 14:16:17 1970-11-10 14:16:17 1970-11-10 14:16:17 1970-11-10 14:16:17 0000-00-00 00:00:00 NULL NULL NULL
+DROP TABLE t1;
+#
+# Test of insertion of NULL, DEFAULT and an empty row for DEFAULT
+# CURRENT_TIMESTAMP.
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME DEFAULT CURRENT_TIMESTAMP,
+c INT
+);
+# 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.163578;
+INSERT INTO t1 VALUES (NULL, NULL, 1), (DEFAULT, DEFAULT, 2);
+INSERT INTO t1 ( a, b, c ) VALUES (NULL, NULL, 3), (DEFAULT, DEFAULT, 4);
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41 NULL 1
+2011-04-20 09:53:41 2011-04-20 09:53:41 2
+2011-04-20 09:53:41 NULL 3
+2011-04-20 09:53:41 2011-04-20 09:53:41 4
+SET TIME_ZONE = "+03:00";
+SELECT * FROM t1;
+a b c
+2011-04-20 12:53:41 NULL 1
+2011-04-20 12:53:41 2011-04-20 09:53:41 2
+2011-04-20 12:53:41 NULL 3
+2011-04-20 12:53:41 2011-04-20 09:53:41 4
+SET TIME_ZONE = "+00:00";
+DROP TABLE t1;
+# 2011-04-20 07:05:39 UTC
+SET TIMESTAMP = 1303283139.195624;
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT '2010-10-11 12:34:56' ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME DEFAULT '2010-10-11 12:34:56'
+);
+INSERT INTO t1 VALUES (NULL, NULL), (DEFAULT, DEFAULT);
+INSERT INTO t1 ( a, b ) VALUES (NULL, NULL), (DEFAULT, DEFAULT);
+SELECT * FROM t1;
+a b
+2011-04-20 07:05:39 NULL
+2010-10-11 12:34:56 2010-10-11 12:34:56
+2011-04-20 07:05:39 NULL
+2010-10-11 12:34:56 2010-10-11 12:34:56
+DROP TABLE t1;
+# 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.136952;
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+e TIMESTAMP NULL,
+f DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+g DATETIME DEFAULT CURRENT_TIMESTAMP,
+h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME NULL,
+j DATETIME DEFAULT '1986-09-27 03:00:00.098765'
+);
+INSERT INTO t1 VALUES ();
+INSERT INTO t1 SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL;
+SELECT * FROM t1;
+a b c d e f g h i j
+2011-04-20 09:53:41 2011-04-20 09:53:41 0000-00-00 00:00:00 1986-09-27 03:00:00 NULL 2011-04-20 09:53:41 2011-04-20 09:53:41 NULL NULL 1986-09-27 03:00:00
+2011-04-20 09:53:41 2011-04-20 09:53:41 2011-04-20 09:53:41 2011-04-20 09:53:41 NULL NULL NULL NULL NULL NULL
+DROP TABLE t1;
+#
+# Test of multiple-table UPDATE for DEFAULT CURRENT_TIMESTAMP
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME DEFAULT CURRENT_TIMESTAMP,
+c INT
+);
+INSERT INTO t1 ( c ) VALUES (1);
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41 2011-04-20 09:53:41 1
+# 2011-04-20 17:06:13 UTC
+SET TIMESTAMP = 1303311973.163587;
+UPDATE t1 t11, t1 t12 SET t11.c = 1;
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41 2011-04-20 09:53:41 1
+UPDATE t1 t11, t1 t12 SET t11.c = 2;
+SELECT * FROM t1;
+a b c
+2011-04-20 15:06:13 2011-04-20 09:53:41 2
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+c DATETIME DEFAULT CURRENT_TIMESTAMP,
+d DATETIME ON UPDATE CURRENT_TIMESTAMP,
+e INT
+);
+CREATE TABLE t2 (
+f INT,
+g DATETIME ON UPDATE CURRENT_TIMESTAMP,
+h DATETIME DEFAULT CURRENT_TIMESTAMP,
+i TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+j TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
+);
+# 1995-03-11 00:02:03 UTC
+SET TIMESTAMP = 794880123.195676;
+INSERT INTO t1 ( e ) VALUES ( 1 ), ( 2 );
+INSERT INTO t2 ( f ) VALUES ( 1 ), ( 2 );
+SELECT * FROM t1;
+a b c d e
+1995-03-11 00:02:03 0000-00-00 00:00:00 1995-03-11 00:02:03 NULL 1
+1995-03-11 00:02:03 0000-00-00 00:00:00 1995-03-11 00:02:03 NULL 2
+SELECT * FROM t2;
+f g h i j
+1 NULL 1995-03-11 00:02:03 0000-00-00 00:00:00 1995-03-11 00:02:03
+2 NULL 1995-03-11 00:02:03 0000-00-00 00:00:00 1995-03-11 00:02:03
+# 1980-12-13 02:02:01 UTC
+SET TIMESTAMP = 345520921.196755;
+UPDATE t1, t2 SET t1.e = 3, t2.f = 4;
+SELECT * FROM t1;
+a b c d e
+1995-03-11 00:02:03 1980-12-13 02:02:01 1995-03-11 00:02:03 1980-12-13 02:02:01 3
+1995-03-11 00:02:03 1980-12-13 02:02:01 1995-03-11 00:02:03 1980-12-13 02:02:01 3
+SELECT * FROM t2;
+f g h i j
+4 1980-12-13 02:02:01 1995-03-11 00:02:03 1980-12-13 02:02:01 1995-03-11 00:02:03
+4 1980-12-13 02:02:01 1995-03-11 00:02:03 1980-12-13 02:02:01 1995-03-11 00:02:03
+DROP TABLE t1, t2;
+#
+# Test of multiple table update with temporary table and on the fly.
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME ON UPDATE CURRENT_TIMESTAMP,
+c INT,
+d INT
+);
+CREATE TABLE t2 (
+a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME ON UPDATE CURRENT_TIMESTAMP,
+c INT KEY,
+d INT
+);
+INSERT INTO t1 ( c ) VALUES (1), (2);
+INSERT INTO t2 ( c ) VALUES (1), (2);
+# Test of multiple table update done on the fly
+# 2011-04-20 15:06:13 UTC
+SET TIMESTAMP = 1303311973.194685;
+UPDATE t1 JOIN t2 USING ( c ) SET t2.d = 1;
+SELECT * FROM t1;
+a b c d
+0000-00-00 00:00:00 NULL 1 NULL
+0000-00-00 00:00:00 NULL 2 NULL
+SELECT * FROM t2;
+a b c d
+2011-04-20 15:06:13 2011-04-20 15:06:13 1 1
+2011-04-20 15:06:13 2011-04-20 15:06:13 2 1
+# Test of multiple table update done with temporary table.
+# 1979-01-15 03:02:01
+SET TIMESTAMP = 285213721.134679;
+UPDATE t1 JOIN t2 USING ( c ) SET t1.d = 1;
+SELECT * FROM t1;
+a b c d
+1979-01-15 02:02:01 1979-01-15 02:02:01 1 1
+1979-01-15 02:02:01 1979-01-15 02:02:01 2 1
+SELECT * FROM t2;
+a b c d
+2011-04-20 15:06:13 2011-04-20 15:06:13 1 1
+2011-04-20 15:06:13 2011-04-20 15:06:13 2 1
+DROP TABLE t1, t2;
+#
+# Test of ON UPDATE CURRENT_TIMESTAMP.
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME ON UPDATE CURRENT_TIMESTAMP,
+c INT
+);
+# 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.794613;
+INSERT INTO t1 ( c ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c
+0000-00-00 00:00:00 NULL 1
+UPDATE t1 SET c = 1;
+SELECT * FROM t1;
+a b c
+0000-00-00 00:00:00 NULL 1
+UPDATE t1 SET c = 2;
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41 2011-04-20 09:53:41 2
+#
+# Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
+#
+# 2011-04-20 15:06:13 UTC
+SET TIMESTAMP = 1303311973.534231;
+UPDATE t1 t11, t1 t12 SET t11.c = 2;
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41 2011-04-20 09:53:41 2
+UPDATE t1 t11, t1 t12 SET t11.c = 3;
+SELECT * FROM t1;
+a b c
+2011-04-20 15:06:13 2011-04-20 15:06:13 3
+DROP TABLE t1;
+#
+# Test of a multiple-table update where only one table is updated and
+# the updated table has a primary key.
+#
+CREATE TABLE t1 ( a INT, b INT, PRIMARY KEY (a) );
+INSERT INTO t1 VALUES (1, 1),(2, 2),(3, 3),(4, 4);
+CREATE TABLE t2 ( a INT, b INT );
+INSERT INTO t2 VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5);
+UPDATE t1, t2 SET t1.b = 100 WHERE t1.a = t2.a;
+SELECT * FROM t1;
+a b
+1 100
+2 100
+3 100
+4 100
+SELECT * FROM t2;
+a b
+1 1
+2 2
+3 3
+4 4
+5 5
+DROP TABLE t1, t2;
+#
+# Test of ALTER TABLE, reordering columns.
+#
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b INT );
+ALTER TABLE t1 MODIFY a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, c TIMESTAMP NULL );
+ALTER TABLE t1 MODIFY b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `a` int(11) DEFAULT NULL,
+ `c` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a INT, b TIMESTAMP NULL );
+ALTER TABLE t1 MODIFY b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b TIMESTAMP NULL );
+ALTER TABLE t1 MODIFY a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp NULL DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, b TIMESTAMP NULL );
+ALTER TABLE t1 MODIFY a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp NULL DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW(), b INT, c TIMESTAMP NULL );
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `b` int(11) DEFAULT NULL,
+ `c` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `c` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW(), b INT, c TIMESTAMP NULL );
+ALTER TABLE t1 MODIFY c TIMESTAMP NULL FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` timestamp NULL DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP, b INT, c TIMESTAMP NULL );
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `b` int(11) DEFAULT NULL,
+ `c` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY a TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `c` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP, b INT, c TIMESTAMP NULL );
+ALTER TABLE t1 MODIFY c TIMESTAMP NULL FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` timestamp NULL DEFAULT NULL,
+ `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# Test of ALTER TABLE, adding columns.
+#
+CREATE TABLE t1 ( a INT );
+ALTER TABLE t1 ADD COLUMN b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# Test of INSERT SELECT.
+#
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+d DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
+CREATE TABLE t2 (
+placeholder1 INT,
+placeholder2 INT,
+placeholder3 INT,
+placeholder4 INT,
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00',
+c DATETIME,
+d DATETIME
+);
+# 1977-08-16 15:30:01 UTC
+SET TIMESTAMP = 240589801.654312;
+INSERT INTO t2 (a, b, c, d) VALUES (
+'1977-08-16 15:30:01.123456',
+'1977-08-16 15:30:01.234567',
+'1977-08-16 15:30:01.345678',
+'1977-08-16 15:30:01.456789'
+);
+# 1986-09-27 01:00:00 UTC
+SET TIMESTAMP = 528166800.132435;
+INSERT INTO t1 ( a, c ) SELECT a, c FROM t2;
+SELECT * FROM t1;
+a b c d
+1977-08-16 15:30:01 1986-09-27 01:00:00 1977-08-16 15:30:01 1986-09-27 01:00:00
+DROP TABLE t1, t2;
+#
+# Test of CREATE TABLE SELECT.
+#
+# We test that the columns of the source table are not used to determine
+# function defaults for the receiving table.
+#
+# 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.657898;
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+e TIMESTAMP NULL,
+f DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+g DATETIME DEFAULT CURRENT_TIMESTAMP,
+h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME NULL,
+j DATETIME DEFAULT '1986-09-27 03:00:00.098765'
+);
+INSERT INTO t1 VALUES ();
+# 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.164937;
+CREATE TABLE t2 SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+a
+1970-04-11 20:13:57
+CREATE TABLE t3 SELECT b FROM t1;
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `b` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t3;
+b
+1970-04-11 20:13:57
+CREATE TABLE t4 SELECT c FROM t1;
+SHOW CREATE TABLE t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `c` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t4;
+c
+0000-00-00 00:00:00
+CREATE TABLE t5 SELECT d FROM t1;
+SHOW CREATE TABLE t5;
+Table Create Table
+t5 CREATE TABLE `t5` (
+ `d` timestamp NOT NULL DEFAULT '1986-09-27 03:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t5;
+d
+1986-09-27 03:00:00
+CREATE TABLE t6 SELECT e FROM t1;
+SHOW CREATE TABLE t6;
+Table Create Table
+t6 CREATE TABLE `t6` (
+ `e` timestamp NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t6;
+e
+NULL
+CREATE TABLE t7 SELECT f FROM t1;
+SHOW CREATE TABLE t7;
+Table Create Table
+t7 CREATE TABLE `t7` (
+ `f` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t7;
+f
+1970-04-11 20:13:57
+CREATE TABLE t8 SELECT g FROM t1;
+SHOW CREATE TABLE t8;
+Table Create Table
+t8 CREATE TABLE `t8` (
+ `g` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t8;
+g
+1970-04-11 20:13:57
+CREATE TABLE t9 SELECT h FROM t1;
+SHOW CREATE TABLE t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `h` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t9;
+h
+NULL
+CREATE TABLE t10 SELECT i FROM t1;
+SHOW CREATE TABLE t10;
+Table Create Table
+t10 CREATE TABLE `t10` (
+ `i` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t10;
+i
+NULL
+CREATE TABLE t11 SELECT j FROM t1;
+SHOW CREATE TABLE t11;
+Table Create Table
+t11 CREATE TABLE `t11` (
+ `j` datetime DEFAULT '1986-09-27 03:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t11;
+j
+1986-09-27 03:00:00
+CREATE TABLE t12 (
+k TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+l TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+m TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+n TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+o TIMESTAMP NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+p TIMESTAMP NULL,
+q DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+r DATETIME DEFAULT CURRENT_TIMESTAMP,
+s DATETIME ON UPDATE CURRENT_TIMESTAMP,
+t DATETIME NULL,
+u DATETIME DEFAULT '1986-09-27 03:00:00.098765'
+)
+SELECT * FROM t1;
+SHOW CREATE TABLE t12;
+Table Create Table
+t12 CREATE TABLE `t12` (
+ `k` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `l` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `m` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `n` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `o` timestamp NOT NULL DEFAULT '1986-09-27 03:00:00',
+ `p` timestamp NULL DEFAULT NULL,
+ `q` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `r` datetime DEFAULT CURRENT_TIMESTAMP,
+ `s` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+ `t` datetime DEFAULT NULL,
+ `u` datetime DEFAULT '1986-09-27 03:00:00',
+ `a` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `b` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `c` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
+ `d` timestamp NOT NULL DEFAULT '1986-09-27 03:00:00',
+ `e` timestamp NULL DEFAULT NULL,
+ `f` datetime DEFAULT NULL,
+ `g` datetime DEFAULT NULL,
+ `h` datetime DEFAULT NULL,
+ `i` datetime DEFAULT NULL,
+ `j` datetime DEFAULT '1986-09-27 03:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12;
+# 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.164953;
+CREATE TABLE t1 (
+a DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME DEFAULT CURRENT_TIMESTAMP,
+c DATETIME ON UPDATE CURRENT_TIMESTAMP,
+d DATETIME NULL,
+e DATETIME DEFAULT '1986-09-27 03:00:00.098765'
+);
+INSERT INTO t1 VALUES ();
+# 1971-01-31 20:13:57 UTC
+SET TIMESTAMP = 34200837.915736;
+CREATE TABLE t2 SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+a
+1970-04-11 20:13:57
+CREATE TABLE t3 SELECT b FROM t1;
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `b` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t3;
+b
+1970-04-11 20:13:57
+CREATE TABLE t4 SELECT c FROM t1;
+SHOW CREATE TABLE t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `c` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t4;
+c
+NULL
+CREATE TABLE t5 SELECT d FROM t1;
+SHOW CREATE TABLE t5;
+Table Create Table
+t5 CREATE TABLE `t5` (
+ `d` datetime DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t5;
+d
+NULL
+CREATE TABLE t6 SELECT e FROM t1;
+SHOW CREATE TABLE t6;
+Table Create Table
+t6 CREATE TABLE `t6` (
+ `e` datetime DEFAULT '1986-09-27 03:00:00'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t6;
+e
+1986-09-27 03:00:00
+DROP TABLE t1, t2, t3, t4, t5, t6;
+#
+# Test of a CREATE TABLE SELECT that also declared columns. In this case
+# the function default should be de-activated during the execution of the
+# CREATE TABLE statement.
+#
+# 1970-01-01 03:16:40
+SET TIMESTAMP = 1000.987654;
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES ( 1 ), ( 2 );
+CREATE TABLE t2 ( b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SET TIMESTAMP = 2000.876543;
+INSERT INTO t2( a ) VALUES ( 3 );
+SELECT * FROM t2;
+b a
+0000-00-00 00:00:00 1
+0000-00-00 00:00:00 2
+1970-01-01 00:33:20 3
+DROP TABLE t1, t2;
+#
+# Test of updating a view.
+#
+CREATE TABLE t1 ( a INT, b DATETIME DEFAULT CURRENT_TIMESTAMP );
+CREATE TABLE t2 ( a INT, b DATETIME ON UPDATE CURRENT_TIMESTAMP );
+CREATE VIEW v1 AS SELECT * FROM t1;
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` latin1 latin1_swedish_ci
+CREATE VIEW v2 AS SELECT * FROM t2;
+SHOW CREATE VIEW v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a`,`t2`.`b` AS `b` from `t2` latin1 latin1_swedish_ci
+# 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.348564;
+INSERT INTO v1 ( a ) VALUES ( 1 );
+INSERT INTO v2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b
+1 1971-01-31 20:13:57
+SELECT * FROM v1;
+a b
+1 1971-01-31 20:13:57
+SELECT * FROM t2;
+a b
+1 NULL
+SELECT * FROM v2;
+a b
+1 NULL
+# 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.567332;
+UPDATE v1 SET a = 2;
+UPDATE v2 SET a = 2;
+SELECT * FROM t1;
+a b
+2 1971-01-31 20:13:57
+SELECT * FROM v1;
+a b
+2 1971-01-31 20:13:57
+SELECT * FROM t2;
+a b
+2 1970-04-11 20:13:57
+SELECT * FROM v2;
+a b
+2 1970-04-11 20:13:57
+DROP VIEW v1, v2;
+DROP TABLE t1, t2;
+#
+# Test with stored procedures.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NULL,
+f DATETIME DEFAULT CURRENT_TIMESTAMP,
+g DATETIME ON UPDATE CURRENT_TIMESTAMP
+);
+CREATE PROCEDURE p1() INSERT INTO test.t1( a ) VALUES ( 1 );
+CREATE PROCEDURE p2() UPDATE t1 SET a = 2 WHERE a = 1;
+# 1971-01-31 20:13:57 UTC
+SET TIMESTAMP = 34200837.876544;
+CALL p1();
+SELECT * FROM t1;
+a b c d e f g
+1 1971-01-31 20:13:57 1971-01-31 20:13:57 0000-00-00 00:00:00 NULL 1971-01-31 20:13:57 NULL
+# 1970-04-11 21:13:57 UTC
+SET TIMESTAMP = 8712837.143546;
+CALL p2();
+SELECT * FROM t1;
+a b c d e f g
+2 1970-04-11 20:13:57 1971-01-31 20:13:57 1970-04-11 20:13:57 NULL 1971-01-31 20:13:57 1970-04-11 20:13:57
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+#
+# Test with triggers.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NULL,
+f DATETIME,
+g DATETIME DEFAULT CURRENT_TIMESTAMP,
+h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
+CREATE TABLE t2 ( a INT );
+CREATE TRIGGER t2_trg BEFORE INSERT ON t2 FOR EACH ROW
+BEGIN
+INSERT INTO t1 ( a ) VALUES ( 1 );
+END|
+# 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.978675;
+INSERT INTO t2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+1 1971-01-31 20:13:57 1971-01-31 20:13:57 0000-00-00 00:00:00 NULL NULL 1971-01-31 20:13:57 NULL 1971-01-31 20:13:57
+DROP TRIGGER t2_trg;
+CREATE TRIGGER t2_trg BEFORE INSERT ON t2 FOR EACH ROW
+BEGIN
+UPDATE t1 SET a = 2;
+END|
+# 1970-04-11 21:13:57 UTC
+SET TIMESTAMP = 8712837.456789;
+INSERT INTO t2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+2 1970-04-11 20:13:57 1971-01-31 20:13:57 1970-04-11 20:13:57 NULL NULL 1971-01-31 20:13:57 1970-04-11 20:13:57 1970-04-11 20:13:57
+DROP TABLE t1, t2;
+#
+# Test where the assignment target is not a column.
+#
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
+CREATE TABLE t2 ( a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
+CREATE TABLE t3 ( a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP );
+CREATE TABLE t4 ( a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP );
+CREATE VIEW v1 AS SELECT a COLLATE latin1_german1_ci AS b FROM t1;
+CREATE VIEW v2 ( b ) AS SELECT a COLLATE latin1_german1_ci FROM t2;
+CREATE VIEW v3 AS SELECT a COLLATE latin1_german1_ci AS b FROM t3;
+CREATE VIEW v4 ( b ) AS SELECT a COLLATE latin1_german1_ci FROM t4;
+INSERT INTO v1 ( b ) VALUES ( '2007-10-24 00:03:34.010203' );
+SELECT a FROM t1;
+a
+2007-10-24 00:03:34
+INSERT INTO v2 ( b ) VALUES ( '2007-10-24 00:03:34.010203' );
+SELECT a FROM t2;
+a
+2007-10-24 00:03:34
+INSERT INTO t3 VALUES ();
+UPDATE v3 SET b = '2007-10-24 00:03:34.010203';
+SELECT a FROM t3;
+a
+2007-10-24 00:03:34
+INSERT INTO t4 VALUES ();
+UPDATE v4 SET b = '2007-10-24 00:03:34.010203';
+SELECT a FROM t4;
+a
+2007-10-24 00:03:34
+DROP VIEW v1, v2, v3, v4;
+DROP TABLE t1, t2, t3, t4;
+#
+# Test of LOAD DATA/XML INFILE
+# This tests behavior of function defaults for TIMESTAMP and DATETIME
+# columns. during LOAD ... INFILE.
+# As can be seen here, a TIMESTAMP column with only ON UPDATE
+# CURRENT_TIMESTAMP will still have CURRENT_TIMESTAMP inserted on LOAD
+# ... INFILE if the value is missing. For DATETIME columns a NULL value
+# is inserted instead.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+f DATETIME,
+g DATETIME DEFAULT CURRENT_TIMESTAMP,
+h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+);
+CREATE TABLE t2 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+c TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+d TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+e DATETIME NOT NULL,
+f DATETIME NOT NULL DEFAULT '1977-01-02 12:13:14',
+g DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL,
+h DATETIME ON UPDATE CURRENT_TIMESTAMP NOT NULL,
+i DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
+);
+SELECT 1 INTO OUTFILE 't3.dat' FROM dual;
+SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+INTO OUTFILE 't4.dat'
+FROM dual;
+SELECT 1, 2 INTO OUTFILE 't5.dat' FROM dual;
+# Mon Aug 1 15:11:19 2011 UTC
+SET TIMESTAMP = 1312211479.918273;
+LOAD DATA INFILE 't3.dat' INTO TABLE t1;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+SELECT * FROM t1;
+a 1
+b 2011-08-01 15:11:19
+c 2011-08-01 15:11:19
+d 2011-08-01 15:11:19
+e 2011-08-01 15:11:19
+f NULL
+g NULL
+h NULL
+i NULL
+LOAD DATA INFILE 't4.dat' INTO TABLE t2;
+Warnings:
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'e' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'f' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'g' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'h' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'i' at row 1
+SELECT a FROM t2;
+a
+2011-08-01 15:11:19
+SELECT b FROM t2;
+b
+2011-08-01 15:11:19
+SELECT c FROM t2;
+c
+2011-08-01 15:11:19
+SELECT d FROM t2;
+d
+2011-08-01 15:11:19
+# As shown here, supplying a NULL value to a non-nullable
+# column with no default value results in the zero date.
+SELECT e FROM t2;
+e
+0000-00-00 00:00:00
+# As shown here, supplying a NULL value to a non-nullable column with a
+# default value results in the zero date.
+SELECT f FROM t2;
+f
+0000-00-00 00:00:00
+# As shown here, supplying a NULL value to a non-nullable column with a
+# default function results in the zero date.
+SELECT g FROM t2;
+g
+0000-00-00 00:00:00
+# As shown here, supplying a NULL value to a non-nullable DATETIME ON
+# UPDATE CURRENT_TIMESTAMP column with no default value results in the
+# zero date.
+SELECT h FROM t2;
+h
+0000-00-00 00:00:00
+SELECT i FROM t2;
+i
+0000-00-00 00:00:00
+DELETE FROM t1;
+DELETE FROM t2;
+# Read t3 file into t1
+# The syntax will cause a different code path to be taken
+# (read_fixed_length()) than under the LOAD ... INTO TABLE t1 command
+# above. The code in this path is copy-pasted code from the path taken
+# under the syntax used in the previous LOAD command.
+LOAD DATA INFILE 't3.dat' INTO TABLE t1
+FIELDS TERMINATED BY '' ENCLOSED BY '';
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+SELECT b FROM t1;
+b
+2011-08-01 15:11:19
+SELECT c FROM t1;
+c
+2011-08-01 15:11:19
+SELECT d FROM t1;
+d
+2011-08-01 15:11:19
+SELECT e FROM t1;
+e
+2011-08-01 15:11:19
+# Yes, a missing field cannot be NULL using this syntax, so it will
+# zero date instead. Says a comment in read_fixed_length() : "No fields
+# specified in fields_vars list can be NULL in this format."
+# It appears to be by design. This is inconsistent with LOAD DATA INFILE
+# syntax in previous test.
+SELECT f FROM t1;
+f
+0000-00-00 00:00:00
+SELECT g FROM t1;
+g
+0000-00-00 00:00:00
+# See comment above "SELECT f FROM f1".
+SELECT h FROM t1;
+h
+0000-00-00 00:00:00
+SELECT i FROM t1;
+i
+0000-00-00 00:00:00
+DELETE FROM t1;
+LOAD DATA INFILE 't5.dat' INTO TABLE t1 ( a, @dummy );
+SELECT * FROM t1;
+a b c d e f g h i
+1 2011-08-01 15:11:19 2011-08-01 15:11:19 0000-00-00 00:00:00 2011-08-01 15:11:19 NULL 2011-08-01 15:11:19 NULL 2011-08-01 15:11:19
+SELECT @dummy;
+@dummy
+2
+DELETE FROM t1;
+LOAD DATA INFILE 't3.dat' INTO TABLE t1 ( a ) SET c = '2005-06-06 08:09:10';
+SELECT * FROM t1;
+a b c d e f g h i
+1 2011-08-01 15:11:19 2005-06-06 08:09:10 0000-00-00 00:00:00 2011-08-01 15:11:19 NULL 2011-08-01 15:11:19 NULL 2011-08-01 15:11:19
+DELETE FROM t1;
+LOAD DATA INFILE 't3.dat' INTO TABLE t1 ( a ) SET g = '2005-06-06 08:09:10';
+SELECT * FROM t1;
+a b c d e f g h i
+1 2011-08-01 15:11:19 2011-08-01 15:11:19 0000-00-00 00:00:00 2011-08-01 15:11:19 NULL 2005-06-06 08:09:10 NULL 2011-08-01 15:11:19
+DELETE FROM t1;
+# Load a static XML file
+LOAD XML INFILE '../../std_data/onerow.xml' INTO TABLE t1
+ROWS IDENTIFIED BY '<row>';
+Missing tags are treated as NULL
+SELECT * FROM t1;
+a 1
+b 2011-08-01 15:11:19
+c 2011-08-01 15:11:19
+d 2011-08-01 15:11:19
+e 2011-08-01 15:11:19
+f NULL
+g NULL
+h NULL
+i NULL
+DROP TABLE t1, t2;
+#
+# Similar LOAD DATA tests in another form
+#
+# All of this test portion has been run on a pre-WL5874 trunk
+# (except that like_b and like_c didn't exist) and all result
+# differences are a bug.
+# Regarding like_b its definition is the same as b's except
+# that the constant default is replaced with a function
+# default. Our expectation is that like_b would behave
+# like b: if b is set to NULL, or set to 0000-00-00, or set to
+# its default, then the same should apply to like_b. Same for
+# like_c vs c.
+# Mon Aug 1 15:11:19 2011 UTC
+SET TIMESTAMP = 1312211479.089786;
+SELECT 1 INTO OUTFILE "file1.dat" FROM dual;
+SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+INTO OUTFILE "file2.dat" FROM dual;
+# Too short row
+CREATE TABLE t1 (
+dummy INT,
+a DATETIME NULL DEFAULT NULL,
+b DATETIME NULL DEFAULT "2011-11-18",
+like_b DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
+c DATETIME NOT NULL DEFAULT "2011-11-18",
+like_c DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NULL DEFAULT "2011-05-03" ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NOT NULL DEFAULT "2011-05-03",
+f TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+g TIMESTAMP NULL DEFAULT NULL,
+h INT NULL,
+i INT NOT NULL DEFAULT 42
+);
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime DEFAULT NULL,
+ `b` datetime DEFAULT '2011-11-18 00:00:00',
+ `like_b` datetime DEFAULT CURRENT_TIMESTAMP,
+ `c` datetime NOT NULL DEFAULT '2011-11-18 00:00:00',
+ `like_c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `d` timestamp NULL DEFAULT '2011-05-03 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `e` timestamp NOT NULL DEFAULT '2011-05-03 00:00:00',
+ `f` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `g` timestamp NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file1.dat" INTO table t1;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+# It is strange that "like_b" gets NULL when "b" gets 0. But
+# this is consistent with how "a" gets NULL when "b" gets 0,
+# with how "g" gets NULL when "d" gets 0, and with how "h" gets
+# NULL when "i" gets 0. Looks like "DEFAULT
+# <non-NULL-constant>" is changed to 0, whereas DEFAULT NULL
+# and DEFAULT NOW are changed to NULL.
+SELECT * FROM t1;
+dummy 1
+a NULL
+b 0000-00-00 00:00:00
+like_b NULL
+c 0000-00-00 00:00:00
+like_c 0000-00-00 00:00:00
+d 0000-00-00 00:00:00
+e 2011-08-01 15:11:19
+f 2011-08-01 15:11:19
+g NULL
+h NULL
+i 0
+delete from t1;
+alter table t1
+modify f TIMESTAMP NULL default CURRENT_TIMESTAMP;
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime DEFAULT NULL,
+ `b` datetime DEFAULT '2011-11-18 00:00:00',
+ `like_b` datetime DEFAULT CURRENT_TIMESTAMP,
+ `c` datetime NOT NULL DEFAULT '2011-11-18 00:00:00',
+ `like_c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `d` timestamp NULL DEFAULT '2011-05-03 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `e` timestamp NOT NULL DEFAULT '2011-05-03 00:00:00',
+ `f` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ `g` timestamp NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file1.dat" INTO table t1;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+SELECT * FROM t1;
+dummy 1
+a NULL
+b 0000-00-00 00:00:00
+like_b NULL
+c 0000-00-00 00:00:00
+like_c 0000-00-00 00:00:00
+d 0000-00-00 00:00:00
+e 2011-08-01 15:11:19
+f NULL
+g NULL
+h NULL
+i 0
+delete from t1;
+drop table t1;
+# Conclusion derived from trunk's results:
+# DATETIME DEFAULT <non-NULL-constant> (b,c) gets 0000-00-00,
+# DATETIME DEFAULT NULL (a) gets NULL,
+# TIMESTAMP NULL DEFAULT <non-NULL-constant> (d) gets 0000-00-00,
+# TIMESTAMP NULL DEFAULT NULL (g) gets NULL,
+# TIMESTAMP NULL DEFAULT NOW (f after ALTER) gets NULL,
+# TIMESTAMP NOT NULL (f before ALTER, e) gets NOW.
+### Loading NULL ###
+CREATE TABLE t1 (
+dummy INT,
+a DATETIME NULL DEFAULT NULL,
+b DATETIME NULL DEFAULT "2011-11-18",
+like_b DATETIME NULL DEFAULT CURRENT_TIMESTAMP,
+c DATETIME NOT NULL DEFAULT "2011-11-18",
+like_c DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
+d TIMESTAMP NULL DEFAULT "2011-05-03" ON UPDATE CURRENT_TIMESTAMP,
+e TIMESTAMP NOT NULL DEFAULT "2011-05-03",
+f TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+g TIMESTAMP NULL DEFAULT NULL,
+h INT NULL,
+i INT NOT NULL DEFAULT 42
+);
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime DEFAULT NULL,
+ `b` datetime DEFAULT '2011-11-18 00:00:00',
+ `like_b` datetime DEFAULT CURRENT_TIMESTAMP,
+ `c` datetime NOT NULL DEFAULT '2011-11-18 00:00:00',
+ `like_c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `d` timestamp NULL DEFAULT '2011-05-03 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `e` timestamp NOT NULL DEFAULT '2011-05-03 00:00:00',
+ `f` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `g` timestamp NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file2.dat" INTO table t1;
+Warnings:
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'like_c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'i' at row 1
+SELECT * FROM t1;
+dummy NULL
+a NULL
+b NULL
+like_b NULL
+c 0000-00-00 00:00:00
+like_c 0000-00-00 00:00:00
+d NULL
+e 2011-08-01 15:11:19
+f 2011-08-01 15:11:19
+g NULL
+h NULL
+i 0
+delete from t1;
+alter table t1
+modify f TIMESTAMP NULL default CURRENT_TIMESTAMP;
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime DEFAULT NULL,
+ `b` datetime DEFAULT '2011-11-18 00:00:00',
+ `like_b` datetime DEFAULT CURRENT_TIMESTAMP,
+ `c` datetime NOT NULL DEFAULT '2011-11-18 00:00:00',
+ `like_c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `d` timestamp NULL DEFAULT '2011-05-03 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ `e` timestamp NOT NULL DEFAULT '2011-05-03 00:00:00',
+ `f` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ `g` timestamp NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file2.dat" INTO table t1;
+Warnings:
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'like_c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'i' at row 1
+SELECT * FROM t1;
+dummy NULL
+a NULL
+b NULL
+like_b NULL
+c 0000-00-00 00:00:00
+like_c 0000-00-00 00:00:00
+d NULL
+e 2011-08-01 15:11:19
+f NULL
+g NULL
+h NULL
+i 0
+delete from t1;
+# Conclusion derived from trunk's results:
+# DATETIME NULL (a,b) gets NULL,
+# DATETIME NOT NULL (c) gets 0000-00-00,
+# TIMESTAMP NULL (d,f,g) gets NULL,
+# TIMESTAMP NOT NULL (e) gets NOW.
+drop table t1;
+#
+# Test of updatable views with check options. The option can be violated
+# using ON UPDATE updates which is very strange as this offers a loophole
+# in this integrity check.
+#
+SET TIME_ZONE = "+03:00";
+# 1970-01-01 03:16:40
+SET TIMESTAMP = 1000.123456;
+CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) ENGINE = INNODB;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b
+1 1970-01-01 03:16:40
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE b <= '1970-01-01 03:16:40.123456'
+WITH CHECK OPTION;
+SELECT * FROM v1;
+a b
+1 1970-01-01 03:16:40
+# 1970-01-01 03:33:20
+SET TIMESTAMP = 2000.000234;
+UPDATE v1 SET a = 2;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+SELECT * FROM t1;
+a b
+1 1970-01-01 03:16:40
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT '1973-08-14 09:11:22.089786' ON UPDATE CURRENT_TIMESTAMP,
+c INT KEY
+);
+# 1973-08-14 09:11:22 UTC
+SET TIMESTAMP = 114167482.534231;
+INSERT INTO t1 ( c ) VALUES ( 1 );
+CREATE VIEW v1 AS
+SELECT *
+FROM t1
+WHERE a >= '1973-08-14 09:11:22'
+WITH LOCAL CHECK OPTION;
+SELECT * FROM v1;
+a c
+1973-08-14 09:11:22 1
+SET TIMESTAMP = 1.126789;
+INSERT INTO v1 ( c ) VALUES ( 1 ) ON DUPLICATE KEY UPDATE c = 2;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+SELECT * FROM v1;
+a c
+1973-08-14 09:11:22 1
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug 13095459 - MULTI-TABLE UPDATE MODIFIES A ROW TWICE
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY ( a, ts )
+) ENGINE = INNODB;
+INSERT INTO t1( a, b, ts ) VALUES ( 1, 0, '2000-09-28 17:44:34' );
+CREATE TABLE t2 ( a INT ) ENGINE = INNODB;
+INSERT INTO t2 VALUES ( 1 );
+UPDATE t1 STRAIGHT_JOIN t2
+SET t1.b = t1.b + 1
+WHERE t1.a = 1 AND t1.ts >= '2000-09-28 00:00:00';
+SELECT b FROM t1;
+b
+1
+DROP TABLE t1, t2;
+#
+# Bug#11745578: 17392: ALTER TABLE ADD COLUMN TIMESTAMP DEFAULT
+# CURRENT_TIMESTAMP INSERTS ZERO
+#
+SET timestamp = 1000;
+CREATE TABLE t1 ( b INT );
+INSERT INTO t1 VALUES (1);
+ALTER TABLE t1 ADD COLUMN a6 DATETIME DEFAULT NOW() ON UPDATE NOW() FIRST;
+ALTER TABLE t1 ADD COLUMN a5 DATETIME DEFAULT NOW() FIRST;
+ALTER TABLE t1 ADD COLUMN a4 DATETIME ON UPDATE NOW() FIRST;
+ALTER TABLE t1 ADD COLUMN a3 TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW() FIRST;
+ALTER TABLE t1 ADD COLUMN a2 TIMESTAMP NOT NULL DEFAULT NOW() FIRST;
+ALTER TABLE t1 ADD COLUMN a1 TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW() FIRST;
+ALTER TABLE t1 ADD COLUMN c1 TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW() AFTER b;
+ALTER TABLE t1 ADD COLUMN c2 TIMESTAMP NOT NULL DEFAULT NOW() AFTER c1;
+ALTER TABLE t1 ADD COLUMN c3 TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE NOW() AFTER c2;
+ALTER TABLE t1 ADD COLUMN c4 DATETIME ON UPDATE NOW() AFTER c3;
+ALTER TABLE t1 ADD COLUMN c5 DATETIME DEFAULT NOW() AFTER c4;
+ALTER TABLE t1 ADD COLUMN c6 DATETIME DEFAULT NOW() ON UPDATE NOW() AFTER c5;
+SELECT * FROM t1;
+a1 a2 a3 a4 a5 a6 b c1 c2 c3 c4 c5 c6
+0000-00-00 00:00:00 1970-01-01 03:16:40 1970-01-01 03:16:40 NULL 1970-01-01 03:16:40 1970-01-01 03:16:40 1 0000-00-00 00:00:00 1970-01-01 03:16:40 1970-01-01 03:16:40 NULL 1970-01-01 03:16:40 1970-01-01 03:16:40
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP NOT NULL DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP, b DATETIME DEFAULT NOW() );
+INSERT INTO t1 VALUES ();
+SET timestamp = 1000000000;
+ALTER TABLE t1 MODIFY COLUMN a TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3);
+ALTER TABLE t1 MODIFY COLUMN b DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3);
+SELECT * FROM t1;
+a b
+1970-01-01 03:16:40.000 1970-01-01 03:16:40.000
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT '1999-12-01 11:22:33' ON UPDATE CURRENT_TIMESTAMP,
+b DATETIME DEFAULT '1999-12-01 11:22:33'
+);
+INSERT INTO t1 VALUES ();
+ALTER TABLE t1 MODIFY COLUMN a TIMESTAMP DEFAULT NOW();
+ALTER TABLE t1 MODIFY COLUMN b DATETIME DEFAULT NOW();
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1;
+a b
+1999-12-01 11:22:33 1999-12-01 11:22:33
+2001-09-09 04:46:40 2001-09-09 04:46:40
+DROP TABLE t1;
+#
+# Function defaults run 2. Six digits scale on seconds precision.
+#
+SET TIME_ZONE = "+00:00";
+#
+# Test of errors for column data types that dont support function
+# defaults.
+#
+CREATE TABLE t1( a BIT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a TINYINT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a SMALLINT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a MEDIUMINT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a INT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a BIGINT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a FLOAT DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a DECIMAL DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a DATE DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a TIME DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a YEAR DEFAULT CURRENT_TIMESTAMP(6) );
+ERROR 42000: Invalid default value for 'a'
+CREATE TABLE t1( a BIT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a TINYINT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a SMALLINT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a MEDIUMINT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a INT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a BIGINT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a FLOAT ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a DECIMAL ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a DATE ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a TIME ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+CREATE TABLE t1( a YEAR ON UPDATE CURRENT_TIMESTAMP(6) );
+ERROR HY000: Invalid ON UPDATE clause for 'a' column
+#
+# Test that the default clause behaves like NOW() regarding time zones.
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NULL,
+e DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+f DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+g DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+h DATETIME(6)
+);
+# 2011-09-27 14:11:08 UTC
+SET TIMESTAMP = 1317132668.654321;
+SET @old_time_zone = @@TIME_ZONE;
+SET TIME_ZONE = "+05:00";
+INSERT INTO t1( d, h ) VALUES ( NOW(6), NOW(6) );
+SELECT * FROM t1;
+a b c d e f g h
+2011-09-27 19:11:08.654321 2011-09-27 19:11:08.654321 0000-00-00 00:00:00.000000 2011-09-27 19:11:08.654321 2011-09-27 19:11:08.654321 2011-09-27 19:11:08.654321 NULL 2011-09-27 19:11:08.654321
+# 1989-05-13 01:02:03
+SET TIMESTAMP = 611017323.543212;
+UPDATE t1 SET d = NOW(6), h = NOW(6);
+SELECT * FROM t1;
+a b c d e f g h
+1989-05-13 04:02:03.543212 2011-09-27 19:11:08.654321 1989-05-13 04:02:03.543212 1989-05-13 04:02:03.543212 1989-05-13 04:02:03.543212 2011-09-27 19:11:08.654321 1989-05-13 04:02:03.543212 1989-05-13 04:02:03.543212
+SET TIME_ZONE = @old_time_zone;
+DROP TABLE t1;
+#
+# Test of several TIMESTAMP columns with different function defaults.
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+f INT
+);
+# 2011-04-19 07:22:02 UTC
+SET TIMESTAMP = 1303197722.534231;
+INSERT INTO t1 ( f ) VALUES (1);
+SELECT * FROM t1;
+a b c d e f
+2011-04-19 07:22:02.534231 2011-04-19 07:22:02.534231 2011-04-19 07:22:02.534231 0000-00-00 00:00:00.000000 0000-00-00 00:00:00.000000 1
+# 2011-04-19 07:23:18 UTC
+SET TIMESTAMP = 1303197798.132435;
+UPDATE t1 SET f = 2;
+SELECT * FROM t1;
+a b c d e f
+2011-04-19 07:23:18.132435 2011-04-19 07:23:18.132435 2011-04-19 07:22:02.534231 2011-04-19 07:23:18.132435 2011-04-19 07:23:18.132435 2
+DROP TABLE t1;
+#
+# Test of inserted values out of order.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NULL,
+f DATETIME(6),
+g DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+h DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+i DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+j INT
+);
+# 2011-04-19 07:22:02 UTC
+SET TIMESTAMP = 1303197722.534231;
+INSERT INTO t1 ( j, a ) VALUES ( 1, 1 );
+SELECT * FROM t1;
+a b c d e f g h i j
+1 2011-04-19 07:22:02.534231 2011-04-19 07:22:02.534231 0000-00-00 00:00:00.000000 NULL NULL 2011-04-19 07:22:02.534231 NULL 2011-04-19 07:22:02.534231 1
+DROP TABLE t1;
+#
+# Test of ON DUPLICATE KEY UPDATE
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY,
+b INT,
+c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+f TIMESTAMP(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+g TIMESTAMP(6) NULL,
+h DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+i DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+j DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+k DATETIME(6) NULL,
+l DATETIME(6) DEFAULT '1986-09-27 03:00:00.098765'
+);
+# 1977-12-21 23:00:00 UTC
+SET TIMESTAMP = 251593200.192837;
+INSERT INTO t1(a) VALUES (1) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+a b c d e f g h i j k l
+1 NULL 1977-12-21 23:00:00.192837 1977-12-21 23:00:00.192837 0000-00-00 00:00:00.000000 1986-09-27 03:00:00.098765 NULL 1977-12-21 23:00:00.192837 1977-12-21 23:00:00.192837 NULL NULL 1986-09-27 03:00:00.098765
+# 1975-05-21 23:00:00 UTC
+SET TIMESTAMP = 169945200.918273;
+INSERT INTO t1(a) VALUES (1) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+a b c d e f g h i j k l
+1 2 1975-05-21 23:00:00.918273 1977-12-21 23:00:00.192837 1975-05-21 23:00:00.918273 1986-09-27 03:00:00.098765 NULL 1975-05-21 23:00:00.918273 1977-12-21 23:00:00.192837 1975-05-21 23:00:00.918273 NULL 1986-09-27 03:00:00.098765
+# 1973-08-14 09:11:22 UTC
+SET TIMESTAMP = 114167482.534231;
+INSERT INTO t1(a) VALUES (2) ON DUPLICATE KEY UPDATE b = 2;
+SELECT * FROM t1;
+a b c d e f g h i j k l
+1 2 1975-05-21 23:00:00.918273 1977-12-21 23:00:00.192837 1975-05-21 23:00:00.918273 1986-09-27 03:00:00.098765 NULL 1975-05-21 23:00:00.918273 1977-12-21 23:00:00.192837 1975-05-21 23:00:00.918273 NULL 1986-09-27 03:00:00.098765
+2 NULL 1973-08-14 09:11:22.534231 1973-08-14 09:11:22.534231 0000-00-00 00:00:00.000000 1986-09-27 03:00:00.098765 NULL 1973-08-14 09:11:22.534231 1973-08-14 09:11:22.534231 NULL NULL 1986-09-27 03:00:00.098765
+DROP TABLE t1;
+CREATE TABLE t1 ( a INT PRIMARY KEY, b INT, c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) );
+# 2011-04-19 07:23:18 UTC
+SET TIMESTAMP = 1303197798.945156;
+INSERT INTO t1 VALUES
+(1, 0, '2001-01-01 01:01:01.111111'),
+(2, 0, '2002-02-02 02:02:02.222222'),
+(3, 0, '2003-03-03 03:03:03.333333');
+SELECT * FROM t1;
+a b c
+1 0 2001-01-01 01:01:01.111111
+2 0 2002-02-02 02:02:02.222222
+3 0 2003-03-03 03:03:03.333333
+UPDATE t1 SET b = 2, c = c WHERE a = 2;
+SELECT * FROM t1;
+a b c
+1 0 2001-01-01 01:01:01.111111
+2 2 2002-02-02 02:02:02.222222
+3 0 2003-03-03 03:03:03.333333
+INSERT INTO t1 (a) VALUES (4);
+SELECT * FROM t1;
+a b c
+1 0 2001-01-01 01:01:01.111111
+2 2 2002-02-02 02:02:02.222222
+3 0 2003-03-03 03:03:03.333333
+4 NULL 2011-04-19 07:23:18.945156
+UPDATE t1 SET c = '2004-04-04 04:04:04.444444' WHERE a = 4;
+SELECT * FROM t1;
+a b c
+1 0 2001-01-01 01:01:01.111111
+2 2 2002-02-02 02:02:02.222222
+3 0 2003-03-03 03:03:03.333333
+4 NULL 2004-04-04 04:04:04.444444
+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.111111
+2 2 2002-02-02 02:02:02.222222
+3 3 2003-03-03 03:03:03.333333
+4 NULL 2004-04-04 04:04:04.444444
+5 NULL 2011-04-19 07:23:18.945156
+INSERT INTO t1 (a, c) VALUES
+(4, '2004-04-04 00:00:00.444444'),
+(6, '2006-06-06 06:06:06.666666')
+ON DUPLICATE KEY UPDATE b = 4;
+SELECT * FROM t1;
+a b c
+1 0 2001-01-01 01:01:01.111111
+2 2 2002-02-02 02:02:02.222222
+3 3 2003-03-03 03:03:03.333333
+4 4 2011-04-19 07:23:18.945156
+5 NULL 2011-04-19 07:23:18.945156
+6 NULL 2006-06-06 06:06:06.666666
+DROP TABLE t1;
+#
+# Test of REPLACE INTO executed as UPDATE.
+#
+CREATE TABLE t1 (
+a INT PRIMARY KEY,
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+e DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+f TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+g DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+h TIMESTAMP(6) NULL,
+i DATETIME(6)
+);
+# 1970-09-21 09:11:12 UTC
+SET TIMESTAMP = 22756272.163584;
+REPLACE INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+1 1970-09-21 09:11:12.163584 1970-09-21 09:11:12.163584 1970-09-21 09:11:12.163584 1970-09-21 09:11:12.163584 0000-00-00 00:00:00.000000 NULL NULL NULL
+# 1970-11-10 14:16:17 UTC
+SET TIMESTAMP = 27094577.852954;
+REPLACE INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+1 1970-11-10 14:16:17.852954 1970-11-10 14:16:17.852954 1970-11-10 14:16:17.852954 1970-11-10 14:16:17.852954 0000-00-00 00:00:00.000000 NULL NULL NULL
+DROP TABLE t1;
+#
+# Test of insertion of NULL, DEFAULT and an empty row for DEFAULT
+# CURRENT_TIMESTAMP.
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+c INT
+);
+# 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.163578;
+INSERT INTO t1 VALUES (NULL, NULL, 1), (DEFAULT, DEFAULT, 2);
+INSERT INTO t1 ( a, b, c ) VALUES (NULL, NULL, 3), (DEFAULT, DEFAULT, 4);
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41.163578 NULL 1
+2011-04-20 09:53:41.163578 2011-04-20 09:53:41.163578 2
+2011-04-20 09:53:41.163578 NULL 3
+2011-04-20 09:53:41.163578 2011-04-20 09:53:41.163578 4
+SET TIME_ZONE = "+03:00";
+SELECT * FROM t1;
+a b c
+2011-04-20 12:53:41.163578 NULL 1
+2011-04-20 12:53:41.163578 2011-04-20 09:53:41.163578 2
+2011-04-20 12:53:41.163578 NULL 3
+2011-04-20 12:53:41.163578 2011-04-20 09:53:41.163578 4
+SET TIME_ZONE = "+00:00";
+DROP TABLE t1;
+# 2011-04-20 07:05:39 UTC
+SET TIMESTAMP = 1303283139.195624;
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT '2010-10-11 12:34:56' ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) DEFAULT '2010-10-11 12:34:56'
+);
+INSERT INTO t1 VALUES (NULL, NULL), (DEFAULT, DEFAULT);
+INSERT INTO t1 ( a, b ) VALUES (NULL, NULL), (DEFAULT, DEFAULT);
+SELECT * FROM t1;
+a b
+2011-04-20 07:05:39.195624 NULL
+2010-10-11 12:34:56.000000 2010-10-11 12:34:56.000000
+2011-04-20 07:05:39.195624 NULL
+2010-10-11 12:34:56.000000 2010-10-11 12:34:56.000000
+DROP TABLE t1;
+# 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.136952;
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+e TIMESTAMP(6) NULL,
+f DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+g DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+h DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+i DATETIME(6) NULL,
+j DATETIME(6) DEFAULT '1986-09-27 03:00:00.098765'
+);
+INSERT INTO t1 VALUES ();
+INSERT INTO t1 SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL;
+SELECT * FROM t1;
+a b c d e f g h i j
+2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 0000-00-00 00:00:00.000000 1986-09-27 03:00:00.098765 NULL 2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 NULL NULL 1986-09-27 03:00:00.098765
+2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 NULL NULL NULL NULL NULL NULL
+DROP TABLE t1;
+#
+# Test of multiple-table UPDATE for DEFAULT CURRENT_TIMESTAMP
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+c INT
+);
+INSERT INTO t1 ( c ) VALUES (1);
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 1
+# 2011-04-20 17:06:13 UTC
+SET TIMESTAMP = 1303311973.163587;
+UPDATE t1 t11, t1 t12 SET t11.c = 1;
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41.136952 2011-04-20 09:53:41.136952 1
+UPDATE t1 t11, t1 t12 SET t11.c = 2;
+SELECT * FROM t1;
+a b c
+2011-04-20 15:06:13.163587 2011-04-20 09:53:41.136952 2
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+c DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+d DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+e INT
+);
+CREATE TABLE t2 (
+f INT,
+g DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+h DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+i TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+j TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)
+);
+# 1995-03-11 00:02:03 UTC
+SET TIMESTAMP = 794880123.195676;
+INSERT INTO t1 ( e ) VALUES ( 1 ), ( 2 );
+INSERT INTO t2 ( f ) VALUES ( 1 ), ( 2 );
+SELECT * FROM t1;
+a b c d e
+1995-03-11 00:02:03.195676 0000-00-00 00:00:00.000000 1995-03-11 00:02:03.195676 NULL 1
+1995-03-11 00:02:03.195676 0000-00-00 00:00:00.000000 1995-03-11 00:02:03.195676 NULL 2
+SELECT * FROM t2;
+f g h i j
+1 NULL 1995-03-11 00:02:03.195676 0000-00-00 00:00:00.000000 1995-03-11 00:02:03.195676
+2 NULL 1995-03-11 00:02:03.195676 0000-00-00 00:00:00.000000 1995-03-11 00:02:03.195676
+# 1980-12-13 02:02:01 UTC
+SET TIMESTAMP = 345520921.196755;
+UPDATE t1, t2 SET t1.e = 3, t2.f = 4;
+SELECT * FROM t1;
+a b c d e
+1995-03-11 00:02:03.195676 1980-12-13 02:02:01.196755 1995-03-11 00:02:03.195676 1980-12-13 02:02:01.196755 3
+1995-03-11 00:02:03.195676 1980-12-13 02:02:01.196755 1995-03-11 00:02:03.195676 1980-12-13 02:02:01.196755 3
+SELECT * FROM t2;
+f g h i j
+4 1980-12-13 02:02:01.196755 1995-03-11 00:02:03.195676 1980-12-13 02:02:01.196755 1995-03-11 00:02:03.195676
+4 1980-12-13 02:02:01.196755 1995-03-11 00:02:03.195676 1980-12-13 02:02:01.196755 1995-03-11 00:02:03.195676
+DROP TABLE t1, t2;
+#
+# Test of multiple table update with temporary table and on the fly.
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c INT,
+d INT
+);
+CREATE TABLE t2 (
+a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c INT KEY,
+d INT
+);
+INSERT INTO t1 ( c ) VALUES (1), (2);
+INSERT INTO t2 ( c ) VALUES (1), (2);
+# Test of multiple table update done on the fly
+# 2011-04-20 15:06:13 UTC
+SET TIMESTAMP = 1303311973.194685;
+UPDATE t1 JOIN t2 USING ( c ) SET t2.d = 1;
+SELECT * FROM t1;
+a b c d
+0000-00-00 00:00:00.000000 NULL 1 NULL
+0000-00-00 00:00:00.000000 NULL 2 NULL
+SELECT * FROM t2;
+a b c d
+2011-04-20 15:06:13.194685 2011-04-20 15:06:13.194685 1 1
+2011-04-20 15:06:13.194685 2011-04-20 15:06:13.194685 2 1
+# Test of multiple table update done with temporary table.
+# 1979-01-15 03:02:01
+SET TIMESTAMP = 285213721.134679;
+UPDATE t1 JOIN t2 USING ( c ) SET t1.d = 1;
+SELECT * FROM t1;
+a b c d
+1979-01-15 02:02:01.134679 1979-01-15 02:02:01.134679 1 1
+1979-01-15 02:02:01.134679 1979-01-15 02:02:01.134679 2 1
+SELECT * FROM t2;
+a b c d
+2011-04-20 15:06:13.194685 2011-04-20 15:06:13.194685 1 1
+2011-04-20 15:06:13.194685 2011-04-20 15:06:13.194685 2 1
+DROP TABLE t1, t2;
+#
+# Test of ON UPDATE CURRENT_TIMESTAMP.
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c INT
+);
+# 2011-04-20 09:53:41 UTC
+SET TIMESTAMP = 1303293221.794613;
+INSERT INTO t1 ( c ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c
+0000-00-00 00:00:00.000000 NULL 1
+UPDATE t1 SET c = 1;
+SELECT * FROM t1;
+a b c
+0000-00-00 00:00:00.000000 NULL 1
+UPDATE t1 SET c = 2;
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41.794613 2011-04-20 09:53:41.794613 2
+#
+# Test of multiple-table UPDATE for ON UPDATE CURRENT_TIMESTAMP
+#
+# 2011-04-20 15:06:13 UTC
+SET TIMESTAMP = 1303311973.534231;
+UPDATE t1 t11, t1 t12 SET t11.c = 2;
+SELECT * FROM t1;
+a b c
+2011-04-20 09:53:41.794613 2011-04-20 09:53:41.794613 2
+UPDATE t1 t11, t1 t12 SET t11.c = 3;
+SELECT * FROM t1;
+a b c
+2011-04-20 15:06:13.534231 2011-04-20 15:06:13.534231 3
+DROP TABLE t1;
+#
+# Test of a multiple-table update where only one table is updated and
+# the updated table has a primary key.
+#
+CREATE TABLE t1 ( a INT, b INT, PRIMARY KEY (a) );
+INSERT INTO t1 VALUES (1, 1),(2, 2),(3, 3),(4, 4);
+CREATE TABLE t2 ( a INT, b INT );
+INSERT INTO t2 VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5);
+UPDATE t1, t2 SET t1.b = 100 WHERE t1.a = t2.a;
+SELECT * FROM t1;
+a b
+1 100
+2 100
+3 100
+4 100
+SELECT * FROM t2;
+a b
+1 1
+2 2
+3 3
+4 4
+5 5
+DROP TABLE t1, t2;
+#
+# Test of ALTER TABLE, reordering columns.
+#
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), b INT );
+ALTER TABLE t1 MODIFY a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), c TIMESTAMP(6) NULL );
+ALTER TABLE t1 MODIFY b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `a` int(11) DEFAULT NULL,
+ `c` timestamp(6) NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NULL );
+ALTER TABLE t1 MODIFY b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), b TIMESTAMP(6) NULL );
+ALTER TABLE t1 MODIFY a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp(6) NULL DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6), b TIMESTAMP(6) NULL );
+ALTER TABLE t1 MODIFY a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` timestamp(6) NULL DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW(6), b INT, c TIMESTAMP(6) NULL );
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `b` int(11) DEFAULT NULL,
+ `c` timestamp(6) NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `c` timestamp(6) NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW(6), b INT, c TIMESTAMP(6) NULL );
+ALTER TABLE t1 MODIFY c TIMESTAMP(6) NULL FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` timestamp(6) NULL DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT NOW(6) ON UPDATE CURRENT_TIMESTAMP(6), b INT, c TIMESTAMP(6) NULL );
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `b` int(11) DEFAULT NULL,
+ `c` timestamp(6) NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ALTER TABLE t1 MODIFY a TIMESTAMP(6) NOT NULL DEFAULT NOW(6) ON UPDATE CURRENT_TIMESTAMP(6) AFTER b;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `b` int(11) DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `c` timestamp(6) NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT NOW(6) ON UPDATE CURRENT_TIMESTAMP(6), b INT, c TIMESTAMP(6) NULL );
+ALTER TABLE t1 MODIFY c TIMESTAMP(6) NULL FIRST;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c` timestamp(6) NULL DEFAULT NULL,
+ `a` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `b` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# Test of ALTER TABLE, adding columns.
+#
+CREATE TABLE t1 ( a INT );
+ALTER TABLE t1 ADD COLUMN b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# Test of INSERT SELECT.
+#
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+d DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
+);
+CREATE TABLE t2 (
+placeholder1 INT,
+placeholder2 INT,
+placeholder3 INT,
+placeholder4 INT,
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00',
+c DATETIME(6),
+d DATETIME(6)
+);
+# 1977-08-16 15:30:01 UTC
+SET TIMESTAMP = 240589801.654312;
+INSERT INTO t2 (a, b, c, d) VALUES (
+'1977-08-16 15:30:01.123456',
+'1977-08-16 15:30:01.234567',
+'1977-08-16 15:30:01.345678',
+'1977-08-16 15:30:01.456789'
+);
+# 1986-09-27 01:00:00 UTC
+SET TIMESTAMP = 528166800.132435;
+INSERT INTO t1 ( a, c ) SELECT a, c FROM t2;
+SELECT * FROM t1;
+a b c d
+1977-08-16 15:30:01.123456 1986-09-27 01:00:00.132435 1977-08-16 15:30:01.345678 1986-09-27 01:00:00.132435
+DROP TABLE t1, t2;
+#
+# Test of CREATE TABLE SELECT.
+#
+# We test that the columns of the source table are not used to determine
+# function defaults for the receiving table.
+#
+# 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.657898;
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+e TIMESTAMP(6) NULL,
+f DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+g DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+h DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+i DATETIME(6) NULL,
+j DATETIME(6) DEFAULT '1986-09-27 03:00:00.098765'
+);
+INSERT INTO t1 VALUES ();
+# 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.164937;
+CREATE TABLE t2 SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+a
+1970-04-11 20:13:57.657897
+CREATE TABLE t3 SELECT b FROM t1;
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `b` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t3;
+b
+1970-04-11 20:13:57.657897
+CREATE TABLE t4 SELECT c FROM t1;
+SHOW CREATE TABLE t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `c` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t4;
+c
+0000-00-00 00:00:00.000000
+CREATE TABLE t5 SELECT d FROM t1;
+SHOW CREATE TABLE t5;
+Table Create Table
+t5 CREATE TABLE `t5` (
+ `d` timestamp(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t5;
+d
+1986-09-27 03:00:00.098765
+CREATE TABLE t6 SELECT e FROM t1;
+SHOW CREATE TABLE t6;
+Table Create Table
+t6 CREATE TABLE `t6` (
+ `e` timestamp(6) NULL DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t6;
+e
+NULL
+CREATE TABLE t7 SELECT f FROM t1;
+SHOW CREATE TABLE t7;
+Table Create Table
+t7 CREATE TABLE `t7` (
+ `f` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t7;
+f
+1970-04-11 20:13:57.657897
+CREATE TABLE t8 SELECT g FROM t1;
+SHOW CREATE TABLE t8;
+Table Create Table
+t8 CREATE TABLE `t8` (
+ `g` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t8;
+g
+1970-04-11 20:13:57.657897
+CREATE TABLE t9 SELECT h FROM t1;
+SHOW CREATE TABLE t9;
+Table Create Table
+t9 CREATE TABLE `t9` (
+ `h` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t9;
+h
+NULL
+CREATE TABLE t10 SELECT i FROM t1;
+SHOW CREATE TABLE t10;
+Table Create Table
+t10 CREATE TABLE `t10` (
+ `i` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t10;
+i
+NULL
+CREATE TABLE t11 SELECT j FROM t1;
+SHOW CREATE TABLE t11;
+Table Create Table
+t11 CREATE TABLE `t11` (
+ `j` datetime(6) DEFAULT '1986-09-27 03:00:00.098765'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t11;
+j
+1986-09-27 03:00:00.098765
+CREATE TABLE t12 (
+k TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+l TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+m TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+n TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+o TIMESTAMP(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+p TIMESTAMP(6) NULL,
+q DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+r DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+s DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+t DATETIME(6) NULL,
+u DATETIME(6) DEFAULT '1986-09-27 03:00:00.098765'
+)
+SELECT * FROM t1;
+SHOW CREATE TABLE t12;
+Table Create Table
+t12 CREATE TABLE `t12` (
+ `k` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `l` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `m` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `n` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `o` timestamp(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+ `p` timestamp(6) NULL DEFAULT NULL,
+ `q` datetime(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `r` datetime(6) DEFAULT CURRENT_TIMESTAMP(6),
+ `s` datetime(6) DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(6),
+ `t` datetime(6) DEFAULT NULL,
+ `u` datetime(6) DEFAULT '1986-09-27 03:00:00.098765',
+ `a` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `b` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `c` timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
+ `d` timestamp(6) NOT NULL DEFAULT '1986-09-27 03:00:00.098765',
+ `e` timestamp(6) NULL DEFAULT NULL,
+ `f` datetime(6) DEFAULT NULL,
+ `g` datetime(6) DEFAULT NULL,
+ `h` datetime(6) DEFAULT NULL,
+ `i` datetime(6) DEFAULT NULL,
+ `j` datetime(6) DEFAULT '1986-09-27 03:00:00.098765'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1, t2, t3, t4, t5, t6, t7, t8, t9, t10, t11, t12;
+# 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.164953;
+CREATE TABLE t1 (
+a DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+c DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+d DATETIME(6) NULL,
+e DATETIME(6) DEFAULT '1986-09-27 03:00:00.098765'
+);
+INSERT INTO t1 VALUES ();
+# 1971-01-31 20:13:57 UTC
+SET TIMESTAMP = 34200837.915736;
+CREATE TABLE t2 SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+a
+1970-04-11 20:13:57.164953
+CREATE TABLE t3 SELECT b FROM t1;
+SHOW CREATE TABLE t3;
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `b` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t3;
+b
+1970-04-11 20:13:57.164953
+CREATE TABLE t4 SELECT c FROM t1;
+SHOW CREATE TABLE t4;
+Table Create Table
+t4 CREATE TABLE `t4` (
+ `c` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t4;
+c
+NULL
+CREATE TABLE t5 SELECT d FROM t1;
+SHOW CREATE TABLE t5;
+Table Create Table
+t5 CREATE TABLE `t5` (
+ `d` datetime(6) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t5;
+d
+NULL
+CREATE TABLE t6 SELECT e FROM t1;
+SHOW CREATE TABLE t6;
+Table Create Table
+t6 CREATE TABLE `t6` (
+ `e` datetime(6) DEFAULT '1986-09-27 03:00:00.098765'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t6;
+e
+1986-09-27 03:00:00.098765
+DROP TABLE t1, t2, t3, t4, t5, t6;
+#
+# Test of a CREATE TABLE SELECT that also declared columns. In this case
+# the function default should be de-activated during the execution of the
+# CREATE TABLE statement.
+#
+# 1970-01-01 03:16:40
+SET TIMESTAMP = 1000.987654;
+CREATE TABLE t1 ( a INT );
+INSERT INTO t1 VALUES ( 1 ), ( 2 );
+CREATE TABLE t2 ( b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)) SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `b` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SET TIMESTAMP = 2000.876543;
+INSERT INTO t2( a ) VALUES ( 3 );
+SELECT * FROM t2;
+b a
+0000-00-00 00:00:00.000000 1
+0000-00-00 00:00:00.000000 2
+1970-01-01 00:33:20.876543 3
+DROP TABLE t1, t2;
+#
+# Test of updating a view.
+#
+CREATE TABLE t1 ( a INT, b DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) );
+CREATE TABLE t2 ( a INT, b DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6) );
+CREATE VIEW v1 AS SELECT * FROM t1;
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` latin1 latin1_swedish_ci
+CREATE VIEW v2 AS SELECT * FROM t2;
+SHOW CREATE VIEW v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a`,`t2`.`b` AS `b` from `t2` latin1 latin1_swedish_ci
+# 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.348564;
+INSERT INTO v1 ( a ) VALUES ( 1 );
+INSERT INTO v2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b
+1 1971-01-31 20:13:57.348564
+SELECT * FROM v1;
+a b
+1 1971-01-31 20:13:57.348564
+SELECT * FROM t2;
+a b
+1 NULL
+SELECT * FROM v2;
+a b
+1 NULL
+# 1970-04-11 20:13:57 UTC
+SET TIMESTAMP = 8712837.567332;
+UPDATE v1 SET a = 2;
+UPDATE v2 SET a = 2;
+SELECT * FROM t1;
+a b
+2 1971-01-31 20:13:57.348564
+SELECT * FROM v1;
+a b
+2 1971-01-31 20:13:57.348564
+SELECT * FROM t2;
+a b
+2 1970-04-11 20:13:57.567332
+SELECT * FROM v2;
+a b
+2 1970-04-11 20:13:57.567332
+DROP VIEW v1, v2;
+DROP TABLE t1, t2;
+#
+# Test with stored procedures.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NULL,
+f DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+g DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6)
+);
+CREATE PROCEDURE p1() INSERT INTO test.t1( a ) VALUES ( 1 );
+CREATE PROCEDURE p2() UPDATE t1 SET a = 2 WHERE a = 1;
+# 1971-01-31 20:13:57 UTC
+SET TIMESTAMP = 34200837.876544;
+CALL p1();
+SELECT * FROM t1;
+a b c d e f g
+1 1971-01-31 20:13:57.876544 1971-01-31 20:13:57.876544 0000-00-00 00:00:00.000000 NULL 1971-01-31 20:13:57.876544 NULL
+# 1970-04-11 21:13:57 UTC
+SET TIMESTAMP = 8712837.143546;
+CALL p2();
+SELECT * FROM t1;
+a b c d e f g
+2 1970-04-11 20:13:57.143546 1971-01-31 20:13:57.876544 1970-04-11 20:13:57.143546 NULL 1971-01-31 20:13:57.876544 1970-04-11 20:13:57.143546
+DROP PROCEDURE p1;
+DROP PROCEDURE p2;
+DROP TABLE t1;
+#
+# Test with triggers.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NULL,
+f DATETIME(6),
+g DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+h DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+i DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
+);
+CREATE TABLE t2 ( a INT );
+CREATE TRIGGER t2_trg BEFORE INSERT ON t2 FOR EACH ROW
+BEGIN
+INSERT INTO t1 ( a ) VALUES ( 1 );
+END|
+# 1971-01-31 21:13:57 UTC
+SET TIMESTAMP = 34200837.978675;
+INSERT INTO t2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+1 1971-01-31 20:13:57.978675 1971-01-31 20:13:57.978675 0000-00-00 00:00:00.000000 NULL NULL 1971-01-31 20:13:57.978675 NULL 1971-01-31 20:13:57.978675
+DROP TRIGGER t2_trg;
+CREATE TRIGGER t2_trg BEFORE INSERT ON t2 FOR EACH ROW
+BEGIN
+UPDATE t1 SET a = 2;
+END|
+# 1970-04-11 21:13:57 UTC
+SET TIMESTAMP = 8712837.456789;
+INSERT INTO t2 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b c d e f g h i
+2 1970-04-11 20:13:57.456789 1971-01-31 20:13:57.978675 1970-04-11 20:13:57.456789 NULL NULL 1971-01-31 20:13:57.978675 1970-04-11 20:13:57.456789 1970-04-11 20:13:57.456789
+DROP TABLE t1, t2;
+#
+# Test where the assignment target is not a column.
+#
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) );
+CREATE TABLE t2 ( a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) );
+CREATE TABLE t3 ( a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6) );
+CREATE TABLE t4 ( a TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6) );
+CREATE VIEW v1 AS SELECT a COLLATE latin1_german1_ci AS b FROM t1;
+CREATE VIEW v2 ( b ) AS SELECT a COLLATE latin1_german1_ci FROM t2;
+CREATE VIEW v3 AS SELECT a COLLATE latin1_german1_ci AS b FROM t3;
+CREATE VIEW v4 ( b ) AS SELECT a COLLATE latin1_german1_ci FROM t4;
+INSERT INTO v1 ( b ) VALUES ( '2007-10-24 00:03:34.010203' );
+SELECT a FROM t1;
+a
+2007-10-24 00:03:34.010203
+INSERT INTO v2 ( b ) VALUES ( '2007-10-24 00:03:34.010203' );
+SELECT a FROM t2;
+a
+2007-10-24 00:03:34.010203
+INSERT INTO t3 VALUES ();
+UPDATE v3 SET b = '2007-10-24 00:03:34.010203';
+SELECT a FROM t3;
+a
+2007-10-24 00:03:34.010203
+INSERT INTO t4 VALUES ();
+UPDATE v4 SET b = '2007-10-24 00:03:34.010203';
+SELECT a FROM t4;
+a
+2007-10-24 00:03:34.010203
+DROP VIEW v1, v2, v3, v4;
+DROP TABLE t1, t2, t3, t4;
+#
+# Test of LOAD DATA/XML INFILE
+# This tests behavior of function defaults for TIMESTAMP and DATETIME
+# columns. during LOAD ... INFILE.
+# As can be seen here, a TIMESTAMP column with only ON UPDATE
+# CURRENT_TIMESTAMP will still have CURRENT_TIMESTAMP inserted on LOAD
+# ... INFILE if the value is missing. For DATETIME columns a NULL value
+# is inserted instead.
+#
+CREATE TABLE t1 (
+a INT,
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+f DATETIME(6),
+g DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+h DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+i DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
+);
+CREATE TABLE t2 (
+a TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+c TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+e DATETIME(6) NOT NULL,
+f DATETIME(6) NOT NULL DEFAULT '1977-01-02 12:13:14',
+g DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) NOT NULL,
+h DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6) NOT NULL,
+i DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) NOT NULL
+);
+SELECT 1 INTO OUTFILE 't3.dat' FROM dual;
+SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+INTO OUTFILE 't4.dat'
+FROM dual;
+SELECT 1, 2 INTO OUTFILE 't5.dat' FROM dual;
+# Mon Aug 1 15:11:19 2011 UTC
+SET TIMESTAMP = 1312211479.918273;
+LOAD DATA INFILE 't3.dat' INTO TABLE t1;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+SELECT * FROM t1;
+a 1
+b 2011-08-01 15:11:19.918273
+c 2011-08-01 15:11:19.918273
+d 2011-08-01 15:11:19.918273
+e 2011-08-01 15:11:19.918273
+f NULL
+g NULL
+h NULL
+i NULL
+LOAD DATA INFILE 't4.dat' INTO TABLE t2;
+Warnings:
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'e' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'f' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'g' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'h' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'i' at row 1
+SELECT a FROM t2;
+a
+2011-08-01 15:11:19.918273
+SELECT b FROM t2;
+b
+2011-08-01 15:11:19.918273
+SELECT c FROM t2;
+c
+2011-08-01 15:11:19.918273
+SELECT d FROM t2;
+d
+2011-08-01 15:11:19.918273
+# As shown here, supplying a NULL value to a non-nullable
+# column with no default value results in the zero date.
+SELECT e FROM t2;
+e
+0000-00-00 00:00:00.000000
+# As shown here, supplying a NULL value to a non-nullable column with a
+# default value results in the zero date.
+SELECT f FROM t2;
+f
+0000-00-00 00:00:00.000000
+# As shown here, supplying a NULL value to a non-nullable column with a
+# default function results in the zero date.
+SELECT g FROM t2;
+g
+0000-00-00 00:00:00.000000
+# As shown here, supplying a NULL value to a non-nullable DATETIME ON
+# UPDATE CURRENT_TIMESTAMP column with no default value results in the
+# zero date.
+SELECT h FROM t2;
+h
+0000-00-00 00:00:00.000000
+SELECT i FROM t2;
+i
+0000-00-00 00:00:00.000000
+DELETE FROM t1;
+DELETE FROM t2;
+# Read t3 file into t1
+# The syntax will cause a different code path to be taken
+# (read_fixed_length()) than under the LOAD ... INTO TABLE t1 command
+# above. The code in this path is copy-pasted code from the path taken
+# under the syntax used in the previous LOAD command.
+LOAD DATA INFILE 't3.dat' INTO TABLE t1
+FIELDS TERMINATED BY '' ENCLOSED BY '';
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+SELECT b FROM t1;
+b
+2011-08-01 15:11:19.918273
+SELECT c FROM t1;
+c
+2011-08-01 15:11:19.918273
+SELECT d FROM t1;
+d
+2011-08-01 15:11:19.918273
+SELECT e FROM t1;
+e
+2011-08-01 15:11:19.918273
+# Yes, a missing field cannot be NULL using this syntax, so it will
+# zero date instead. Says a comment in read_fixed_length() : "No fields
+# specified in fields_vars list can be NULL in this format."
+# It appears to be by design. This is inconsistent with LOAD DATA INFILE
+# syntax in previous test.
+SELECT f FROM t1;
+f
+0000-00-00 00:00:00.000000
+SELECT g FROM t1;
+g
+0000-00-00 00:00:00.000000
+# See comment above "SELECT f FROM f1".
+SELECT h FROM t1;
+h
+0000-00-00 00:00:00.000000
+SELECT i FROM t1;
+i
+0000-00-00 00:00:00.000000
+DELETE FROM t1;
+LOAD DATA INFILE 't5.dat' INTO TABLE t1 ( a, @dummy );
+SELECT * FROM t1;
+a b c d e f g h i
+1 2011-08-01 15:11:19.918273 2011-08-01 15:11:19.918273 0000-00-00 00:00:00.000000 2011-08-01 15:11:19.918273 NULL 2011-08-01 15:11:19.918273 NULL 2011-08-01 15:11:19.918273
+SELECT @dummy;
+@dummy
+2
+DELETE FROM t1;
+LOAD DATA INFILE 't3.dat' INTO TABLE t1 ( a ) SET c = '2005-06-06 08:09:10';
+SELECT * FROM t1;
+a b c d e f g h i
+1 2011-08-01 15:11:19.918273 2005-06-06 08:09:10.000000 0000-00-00 00:00:00.000000 2011-08-01 15:11:19.918273 NULL 2011-08-01 15:11:19.918273 NULL 2011-08-01 15:11:19.918273
+DELETE FROM t1;
+LOAD DATA INFILE 't3.dat' INTO TABLE t1 ( a ) SET g = '2005-06-06 08:09:10';
+SELECT * FROM t1;
+a b c d e f g h i
+1 2011-08-01 15:11:19.918273 2011-08-01 15:11:19.918273 0000-00-00 00:00:00.000000 2011-08-01 15:11:19.918273 NULL 2005-06-06 08:09:10.000000 NULL 2011-08-01 15:11:19.918273
+DELETE FROM t1;
+# Load a static XML file
+LOAD XML INFILE '../../std_data/onerow.xml' INTO TABLE t1
+ROWS IDENTIFIED BY '<row>';
+Missing tags are treated as NULL
+SELECT * FROM t1;
+a 1
+b 2011-08-01 15:11:19.918273
+c 2011-08-01 15:11:19.918273
+d 2011-08-01 15:11:19.918273
+e 2011-08-01 15:11:19.918273
+f NULL
+g NULL
+h NULL
+i NULL
+DROP TABLE t1, t2;
+#
+# Similar LOAD DATA tests in another form
+#
+# All of this test portion has been run on a pre-WL5874 trunk
+# (except that like_b and like_c didn't exist) and all result
+# differences are a bug.
+# Regarding like_b its definition is the same as b's except
+# that the constant default is replaced with a function
+# default. Our expectation is that like_b would behave
+# like b: if b is set to NULL, or set to 0000-00-00, or set to
+# its default, then the same should apply to like_b. Same for
+# like_c vs c.
+# Mon Aug 1 15:11:19 2011 UTC
+SET TIMESTAMP = 1312211479.089786;
+SELECT 1 INTO OUTFILE "file1.dat" FROM dual;
+SELECT NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+INTO OUTFILE "file2.dat" FROM dual;
+# Too short row
+CREATE TABLE t1 (
+dummy INT,
+a DATETIME(6) NULL DEFAULT NULL,
+b DATETIME(6) NULL DEFAULT "2011-11-18",
+like_b DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
+c DATETIME(6) NOT NULL DEFAULT "2011-11-18",
+like_c DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NULL DEFAULT "2011-05-03" ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NOT NULL DEFAULT "2011-05-03",
+f TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+g TIMESTAMP(6) NULL DEFAULT NULL,
+h INT NULL,
+i INT NOT NULL DEFAULT 42
+);
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime(6) DEFAULT NULL,
+ `b` datetime(6) DEFAULT '2011-11-18 00:00:00.000000',
+ `like_b` datetime(6) DEFAULT CURRENT_TIMESTAMP(6),
+ `c` datetime(6) NOT NULL DEFAULT '2011-11-18 00:00:00.000000',
+ `like_c` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `d` timestamp(6) NULL DEFAULT '2011-05-03 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `e` timestamp(6) NOT NULL DEFAULT '2011-05-03 00:00:00.000000',
+ `f` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `g` timestamp(6) NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file1.dat" INTO table t1;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+# It is strange that "like_b" gets NULL when "b" gets 0. But
+# this is consistent with how "a" gets NULL when "b" gets 0,
+# with how "g" gets NULL when "d" gets 0, and with how "h" gets
+# NULL when "i" gets 0. Looks like "DEFAULT
+# <non-NULL-constant>" is changed to 0, whereas DEFAULT NULL
+# and DEFAULT NOW are changed to NULL.
+SELECT * FROM t1;
+dummy 1
+a NULL
+b 0000-00-00 00:00:00.000000
+like_b NULL
+c 0000-00-00 00:00:00.000000
+like_c 0000-00-00 00:00:00.000000
+d 0000-00-00 00:00:00.000000
+e 2011-08-01 15:11:19.089786
+f 2011-08-01 15:11:19.089786
+g NULL
+h NULL
+i 0
+delete from t1;
+alter table t1
+modify f TIMESTAMP NULL default CURRENT_TIMESTAMP;
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime(6) DEFAULT NULL,
+ `b` datetime(6) DEFAULT '2011-11-18 00:00:00.000000',
+ `like_b` datetime(6) DEFAULT CURRENT_TIMESTAMP(6),
+ `c` datetime(6) NOT NULL DEFAULT '2011-11-18 00:00:00.000000',
+ `like_c` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `d` timestamp(6) NULL DEFAULT '2011-05-03 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `e` timestamp(6) NOT NULL DEFAULT '2011-05-03 00:00:00.000000',
+ `f` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ `g` timestamp(6) NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file1.dat" INTO table t1;
+Warnings:
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+Warning 1261 Row 1 doesn't contain data for all columns
+SELECT * FROM t1;
+dummy 1
+a NULL
+b 0000-00-00 00:00:00.000000
+like_b NULL
+c 0000-00-00 00:00:00.000000
+like_c 0000-00-00 00:00:00.000000
+d 0000-00-00 00:00:00.000000
+e 2011-08-01 15:11:19.089786
+f NULL
+g NULL
+h NULL
+i 0
+delete from t1;
+drop table t1;
+# Conclusion derived from trunk's results:
+# DATETIME DEFAULT <non-NULL-constant> (b,c) gets 0000-00-00,
+# DATETIME DEFAULT NULL (a) gets NULL,
+# TIMESTAMP NULL DEFAULT <non-NULL-constant> (d) gets 0000-00-00,
+# TIMESTAMP NULL DEFAULT NULL (g) gets NULL,
+# TIMESTAMP NULL DEFAULT NOW (f after ALTER) gets NULL,
+# TIMESTAMP NOT NULL (f before ALTER, e) gets NOW.
+### Loading NULL ###
+CREATE TABLE t1 (
+dummy INT,
+a DATETIME(6) NULL DEFAULT NULL,
+b DATETIME(6) NULL DEFAULT "2011-11-18",
+like_b DATETIME(6) NULL DEFAULT CURRENT_TIMESTAMP(6),
+c DATETIME(6) NOT NULL DEFAULT "2011-11-18",
+like_c DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+d TIMESTAMP(6) NULL DEFAULT "2011-05-03" ON UPDATE CURRENT_TIMESTAMP(6),
+e TIMESTAMP(6) NOT NULL DEFAULT "2011-05-03",
+f TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+g TIMESTAMP(6) NULL DEFAULT NULL,
+h INT NULL,
+i INT NOT NULL DEFAULT 42
+);
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime(6) DEFAULT NULL,
+ `b` datetime(6) DEFAULT '2011-11-18 00:00:00.000000',
+ `like_b` datetime(6) DEFAULT CURRENT_TIMESTAMP(6),
+ `c` datetime(6) NOT NULL DEFAULT '2011-11-18 00:00:00.000000',
+ `like_c` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `d` timestamp(6) NULL DEFAULT '2011-05-03 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `e` timestamp(6) NOT NULL DEFAULT '2011-05-03 00:00:00.000000',
+ `f` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `g` timestamp(6) NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file2.dat" INTO table t1;
+Warnings:
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'like_c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'i' at row 1
+SELECT * FROM t1;
+dummy NULL
+a NULL
+b NULL
+like_b NULL
+c 0000-00-00 00:00:00.000000
+like_c 0000-00-00 00:00:00.000000
+d NULL
+e 2011-08-01 15:11:19.089786
+f 2011-08-01 15:11:19.089786
+g NULL
+h NULL
+i 0
+delete from t1;
+alter table t1
+modify f TIMESTAMP NULL default CURRENT_TIMESTAMP;
+# There is no promotion
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `dummy` int(11) DEFAULT NULL,
+ `a` datetime(6) DEFAULT NULL,
+ `b` datetime(6) DEFAULT '2011-11-18 00:00:00.000000',
+ `like_b` datetime(6) DEFAULT CURRENT_TIMESTAMP(6),
+ `c` datetime(6) NOT NULL DEFAULT '2011-11-18 00:00:00.000000',
+ `like_c` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ `d` timestamp(6) NULL DEFAULT '2011-05-03 00:00:00.000000' ON UPDATE CURRENT_TIMESTAMP(6),
+ `e` timestamp(6) NOT NULL DEFAULT '2011-05-03 00:00:00.000000',
+ `f` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
+ `g` timestamp(6) NULL DEFAULT NULL,
+ `h` int(11) DEFAULT NULL,
+ `i` int(11) NOT NULL DEFAULT '42'
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+LOAD DATA INFILE "file2.dat" INTO table t1;
+Warnings:
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'like_c' at row 1
+Warning 1263 Column set to default value; NULL supplied to NOT NULL column 'i' at row 1
+SELECT * FROM t1;
+dummy NULL
+a NULL
+b NULL
+like_b NULL
+c 0000-00-00 00:00:00.000000
+like_c 0000-00-00 00:00:00.000000
+d NULL
+e 2011-08-01 15:11:19.089786
+f NULL
+g NULL
+h NULL
+i 0
+delete from t1;
+# Conclusion derived from trunk's results:
+# DATETIME NULL (a,b) gets NULL,
+# DATETIME NOT NULL (c) gets 0000-00-00,
+# TIMESTAMP NULL (d,f,g) gets NULL,
+# TIMESTAMP NOT NULL (e) gets NOW.
+drop table t1;
+#
+# Test of updatable views with check options. The option can be violated
+# using ON UPDATE updates which is very strange as this offers a loophole
+# in this integrity check.
+#
+SET TIME_ZONE = "+03:00";
+# 1970-01-01 03:16:40
+SET TIMESTAMP = 1000.123456;
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)) ENGINE = INNODB;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `b` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+INSERT INTO t1 ( a ) VALUES ( 1 );
+SELECT * FROM t1;
+a b
+1 1970-01-01 03:16:40.123456
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE b <= '1970-01-01 03:16:40.123456'
+WITH CHECK OPTION;
+SELECT * FROM v1;
+a b
+1 1970-01-01 03:16:40.123456
+# 1970-01-01 03:33:20
+SET TIMESTAMP = 2000.000234;
+UPDATE v1 SET a = 2;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+SELECT * FROM t1;
+a b
+1 1970-01-01 03:16:40.123456
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT '1973-08-14 09:11:22.089786' ON UPDATE CURRENT_TIMESTAMP(6),
+c INT KEY
+);
+# 1973-08-14 09:11:22 UTC
+SET TIMESTAMP = 114167482.534231;
+INSERT INTO t1 ( c ) VALUES ( 1 );
+CREATE VIEW v1 AS
+SELECT *
+FROM t1
+WHERE a >= '1973-08-14 09:11:22'
+WITH LOCAL CHECK OPTION;
+SELECT * FROM v1;
+a c
+1973-08-14 09:11:22.089786 1
+SET TIMESTAMP = 1.126789;
+INSERT INTO v1 ( c ) VALUES ( 1 ) ON DUPLICATE KEY UPDATE c = 2;
+ERROR HY000: CHECK OPTION failed 'test.v1'
+SELECT * FROM v1;
+a c
+1973-08-14 09:11:22.089786 1
+DROP VIEW v1;
+DROP TABLE t1;
+#
+# Bug 13095459 - MULTI-TABLE UPDATE MODIFIES A ROW TWICE
+#
+CREATE TABLE t1 (
+a INT,
+b INT,
+ts TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
+PRIMARY KEY ( a, ts )
+) ENGINE = INNODB;
+INSERT INTO t1( a, b, ts ) VALUES ( 1, 0, '2000-09-28 17:44:34' );
+CREATE TABLE t2 ( a INT ) ENGINE = INNODB;
+INSERT INTO t2 VALUES ( 1 );
+UPDATE t1 STRAIGHT_JOIN t2
+SET t1.b = t1.b + 1
+WHERE t1.a = 1 AND t1.ts >= '2000-09-28 00:00:00';
+SELECT b FROM t1;
+b
+1
+DROP TABLE t1, t2;
+#
+# Bug#11745578: 17392: ALTER TABLE ADD COLUMN TIMESTAMP DEFAULT
+# CURRENT_TIMESTAMP INSERTS ZERO
+#
+SET timestamp = 1000;
+CREATE TABLE t1 ( b INT );
+INSERT INTO t1 VALUES (1);
+ALTER TABLE t1 ADD COLUMN a6 DATETIME(6) DEFAULT NOW(6) ON UPDATE NOW(6) FIRST;
+ALTER TABLE t1 ADD COLUMN a5 DATETIME(6) DEFAULT NOW(6) FIRST;
+ALTER TABLE t1 ADD COLUMN a4 DATETIME(6) ON UPDATE NOW(6) FIRST;
+ALTER TABLE t1 ADD COLUMN a3 TIMESTAMP(6) NOT NULL DEFAULT NOW(6) ON UPDATE NOW(6) FIRST;
+ALTER TABLE t1 ADD COLUMN a2 TIMESTAMP(6) NOT NULL DEFAULT NOW(6) FIRST;
+ALTER TABLE t1 ADD COLUMN a1 TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW(6) FIRST;
+ALTER TABLE t1 ADD COLUMN c1 TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE NOW(6) AFTER b;
+ALTER TABLE t1 ADD COLUMN c2 TIMESTAMP(6) NOT NULL DEFAULT NOW(6) AFTER c1;
+ALTER TABLE t1 ADD COLUMN c3 TIMESTAMP(6) NOT NULL DEFAULT NOW(6) ON UPDATE NOW(6) AFTER c2;
+ALTER TABLE t1 ADD COLUMN c4 DATETIME(6) ON UPDATE NOW(6) AFTER c3;
+ALTER TABLE t1 ADD COLUMN c5 DATETIME(6) DEFAULT NOW(6) AFTER c4;
+ALTER TABLE t1 ADD COLUMN c6 DATETIME(6) DEFAULT NOW(6) ON UPDATE NOW(6) AFTER c5;
+SELECT * FROM t1;
+a1 a2 a3 a4 a5 a6 b c1 c2 c3 c4 c5 c6
+0000-00-00 00:00:00.000000 1970-01-01 03:16:40.000000 1970-01-01 03:16:40.000000 NULL 1970-01-01 03:16:40.000000 1970-01-01 03:16:40.000000 1 0000-00-00 00:00:00.000000 1970-01-01 03:16:40.000000 1970-01-01 03:16:40.000000 NULL 1970-01-01 03:16:40.000000 1970-01-01 03:16:40.000000
+DROP TABLE t1;
+CREATE TABLE t1 ( a TIMESTAMP(6) NOT NULL DEFAULT NOW(6) ON UPDATE CURRENT_TIMESTAMP(6), b DATETIME(6) DEFAULT NOW(6) );
+INSERT INTO t1 VALUES ();
+SET timestamp = 1000000000;
+ALTER TABLE t1 MODIFY COLUMN a TIMESTAMP(3) DEFAULT CURRENT_TIMESTAMP(3);
+ALTER TABLE t1 MODIFY COLUMN b DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3);
+SELECT * FROM t1;
+a b
+1970-01-01 03:16:40.000 1970-01-01 03:16:40.000
+DROP TABLE t1;
+CREATE TABLE t1 (
+a TIMESTAMP(6) NOT NULL DEFAULT '1999-12-01 11:22:33' ON UPDATE CURRENT_TIMESTAMP(6),
+b DATETIME(6) DEFAULT '1999-12-01 11:22:33'
+);
+INSERT INTO t1 VALUES ();
+ALTER TABLE t1 MODIFY COLUMN a TIMESTAMP(6) DEFAULT NOW(6);
+ALTER TABLE t1 MODIFY COLUMN b DATETIME(6) DEFAULT NOW(6);
+INSERT INTO t1 VALUES ();
+SELECT * FROM t1;
+a b
+1999-12-01 11:22:33.000000 1999-12-01 11:22:33.000000
+2001-09-09 04:46:40.000000 2001-09-09 04:46:40.000000
+DROP TABLE t1;
diff --git a/mysql-test/r/function_defaults_notembedded.result b/mysql-test/r/function_defaults_notembedded.result
new file mode 100644
index 00000000000..c54ae14aef4
--- /dev/null
+++ b/mysql-test/r/function_defaults_notembedded.result
@@ -0,0 +1,171 @@
+#
+# Test of function defaults for non-embedded server.
+#
+#
+# Function defaults run 1. No microsecond precision.
+#
+SET TIME_ZONE = "+00:00";
+#
+# Test of INSERT DELAYED ... SET ...
+#
+# 2011-04-19 08:02:40 UTC
+SET TIMESTAMP = 1303200160.123456;
+CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
+INSERT DELAYED INTO t1 SET a = 1;
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:02:40
+SELECT * FROM t1 WHERE b = 0;
+a b
+INSERT DELAYED INTO t1 SET a = 2, b = '1980-01-02 10:20:30.405060';
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:02:40
+2 1980-01-02 10:20:30
+DROP TABLE t1;
+#
+# Test of INSERT DELAYED ... VALUES ...
+#
+# 2011-04-19 08:04:01 UTC
+SET TIMESTAMP = 1303200241.234567;
+CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
+INSERT DELAYED INTO t1 ( a ) VALUES (1);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:04:01
+INSERT DELAYED INTO t1 VALUES (2, '1977-12-19 12:34:56.789123');
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:04:01
+2 1977-12-19 12:34:56
+DROP TABLE t1;
+#
+# Test of a delayed insert handler servicing two insert operations
+# with different sets of active defaults.
+#
+CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
+# 2011-04-19 08:04:01 UTC
+SET TIMESTAMP = 1303200241.345678;
+SET debug_sync = 'before_write_delayed SIGNAL parked WAIT_FOR go';
+INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
+SET debug_sync = 'now WAIT_FOR parked';
+# 2011-04-19 08:04:01 UTC
+SET TIME_ZONE="+03:00";
+SET TIMESTAMP = 1303200241.456789;
+INSERT DELAYED INTO t1 ( a, b ) VALUES (4, '1977-12-19 12:34:56.789123'), (5, '1977-12-19 12:34:57.891234'), (6, '1977-12-19 12:34:58.912345');
+SET debug_sync = 'now SIGNAL go';
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:04:01
+2 2011-04-19 08:04:01
+3 2011-04-19 08:04:01
+4 1977-12-19 09:34:56
+5 1977-12-19 09:34:57
+6 1977-12-19 09:34:58
+DROP TABLE t1;
+#
+# Test of early activation of function defaults.
+#
+CREATE TABLE t1 ( a INT, b TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
+SET TIMESTAMP = 1317235172.987654;
+INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
+SET TIMESTAMP = 385503754.876543;
+INSERT DELAYED INTO t1 ( a ) VALUES (4), (5), (6);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-09-28 18:39:32
+2 2011-09-28 18:39:32
+3 2011-09-28 18:39:32
+4 1982-03-20 20:22:34
+5 1982-03-20 20:22:34
+6 1982-03-20 20:22:34
+DROP TABLE t1;
+#
+# Function defaults run 2. Six digits scale on seconds precision.
+#
+SET TIME_ZONE = "+00:00";
+#
+# Test of INSERT DELAYED ... SET ...
+#
+# 2011-04-19 08:02:40 UTC
+SET TIMESTAMP = 1303200160.123456;
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
+INSERT DELAYED INTO t1 SET a = 1;
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:02:40.123456
+SELECT * FROM t1 WHERE b = 0;
+a b
+INSERT DELAYED INTO t1 SET a = 2, b = '1980-01-02 10:20:30.405060';
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:02:40.123456
+2 1980-01-02 10:20:30.405060
+DROP TABLE t1;
+#
+# Test of INSERT DELAYED ... VALUES ...
+#
+# 2011-04-19 08:04:01 UTC
+SET TIMESTAMP = 1303200241.234567;
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
+INSERT DELAYED INTO t1 ( a ) VALUES (1);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:04:01.234567
+INSERT DELAYED INTO t1 VALUES (2, '1977-12-19 12:34:56.789123');
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:04:01.234567
+2 1977-12-19 12:34:56.789123
+DROP TABLE t1;
+#
+# Test of a delayed insert handler servicing two insert operations
+# with different sets of active defaults.
+#
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
+# 2011-04-19 08:04:01 UTC
+SET TIMESTAMP = 1303200241.345678;
+SET debug_sync = 'before_write_delayed SIGNAL parked WAIT_FOR go';
+INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
+SET debug_sync = 'now WAIT_FOR parked';
+# 2011-04-19 08:04:01 UTC
+SET TIME_ZONE="+03:00";
+SET TIMESTAMP = 1303200241.456789;
+INSERT DELAYED INTO t1 ( a, b ) VALUES (4, '1977-12-19 12:34:56.789123'), (5, '1977-12-19 12:34:57.891234'), (6, '1977-12-19 12:34:58.912345');
+SET debug_sync = 'now SIGNAL go';
+SELECT * FROM t1;
+a b
+1 2011-04-19 08:04:01.345678
+2 2011-04-19 08:04:01.345678
+3 2011-04-19 08:04:01.345678
+4 1977-12-19 09:34:56.789123
+5 1977-12-19 09:34:57.891234
+6 1977-12-19 09:34:58.912345
+DROP TABLE t1;
+#
+# Test of early activation of function defaults.
+#
+CREATE TABLE t1 ( a INT, b TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6));
+SET TIMESTAMP = 1317235172.987654;
+INSERT DELAYED INTO t1 ( a ) VALUES (1), (2), (3);
+SET TIMESTAMP = 385503754.876543;
+INSERT DELAYED INTO t1 ( a ) VALUES (4), (5), (6);
+FLUSH TABLE t1;
+SELECT * FROM t1;
+a b
+1 2011-09-28 18:39:32.987654
+2 2011-09-28 18:39:32.987654
+3 2011-09-28 18:39:32.987654
+4 1982-03-20 20:22:34.876543
+5 1982-03-20 20:22:34.876543
+6 1982-03-20 20:22:34.876543
+DROP TABLE t1;
diff --git a/mysql-test/r/log_slow.result b/mysql-test/r/log_slow.result
index 75e92e7a0b5..76cf45631bd 100644
--- a/mysql-test/r/log_slow.result
+++ b/mysql-test/r/log_slow.result
@@ -44,7 +44,7 @@ select @@log_slow_verbosity;
innodb
show fields from mysql.slow_log;
Field Type Null Key Default Extra
-start_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+start_time timestamp(6) NO CURRENT_TIMESTAMP(6) on update CURRENT_TIMESTAMP
user_host mediumtext NO NULL
query_time time(6) NO NULL
lock_time time(6) NO NULL
diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result
index 62775f3db4d..dd3bee0ac88 100644
--- a/mysql-test/r/log_tables.result
+++ b/mysql-test/r/log_tables.result
@@ -53,7 +53,7 @@ ERROR HY000: You can't use locks with log tables.
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -62,7 +62,7 @@ general_log CREATE TABLE `general_log` (
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='General log'
show fields from mysql.general_log;
Field Type Null Key Default Extra
-event_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+event_time timestamp(6) NO CURRENT_TIMESTAMP(6) on update CURRENT_TIMESTAMP
user_host mediumtext NO NULL
thread_id int(11) NO NULL
server_id int(10) unsigned NO NULL
@@ -71,7 +71,7 @@ argument mediumtext NO NULL
show create table mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
@@ -85,7 +85,7 @@ slow_log CREATE TABLE `slow_log` (
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log'
show fields from mysql.slow_log;
Field Type Null Key Default Extra
-start_time timestamp(6) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+start_time timestamp(6) NO CURRENT_TIMESTAMP(6) on update CURRENT_TIMESTAMP
user_host mediumtext NO NULL
query_time time(6) NO NULL
lock_time time(6) NO NULL
@@ -164,7 +164,7 @@ set global slow_query_log='OFF';
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -174,7 +174,7 @@ general_log CREATE TABLE `general_log` (
show create table mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
@@ -191,7 +191,7 @@ alter table mysql.slow_log engine=myisam;
show create table mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -201,7 +201,7 @@ general_log CREATE TABLE `general_log` (
show create table mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 7b650addd3d..ef8bcea3649 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -5239,7 +5239,7 @@ Error 1146 Table 'mysql.event' doesn't exist
SHOW CREATE TABLE mysql.general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -5249,7 +5249,7 @@ general_log CREATE TABLE `general_log` (
SHOW CREATE TABLE mysql.slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
diff --git a/mysql-test/r/system_mysql_db.result b/mysql-test/r/system_mysql_db.result
index d5409136ed4..9eb617d94f7 100644
--- a/mysql-test/r/system_mysql_db.result
+++ b/mysql-test/r/system_mysql_db.result
@@ -242,7 +242,7 @@ event CREATE TABLE `event` (
show create table general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
show create table slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
diff --git a/mysql-test/r/system_mysql_db_fix40123.result b/mysql-test/r/system_mysql_db_fix40123.result
index d5409136ed4..9eb617d94f7 100644
--- a/mysql-test/r/system_mysql_db_fix40123.result
+++ b/mysql-test/r/system_mysql_db_fix40123.result
@@ -242,7 +242,7 @@ event CREATE TABLE `event` (
show create table general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
show create table slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
diff --git a/mysql-test/r/system_mysql_db_fix50030.result b/mysql-test/r/system_mysql_db_fix50030.result
index d5409136ed4..9eb617d94f7 100644
--- a/mysql-test/r/system_mysql_db_fix50030.result
+++ b/mysql-test/r/system_mysql_db_fix50030.result
@@ -242,7 +242,7 @@ event CREATE TABLE `event` (
show create table general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
show create table slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
diff --git a/mysql-test/r/system_mysql_db_fix50117.result b/mysql-test/r/system_mysql_db_fix50117.result
index d5409136ed4..9eb617d94f7 100644
--- a/mysql-test/r/system_mysql_db_fix50117.result
+++ b/mysql-test/r/system_mysql_db_fix50117.result
@@ -242,7 +242,7 @@ event CREATE TABLE `event` (
show create table general_log;
Table Create Table
general_log CREATE TABLE `general_log` (
- `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `event_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`thread_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
@@ -252,7 +252,7 @@ general_log CREATE TABLE `general_log` (
show create table slow_log;
Table Create Table
slow_log CREATE TABLE `slow_log` (
- `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+ `start_time` timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
`user_host` mediumtext NOT NULL,
`query_time` time(6) NOT NULL,
`lock_time` time(6) NOT NULL,
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index 52c7f05839e..e7add0d80a7 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -148,15 +148,15 @@ ix+0
20030101000000
drop table t1;
create table t1 (t1 timestamp, t2 timestamp default now());
-ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
+drop table t1;
create table t1 (t1 timestamp, t2 timestamp on update now());
-ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
+drop table t1;
create table t1 (t1 timestamp, t2 timestamp default now() on update now());
-ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
+drop table t1;
create table t1 (t1 timestamp default now(), t2 timestamp on update now());
-ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
+drop table t1;
create table t1 (t1 timestamp on update now(), t2 timestamp default now() on update now());
-ERROR HY000: Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
+drop table t1;
create table t1 (t1 timestamp default '2003-01-01 00:00:00', t2 datetime, t3 timestamp);
SET TIMESTAMP=1000000000;
insert into t1 values ();
diff --git a/mysql-test/r/type_timestamp_hires.result b/mysql-test/r/type_timestamp_hires.result
index 3f1e05f4870..070f3032987 100644
--- a/mysql-test/r/type_timestamp_hires.result
+++ b/mysql-test/r/type_timestamp_hires.result
@@ -63,15 +63,15 @@ a
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+ `a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4) ON UPDATE CURRENT_TIMESTAMP(4)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
show columns from t1;
Field Type Null Key Default Extra
-a timestamp(4) NO CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
+a timestamp(4) NO CURRENT_TIMESTAMP(4) on update CURRENT_TIMESTAMP
select table_name, column_name, column_default, is_nullable, data_type, character_maximum_length, character_octet_length, numeric_precision, numeric_scale, datetime_precision, character_set_name, collation_name, column_type, column_key, extra from information_schema.columns where table_name='t1';
table_name t1
column_name a
-column_default CURRENT_TIMESTAMP
+column_default CURRENT_TIMESTAMP(4)
is_nullable NO
data_type timestamp
character_maximum_length NULL
@@ -113,7 +113,7 @@ t2 CREATE TABLE `t2` (
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
- `a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+ `a` timestamp(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4) ON UPDATE CURRENT_TIMESTAMP(4)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t2, t3;
insert t1 values ('2010-12-13 14:15:16.222222');
diff --git a/mysql-test/std_data/onerow.xml b/mysql-test/std_data/onerow.xml
new file mode 100644
index 00000000000..094dd813b2d
--- /dev/null
+++ b/mysql-test/std_data/onerow.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+<database name="test">
+ <table_structure name="onerow">
+ <field Field="a" Type="int(11)" Null="YES" Key="" Extra="" />
+ </table_structure>
+ <table_data name="onerow">
+ <row>
+ <field name="a">1</field>
+ </row>
+ </table_data>
+</database>
+</mysqldump>
diff --git a/mysql-test/suite/funcs_1/r/is_columns_mysql.result b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
index 4eff12dab7b..2a0c9296987 100644
--- a/mysql-test/suite/funcs_1/r/is_columns_mysql.result
+++ b/mysql-test/suite/funcs_1/r/is_columns_mysql.result
@@ -59,7 +59,7 @@ def mysql func ret 2 0 NO tinyint NULL NULL 3 0 NULL NULL NULL tinyint(1) sele
def mysql func type 4 NULL NO enum 9 27 NULL NULL NULL utf8 utf8_general_ci enum('function','aggregate') select,insert,update,references
def mysql general_log argument 6 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
def mysql general_log command_type 5 NULL NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select,insert,update,references
-def mysql general_log event_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
+def mysql general_log event_time 1 CURRENT_TIMESTAMP(6) NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
def mysql general_log server_id 4 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
def mysql general_log thread_id 3 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
def mysql general_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
@@ -159,7 +159,7 @@ def mysql slow_log rows_examined 6 NULL NO int NULL NULL 10 0 NULL NULL NULL int
def mysql slow_log rows_sent 5 NULL NO int NULL NULL 10 0 NULL NULL NULL int(11) select,insert,update,references
def mysql slow_log server_id 10 NULL NO int NULL NULL 10 0 NULL NULL NULL int(10) unsigned select,insert,update,references
def mysql slow_log sql_text 11 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
-def mysql slow_log start_time 1 CURRENT_TIMESTAMP NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
+def mysql slow_log start_time 1 CURRENT_TIMESTAMP(6) NO timestamp NULL NULL NULL NULL 6 NULL NULL timestamp(6) on update CURRENT_TIMESTAMP select,insert,update,references
def mysql slow_log user_host 2 NULL NO mediumtext 16777215 16777215 NULL NULL NULL utf8 utf8_general_ci mediumtext select,insert,update,references
def mysql tables_priv Column_priv 8 NO set 31 93 NULL NULL NULL utf8 utf8_general_ci set('Select','Insert','Update','References') select,insert,update,references
def mysql tables_priv Db 2 NO char 64 192 NULL NULL NULL utf8 utf8_bin char(64) PRI select,insert,update,references
diff --git a/mysql-test/suite/rpl/r/rpl_function_defaults.result b/mysql-test/suite/rpl/r/rpl_function_defaults.result
new file mode 100644
index 00000000000..264bb3c9c6d
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_function_defaults.result
@@ -0,0 +1,132 @@
+#
+# Test of function defaults on replicated tables.
+#
+include/master-slave.inc
+[connection master]
+connection master
+SET TIME_ZONE="+10:30";
+SET TIMESTAMP=123456.789123;
+SELECT CURRENT_TIMESTAMP;
+CURRENT_TIMESTAMP
+1970-01-02 20:47:36
+connection slave
+SET TIME_ZONE="+00:00";
+SET TIMESTAMP=987654321.123456;
+SELECT CURRENT_TIMESTAMP;
+CURRENT_TIMESTAMP
+2001-04-19 04:25:21
+connection master
+CREATE TABLE t1 (
+a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+b TIMESTAMP(1) NOT NULL DEFAULT CURRENT_TIMESTAMP(1),
+c TIMESTAMP(2) NOT NULL DEFAULT CURRENT_TIMESTAMP(2),
+d TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
+e TIMESTAMP(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4),
+f TIMESTAMP(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5),
+g TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+h DATETIME DEFAULT CURRENT_TIMESTAMP,
+i DATETIME(1) DEFAULT CURRENT_TIMESTAMP(1),
+j DATETIME(2) DEFAULT CURRENT_TIMESTAMP(2),
+k DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
+l DATETIME(4) DEFAULT CURRENT_TIMESTAMP(4),
+m DATETIME(5) DEFAULT CURRENT_TIMESTAMP(5),
+n DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+o INT
+);
+INSERT INTO t1 ( o ) VALUES ( 1 );
+CREATE TABLE t2 (
+a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+b TIMESTAMP(1) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(1),
+c TIMESTAMP(2) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(2),
+d TIMESTAMP(3) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(3),
+e TIMESTAMP(4) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(4),
+f TIMESTAMP(5) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(5),
+g TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+i DATETIME(1) ON UPDATE CURRENT_TIMESTAMP(1),
+j DATETIME(2) ON UPDATE CURRENT_TIMESTAMP(2),
+k DATETIME(3) ON UPDATE CURRENT_TIMESTAMP(3),
+l DATETIME(4) ON UPDATE CURRENT_TIMESTAMP(4),
+m DATETIME(5) ON UPDATE CURRENT_TIMESTAMP(5),
+n DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+o INT
+);
+INSERT INTO t2 ( o ) VALUES ( 1 );
+sync_slave_with_master
+connection slave
+SELECT * FROM t1;
+a 1970-01-02 10:17:36
+b 1970-01-02 10:17:36.7
+c 1970-01-02 10:17:36.78
+d 1970-01-02 10:17:36.789
+e 1970-01-02 10:17:36.7891
+f 1970-01-02 10:17:36.78912
+g 1970-01-02 10:17:36.789123
+h 1970-01-02 20:47:36
+i 1970-01-02 20:47:36.7
+j 1970-01-02 20:47:36.78
+k 1970-01-02 20:47:36.789
+l 1970-01-02 20:47:36.7891
+m 1970-01-02 20:47:36.78912
+n 1970-01-02 20:47:36.789123
+o 1
+SELECT * FROM t2;
+a 0000-00-00 00:00:00
+b 0000-00-00 00:00:00.0
+c 0000-00-00 00:00:00.00
+d 0000-00-00 00:00:00.000
+e 0000-00-00 00:00:00.0000
+f 0000-00-00 00:00:00.00000
+g 0000-00-00 00:00:00.000000
+h NULL
+i NULL
+j NULL
+k NULL
+l NULL
+m NULL
+n NULL
+o 1
+connection master
+SET TIMESTAMP=1234567890.123456;
+SELECT CURRENT_TIMESTAMP;
+CURRENT_TIMESTAMP
+2009-02-14 10:01:30
+UPDATE t1 SET o = 2;
+UPDATE t2 SET o = 2;
+sync_slave_with_master
+connection slave
+SELECT * FROM t1;
+a 1970-01-02 10:17:36
+b 1970-01-02 10:17:36.7
+c 1970-01-02 10:17:36.78
+d 1970-01-02 10:17:36.789
+e 1970-01-02 10:17:36.7891
+f 1970-01-02 10:17:36.78912
+g 1970-01-02 10:17:36.789123
+h 1970-01-02 20:47:36
+i 1970-01-02 20:47:36.7
+j 1970-01-02 20:47:36.78
+k 1970-01-02 20:47:36.789
+l 1970-01-02 20:47:36.7891
+m 1970-01-02 20:47:36.78912
+n 1970-01-02 20:47:36.789123
+o 2
+SELECT * FROM t2;
+a 2009-02-13 23:31:30
+b 2009-02-13 23:31:30.1
+c 2009-02-13 23:31:30.12
+d 2009-02-13 23:31:30.123
+e 2009-02-13 23:31:30.1234
+f 2009-02-13 23:31:30.12345
+g 2009-02-13 23:31:30.123456
+h 2009-02-14 10:01:30
+i 2009-02-14 10:01:30.1
+j 2009-02-14 10:01:30.12
+k 2009-02-14 10:01:30.123
+l 2009-02-14 10:01:30.1234
+m 2009-02-14 10:01:30.12345
+n 2009-02-14 10:01:30.123456
+o 2
+connection master
+DROP TABLE t1, t2;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_function_defaults.test b/mysql-test/suite/rpl/t/rpl_function_defaults.test
new file mode 100644
index 00000000000..24bec10d305
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_function_defaults.test
@@ -0,0 +1,93 @@
+--echo #
+--echo # Test of function defaults on replicated tables.
+--echo #
+
+source include/master-slave.inc;
+
+--echo connection master
+connection master;
+SET TIME_ZONE="+10:30";
+SET TIMESTAMP=123456.789123;
+SELECT CURRENT_TIMESTAMP;
+
+--echo connection slave
+connection slave;
+SET TIME_ZONE="+00:00";
+SET TIMESTAMP=987654321.123456;
+SELECT CURRENT_TIMESTAMP;
+
+--echo connection master
+connection master;
+CREATE TABLE t1 (
+ a TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ b TIMESTAMP(1) NOT NULL DEFAULT CURRENT_TIMESTAMP(1),
+ c TIMESTAMP(2) NOT NULL DEFAULT CURRENT_TIMESTAMP(2),
+ d TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
+ e TIMESTAMP(4) NOT NULL DEFAULT CURRENT_TIMESTAMP(4),
+ f TIMESTAMP(5) NOT NULL DEFAULT CURRENT_TIMESTAMP(5),
+ g TIMESTAMP(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
+ h DATETIME DEFAULT CURRENT_TIMESTAMP,
+ i DATETIME(1) DEFAULT CURRENT_TIMESTAMP(1),
+ j DATETIME(2) DEFAULT CURRENT_TIMESTAMP(2),
+ k DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3),
+ l DATETIME(4) DEFAULT CURRENT_TIMESTAMP(4),
+ m DATETIME(5) DEFAULT CURRENT_TIMESTAMP(5),
+ n DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
+ o INT
+);
+
+INSERT INTO t1 ( o ) VALUES ( 1 );
+
+CREATE TABLE t2 (
+ a TIMESTAMP NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP,
+ b TIMESTAMP(1) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(1),
+ c TIMESTAMP(2) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(2),
+ d TIMESTAMP(3) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(3),
+ e TIMESTAMP(4) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(4),
+ f TIMESTAMP(5) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(5),
+ g TIMESTAMP(6) NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP(6),
+ h DATETIME ON UPDATE CURRENT_TIMESTAMP,
+ i DATETIME(1) ON UPDATE CURRENT_TIMESTAMP(1),
+ j DATETIME(2) ON UPDATE CURRENT_TIMESTAMP(2),
+ k DATETIME(3) ON UPDATE CURRENT_TIMESTAMP(3),
+ l DATETIME(4) ON UPDATE CURRENT_TIMESTAMP(4),
+ m DATETIME(5) ON UPDATE CURRENT_TIMESTAMP(5),
+ n DATETIME(6) ON UPDATE CURRENT_TIMESTAMP(6),
+ o INT
+);
+
+INSERT INTO t2 ( o ) VALUES ( 1 );
+
+--echo sync_slave_with_master
+sync_slave_with_master;
+
+--echo connection slave
+connection slave;
+
+query_vertical SELECT * FROM t1;
+query_vertical SELECT * FROM t2;
+
+--echo connection master
+connection master;
+
+SET TIMESTAMP=1234567890.123456;
+SELECT CURRENT_TIMESTAMP;
+
+UPDATE t1 SET o = 2;
+UPDATE t2 SET o = 2;
+
+--echo sync_slave_with_master
+sync_slave_with_master;
+
+--echo connection slave
+connection slave;
+
+query_vertical SELECT * FROM t1;
+query_vertical SELECT * FROM t2;
+
+--echo connection master
+connection master;
+
+DROP TABLE t1, t2;
+
+--source include/rpl_end.inc
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index d80127df860..258213620ce 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -55,10 +55,10 @@ create table a (`aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
#
# Some wrong defaults, so these creates should fail too (Bug #5902)
#
---error 1067
create table t1 (a datetime default now());
---error 1294
+drop table t1;
create table t1 (a datetime on update now());
+drop table t1;
--error 1067
create table t1 (a int default 100 auto_increment);
--error 1067
diff --git a/mysql-test/t/function_defaults.test b/mysql-test/t/function_defaults.test
new file mode 100644
index 00000000000..dd29b4609cb
--- /dev/null
+++ b/mysql-test/t/function_defaults.test
@@ -0,0 +1,23 @@
+--echo #
+--echo # Test of function defaults for any server, including embedded.
+--echo #
+
+--source include/have_innodb.inc
+
+--echo #
+--echo # Function defaults run 1. No microsecond precision.
+--echo #
+let $current_timestamp=CURRENT_TIMESTAMP;
+let $now=NOW();
+let $timestamp=TIMESTAMP;
+let $datetime=DATETIME;
+source 'include/function_defaults.inc';
+
+--echo #
+--echo # Function defaults run 2. Six digits scale on seconds precision.
+--echo #
+let $current_timestamp=CURRENT_TIMESTAMP(6);
+let $now=NOW(6);
+let $timestamp=TIMESTAMP(6);
+let $datetime=DATETIME(6);
+source 'include/function_defaults.inc';
diff --git a/mysql-test/t/function_defaults_notembedded.test b/mysql-test/t/function_defaults_notembedded.test
new file mode 100644
index 00000000000..3d686c4b272
--- /dev/null
+++ b/mysql-test/t/function_defaults_notembedded.test
@@ -0,0 +1,18 @@
+--echo #
+--echo # Test of function defaults for non-embedded server.
+--echo #
+
+--source include/not_embedded.inc
+--source include/have_debug_sync.inc
+
+--echo #
+--echo # Function defaults run 1. No microsecond precision.
+--echo #
+let $timestamp=TIMESTAMP;
+--source include/function_defaults_notembedded.inc
+
+--echo #
+--echo # Function defaults run 2. Six digits scale on seconds precision.
+--echo #
+let $timestamp=TIMESTAMP(6);
+--source include/function_defaults_notembedded.inc
diff --git a/mysql-test/t/type_timestamp.test b/mysql-test/t/type_timestamp.test
index 575c30431b6..1c17743e7f1 100644
--- a/mysql-test/t/type_timestamp.test
+++ b/mysql-test/t/type_timestamp.test
@@ -86,17 +86,16 @@ drop table t1;
# Test for TIMESTAMP column with default now() and on update now() clauses
#
-# These statements should fail.
---error 1293
create table t1 (t1 timestamp, t2 timestamp default now());
---error 1293
+drop table t1;
create table t1 (t1 timestamp, t2 timestamp on update now());
---error 1293
+drop table t1;
create table t1 (t1 timestamp, t2 timestamp default now() on update now());
---error 1293
+drop table t1;
create table t1 (t1 timestamp default now(), t2 timestamp on update now());
---error 1293
+drop table t1;
create table t1 (t1 timestamp on update now(), t2 timestamp default now() on update now());
+drop table t1;
# Let us test TIMESTAMP auto-update behaviour
# Also we will test behaviour of TIMESTAMP field in SHOW CREATE TABLE and
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 21e3634f6c7..fb0887e25d1 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -829,9 +829,6 @@ Event_db_repository::update_event(THD *thd, Event_parse_data *parse_data,
(int) table->field[ET_FIELD_ON_COMPLETION]->val_int()))
goto end;
- /* Don't update create on row update. */
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
/*
mysql_event_fill_row() calls my_error() in case of error so no need to
handle it here
@@ -1133,8 +1130,6 @@ update_timing_fields_for_event(THD *thd,
goto end;
store_record(table, record[1]);
- /* Don't update create on row update. */
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
my_tz_OFFSET0->gmt_sec_to_TIME(&time, last_executed);
fields[ET_FIELD_LAST_EXECUTED]->set_notnull();
diff --git a/sql/field.cc b/sql/field.cc
index a3d3d951887..9a54dbf6c49 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -4419,10 +4419,12 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
{
/* For 4.0 MYD and 4.0 InnoDB compatibility */
flags|= UNSIGNED_FLAG | BINARY_FLAG;
- if (unireg_check != NONE && !share->timestamp_field)
+ if (unireg_check != NONE)
{
- /* This timestamp has auto-update */
- share->timestamp_field= this;
+ /*
+ This TIMESTAMP column is hereby quietly assumed to have an insert or
+ update default function.
+ */
flags|= TIMESTAMP_FLAG;
if (unireg_check != TIMESTAMP_DN_FIELD)
flags|= ON_UPDATE_NOW_FLAG;
@@ -4430,40 +4432,6 @@ Field_timestamp::Field_timestamp(uchar *ptr_arg, uint32 len_arg,
}
-/**
- Get auto-set type for TIMESTAMP field.
-
- Returns value indicating during which operations this TIMESTAMP field
- should be auto-set to current timestamp.
-*/
-timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
-{
- switch (unireg_check)
- {
- case TIMESTAMP_DN_FIELD:
- return TIMESTAMP_AUTO_SET_ON_INSERT;
- case TIMESTAMP_UN_FIELD:
- return TIMESTAMP_AUTO_SET_ON_UPDATE;
- case TIMESTAMP_OLD_FIELD:
- /*
- Although we can have several such columns in legacy tables this
- function should be called only for first of them (i.e. the one
- having auto-set property).
- */
- DBUG_ASSERT(table->timestamp_field == this);
- /* Fall-through */
- case TIMESTAMP_DNUN_FIELD:
- return TIMESTAMP_AUTO_SET_ON_BOTH;
- default:
- /*
- Normally this function should not be called for TIMESTAMPs without
- auto-set property.
- */
- DBUG_ASSERT(0);
- return TIMESTAMP_NO_AUTO_SET;
- }
-}
-
my_time_t Field_timestamp::get_timestamp(ulong *sec_part) const
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -4713,6 +4681,16 @@ int Field_timestamp::set_time()
return 0;
}
+void Field_timestamp::set_explicit_default(Item *value)
+{
+ if (value &&
+ ((value->type() == Item::DEFAULT_VALUE_ITEM &&
+ !((Item_default_value*)value)->arg) ||
+ (!maybe_null() && value->is_null())))
+ return;
+ flags|= HAS_EXPLICIT_DEFAULT;
+}
+
void Field_timestamp_hires::sql_type(String &res) const
{
CHARSET_INFO *cs=res.charset();
@@ -5836,6 +5814,20 @@ void Field_datetime::sql_type(String &res) const
res.set_ascii(STRING_WITH_LEN("datetime"));
}
+
+int Field_datetime::set_time()
+{
+ THD *thd= current_thd;
+ MYSQL_TIME now_time;
+ thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->query_start());
+ now_time.second_part= thd->query_start_sec_part();
+ set_notnull();
+ store_TIME(&now_time);
+ thd->time_zone_used= 1;
+ return 0;
+}
+
+
void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime)
{
ulonglong packed= sec_part_shift(pack_time(ltime), dec);
@@ -8857,16 +8849,37 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
{
uint sign_len, allowed_type_modifier= 0;
ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
+ const bool on_update_is_function=
+ (fld_on_update_value != NULL &&
+ fld_on_update_value->type() == Item::FUNC_ITEM);
DBUG_ENTER("Create_field::init()");
field= 0;
field_name= fld_name;
- def= fld_default_value;
flags= fld_type_modifier;
option_list= create_opt;
- unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
- Field::NEXT_NUMBER : Field::NONE);
+
+ if (fld_default_value != NULL && fld_default_value->type() == Item::FUNC_ITEM)
+ {
+ /* We have a function default for insertions. */
+ def= NULL;
+ unireg_check= on_update_is_function ?
+ Field::TIMESTAMP_DNUN_FIELD : // for insertions and for updates.
+ Field::TIMESTAMP_DN_FIELD; // only for insertions.
+ }
+ else
+ {
+ /* No function default for insertions. Either NULL or a constant. */
+ def= fld_default_value;
+ if (on_update_is_function)
+ unireg_check= Field::TIMESTAMP_UN_FIELD; // function default for updates
+ else
+ unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG) != 0 ?
+ Field::NEXT_NUMBER : // Automatic increment.
+ Field::NONE;
+ }
+
decimals= fld_decimals ? (uint)atoi(fld_decimals) : 0;
if (decimals >= NOT_FIXED_DEC)
{
@@ -9089,44 +9102,6 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
}
length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
flags|= UNSIGNED_FLAG;
-
- if (fld_default_value)
- {
- /* Grammar allows only NOW() value for ON UPDATE clause */
- if (fld_default_value->type() == Item::FUNC_ITEM &&
- ((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
- {
- unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
- Field::TIMESTAMP_DN_FIELD);
- /*
- We don't need default value any longer moreover it is dangerous.
- Everything handled by unireg_check further.
- */
- def= 0;
- }
- else
- unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
- Field::NONE);
- }
- else
- {
- /*
- If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
- or ON UPDATE values then for the sake of compatiblity we should treat
- this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
- have another TIMESTAMP column with auto-set option before this one)
- or DEFAULT 0 (in other cases).
- So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
- replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
- information about all TIMESTAMP fields in table will be availiable.
-
- If we have TIMESTAMP NULL column without explicit DEFAULT value
- we treat it as having DEFAULT NULL attribute.
- */
- unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
- (flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
- Field::NONE));
- }
break;
case MYSQL_TYPE_DATE:
/* We don't support creation of MYSQL_TYPE_DATE anymore */
@@ -9592,11 +9567,18 @@ Create_field::Create_field(Field *old_field,Field *orig_field)
def=0;
char_length= length;
- if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) &&
- old_field->ptr && orig_field &&
- (sql_type != MYSQL_TYPE_TIMESTAMP || /* set def only if */
- old_field->table->timestamp_field != old_field || /* timestamp field */
- unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */
+ /*
+ Copy the default value from the column object orig_field, if:
+ 1) The column has a constant default value.
+ 2) The column type is not a BLOB type.
+ 3) The original column (old_field) was properly initialized with a record
+ buffer pointer.
+ 4) The original column doesn't have a default function to auto-initialize
+ the column on INSERT
+ */
+ if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) && // 1) 2)
+ old_field->ptr && orig_field && // 3)
+ !old_field->has_insert_default_function()) // 4)
{
char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff), charset);
@@ -9780,3 +9762,12 @@ key_map Field::get_possible_keys()
return (table->pos_in_table_list->is_materialized_derived() ?
part_of_key : key_start);
}
+
+
+void Field::set_explicit_default(Item *value)
+{
+ if (value && value->type() == Item::DEFAULT_VALUE_ITEM &&
+ !((Item_default_value*)value)->arg)
+ return;
+ flags|= HAS_EXPLICIT_DEFAULT;
+}
diff --git a/sql/field.h b/sql/field.h
index f22bab0409d..7006e0bfbe8 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -329,6 +329,37 @@ public:
*null_ptr= ((*null_ptr & (uchar) ~null_bit) |
(null_ptr[l_offset] & null_bit));
}
+
+ bool has_insert_default_function() const
+ {
+ return unireg_check == TIMESTAMP_DN_FIELD ||
+ unireg_check == TIMESTAMP_DNUN_FIELD;
+ }
+
+ bool has_update_default_function() const
+ {
+ return unireg_check == TIMESTAMP_UN_FIELD ||
+ unireg_check == TIMESTAMP_DNUN_FIELD;
+ }
+
+ virtual void set_explicit_default(Item *value);
+
+ /**
+ Evaluates the @c INSERT default function and stores the result in the
+ field. If no such function exists for the column, or the function is not
+ valid for the column's data type, invoking this function has no effect.
+ */
+ virtual int evaluate_insert_default_function() { return 0; }
+
+
+ /**
+ Evaluates the @c UPDATE default function, if one exists, and stores the
+ result in the record buffer. If no such function exists for the column,
+ or the function is not valid for the column's data type, invoking this
+ function has no effect.
+ */
+ virtual int evaluate_update_default_function() { return 0; }
+
virtual bool binary() const { return 1; }
virtual bool zero_pack() const { return 1; }
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
@@ -1239,12 +1270,26 @@ public:
virtual int set_time();
virtual void set_default()
{
- if (table->timestamp_field == this &&
- unireg_check != TIMESTAMP_UN_FIELD)
+ if (has_insert_default_function())
set_time();
else
Field::set_default();
}
+ virtual void set_explicit_default(Item *value);
+ virtual int evaluate_insert_default_function()
+ {
+ int res= 0;
+ if (has_insert_default_function())
+ res= set_time();
+ return res;
+ }
+ virtual int evaluate_update_default_function()
+ {
+ int res= 0;
+ if (has_update_default_function())
+ res= set_time();
+ return res;
+ }
/* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
virtual my_time_t get_timestamp(ulong *sec_part) const;
virtual void store_TIME(my_time_t timestamp, ulong sec_part)
@@ -1252,7 +1297,6 @@ public:
int4store(ptr,timestamp);
}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
- timestamp_auto_set_type get_auto_set_type() const;
uchar *pack(uchar *to, const uchar *from,
uint max_length __attribute__((unused)))
{
@@ -1503,6 +1547,28 @@ public:
void sql_type(String &str) const;
bool zero_pack() const { return 1; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ virtual int set_time();
+ virtual void set_default()
+ {
+ if (has_insert_default_function())
+ set_time();
+ else
+ Field::set_default();
+ }
+ virtual int evaluate_insert_default_function()
+ {
+ int res= 0;
+ if (has_insert_default_function())
+ res= set_time();
+ return res;
+ }
+ virtual int evaluate_update_default_function()
+ {
+ int res= 0;
+ if (has_update_default_function())
+ res= set_time();
+ return res;
+ }
uchar *pack(uchar* to, const uchar *from,
uint max_length __attribute__((unused)))
{
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 2878f25ed14..6ba4fe46441 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -2906,8 +2906,6 @@ int ha_ndbcluster::write_row(uchar *record)
}
ha_statistic_increment(&SSV::ha_write_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
if (!(op= trans->getNdbOperation(m_table)))
ERR_RETURN(trans->getNdbError());
@@ -3146,11 +3144,6 @@ int ha_ndbcluster::update_row(const uchar *old_data, uchar *new_data)
}
ha_statistic_increment(&SSV::ha_update_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- {
- table->timestamp_field->set_time();
- bitmap_set_bit(table->write_set, table->timestamp_field->field_index);
- }
if (m_use_partition_function &&
(error= get_parts_for_update(old_data, new_data, table->record[0],
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index b3f97d35033..5f58247a79d 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -3451,8 +3451,8 @@ void ha_partition::try_semi_consistent_read(bool yes)
ADDITIONAL INFO:
- We have to set timestamp fields and auto_increment fields, because those
- may be used in determining which partition the row should be written to.
+ We have to set auto_increment fields, because those may be used in
+ determining which partition the row should be written to.
*/
int ha_partition::write_row(uchar * buf)
@@ -3463,7 +3463,6 @@ int ha_partition::write_row(uchar * buf)
bool have_auto_increment= table->next_number_field && buf == table->record[0];
my_bitmap_map *old_map;
THD *thd= ha_thd();
- timestamp_auto_set_type saved_timestamp_type= table->timestamp_field_type;
ulonglong saved_sql_mode= thd->variables.sql_mode;
bool saved_auto_inc_field_not_null= table->auto_increment_field_not_null;
#ifdef NOT_NEEDED
@@ -3472,11 +3471,6 @@ int ha_partition::write_row(uchar * buf)
DBUG_ENTER("ha_partition::write_row");
DBUG_ASSERT(buf == m_rec0);
- /* If we have a timestamp column, update it to the current time */
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
/*
If we have an auto_increment column and we are writing a changed row
or a new row, then update the auto_increment value in the record.
@@ -3552,7 +3546,6 @@ int ha_partition::write_row(uchar * buf)
exit:
thd->variables.sql_mode= saved_sql_mode;
table->auto_increment_field_not_null= saved_auto_inc_field_not_null;
- table->timestamp_field_type= saved_timestamp_type;
DBUG_RETURN(error);
}
@@ -3587,18 +3580,8 @@ int ha_partition::update_row(const uchar *old_data, uchar *new_data)
uint32 new_part_id, old_part_id;
int error= 0;
longlong func_value;
- timestamp_auto_set_type orig_timestamp_type= table->timestamp_field_type;
DBUG_ENTER("ha_partition::update_row");
- /*
- We need to set timestamp field once before we calculate
- the partition. Then we disable timestamp calculations
- inside m_file[*]->update_row() methods
- */
- if (orig_timestamp_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
if ((error= get_parts_for_update(old_data, new_data, table->record[0],
m_part_info, &old_part_id, &new_part_id,
&func_value)))
@@ -3672,7 +3655,6 @@ exit:
info(HA_STATUS_AUTO);
set_auto_increment_if_higher(table->found_next_number_field);
}
- table->timestamp_field_type= orig_timestamp_type;
DBUG_RETURN(error);
}
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 132f778ee08..bc787db95da 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -9885,23 +9885,6 @@ Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability
*/
}
- /*
- We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
- any TIMESTAMP column with data from the row but instead will use
- the event's current time.
- As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
- columns, we know that all TIMESTAMP columns on slave will receive explicit
- data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
- When we allow a table without TIMESTAMP to be replicated to a table having
- more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
- column to be replicated into a BIGINT column and the slave's table has a
- TIMESTAMP column, then the slave's TIMESTAMP column will take its value
- from set_time() which we called earlier (consistent with SBR). And then in
- some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
- analyze if explicit data is provided for slave's TIMESTAMP columns).
- */
- m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
/* Honor next number column if present */
m_table->next_number_field= m_table->found_next_number_field;
/*
@@ -10984,8 +10967,6 @@ Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability
if ((err= find_key()))
return err;
- m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
return 0;
}
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index d7c66af769a..bd837adc9d9 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -924,22 +924,6 @@ int Write_rows_log_event_old::do_before_row_operations(TABLE *table)
from the start.
*/
table->file->ha_start_bulk_insert(0);
- /*
- We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
- any TIMESTAMP column with data from the row but instead will use
- the event's current time.
- As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
- columns, we know that all TIMESTAMP columns on slave will receive explicit
- data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
- When we allow a table without TIMESTAMP to be replicated to a table having
- more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
- column to be replicated into a BIGINT column and the slave's table has a
- TIMESTAMP column, then the slave's TIMESTAMP column will take its value
- from set_time() which we called earlier (consistent with SBR). And then in
- some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
- analyze if explicit data is provided for slave's TIMESTAMP columns).
- */
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
return error;
}
@@ -1128,8 +1112,6 @@ int Update_rows_log_event_old::do_before_row_operations(TABLE *table)
if (!m_memory)
return HA_ERR_OUT_OF_MEM;
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
return error;
}
@@ -2589,22 +2571,6 @@ Write_rows_log_event_old::do_before_row_operations(const Slave_reporting_capabil
from the start.
*/
m_table->file->ha_start_bulk_insert(0);
- /*
- We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
- any TIMESTAMP column with data from the row but instead will use
- the event's current time.
- As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
- columns, we know that all TIMESTAMP columns on slave will receive explicit
- data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
- When we allow a table without TIMESTAMP to be replicated to a table having
- more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
- column to be replicated into a BIGINT column and the slave's table has a
- TIMESTAMP column, then the slave's TIMESTAMP column will take its value
- from set_time() which we called earlier (consistent with SBR). And then in
- some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
- analyze if explicit data is provided for slave's TIMESTAMP columns).
- */
- m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
return error;
}
@@ -2814,8 +2780,6 @@ Update_rows_log_event_old::do_before_row_operations(const Slave_reporting_capabi
return HA_ERR_OUT_OF_MEM;
}
- m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
return 0;
}
diff --git a/sql/sp.cc b/sql/sp.cc
index a1ff4db375b..0d9bbb37ede 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1350,7 +1350,6 @@ sp_update_routine(THD *thd, stored_procedure_type type, sp_name *name,
}
store_record(table,record[1]);
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
if (chistics->suid != SP_IS_DEFAULT_SUID)
table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index f3ba0073c69..11f962dd414 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -2426,7 +2426,6 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
{
LEX_STRING cmt = { 0, 0 };
uint unused1= 0;
- int unused2= 0;
if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec,
lex->type, (Item*) 0, (Item*) 0, &cmt, 0,
@@ -2443,8 +2442,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
sp_prepare_create_field(thd, field_def);
- if (prepare_create_field(field_def, &unused1, &unused2, &unused2,
- HA_CAN_GEOMETRY))
+ if (prepare_create_field(field_def, &unused1, HA_CAN_GEOMETRY))
{
return TRUE;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 85e9227c154..fd587640503 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -8800,13 +8800,13 @@ err_no_arena:
*/
static bool
-fill_record(THD * thd, List<Item> &fields, List<Item> &values,
+fill_record(THD * thd, TABLE *table_arg, List<Item> &fields, List<Item> &values,
bool ignore_errors)
{
List_iterator_fast<Item> f(fields),v(values);
Item *value, *fld;
Item_field *field;
- TABLE *table= 0, *vcol_table= 0;
+ TABLE *vcol_table= 0;
bool save_abort_on_warning= thd->abort_on_warning;
bool save_no_errors= thd->no_errors;
DBUG_ENTER("fill_record");
@@ -8828,12 +8828,13 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), fld->name);
goto err;
}
- table= field->field->table;
- table->auto_increment_field_not_null= FALSE;
+ DBUG_ASSERT(field->field->table == table_arg);
+ table_arg->auto_increment_field_not_null= FALSE;
f.rewind();
}
else if (thd->lex->unit.insert_table_with_stored_vcol)
vcol_table= thd->lex->unit.insert_table_with_stored_vcol;
+
while ((fld= f++))
{
if (!(field= fld->filed_for_view_update()))
@@ -8843,7 +8844,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
}
value=v++;
Field *rfield= field->field;
- table= rfield->table;
+ TABLE* table= rfield->table;
if (rfield == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
if (rfield->vcol_info &&
@@ -8861,6 +8862,7 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
goto err;
}
+ rfield->set_explicit_default(value);
DBUG_ASSERT(vcol_table == 0 || vcol_table == table);
vcol_table= table;
}
@@ -8875,8 +8877,8 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
err:
thd->abort_on_warning= save_abort_on_warning;
thd->no_errors= save_no_errors;
- if (table)
- table->auto_increment_field_not_null= FALSE;
+ if (fields.elements)
+ table_arg->auto_increment_field_not_null= FALSE;
DBUG_RETURN(TRUE);
}
@@ -8905,13 +8907,13 @@ err:
*/
bool
-fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
+fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, List<Item> &fields,
List<Item> &values, bool ignore_errors,
- Table_triggers_list *triggers,
enum trg_event_type event)
{
bool result;
- result= (fill_record(thd, fields, values, ignore_errors) ||
+ Table_triggers_list *triggers= table->triggers;
+ result= (fill_record(thd, table, fields, values, ignore_errors) ||
(triggers && triggers->process_triggers(thd, event,
TRG_ACTION_BEFORE, TRUE)));
/*
@@ -8920,7 +8922,6 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
*/
if (!result && triggers)
{
- TABLE *table= 0;
List_iterator_fast<Item> f(fields);
Item *fld;
Item_field *item_field;
@@ -8928,9 +8929,7 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
{
fld= (Item_field*)f++;
item_field= fld->filed_for_view_update();
- if (item_field && item_field->field &&
- (table= item_field->field->table) &&
- table->vfield)
+ if (item_field && item_field->field && table && table->vfield)
result= update_virtual_fields(thd, table, TRUE);
}
}
@@ -8960,13 +8959,12 @@ fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
*/
bool
-fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
- bool use_value)
+fill_record(THD *thd, TABLE *table, Field **ptr, List<Item> &values,
+ bool ignore_errors, bool use_value)
{
List_iterator_fast<Item> v(values);
List<TABLE> tbl_list;
Item *value;
- TABLE *table= 0;
Field *field;
bool abort_on_warning_saved= thd->abort_on_warning;
DBUG_ENTER("fill_record");
@@ -8981,7 +8979,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
On INSERT or UPDATE fields are checked to be from the same table,
thus we safely can take table from the first field.
*/
- table= (*ptr)->table;
+ DBUG_ASSERT((*ptr)->table == table);
/*
Reset the table->auto_increment_field_not_null as it is valid for
@@ -9012,6 +9010,7 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors,
else
if (value->save_in_field(field, 0) < 0)
goto err;
+ field->set_explicit_default(value);
}
/* Update virtual fields*/
thd->abort_on_warning= FALSE;
@@ -9051,13 +9050,13 @@ err:
*/
bool
-fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
+fill_record_n_invoke_before_triggers(THD *thd, TABLE *table, Field **ptr,
List<Item> &values, bool ignore_errors,
- Table_triggers_list *triggers,
enum trg_event_type event)
{
bool result;
- result= (fill_record(thd, ptr, values, ignore_errors, FALSE) ||
+ Table_triggers_list *triggers= table->triggers;
+ result= (fill_record(thd, table, ptr, values, ignore_errors, FALSE) ||
(triggers && triggers->process_triggers(thd, event,
TRG_ACTION_BEFORE, TRUE)));
/*
@@ -9066,7 +9065,6 @@ fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
*/
if (!result && triggers && *ptr)
{
- TABLE *table= (*ptr)->table;
if (table->vfield)
result= update_virtual_fields(thd, table, TRUE);
}
@@ -9706,11 +9704,6 @@ open_log_table(THD *thd, TABLE_LIST *one_table, Open_tables_backup *backup)
/* Make sure all columns get assigned to a default value */
table->use_all_columns();
table->no_replicate= 1;
- /*
- Don't set automatic timestamps as we may want to use time of logging,
- not from query start
- */
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
}
else
thd->restore_backup_open_tables_state(backup);
diff --git a/sql/sql_base.h b/sql/sql_base.h
index 3deb97c9730..fbe905375bb 100644
--- a/sql/sql_base.h
+++ b/sql/sql_base.h
@@ -170,15 +170,15 @@ TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
TABLE *find_temporary_table(THD *thd, const char *table_key,
uint table_key_length);
void close_thread_tables(THD *thd);
-bool fill_record_n_invoke_before_triggers(THD *thd, List<Item> &fields,
+bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
+ List<Item> &fields,
List<Item> &values,
bool ignore_errors,
- Table_triggers_list *triggers,
enum trg_event_type event);
-bool fill_record_n_invoke_before_triggers(THD *thd, Field **field,
+bool fill_record_n_invoke_before_triggers(THD *thd, TABLE *table,
+ Field **field,
List<Item> &values,
bool ignore_errors,
- Table_triggers_list *triggers,
enum trg_event_type event);
bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name, const char *table_name,
@@ -191,7 +191,7 @@ bool setup_fields(THD *thd, Item** ref_pointer_array,
List<Item> &item, enum_mark_columns mark_used_columns,
List<Item> *sum_func_list, bool allow_sum_func);
void unfix_fields(List<Item> &items);
-bool fill_record(THD *thd, Field **field, List<Item> &values,
+bool fill_record(THD *thd, TABLE *table, Field **field, List<Item> &values,
bool ignore_errors, bool use_value);
Field *
@@ -304,6 +304,7 @@ TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
void mark_tmp_table_for_reuse(TABLE *table);
bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists);
int update_virtual_fields(THD *thd, TABLE *table, bool ignore_stored= FALSE);
+int update_default_fields(TABLE *table);
int dynamic_column_error_message(enum_dyncol_func_result rc);
extern TABLE *unused_tables;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 3aa0c5ae9c7..b1153edbac8 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -4120,6 +4120,16 @@ public:
*/
#define CF_FORCE_ORIGINAL_BINLOG_FORMAT (1U << 10)
+/**
+ Statement that inserts new rows (INSERT, REPLACE, LOAD)
+*/
+#define CF_INSERTS_DATA (1U << 11)
+
+/**
+ Statement that updates existing rows (UPDATE, multi-update)
+*/
+#define CF_UPDATES_DATA (1U << 12)
+
/* Bits in server_command_flags */
/**
diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc
index e65ec3c22b0..1193c7c27f4 100644
--- a/sql/sql_expression_cache.cc
+++ b/sql/sql_expression_cache.cc
@@ -257,7 +257,7 @@ my_bool Expression_cache_tmptable::put_value(Item *value)
}
*(items.head_ref())= value;
- fill_record(table_thd, cache_table->field, items, TRUE, TRUE);
+ fill_record(table_thd, cache_table, cache_table->field, items, TRUE, TRUE);
if (table_thd->is_error())
goto err;;
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 3c3b9f85727..5d95ac2716d 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -191,11 +191,6 @@ error:
different table maps, like on select ... insert
map Store here table map for used fields
- 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
@@ -234,8 +229,6 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
if (check_grant_all_columns(thd, INSERT_ACL, &field_it))
return -1;
#endif
- clear_timestamp_auto_bits(table->timestamp_field_type,
- TIMESTAMP_AUTO_SET_ON_INSERT);
/*
No fields are provided so all fields must be provided in the values.
Thus we set all bits in the write set.
@@ -295,18 +288,8 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
my_error(ER_FIELD_SPECIFIED_TWICE, MYF(0), thd->dup_field->field_name);
return -1;
}
- if (table->timestamp_field) // Don't automaticly set timestamp if used
- {
- if (bitmap_is_set(table->write_set,
- table->timestamp_field->field_index))
- clear_timestamp_auto_bits(table->timestamp_field_type,
- TIMESTAMP_AUTO_SET_ON_INSERT);
- else
- {
- bitmap_set_bit(table->write_set,
- table->timestamp_field->field_index);
- }
- }
+ if (table->default_field)
+ table->mark_default_fields_for_write();
}
/* Mark virtual columns used in the insert statement */
if (table->vfield)
@@ -339,9 +322,6 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
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.
-
If the update fields include an autoinc field, set the
table->next_number_field_updated flag.
@@ -355,21 +335,9 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
List<Item> &update_values, table_map *map)
{
TABLE *table= insert_table_list->table;
- my_bool timestamp_mark;
my_bool autoinc_mark;
- LINT_INIT(timestamp_mark);
LINT_INIT(autoinc_mark);
- if (table->timestamp_field)
- {
- /*
- Unmark the timestamp field so that we can check if this is modified
- by update_fields
- */
- timestamp_mark= bitmap_test_and_clear(table->write_set,
- table->timestamp_field->field_index);
- }
-
table->next_number_field_updated= FALSE;
if (table->found_next_number_field)
@@ -393,17 +361,8 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
insert_table_list, map, false))
return -1;
- if (table->timestamp_field)
- {
- /* Don't set timestamp column if this is modified. */
- if (bitmap_is_set(table->write_set,
- table->timestamp_field->field_index))
- clear_timestamp_auto_bits(table->timestamp_field_type,
- TIMESTAMP_AUTO_SET_ON_UPDATE);
- if (timestamp_mark)
- bitmap_set_bit(table->write_set,
- table->timestamp_field->field_index);
- }
+ if (table->default_field)
+ table->mark_default_fields_for_write();
if (table->found_next_number_field)
{
@@ -709,7 +668,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
int error, res;
bool transactional_table, joins_freed= FALSE;
bool changed;
- bool was_insert_delayed= (table_list->lock_type == TL_WRITE_DELAYED);
+ const bool was_insert_delayed= (table_list->lock_type == TL_WRITE_DELAYED);
bool using_bulk_insert= 0;
uint value_count;
ulong counter = 1;
@@ -913,8 +872,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (fields.elements || !value_count)
{
restore_record(table,s->default_values); // Get empty record
- if (fill_record_n_invoke_before_triggers(thd, fields, *values, 0,
- table->triggers,
+ if (fill_record_n_invoke_before_triggers(thd, table, fields, *values, 0,
TRG_EVENT_INSERT))
{
if (values_list.elements != 1 && ! thd->is_error())
@@ -958,8 +916,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
share->default_values[share->null_bytes - 1];
}
}
- if (fill_record_n_invoke_before_triggers(thd, table->field, *values, 0,
- table->triggers,
+ if (fill_record_n_invoke_before_triggers(thd, table, table->field, *values, 0,
TRG_EVENT_INSERT))
{
if (values_list.elements != 1 && ! thd->is_error())
@@ -971,6 +928,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
break;
}
}
+ if (table->default_field && table->update_default_fields())
+ {
+ error= 1;
+ break;
+ }
if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ?
@@ -987,7 +949,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (lock_type == TL_WRITE_DELAYED)
{
LEX_STRING const st_query = { query, thd->query_length() };
+ DEBUG_SYNC(thd, "before_write_delayed");
error=write_delayed(thd, table, duplic, st_query, ignore, log_on);
+ DEBUG_SYNC(thd, "after_write_delayed");
query=0;
}
else
@@ -1696,13 +1660,32 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
restore_record(table,record[1]);
DBUG_ASSERT(info->update_fields->elements ==
info->update_values->elements);
- if (fill_record_n_invoke_before_triggers(thd, *info->update_fields,
+ if (fill_record_n_invoke_before_triggers(thd, table, *info->update_fields,
*info->update_values,
info->ignore,
- table->triggers,
TRG_EVENT_UPDATE))
goto before_trg_err;
+ bool different_records= (!records_are_comparable(table) ||
+ compare_record(table));
+ /*
+ Default fields must be updated before checking view updateability.
+ This branch of INSERT is executed only when a UNIQUE key was violated
+ with the ON DUPLICATE KEY UPDATE option. In this case the INSERT
+ operation is transformed to an UPDATE, and the default fields must
+ be updated as this is an UPDATE.
+ */
+ if (different_records && table->default_field)
+ {
+ bool res;
+ enum_sql_command cmd= thd->lex->sql_command;
+ thd->lex->sql_command= SQLCOM_UPDATE;
+ res= table->update_default_fields();
+ thd->lex->sql_command= cmd;
+ if (res)
+ goto err;
+ }
+
/* CHECK OPTION for VIEW ... ON DUPLICATE KEY UPDATE ... */
if (info->view &&
(res= info->view->view_check_option(current_thd, info->ignore)) ==
@@ -1713,7 +1696,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
table->file->restore_auto_increment(prev_insert_id);
info->touched++;
- if (!records_are_comparable(table) || compare_record(table))
+ if (different_records)
{
if ((error=table->file->ha_update_row(table->record[1],
table->record[0])) &&
@@ -1784,8 +1767,6 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
*/
if (last_uniq_key(table,key_nr) &&
!table->file->referenced_by_foreign_key() &&
- (table->timestamp_field_type == TIMESTAMP_NO_AUTO_SET ||
- table->timestamp_field_type == TIMESTAMP_AUTO_SET_ON_BOTH) &&
(!table->triggers || !table->triggers->has_delete_triggers()))
{
if ((error=table->file->ha_update_row(table->record[1],
@@ -1948,7 +1929,6 @@ public:
ulonglong forced_insert_id;
ulong auto_increment_increment;
ulong auto_increment_offset;
- timestamp_auto_set_type timestamp_field_type;
LEX_STRING query;
Time_zone *time_zone;
@@ -2321,7 +2301,7 @@ end_create:
TABLE *Delayed_insert::get_local_table(THD* client_thd)
{
my_ptrdiff_t adjust_ptrs;
- Field **field,**org_field, *found_next_number_field;
+ Field **field,**org_field, *found_next_number_field, **dfield_ptr;
TABLE *copy;
TABLE_SHARE *share;
uchar *bitmap;
@@ -2390,6 +2370,12 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
bitmap= (uchar*) (field + share->fields + 1);
copy->record[0]= (bitmap + share->column_bitmap_size*3);
memcpy((char*) copy->record[0], (char*) table->record[0], share->reclength);
+ if (share->default_fields)
+ {
+ copy->default_field= (Field**) client_thd->alloc((share->default_fields+1)*
+ sizeof(Field**));
+ dfield_ptr= copy->default_field;
+ }
/*
Make a copy of all fields.
The copied fields need to point into the copied record. This is done
@@ -2407,18 +2393,19 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
if (*org_field == found_next_number_field)
(*field)->table->found_next_number_field= *field;
+ if (share->default_fields &&
+ ((*org_field)->has_insert_default_function() ||
+ (*org_field)->has_update_default_function()))
+ {
+ /* Put the newly copied field into the set of default fields. */
+ *dfield_ptr= *field;
+ (*dfield_ptr)->unireg_check= (*org_field)->unireg_check;
+ dfield_ptr++;
+ }
}
*field=0;
-
- /* Adjust timestamp */
- if (table->timestamp_field)
- {
- /* Restore offset as this may have been reset in handle_inserts */
- copy->timestamp_field=
- (Field_timestamp*) copy->field[share->timestamp_field_offset];
- copy->timestamp_field->unireg_check= table->timestamp_field->unireg_check;
- copy->timestamp_field_type= copy->timestamp_field->get_auto_set_type();
- }
+ if (share->default_fields)
+ *dfield_ptr= NULL;
/* Adjust in_use for pointing to client thread */
copy->in_use= client_thd;
@@ -2508,7 +2495,6 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic,
thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
row->first_successful_insert_id_in_prev_stmt=
thd->first_successful_insert_id_in_prev_stmt;
- row->timestamp_field_type= table->timestamp_field_type;
/* Add session variable timezone
Time_zone object will not be freed even the thread is ended.
@@ -3051,7 +3037,6 @@ bool Delayed_insert::handle_inserts(void)
row->first_successful_insert_id_in_prev_stmt;
thd.stmt_depends_on_first_successful_insert_id_in_prev_stmt=
row->stmt_depends_on_first_successful_insert_id_in_prev_stmt;
- table->timestamp_field_type= row->timestamp_field_type;
table->auto_increment_field_not_null= row->auto_increment_field_not_null;
/* Copy the session variables. */
@@ -3527,6 +3512,8 @@ int select_insert::send_data(List<Item> &values)
thd->count_cuted_fields= CHECK_FIELD_WARN; // Calculate cuted fields
store_values(values);
+ if (table->default_field && table->update_default_fields())
+ DBUG_RETURN(1);
thd->count_cuted_fields= CHECK_FIELD_ERROR_FOR_NULL;
if (thd->is_error())
{
@@ -3586,11 +3573,11 @@ int select_insert::send_data(List<Item> &values)
void select_insert::store_values(List<Item> &values)
{
if (fields->elements)
- fill_record_n_invoke_before_triggers(thd, *fields, values, 1,
- table->triggers, TRG_EVENT_INSERT);
+ fill_record_n_invoke_before_triggers(thd, table, *fields, values, 1,
+ TRG_EVENT_INSERT);
else
- fill_record_n_invoke_before_triggers(thd, table->field, values, 1,
- table->triggers, TRG_EVENT_INSERT);
+ fill_record_n_invoke_before_triggers(thd, table, table->field, values, 1,
+ TRG_EVENT_INSERT);
}
void select_insert::send_error(uint errcode,const char *err)
@@ -3808,7 +3795,6 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
DBUG_ENTER("create_table_from_items");
tmp_table.alias= 0;
- tmp_table.timestamp_field= 0;
tmp_table.s= &share;
init_tmp_table_share(thd, &share, "", 0, "", "");
@@ -3817,6 +3803,8 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
tmp_table.null_row= 0;
tmp_table.maybe_null= 0;
+ promote_first_timestamp_column(&alter_info->create_list);
+
while ((item=it++))
{
Create_field *cr_field;
@@ -4056,8 +4044,6 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
for (Field **f= field ; *f ; f++)
bitmap_set_bit(table->write_set, (*f)->field_index);
- /* Don't set timestamp if used */
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
table->next_number_field=table->found_next_number_field;
restore_record(table,s->default_values); // Get empty record
@@ -4133,8 +4119,8 @@ select_create::binlog_show_create_table(TABLE **tables, uint count)
void select_create::store_values(List<Item> &values)
{
- fill_record_n_invoke_before_triggers(thd, field, values, 1,
- table->triggers, TRG_EVENT_INSERT);
+ fill_record_n_invoke_before_triggers(thd, table, field, values, 1,
+ TRG_EVENT_INSERT);
}
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index 98031c96225..18cea96dd92 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -273,7 +273,6 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
for (field=table->field; *field ; field++)
fields_vars.push_back(new Item_field(*field));
bitmap_set_all(table->write_set);
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
/*
Let us also prepare SET clause, altough it is probably empty
in this case.
@@ -289,21 +288,9 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
setup_fields(thd, 0, set_fields, MARK_COLUMNS_WRITE, 0, 0) ||
check_that_all_fields_are_given_values(thd, table, table_list))
DBUG_RETURN(TRUE);
- /*
- Check whenever TIMESTAMP field with auto-set feature specified
- explicitly.
- */
- if (table->timestamp_field)
- {
- if (bitmap_is_set(table->write_set,
- table->timestamp_field->field_index))
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
- else
- {
- bitmap_set_bit(table->write_set,
- table->timestamp_field->field_index);
- }
- }
+ /* Add all fields with default functions to table->write_set. */
+ if (table->default_field)
+ table->mark_default_fields_for_write();
/* Fix the expressions in SET clause */
if (setup_fields(thd, 0, set_values, MARK_COLUMNS_READ, 0, 0))
DBUG_RETURN(TRUE);
@@ -850,7 +837,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
ER(ER_WARN_TOO_FEW_RECORDS),
thd->warning_info->current_row_for_warning());
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
- ((Field_timestamp*) field)->set_time();
+ field->set_time();
}
else
{
@@ -864,6 +851,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
pos[length]=save_chr;
if ((pos+=length) > read_info.row_end)
pos= read_info.row_end; /* Fills rest with space */
+ field->set_explicit_default(NULL);
}
}
if (pos != read_info.row_end)
@@ -876,10 +864,10 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
if (thd->killed ||
- fill_record_n_invoke_before_triggers(thd, set_fields, set_values,
+ fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
ignore_check_option_errors,
- table->triggers,
- TRG_EVENT_INSERT))
+ TRG_EVENT_INSERT) ||
+ (table->default_field && table->update_default_fields()))
DBUG_RETURN(1);
switch (table_list->view_check_option(thd,
@@ -994,10 +982,11 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(1);
}
field->set_null();
+ field->set_explicit_default(NULL);
if (!field->maybe_null())
{
if (field->type() == MYSQL_TYPE_TIMESTAMP)
- ((Field_timestamp*) field)->set_time();
+ field->set_time();
else if (field != table->next_number_field)
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_NULL_TO_NOTNULL, 1);
@@ -1025,6 +1014,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (field == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
field->store((char*) pos, length, read_info.read_charset);
+ field->set_explicit_default(NULL);
}
else if (item->type() == Item::STRING_ITEM)
{
@@ -1066,7 +1056,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(1);
}
if (!field->maybe_null() && field->type() == FIELD_TYPE_TIMESTAMP)
- ((Field_timestamp*) field)->set_time();
+ field->set_time();
/*
TODO: We probably should not throw warning for each field.
But how about intention to always have the same number
@@ -1093,10 +1083,10 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
if (thd->killed ||
- fill_record_n_invoke_before_triggers(thd, set_fields, set_values,
+ fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
ignore_check_option_errors,
- table->triggers,
- TRG_EVENT_INSERT))
+ TRG_EVENT_INSERT) ||
+ (table->default_field && table->update_default_fields()))
DBUG_RETURN(1);
switch (table_list->view_check_option(thd,
@@ -1206,7 +1196,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (!field->maybe_null())
{
if (field->type() == FIELD_TYPE_TIMESTAMP)
- ((Field_timestamp *) field)->set_time();
+ field->set_time();
else if (field != table->next_number_field)
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_NULL_TO_NOTNULL, 1);
@@ -1225,6 +1215,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
if (field == table->next_number_field)
table->auto_increment_field_not_null= TRUE;
field->store((char *) tag->value.ptr(), tag->value.length(), cs);
+ field->set_explicit_default(NULL);
}
else
((Item_user_var_as_out_param *) item)->set_value(
@@ -1269,10 +1260,10 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
if (thd->killed ||
- fill_record_n_invoke_before_triggers(thd, set_fields, set_values,
+ fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
ignore_check_option_errors,
- table->triggers,
- TRG_EVENT_INSERT))
+ TRG_EVENT_INSERT) ||
+ (table->default_field && table->update_default_fields()))
DBUG_RETURN(1);
switch (table_list->view_check_option(thd,
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 175c2c1d672..aa62e450f9d 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -268,12 +268,14 @@ void init_update_queries(void)
CF_CAN_GENERATE_ROW_EVENTS;
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
- CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS ;
+ CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS |
+ CF_INSERTS_DATA;
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS | CF_REPORT_PROGRESS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_REPORT_PROGRESS |
+ CF_INSERTS_DATA;
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
@@ -290,21 +292,21 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_UPDATES_DATA;
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_UPDATES_DATA;
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS;
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS;
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
- CF_CAN_GENERATE_ROW_EVENTS;
+ CF_CAN_GENERATE_ROW_EVENTS | CF_INSERTS_DATA;
sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE |
CF_CAN_GENERATE_ROW_EVENTS;
sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
@@ -5881,11 +5883,11 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
no need fix_fields()
We allow only one function as part of default value -
- NOW() as default for TIMESTAMP type.
+ NOW() as default for TIMESTAMP and DATETIME type.
*/
if (default_value->type() == Item::FUNC_ITEM &&
!(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
- type == MYSQL_TYPE_TIMESTAMP))
+ (type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_DATETIME)))
{
my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
DBUG_RETURN(1);
@@ -5907,7 +5909,8 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
}
}
- if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
+ if (on_update_value &&
+ !(type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_DATETIME))
{
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
DBUG_RETURN(1);
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index 2bec12e4f66..f042f028450 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -6526,9 +6526,6 @@ uint fast_alter_partition_table(THD *thd, TABLE *table,
lpt->pack_frm_data= NULL;
lpt->pack_frm_len= 0;
- /* Never update timestamp columns when alter */
- lpt->table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-
if (table->file->alter_table_flags(alter_info->flags) &
HA_PARTITION_ONE_PHASE)
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f0c786dea86..e89d4c14c96 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -9463,7 +9463,7 @@ end_sj_materialize(JOIN *join, JOIN_TAB *join_tab, bool end_of_records)
if (item->is_null())
DBUG_RETURN(NESTED_LOOP_OK);
}
- fill_record(thd, table->field, sjm->sjm_table_cols, TRUE, FALSE);
+ fill_record(thd, table, table->field, sjm->sjm_table_cols, TRUE, FALSE);
if (thd->is_error())
DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
if ((error= table->file->ha_write_tmp_row(table->record[0])))
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 8a106b8ec6f..a71ca73789f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1108,8 +1108,35 @@ static void append_directory(THD *thd, String *packet, const char *dir_type,
#define LIST_PROCESS_HOST_LEN 64
-static bool get_field_default_value(THD *thd, Field *timestamp_field,
- Field *field, String *def_value,
+
+/**
+ Print "ON UPDATE" clause of a field into a string.
+
+ @param timestamp_field Pointer to timestamp field of a table.
+ @param field The field to generate ON UPDATE clause for.
+ @bool lcase Whether to print in lower case.
+ @return false on success, true on error.
+*/
+static bool print_on_update_clause(Field *field, String *val, bool lcase)
+{
+ DBUG_ASSERT(val->charset()->mbminlen == 1);
+ val->length(0);
+ if (field->has_update_default_function())
+ {
+ if (lcase)
+ val->append(STRING_WITH_LEN("on update "));
+ else
+ val->append(STRING_WITH_LEN("ON UPDATE "));
+ val->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
+ if (field->decimals() > 0)
+ val->append_parenthesized(field->decimals());
+ return true;
+ }
+ return false;
+}
+
+
+static bool get_field_default_value(THD *thd, Field *field, String *def_value,
bool quoted)
{
bool has_default;
@@ -1120,8 +1147,7 @@ static bool get_field_default_value(THD *thd, Field *timestamp_field,
We are using CURRENT_TIMESTAMP instead of NOW because it is
more standard
*/
- has_now_default= (timestamp_field == field &&
- field->unireg_check != Field::TIMESTAMP_UN_FIELD);
+ has_now_default= field->has_insert_default_function();
has_default= (field_type != FIELD_TYPE_BLOB &&
!(field->flags & NO_DEFAULT_VALUE_FLAG) &&
@@ -1133,7 +1159,11 @@ static bool get_field_default_value(THD *thd, Field *timestamp_field,
if (has_default)
{
if (has_now_default)
+ {
def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
+ if (field->decimals() > 0)
+ def_value->append_parenthesized(field->decimals());
+ }
else if (!field->is_null())
{ // Not null by default
char tmp[MAX_FIELD_WIDTH];
@@ -1365,16 +1395,18 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
}
if (!field->vcol_info &&
- get_field_default_value(thd, table->timestamp_field,
- field, &def_value, 1))
+ get_field_default_value(thd, field, &def_value, 1))
{
packet->append(STRING_WITH_LEN(" DEFAULT "));
packet->append(def_value.ptr(), def_value.length(), system_charset_info);
}
- if (!limited_mysql_mode && table->timestamp_field == field &&
- field->unireg_check != Field::TIMESTAMP_DN_FIELD)
- packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
+ if (!limited_mysql_mode && print_on_update_clause(field, &def_value, false))
+ {
+ packet->append(STRING_WITH_LEN(" "));
+ packet->append(def_value);
+ }
+
if (field->unireg_check == Field::NEXT_NUMBER &&
!(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
@@ -4758,7 +4790,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
const char *wild= lex->wild ? lex->wild->ptr() : NullS;
CHARSET_INFO *cs= system_charset_info;
TABLE *show_table;
- Field **ptr, *field, *timestamp_field;
+ Field **ptr, *field;
int count;
DBUG_ENTER("get_schema_column_record");
@@ -4782,7 +4814,6 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
show_table= tables->table;
count= 0;
ptr= show_table->field;
- timestamp_field= show_table->timestamp_field;
show_table->use_all_columns(); // Required for default
restore_record(show_table, s->default_values);
@@ -4830,7 +4861,7 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
cs);
table->field[4]->store((longlong) count, TRUE);
- if (get_field_default_value(thd, timestamp_field, field, &type, 0))
+ if (get_field_default_value(thd, field, &type, 0))
{
table->field[5]->store(type.ptr(), type.length(), cs);
table->field[5]->set_notnull();
@@ -4847,10 +4878,8 @@ static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
if (field->unireg_check == Field::NEXT_NUMBER)
table->field[17]->store(STRING_WITH_LEN("auto_increment"), cs);
- if (timestamp_field == field &&
- field->unireg_check != Field::TIMESTAMP_DN_FIELD)
- table->field[17]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
- cs);
+ if (print_on_update_clause(field, &type, true))
+ table->field[17]->store(type.ptr(), type.length(), cs);
if (field->vcol_info)
{
if (field->stored_in_db)
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 75029a03790..89536b93feb 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -502,6 +502,24 @@ bool String::append(IO_CACHE* file, uint32 arg_length)
return FALSE;
}
+
+/**
+ Append a parenthesized number to String.
+ Used in various pieces of SHOW related code.
+
+ @param nr Number
+ @param radix Radix, optional parameter, 10 by default.
+*/
+bool String::append_parenthesized(long nr, int radix)
+{
+ char buff[64], *end;
+ buff[0]= '(';
+ end= int10_to_str(nr, buff + 1, radix);
+ *end++ = ')';
+ return append(buff, (uint) (end - buff));
+}
+
+
bool String::append_with_prefill(const char *s,uint32 arg_length,
uint32 full_length, char fill_char)
{
diff --git a/sql/sql_string.h b/sql/sql_string.h
index 2f0cd9103dc..633170a5e20 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -343,6 +343,7 @@ public:
bool append(IO_CACHE* file, uint32 arg_length);
bool append_with_prefill(const char *s, uint32 arg_length,
uint32 full_length, char fill_char);
+ bool append_parenthesized(long nr, int radix= 10);
int strstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
int strrstr(const String &search,uint32 offset=0); // Returns offset to substring or -1
bool replace(uint32 offset,uint32 arg_length,const char *to,uint32 length);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 5a6090e5d9a..e66d4f529de 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2607,7 +2607,6 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
prepare_create_field()
sql_field field to prepare for packing
blob_columns count for BLOBs
- timestamps count for timestamps
table_flags table flags
DESCRIPTION
@@ -2621,7 +2620,6 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
int prepare_create_field(Create_field *sql_field,
uint *blob_columns,
- int *timestamps, int *timestamps_with_niladic,
longlong table_flags)
{
unsigned int dup_val_count;
@@ -2743,21 +2741,6 @@ int prepare_create_field(Create_field *sql_field,
(sql_field->decimals << FIELDFLAG_DEC_SHIFT));
break;
case MYSQL_TYPE_TIMESTAMP:
- /* We should replace old TIMESTAMP fields with their newer analogs */
- if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
- {
- if (!*timestamps)
- {
- sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
- (*timestamps_with_niladic)++;
- }
- else
- sql_field->unireg_check= Field::NONE;
- }
- else if (sql_field->unireg_check != Field::NONE)
- (*timestamps_with_niladic)++;
-
- (*timestamps)++;
/* fall-through */
default:
sql_field->pack_flag=(FIELDFLAG_NUMBER |
@@ -2829,6 +2812,40 @@ bool check_duplicate_warning(THD *thd, char *msg, ulong length)
}
+/**
+ Modifies the first column definition whose SQL type is TIMESTAMP
+ by adding the features DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP.
+
+ @param column_definitions The list of column definitions, in the physical
+ order in which they appear in the table.
+ */
+void promote_first_timestamp_column(List<Create_field> *column_definitions)
+{
+ List_iterator<Create_field> it(*column_definitions);
+ Create_field *column_definition;
+
+ while ((column_definition= it++) != NULL)
+ {
+ if (column_definition->sql_type == MYSQL_TYPE_TIMESTAMP || // TIMESTAMP
+ column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD) // Legacy
+ {
+ if ((column_definition->flags & NOT_NULL_FLAG) != 0 && // NOT NULL,
+ column_definition->def == NULL && // no constant default,
+ column_definition->unireg_check == Field::NONE) // no function default
+ {
+ DBUG_PRINT("info", ("First TIMESTAMP column '%s' was promoted to "
+ "DEFAULT CURRENT_TIMESTAMP ON UPDATE "
+ "CURRENT_TIMESTAMP",
+ column_definition->field_name
+ ));
+ column_definition->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
+ }
+ return;
+ }
+ }
+}
+
+
/*
Preparation for table creation
@@ -2869,7 +2886,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
ulong record_offset= 0;
KEY *key_info;
KEY_PART_INFO *key_part_info;
- int timestamps= 0, timestamps_with_niladic= 0;
int field_no,dup_no;
int select_field_pos,auto_increment=0;
List_iterator<Create_field> it(alter_info->create_list);
@@ -3153,7 +3169,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_ASSERT(sql_field->charset != 0);
if (prepare_create_field(sql_field, &blob_columns,
- &timestamps, &timestamps_with_niladic,
file->ha_table_flags()))
DBUG_RETURN(TRUE);
if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
@@ -3184,12 +3199,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
record_offset+= sql_field->pack_length;
}
}
- if (timestamps_with_niladic > 1)
- {
- my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
- ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
- DBUG_RETURN(TRUE);
- }
if (auto_increment > 1)
{
my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
@@ -4558,6 +4567,8 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table,
/* Got lock. */
DEBUG_SYNC(thd, "locked_table_name");
+ promote_first_timestamp_column(&alter_info->create_list);
+
result= mysql_create_table_no_lock(thd, create_table->db,
create_table->table_name, create_info,
alter_info, FALSE, 0, &is_trans);
@@ -6371,6 +6382,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
need_copy_table= alter_info->change_level;
set_table_default_charset(thd, create_info, db);
+ promote_first_timestamp_column(&alter_info->create_list);
if (thd->variables.old_alter_table
|| (table->s->db_type() != create_info->db_type)
@@ -6668,6 +6680,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
DBUG_EXECUTE_IF("sleep_before_create_table_no_lock",
my_sleep(100000););
+
/*
Create a table with a temporary name.
With create_info->frm_only == 1 this creates a .frm file only.
@@ -6738,8 +6751,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
*/
if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
{
- /* We don't want update TIMESTAMP fields during ALTER TABLE. */
- new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
new_table->next_number_field=new_table->found_next_number_field;
DBUG_EXECUTE_IF("abort_copy_table", {
my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
@@ -7316,6 +7327,7 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
ulonglong prev_insert_id, time_to_report_progress;
List_iterator<Create_field> it(create);
Create_field *def;
+ Field **dfield_ptr= to->default_field;
DBUG_ENTER("copy_data_between_tables");
/* Two or 3 stages; Sorting, copying data and update indexes */
@@ -7345,6 +7357,7 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
errpos= 3;
copy_end=copy;
+ to->s->default_fields= 0;
for (Field **ptr=to->field ; *ptr ; ptr++)
{
def=it++;
@@ -7364,8 +7377,23 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
}
(copy_end++)->set(*ptr,def->field,0);
}
-
+ else
+ {
+ /*
+ Update the set of auto-update fields to contain only the newly added
+ fields. Only these fields should be updated automatically. Old fields
+ keep their current values, and therefore should not be present in the
+ set of autoupdate fields.
+ */
+ if ((*ptr)->has_insert_default_function())
+ {
+ *(dfield_ptr++)= *ptr;
+ ++to->s->default_fields;
+ }
+ }
}
+ if (dfield_ptr)
+ *dfield_ptr= NULL;
if (order)
{
@@ -7456,6 +7484,11 @@ copy_data_between_tables(THD *thd, TABLE *from,TABLE *to,
prev_insert_id= to->file->next_insert_id;
if (to->vfield)
update_virtual_fields(thd, to, TRUE);
+ if (to->default_field && to->update_default_fields())
+ {
+ error= 1;
+ break;
+ }
if (thd->is_error())
{
error= 1;
diff --git a/sql/sql_table.h b/sql/sql_table.h
index 00de6ed1b8d..9d5e768a5a3 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -187,7 +187,6 @@ void close_cached_table(THD *thd, TABLE *table);
void sp_prepare_create_field(THD *thd, Create_field *sql_field);
int prepare_create_field(Create_field *sql_field,
uint *blob_columns,
- int *timestamps, int *timestamps_with_niladic,
longlong table_flags);
CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
HA_CREATE_INFO *create_info);
@@ -208,6 +207,9 @@ void execute_ddl_log_recovery();
bool execute_ddl_log_entry(THD *thd, uint first_entry);
bool check_duplicate_warning(THD *thd, char *msg, ulong length);
+template<typename T> class List;
+void promote_first_timestamp_column(List<Create_field> *column_definitions);
+
/*
These prototypes where under INNODB_COMPATIBILITY_HOOKS.
*/
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 8dcae907926..e6c9d7e4977 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -63,7 +63,7 @@ int select_union::send_data(List<Item> &values)
return 0;
if (table->no_rows_with_nulls)
table->null_catch_flags= CHECK_ROW_FOR_NULLS_TO_REJECT;
- fill_record(thd, table->field, values, TRUE, FALSE);
+ fill_record(thd, table, table->field, values, TRUE, FALSE);
if (thd->is_error())
return 1;
if (table->no_rows_with_nulls)
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index fb0951410a4..4f31da92107 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -342,19 +342,8 @@ int mysql_update(THD *thd,
my_error(ER_NON_UPDATABLE_TABLE, MYF(0), table_list->alias, "UPDATE");
DBUG_RETURN(1);
}
- if (table->timestamp_field)
- {
- // Don't set timestamp column if this is modified
- if (bitmap_is_set(table->write_set,
- table->timestamp_field->field_index))
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
- else
- {
- if (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE)
- bitmap_set_bit(table->write_set,
- table->timestamp_field->field_index);
- }
- }
+ if (table->default_field)
+ table->mark_default_fields_for_write();
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/* Check values */
@@ -389,7 +378,7 @@ int mysql_update(THD *thd,
to compare records and detect data change.
*/
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
- (((uint) table->timestamp_field_type) & TIMESTAMP_AUTO_SET_ON_UPDATE))
+ table->default_field && table->has_default_function(true))
bitmap_union(table->read_set, table->write_set);
// Don't count on usage of 'only index' when calculating which key to use
table->covering_keys.clear_all();
@@ -686,8 +675,7 @@ int mysql_update(THD *thd,
continue; /* repeat the read of the same row if it still exists */
store_record(table,record[1]);
- if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
- table->triggers,
+ if (fill_record_n_invoke_before_triggers(thd, table, fields, values, 0,
TRG_EVENT_UPDATE))
break; /* purecov: inspected */
@@ -695,6 +683,11 @@ int mysql_update(THD *thd,
if (!can_compare_record || compare_record(table))
{
+ if (table->default_field && table->update_default_fields())
+ {
+ error= 1;
+ break;
+ }
if ((res= table_list->view_check_option(thd, ignore)) !=
VIEW_CHECK_OK)
{
@@ -1241,11 +1234,6 @@ int mysql_multi_update_prepare(THD *thd)
while ((tl= ti++))
{
TABLE *table= tl->table;
- /* Only set timestamp column if this is not modified */
- if (table->timestamp_field &&
- bitmap_is_set(table->write_set,
- table->timestamp_field->field_index))
- table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
/* if table will be updated then check that it is unique */
if (table->map & tables_for_update)
@@ -1495,8 +1483,7 @@ int multi_update::prepare(List<Item> &not_used_values,
to compare records and detect data change.
*/
if ((table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) &&
- (((uint) table->timestamp_field_type) &
- TIMESTAMP_AUTO_SET_ON_UPDATE))
+ table->default_field && table->has_default_function(true))
bitmap_union(table->read_set, table->write_set);
}
}
@@ -1875,10 +1862,10 @@ int multi_update::send_data(List<Item> &not_used_values)
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
- if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset],
+ if (fill_record_n_invoke_before_triggers(thd, table, *fields_for_table[offset],
*values_for_table[offset], 0,
- table->triggers,
- TRG_EVENT_UPDATE))
+ TRG_EVENT_UPDATE) ||
+ (table->default_field && table->update_default_fields()))
DBUG_RETURN(1);
/*
@@ -1979,7 +1966,7 @@ int multi_update::send_data(List<Item> &not_used_values)
} while ((tbl= tbl_it++));
/* Store regular updated fields in the row. */
- fill_record(thd,
+ fill_record(thd, tmp_table,
tmp_table->field + 1 + unupdated_check_opt_tables.elements,
*values_for_table[offset], TRUE, FALSE);
@@ -2169,7 +2156,10 @@ int multi_update::do_updates()
for (copy_field_ptr=copy_field;
copy_field_ptr != copy_field_end;
copy_field_ptr++)
+ {
(*copy_field_ptr->do_copy)(copy_field_ptr);
+ copy_field_ptr->to_field->set_explicit_default(NULL);
+ }
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
@@ -2179,6 +2169,8 @@ int multi_update::do_updates()
if (!can_compare_record || compare_record(table))
{
int error;
+ if (table->default_field && (error= table->update_default_fields()))
+ goto err2;
if ((error= cur_table->view_check_option(thd, ignore)) !=
VIEW_CHECK_OK)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 555efaf366d..16bfa16d0a9 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -5873,9 +5873,9 @@ attribute:
NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
| not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
| DEFAULT now_or_signed_literal { Lex->default_value=$2; }
- | ON UPDATE_SYM NOW_SYM optional_braces
+ | ON UPDATE_SYM NOW_SYM opt_time_precision
{
- Item *item= new (YYTHD->mem_root) Item_func_now_local(6);
+ Item *item= new (YYTHD->mem_root) Item_func_now_local($4);
if (item == NULL)
MYSQL_YYABORT;
Lex->on_update_value= item;
@@ -5967,9 +5967,9 @@ type_with_opt_collate:
now_or_signed_literal:
- NOW_SYM optional_braces
+ NOW_SYM opt_time_precision
{
- $$= new (YYTHD->mem_root) Item_func_now_local(6);
+ $$= new (YYTHD->mem_root) Item_func_now_local($2);
if ($$ == NULL)
MYSQL_YYABORT;
}
diff --git a/sql/table.cc b/sql/table.cc
index 47b2cae1a04..cdf11116266 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1250,6 +1250,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
com_length= uint2korr(forminfo+284);
vcol_screen_length= uint2korr(forminfo+286);
share->vfields= 0;
+ share->default_fields= 0;
share->stored_fields= share->fields;
if (forminfo[46] != (uchar)255)
{
@@ -1581,8 +1582,6 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (reg_field->unireg_check == Field::NEXT_NUMBER)
share->found_next_number_field= field_ptr;
- if (share->timestamp_field == reg_field)
- share->timestamp_field_offset= i;
if (use_hash)
{
@@ -1604,6 +1603,9 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
if (share->stored_rec_length>=recpos)
share->stored_rec_length= recpos-1;
}
+ if (reg_field->has_insert_default_function() ||
+ reg_field->has_update_default_function())
+ ++share->default_fields;
}
*field_ptr=0; // End marker
/* Sanity checks: */
@@ -2315,7 +2317,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
uint records, i, bitmap_size;
bool error_reported= FALSE;
uchar *record, *bitmaps;
- Field **field_ptr, **vfield_ptr;
+ Field **field_ptr, **vfield_ptr, **dfield_ptr;
uint8 save_context_analysis_only= thd->lex->context_analysis_only;
DBUG_ENTER("open_table_from_share");
DBUG_PRINT("enter",("name: '%s.%s' form: 0x%lx", share->db.str,
@@ -2419,9 +2421,6 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
if (share->found_next_number_field)
outparam->found_next_number_field=
outparam->field[(uint) (share->found_next_number_field - share->field)];
- if (share->timestamp_field)
- outparam->timestamp_field= (Field_timestamp*) outparam->field[share->timestamp_field_offset];
-
/* Fix key->name and key_part->field */
if (share->key_parts)
@@ -2472,7 +2471,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
}
/*
- Process virtual columns, if any.
+ Process virtual and default columns, if any.
*/
if (!share->vfields)
outparam->vfield= NULL;
@@ -2484,10 +2483,26 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
goto err;
outparam->vfield= vfield_ptr;
+ }
+
+ if (!share->default_fields)
+ outparam->default_field= NULL;
+ else
+ {
+ if (!(dfield_ptr = (Field **) alloc_root(&outparam->mem_root,
+ (uint) ((share->default_fields+1)*
+ sizeof(Field*)))))
+ goto err;
+ outparam->default_field= dfield_ptr;
+ }
+
+ if (share->vfields || share->default_fields)
+ {
+ /* Reuse the same loop both for virtual and default fields. */
for (field_ptr= outparam->field; *field_ptr; field_ptr++)
{
- if ((*field_ptr)->vcol_info)
+ if (share->vfields && (*field_ptr)->vcol_info)
{
if (unpack_vcol_info_from_frm(thd,
outparam,
@@ -2500,8 +2515,15 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
}
*(vfield_ptr++)= *field_ptr;
}
+ if (share->default_fields &&
+ ((*field_ptr)->has_insert_default_function() ||
+ (*field_ptr)->has_update_default_function()))
+ *(dfield_ptr++)= *field_ptr;
}
- *vfield_ptr= 0; // End marker
+ if (share->vfields)
+ *vfield_ptr= 0; // End marker
+ if (share->default_fields)
+ *dfield_ptr= 0; // End marker
}
#ifdef WITH_PARTITION_STORAGE_ENGINE
@@ -3924,9 +3946,6 @@ void TABLE::init(THD *thd, TABLE_LIST *tl)
DBUG_ASSERT(!auto_increment_field_not_null);
auto_increment_field_not_null= FALSE;
- if (timestamp_field)
- timestamp_field_type= timestamp_field->get_auto_set_type();
-
pos_in_table_list= tl;
clear_column_bitmaps();
@@ -5843,6 +5862,48 @@ void TABLE::mark_virtual_columns_for_write(bool insert_fl)
/**
+*/
+
+bool TABLE::has_default_function(bool is_update)
+{
+ Field **dfield_ptr, *dfield;
+ bool res= false;
+ for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
+ {
+ dfield= (*dfield_ptr);
+ if (is_update)
+ res= dfield->has_update_default_function();
+ else
+ res= dfield->has_insert_default_function();
+ if (res)
+ return res;
+ }
+ return res;
+}
+
+
+/**
+*/
+
+void TABLE::mark_default_fields_for_write()
+{
+ Field **dfield_ptr, *dfield;
+ enum_sql_command cmd= in_use->lex->sql_command;
+ for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
+ {
+ dfield= (*dfield_ptr);
+ if (((cmd == SQLCOM_INSERT || cmd == SQLCOM_INSERT_SELECT ||
+ cmd == SQLCOM_REPLACE || cmd == SQLCOM_REPLACE_SELECT ||
+ cmd == SQLCOM_LOAD) &&
+ dfield->has_insert_default_function()) ||
+ ((cmd == SQLCOM_UPDATE || cmd == SQLCOM_UPDATE_MULTI) &&
+ dfield->has_update_default_function()))
+ bitmap_set_bit(write_set, dfield->field_index);
+ }
+}
+
+
+/**
@brief
Allocate space for keys
@@ -6448,6 +6509,50 @@ int update_virtual_fields(THD *thd, TABLE *table, bool for_write)
DBUG_RETURN(0);
}
+
+/**
+ Update all DEFAULT and/or ON INSERT fields.
+
+ @details
+
+ @retval
+ 0 Success
+ @retval
+ >0 Error occurred when storing a virtual field value
+*/
+
+int TABLE::update_default_fields()
+{
+ DBUG_ENTER("update_default_fields");
+ Field **dfield_ptr, *dfield;
+ int res= 0;
+ enum_sql_command cmd= in_use->lex->sql_command;
+
+ DBUG_ASSERT(default_field);
+ /* Iterate over virtual fields in the table */
+ for (dfield_ptr= default_field; *dfield_ptr; dfield_ptr++)
+ {
+ dfield= (*dfield_ptr);
+ /*
+ If an explicit default value for a filed overrides the default,
+ do not update the field with its automatic default value.
+ */
+ if (!(dfield->flags & HAS_EXPLICIT_DEFAULT))
+ {
+ if (sql_command_flags[cmd] & CF_INSERTS_DATA)
+ res= dfield->evaluate_insert_default_function();
+ if (sql_command_flags[cmd] & CF_UPDATES_DATA)
+ res= dfield->evaluate_update_default_function();
+ if (res)
+ DBUG_RETURN(res);
+ }
+ /* Unset the explicit default flag for the next record. */
+ dfield->flags&= ~HAS_EXPLICIT_DEFAULT;
+ }
+ DBUG_RETURN(res);
+}
+
+
/*
@brief Reset const_table flag
diff --git a/sql/table.h b/sql/table.h
index 9e26f907920..e98f93c8bb1 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -350,25 +350,6 @@ public:
};
-/*
- Values in this enum are used to indicate how a tables TIMESTAMP field
- should be treated. It can be set to the current timestamp on insert or
- update or both.
- 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 must be equal to
- (int) TIMESTAMP_AUTO_SET_ON_INSERT | (int) TIMESTAMP_AUTO_SET_ON_UPDATE.
- We use an enum here so that the debugger can display the value names.
-*/
-enum timestamp_auto_set_type
-{
- TIMESTAMP_NO_AUTO_SET= 0, TIMESTAMP_AUTO_SET_ON_INSERT= 1,
- TIMESTAMP_AUTO_SET_ON_UPDATE= 2, TIMESTAMP_AUTO_SET_ON_BOTH= 3
-};
-#define clear_timestamp_auto_bits(_target_, _bits_) \
- (_target_)= (enum timestamp_auto_set_type)((int)(_target_) & ~(int)(_bits_))
-
-class Field_timestamp;
class Field_blob;
class Table_triggers_list;
@@ -608,7 +589,6 @@ struct TABLE_SHARE
/* The following is copied to each TABLE on OPEN */
Field **field;
Field **found_next_number_field;
- Field *timestamp_field; /* Used only during open */
KEY *key_info; /* data of keys in database */
uint *blob_field; /* Index to blobs in Field arrray*/
@@ -680,7 +660,6 @@ struct TABLE_SHARE
uint uniques; /* Number of UNIQUE index */
uint null_fields; /* number of null fields */
uint blob_fields; /* number of blob fields */
- uint timestamp_field_offset; /* Field number for timestamp field */
uint varchar_fields; /* number of varchar fields */
uint db_create_options; /* Create options from database */
uint db_options_in_use; /* Options in use */
@@ -695,6 +674,7 @@ struct TABLE_SHARE
uint column_bitmap_size;
uchar frm_version;
uint vfields; /* Number of computed (virtual) fields */
+ uint default_fields; /* Number of default fields in */
bool use_ext_keys; /* Extended keys can be used */
bool null_field_first;
bool system; /* Set if system table (one record) */
@@ -1007,8 +987,9 @@ public:
Field *next_number_field; /* Set if next_number is activated */
Field *found_next_number_field; /* Set on open */
- Field_timestamp *timestamp_field;
Field **vfield; /* Pointer to virtual fields*/
+ /* Fields that are updated automatically on INSERT or UPDATE. */
+ Field **default_field;
/* Table's triggers, 0 if there are no of them */
Table_triggers_list *triggers;
@@ -1064,19 +1045,6 @@ public:
*/
ha_rows quick_condition_rows;
- /*
- If this table has TIMESTAMP field with auto-set property (pointed by
- timestamp_field member) then this variable indicates during which
- operations (insert only/on update/in both cases) we should set this
- field to current timestamp. If there are no such field in this table
- or we should not automatically set its value during execution of current
- statement then the variable contains TIMESTAMP_NO_AUTO_SET (i.e. 0).
-
- Value of this variable is set for each statement in open_table() and
- if needed cleared later in statement processing code (see mysql_update()
- as example).
- */
- timestamp_auto_set_type timestamp_field_type;
table_map map; /* ID bit of table (1,2,4,8,16...) */
uint lock_position; /* Position in MYSQL_LOCK.table */
@@ -1207,6 +1175,8 @@ public:
void mark_columns_needed_for_insert(void);
bool mark_virtual_col(Field *field);
void mark_virtual_columns_for_write(bool insert_fl);
+ void mark_default_fields_for_write();
+ bool has_default_function(bool is_update);
inline void column_bitmaps_set(MY_BITMAP *read_set_arg,
MY_BITMAP *write_set_arg)
{
@@ -1293,6 +1263,7 @@ public:
bool update_const_key_parts(COND *conds);
uint actual_n_key_parts(KEY *keyinfo);
ulong actual_key_flags(KEY *keyinfo);
+ int update_default_fields();
};
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index b21e0561322..396d5a21be5 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -905,8 +905,6 @@ int ha_archive::write_row(uchar *buf)
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
ha_statistic_increment(&SSV::ha_write_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
mysql_mutex_lock(&share->mutex);
if (!share->archive_write_open)
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index d31e5ee8d89..ba731298d02 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -999,9 +999,6 @@ int ha_tina::write_row(uchar * buf)
ha_statistic_increment(&SSV::ha_write_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
size= encode_quote(buf);
if (!share->tina_write_opened)
@@ -1064,9 +1061,6 @@ int ha_tina::update_row(const uchar * old_data, uchar * new_data)
ha_statistic_increment(&SSV::ha_update_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
-
size= encode_quote(new_data);
/*
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index 549001ab08b..18ba636c0e2 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -1849,8 +1849,6 @@ int ha_federated::write_row(uchar *buf)
values_string.length(0);
insert_field_value_string.length(0);
ha_statistic_increment(&SSV::ha_write_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
/*
start both our field and field values strings
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index a10285a81aa..7f095a9b96e 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -1993,8 +1993,6 @@ int ha_federatedx::write_row(uchar *buf)
values_string.length(0);
insert_field_value_string.length(0);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
/*
start both our field and field values strings
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index 305a8cae720..b9eef0d155b 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -241,8 +241,6 @@ void ha_heap::update_key_stats()
int ha_heap::write_row(uchar * buf)
{
int res;
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
{
if ((res= update_auto_increment()))
@@ -264,8 +262,6 @@ int ha_heap::write_row(uchar * buf)
int ha_heap::update_row(const uchar * old_data, uchar * new_data)
{
int res;
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
res= heap_update(file,old_data,new_data);
if (!res && ++records_changed*HEAP_STATS_UPDATE_THRESHOLD >
file->s->records)
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index c7adc9a7671..62694df0422 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -5163,9 +5163,6 @@ ha_innobase::write_row(
ha_statistic_increment(&SSV::ha_write_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
sql_command = thd_sql_command(user_thd);
if ((sql_command == SQLCOM_ALTER_TABLE
@@ -5573,9 +5570,6 @@ ha_innobase::update_row(
ha_statistic_increment(&SSV::ha_update_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
-
if (prebuilt->upd_node) {
uvect = prebuilt->upd_node->update;
} else {
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 785fe5d8226..f8f3abc41a5 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -1248,10 +1248,6 @@ int ha_maria::close(void)
int ha_maria::write_row(uchar * buf)
{
- /* If we have a timestamp column, update it to the current time */
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
/*
If we have an auto_increment column and we are writing a changed row
or a new row, then update the auto_increment value in the record.
@@ -2245,8 +2241,6 @@ bool ha_maria::is_crashed() const
int ha_maria::update_row(const uchar * old_data, uchar * new_data)
{
CHECK_UNTIL_WE_FULLY_IMPLEMENTED_VERSIONING("UPDATE in WRITE CONCURRENT");
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
return maria_update(file, old_data, new_data);
}
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 73e0fadd530..5f24a002014 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -832,10 +832,6 @@ int ha_myisam::close(void)
int ha_myisam::write_row(uchar *buf)
{
- /* If we have a timestamp column, update it to the current time */
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
/*
If we have an auto_increment column and we are writing a changed row
or a new row, then update the auto_increment value in the record.
@@ -1656,8 +1652,6 @@ bool ha_myisam::is_crashed() const
int ha_myisam::update_row(const uchar *old_data, uchar *new_data)
{
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
return mi_update(file,old_data,new_data);
}
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 47a3abb78d2..2c1e85ec9ff 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1078,8 +1078,6 @@ int ha_myisammrg::write_row(uchar * buf)
if (file->merge_insert_method == MERGE_INSERT_DISABLED || !file->tables)
DBUG_RETURN(HA_ERR_TABLE_READONLY);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
if (table->next_number_field && buf == table->record[0])
{
int error;
@@ -1093,8 +1091,6 @@ int ha_myisammrg::update_row(const uchar * old_data, uchar * new_data)
{
DBUG_ASSERT(this->file->children_attached);
ha_statistic_increment(&SSV::ha_update_count);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
return myrg_update(file,old_data,new_data);
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 97a30a81d12..004d57e6efd 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -5933,9 +5933,6 @@ ha_innobase::write_row(
DBUG_RETURN(HA_ERR_CRASHED);
}
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
-
sql_command = thd_sql_command(user_thd);
if ((sql_command == SQLCOM_ALTER_TABLE
@@ -6359,9 +6356,6 @@ ha_innobase::update_row(
DBUG_RETURN(HA_ERR_CRASHED);
}
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
-
if (prebuilt->upd_node) {
uvect = prebuilt->upd_node->update;
} else {