MySQL8.0.13 からDEFAULT値に簡単な式を書けるようになりました。超便利です。
timestampでデフォルト値を書いたときにALTER TABLE ADD COLUMN
やCREATE INDEX
などテーブル加工をするとエラーになることがあります。
挙動が罠ではあるが、バグではないです。
The exception is that, for TIMESTAMP and DATETIME columns, you can specify the CURRENT_TIMESTAMP function as the default, without enclosing parentheses. See Section 11.2.5, “Automatic Initialization and Updating for TIMESTAMP and DATETIME”.
リファレンスマニュアルを見ても、TIMESTAMP と DATETIME だけは例外と書いてあります。
この2つだけは規定のデフォルト値に従わなければいけません、
詳細は、 https://dev.mysql.com/doc/refman/8.0/en/timestamp-initialization.html
基本は、ここに記述されてるもののみデフォルトにできます。
TIMESTAMPやDATETIMEはデフォルトを指定しないときのImplicit Default の挙動が他の型と異なるため、NOT NULLのときにトラブルになることがあります。
INSERT や UPDATEなどデータを入れるときはExplicit Defaultの式がおかしくてもエラーにならずに良い感じに補正されて動きますが、ALTERなどのときはNOT NULL型ではエラーになります。
mysql> create table tt1 (t timestamp not null default (CURRENT_TIMESTAMP + INTERVAL 1 YEAR), i int);
mysql> create table tt2 (t timestamp not null default CURRENT_TIMESTAMP, i int);
mysql> create table tt3 (t timestamp null default (CURRENT_TIMESTAMP + INTERVAL 1 YEAR), i int);
mysql> create table tt4 (t timestamp null default CURRENT_TIMESTAMP, i int);
mysql> desc tt1;
+-------+-----------+------+-----+---------------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------------------------+-------------------+
| t | timestamp | NO | | (now() + interval 1 year) | DEFAULT_GENERATED |
| i | int | YES | | NULL | |
+-------+-----------+------+-----+---------------------------+-------------------+
2 rows in set (0.00 sec)
mysql> desc tt2;
+-------+-----------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-------------------+
| t | timestamp | NO | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| i | int | YES | | NULL | |
+-------+-----------+------+-----+-------------------+-------------------+
2 rows in set (0.00 sec)
mysql> desc tt3;
+-------+-----------+------+-----+---------------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------------------------+-------------------+
| t | timestamp | YES | | (now() + interval 1 year) | DEFAULT_GENERATED |
| i | int | YES | | NULL | |
+-------+-----------+------+-----+---------------------------+-------------------+
2 rows in set (0.00 sec)
mysql> desc tt4;
+-------+-----------+------+-----+-------------------+-------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-------------------+
| t | timestamp | YES | | CURRENT_TIMESTAMP | DEFAULT_GENERATED |
| i | int | YES | | NULL | |
+-------+-----------+------+-----+-------------------+-------------------+
2 rows in set (0.00 sec)
mysql> insert tt1 set i=0;
mysql> insert tt2 set i=0;
mysql> insert tt3 set i=0;
mysql> insert tt4 set i=0;
普通に入る。
mysql> alter table tt1 add j int;
ERROR 1067 (42000): Invalid default value for 't'
mysql> alter table tt2 add j int;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table tt3 add j int;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> alter table tt4 add j int;
Query OK, 0 rows affected (0.00 sec)
Records: 0 Duplicates: 0 Warnings: 0
tt1 だけALTERがエラーになります。
NULLを許可してる場合はエラーになりませんが、たまたま動いてると考えたほうが良さそうです。