Why is all timestamp on migrations default to current_timestamp?
On my migrations, I have something like this:
$table->timestamp('expiry_date');
but when I do
mysql > describe `table`;
I get
+----------------------------+------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+------------------+------+-----+-------------------+-----------------------------+
| confirm_email_token_expiry | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
I was expecting
+----------------------------+------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------+------------------+------+-----+-------------------+-----------------------------+
| confirm_email_token_expiry | timestamp | NO | | NULL | |
EDIT[1]
manually setting the default value to null still gives me the same output.
$table->timestamp('expiry_date')->default(null);
Sounds like a mysql configuration issue.
If explicit_defaults_for_timestamp is disabled, the server enables the nonstandard behaviors and handles TIMESTAMP columns as follows:
- TIMESTAMP columns not explicitly declared with the NULL attribute are automatically declared with the NOT NULL attribute. Assigning such a column a value of NULL is permitted and sets the column to the current timestamp.
- The first TIMESTAMP column in a table, if not explicitly declared with the NULL attribute or an explicit DEFAULT or ON UPDATE attribute, is automatically declared with the DEFAULT CURRENT_TIMESTAMP and ON UPDATE CURRENT_TIMESTAMP attributes.
Yes, this is mysql configuration. To acheive your desired results, try calling the nullable() method:
$table->timestamp('expiry_date')->nullable()->default(null);
It's worth pointing out that MariaDB does this as well - for some ungodly reason it automatically added the ON UPDATE CURRENT_TIMESTAMP attribute to one of my custom timestamps as well.
Although this is an issue in the database layer, not the application layer, it's still enough of a gotcha that it might be worth making a note of in the migrations documentation.
Most helpful comment
Yes, this is mysql configuration. To acheive your desired results, try calling the nullable() method:
$table->timestamp('expiry_date')->nullable()->default(null);