Bug #89003 Dropping Index on JSON virtual column with default sql_mode is not working

Submitted: 21 Dec 2017 9:45 Modified: 21 Dec 2017 11:22
Reporter: Oli Sennhauser Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: DDL Severity:S3 (Non-critical)
Version:5.7.20 OS:Linux
Assigned to: CPU Architecture:Any
Tags: INDEX, json, SQL_MODE, virtual column

[21 Dec 2017 9:45] Oli Sennhauser
Description:
See also Bug https://bugs.mysql.com/bug.php?id=89002

When we have a table with json and virtual columns and we worked around the problem in #89002 we cannot drop the index any more.

How to repeat:
SELECT @@version, @@version_comment;
+------------+------------------------------+
| @@version  | @@version_comment            |
+------------+------------------------------+
| 5.7.20-log | MySQL Community Server (GPL) |
+------------+------------------------------+

SHOW GLOBAL VARIABLES LIKE 'sql_mode'\G
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

CREATE TABLE `BACKEND_INFO_DEVICE` (
  `ID` VARCHAR(255) NOT NULL,
  `BOX_ID` VARCHAR(255) NOT NULL,
  `DOC` JSON NOT NULL,
  `CREATED_AT` TIMESTAMP NULL DEFAULT NULL,
  `MODIFIED_AT` TIMESTAMP NULL DEFAULT NULL,
  `LAST_REQUEST_UTC` TIMESTAMP AS ((case when isnull(json_unquote(json_extract(`DOC`,'$.last_request'))) then '1980-01-01 00:00:00' else str_to_date(substring_index(json_unquote(json_extract(`DOC`,'$.last_request')),'+',1),'%Y-%m-%dT%H:%i:%s') end)) VIRTUAL,
PRIMARY KEY (`ID`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
;
Query OK, 0 rows affected (0.08 sec)

ALTER TABLE `BACKEND_INFO_DEVICE` ADD INDEX `ix_bid_boxid` (`BOX_ID` ASC);
ERROR 1067 (42000): Invalid default value for 'LAST_REQUEST_UTC'

SET SESSION sql_mode='NO_ZERO_IN_DATE,NO_ZERO_DATE';

ALTER TABLE `BACKEND_INFO_DEVICE` ADD INDEX `ix_bid_boxid` (`BOX_ID` ASC);
show warnings;
+---------+------+-----------------------------------------------------------+
| Level   | Code | Message                                                   |
+---------+------+-----------------------------------------------------------+
| Warning | 1264 | Out of range value for column 'LAST_REQUEST_UTC' at row 1 |
+---------+------+-----------------------------------------------------------+

set session sql_mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION";

ALTER TABLE `BACKEND_INFO_DEVICE` DROP INDEX `ix_bid_boxid`;
ERROR 1067 (42000): Invalid default value for 'LAST_REQUEST_UTC'

Suggested fix:
Dropping and index should always be possible.
[21 Dec 2017 11:22] MySQL Verification Team
Hello Oli,

Thank you for the report and test case.

Thanks,
Umesh
[2 Jan 2018 15:36] Knut Anders Hatlen
Posted by developer:
 
Changing bug category since the bug can be reproduced without using JSON:

mysql> CREATE TABLE t(x INT, ts TIMESTAMP AS (NULL));
Query OK, 0 rows affected (0,01 sec)

mysql> ALTER TABLE t ADD INDEX idx (x);
ERROR 1067 (42000): Invalid default value for 'ts'

mysql> SET SESSION sql_mode='NO_ZERO_IN_DATE,NO_ZERO_DATE';
Query OK, 0 rows affected, 2 warnings (0,00 sec)

mysql> ALTER TABLE t ADD INDEX idx (x);
Query OK, 0 rows affected, 1 warning (0,00 sec)
Records: 0  Duplicates: 0  Warnings: 1

mysql> SET SESSION sql_mode=DEFAULT;
Query OK, 0 rows affected (0,00 sec)

mysql> ALTER TABLE t DROP INDEX idx;
ERROR 1067 (42000): Invalid default value for 'ts'

The problem does not seem to be reproducible when the server is started with --explicit-defaults-for-timestamp=ON, which is the default from MySQL 8.0.2.
[3 Jan 2018 8:11] Knut Anders Hatlen
Posted by developer:
 
Also reproducible without a generated column. For example like this with MySQL 5.7:

mysql> SET sql_mode='';
Query OK, 0 rows affected, 1 warning (0,00 sec)

mysql> CREATE TABLE t (x INT, ts TIMESTAMP DEFAULT '0000-00-00 00:00:00');
Query OK, 0 rows affected (0,01 sec)

mysql> ALTER TABLE t ADD INDEX idx (x);
Query OK, 0 rows affected (0,01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> SET sql_mode=DEFAULT;
Query OK, 0 rows affected (0,00 sec)

mysql> ALTER TABLE t DROP INDEX idx;
ERROR 1067 (42000): Invalid default value for 'ts'

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.040 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.