From 5704c7fe2cf52fb8bec0f8e8006f7a4b181e1660 Mon Sep 17 00:00:00 2001 From: unknown <anozdrin/alik@quad.> Date: Thu, 14 Feb 2008 18:13:40 +0300 Subject: [PATCH] A patch for Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields. The actual problem here was that CREATE TABLE allowed zero date as a default value for a TIMESTAMP column in NO_ZERO_DATE mode. The thing is that for TIMESTAMP date type specific rule is applied: column_name TIMESTAMP == column_name TIMESTAMP DEFAULT 0 whever for any other date data type column_name TYPE == column_name TYPE DEFAULT NULL The fix is to raise an error when we're in NO_ZERO_DATE mode and there is TIMESTAMP column w/o default value. mysql-test/r/create.result: Update result file. mysql-test/t/create.test: Test case for Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields. sql/sql_table.cc: Report an error if NO_ZERO_MODE is set and we have zero date as a default. --- mysql-test/r/create.result | 44 ++++++++++++++++++++++++++ mysql-test/t/create.test | 64 ++++++++++++++++++++++++++++++++++++++ sql/sql_table.cc | 31 ++++++++++++++++++ 3 files changed, 139 insertions(+) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 4bdcca81b74..0dfc9c1e761 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -1789,4 +1789,48 @@ DROP TABLE t2; # -- End of test case for Bug#21380. +# -- +# -- Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields +# -- + +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; + +CREATE TABLE t1(c1 TIMESTAMP, c2 TIMESTAMP); + +SET sql_mode = NO_ZERO_DATE; + +CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP DEFAULT 0); +ERROR 42000: Invalid default value for 'c2' + +CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP); +ERROR 42000: Invalid default value for 'c2' + +# -- Check that NULL column still can be created. +CREATE TABLE t2(c1 TIMESTAMP NULL); + +# -- Check ALTER TABLE. +ALTER TABLE t1 ADD INDEX(c1); +ERROR 42000: Invalid default value for 'c2' + +# -- Check DATETIME. +SET sql_mode = ''; + +CREATE TABLE t3(c1 DATETIME NOT NULL); +INSERT INTO t3 VALUES (0); + +SET sql_mode = TRADITIONAL; + +ALTER TABLE t3 ADD INDEX(c1); +ERROR 22007: Incorrect datetime value: '0000-00-00 00:00:00' for column 'c1' at row 1 + +# -- Cleanup. +SET sql_mode = ''; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +# -- End of Bug#18834. + End of 5.1 tests diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 09170cbc4f5..8912fd46b42 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -1385,4 +1385,68 @@ DROP TABLE t2; --echo # -- End of test case for Bug#21380. --echo +--echo # -- +--echo # -- Bug#18834: ALTER TABLE ADD INDEX on table with two timestamp fields +--echo # -- +--echo + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +DROP TABLE IF EXISTS t3; +--enable_warnings + +--echo + +CREATE TABLE t1(c1 TIMESTAMP, c2 TIMESTAMP); + +--echo + +SET sql_mode = NO_ZERO_DATE; + +--echo +--error ER_INVALID_DEFAULT +CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP DEFAULT 0); + +--echo +--error ER_INVALID_DEFAULT +CREATE TABLE t2(c1 TIMESTAMP, c2 TIMESTAMP); + +--echo +--echo # -- Check that NULL column still can be created. +CREATE TABLE t2(c1 TIMESTAMP NULL); + +--echo +--echo # -- Check ALTER TABLE. +--error ER_INVALID_DEFAULT +ALTER TABLE t1 ADD INDEX(c1); + +--echo +--echo # -- Check DATETIME. +SET sql_mode = ''; + +--echo + +CREATE TABLE t3(c1 DATETIME NOT NULL); +INSERT INTO t3 VALUES (0); + +--echo +SET sql_mode = TRADITIONAL; + +--echo +--error ER_TRUNCATED_WRONG_VALUE +ALTER TABLE t3 ADD INDEX(c1); + +--echo +--echo # -- Cleanup. + +SET sql_mode = ''; +DROP TABLE t1; +DROP TABLE t2; +DROP TABLE t3; + +--echo +--echo # -- End of Bug#18834. +--echo + --echo End of 5.1 tests diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 505bcd1b421..05c73044ddd 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3001,6 +3001,37 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, (qsort_cmp) sort_keys); create_info->null_bits= null_fields; + /* Check fields. */ + it.rewind(); + while ((sql_field=it++)) + { + Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check); + + if (thd->variables.sql_mode & MODE_NO_ZERO_DATE && + !sql_field->def && + sql_field->sql_type == MYSQL_TYPE_TIMESTAMP && + (sql_field->flags & NOT_NULL_FLAG) && + (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD)) + { + /* + An error should be reported if: + - NO_ZERO_DATE SQL mode is active; + - there is no explicit DEFAULT clause (default column value); + - this is a TIMESTAMP column; + - the column is not NULL; + - this is not the DEFAULT CURRENT_TIMESTAMP column. + + In other words, an error should be reported if + - NO_ZERO_DATE SQL mode is active; + - the column definition is equivalent to + 'column_name TIMESTAMP DEFAULT 0'. + */ + + my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name); + DBUG_RETURN(TRUE); + } + } + DBUG_RETURN(FALSE); } -- 2.30.9