LoginSignup
0
0

More than 3 years have passed since last update.

MySQL8 の TIMESTAMP, DATETIME におけるExplicit Default な式定義について

Last updated at Posted at 2021-01-20

MySQL8.0.13 からDEFAULT値に簡単な式を書けるようになりました。超便利です。

timestampでデフォルト値を書いたときにALTER TABLE ADD COLUMNCREATE 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を許可してる場合はエラーになりませんが、たまたま動いてると考えたほうが良さそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0