Bug #100567 | Unexpected cast to float from attribute of a JSON datum | ||
---|---|---|---|
Submitted: | 19 Aug 2020 3:37 | Modified: | 19 Aug 2020 5:44 |
Reporter: | Marcos Albe (OCA) | Email Updates: | |
Status: | Verified | Impact on me: | |
Category: | MySQL Server: JSON | Severity: | S3 (Non-critical) |
Version: | 8.0, 8.0.21, 8.0.11 | OS: | Any |
Assigned to: | CPU Architecture: | Any | |
Tags: | regression |
[19 Aug 2020 3:37]
Marcos Albe
[19 Aug 2020 5:44]
MySQL Verification Team
Hello Marcos, Thank you for the report and test case. Thanks, Umesh
[19 Aug 2020 5:44]
MySQL Verification Team
- 5.7 bin/mysql -uroot -S /tmp/mysql_ushastry.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.31 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> create database test; Query OK, 1 row affected (0.00 sec) mysql> use test Database changed mysql> create table test (id int, data json NOT NULL); Query OK, 0 rows affected (0.00 sec) mysql> insert into test values(1, '{"id": 1}'); Query OK, 1 row affected (0.01 sec) mysql> select CAST(sum(id) as JSON), sum(id), CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON), sum(JSON_EXTRACT(data, '$.id')) from test; +-----------------------+---------+-----------------------------------------------+---------------------------------+ | CAST(sum(id) as JSON) | sum(id) | CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON) | sum(JSON_EXTRACT(data, '$.id')) | +-----------------------+---------+-----------------------------------------------+---------------------------------+ | 1 | 1 | 1 | 1 | +-----------------------+---------+-----------------------------------------------+---------------------------------+ 1 row in set (0.02 sec)
[19 Aug 2020 5:44]
MySQL Verification Team
- 8.0.21 bin/mysql -uroot -S /tmp/mysql_ushastry.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 7 Server version: 8.0.21 MySQL Community Server - GPL Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> create database test; Query OK, 1 row affected (0.01 sec) mysql> use test Database changed mysql> create table test (id int, data json NOT NULL); Query OK, 0 rows affected (0.01 sec) mysql> insert into test values(1, '{"id": 1}'); Query OK, 1 row affected (0.01 sec) mysql> select CAST(sum(id) as JSON), sum(id), CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON), sum(JSON_EXTRACT(data, '$.id')) from test; +-----------------------+---------+-----------------------------------------------+---------------------------------+ | CAST(sum(id) as JSON) | sum(id) | CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON) | sum(JSON_EXTRACT(data, '$.id')) | +-----------------------+---------+-----------------------------------------------+---------------------------------+ | 1 | 1 | 1.0 | 1 | +-----------------------+---------+-----------------------------------------------+---------------------------------+ 1 row in set (0.01 sec)
[19 Aug 2020 5:45]
MySQL Verification Team
- This is not new, seen at least since 8.0.11 bin/mysql -uroot -S /tmp/mysql_ushastry.sock Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 8.0.11 MySQL Community Server - GPL Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> create database test; Query OK, 1 row affected (0.06 sec) mysql> use test Database changed mysql> create table test (id int, data json NOT NULL); Query OK, 0 rows affected (0.10 sec) mysql> insert into test values(1, '{"id": 1}'); Query OK, 1 row affected (0.01 sec) mysql> select CAST(sum(id) as JSON), sum(id), CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON), sum(JSON_EXTRACT(data, '$.id')) from test; +-----------------------+---------+-----------------------------------------------+---------------------------------+ | CAST(sum(id) as JSON) | sum(id) | CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON) | sum(JSON_EXTRACT(data, '$.id')) | +-----------------------+---------+-----------------------------------------------+---------------------------------+ | 1 | 1 | 1.0 | 1 | +-----------------------+---------+-----------------------------------------------+---------------------------------+ 1 row in set (0.00 sec)
[19 Aug 2020 5:51]
MySQL Verification Team
# Related Bug #88230
[20 Aug 2020 13:53]
MySQL Verification Team
Bug #100587 marked as duplicate of this one
[27 Aug 2020 11:24]
Marcelo Altmann
5.7 stores 1.0 as double, but omit the floating part when displaying .0: mysql> SELECT *, JSON_TYPE(JSON_EXTRACT(data, '$.id')) FROM test; +------+-------------+---------------------------------------+ | id | data | JSON_TYPE(JSON_EXTRACT(data, '$.id')) | +------+-------------+---------------------------------------+ | 1 | {"id": 1} | INTEGER | | 2 | {"id": 1} | DOUBLE | | 3 | {"id": 1.5} | DOUBLE | +------+-------------+---------------------------------------+ 3 rows in set (0.00 sec) While on 8.0, the representation of ID 2 comes with the floating-point: mysql> SELECT *, JSON_TYPE(JSON_EXTRACT(data, '$.id')) FROM test; +------+-------------+---------------------------------------+ | id | data | JSON_TYPE(JSON_EXTRACT(data, '$.id')) | +------+-------------+---------------------------------------+ | 1 | {"id": 1} | INTEGER | | 2 | {"id": 1.0} | DOUBLE | | 3 | {"id": 1.5} | DOUBLE | +------+-------------+---------------------------------------+ 3 rows in set (0.00 sec) So, 8.0 is still storing them correctly and displaying them correctly (what is not correct is how 5.7 display a double with .0). If we check the CAST test case provided on this report and check what data type it returns we can see: #5.7 mysql> select * from test; +------+-----------+ | id | data | +------+-----------+ | 1 | {"id": 1} | +------+-----------+ 1 row in set (0.00 sec) mysql> select CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON), JSON_TYPE(CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON)) from test WHERE id = 1; +-----------------------------------------------+----------------------------------------------------------+ | CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON) | JSON_TYPE(CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON)) | +-----------------------------------------------+----------------------------------------------------------+ | 1 | DOUBLE | +-----------------------------------------------+----------------------------------------------------------+ 1 row in set (0.00 sec) # 8.0 mysql> select * from test; +------+-----------+ | id | data | +------+-----------+ | 1 | {"id": 1} | +------+-----------+ 1 row in set (0.00 sec) mysql> select CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON), JSON_TYPE(CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON)) from test WHERE id = 1; +-----------------------------------------------+----------------------------------------------------------+ | CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON) | JSON_TYPE(CAST(sum(JSON_EXTRACT(data, '$.id')) AS JSON)) | +-----------------------------------------------+----------------------------------------------------------+ | 1.0 | DOUBLE | +-----------------------------------------------+----------------------------------------------------------+ 1 row in set (0.00 sec) So I don't think there is nothing wrong with 8.0 here. CAST operation is returning a DOUBLE on 5.7 and 8.0. 8.0 display it with the decimal point which is correct, while 5.7 on the other hand is omitting the floating-point, which is wrong and is what https://github.com/mysql/mysql-server/commit/0b8663708e24aff8c12bcf79886784c1ccf859f2 / https://bugs.mysql.com/bug.php?id=88230 fixed. Botton line is that 5.7 is wrong and https://bugs.mysql.com/bug.php?id=88230 was only fixed on 8.0