Bug #90423 JSON_TABLE returns wrong datatype when INT-value is grater than (2^31-1)

Submitted: 13 Apr 2018 3:17 Modified: 10 Aug 2018 7:19
Reporter: Tsubasa Tanaka (OCA) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: JSON Severity:S2 (Serious)
Version:8.0.4 OS:CentOS (7.4)
Assigned to: CPU Architecture:x86

[13 Apr 2018 3:17] Tsubasa Tanaka
Description:
JSON_TABLE returns wrong datatype when INT-value is grater than (2^31-1).
Unexpected overflowed INT SIGNED is returned.

See "How to repeat" in detail.

How to repeat:
While "id" < (2^31 -1), JSON_TABLE returns "id" correctly.

mysql80 32> SELECT id FROM JSON_TABLE('[{"id":"2147483647"}]', '$[*]' COLUMNS (id BIGINT UNSIGNED PATH '$.id')) AS json;
+------------+
| id         |
+------------+
| 2147483647 |
+------------+
1 row in set (0.00 sec)

When "id" >= (2^31 -1), "id" get to be arithmetic overflow.

mysql80 32> SELECT id FROM JSON_TABLE('[{"id":"2147483648"}]', '$[*]' COLUMNS (id BIGINT UNSIGNED PATH '$.id')) AS json;
+-------------+
| id          |
+-------------+
| -2147483648 |
+-------------+
1 row in set (0.00 sec)

Suggested fix:
Be honest for datatype which is specified in COLUMNS clause.

Workaround is picking AS REAL(NUMERIC) in COLUMNS clause.

mysql80 32> SELECT id FROM JSON_TABLE('[{"id":"2147483648"}]', '$[*]' COLUMNS (id REAL PATH '$.id')) AS json;
+------------+
| id         |
+------------+
| 2147483648 |
+------------+
1 row in set (0.00 sec)
[13 Apr 2018 5:20] MySQL Verification Team
Hello Tanaka-San,

Thank you for the report and feedback!

Thanks,
Umesh
[13 Apr 2018 5:21] MySQL Verification Team
--
[umshastr@hod03]/export/umesh/server/binaries/Trunk/mysql-8.0.12: 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.12-commercial MySQL Enterprise Server - Commercial

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> SELECT id FROM JSON_TABLE('[{"id":"2147483647"}]', '$[*]' COLUMNS (id BIGINT UNSIGNED PATH '$.id')) AS json;
+------------+
| id         |
+------------+
| 2147483647 |
+------------+
1 row in set (0.01 sec)

mysql> SELECT id FROM JSON_TABLE('[{"id":"2147483648"}]', '$[*]' COLUMNS (id BIGINT UNSIGNED PATH '$.id')) AS json;
+-------------+
| id          |
+-------------+
| -2147483648 |
+-------------+
1 row in set (0.00 sec)

mysql> SELECT id FROM JSON_TABLE('[{"id":"2147483648"}]', '$[*]' COLUMNS (id REAL PATH '$.id')) AS json;
+------------+
| id         |
+------------+
| 2147483648 |
+------------+
1 row in set (0.00 sec)
[10 Aug 2018 7:19] Jon Stephens
Documented fix in the 8.0.13 changelog as follows:

    The JSON_TABLE() function subjected integer values greater than 
    or equal to 2³¹ to wraparound. For example, the query SELECT id 
    FROM JSON_TABLE('[{"id":"2147483648"}]', '$[*]' COLUMNS (id 
    BIGINT UNSIGNED PATH '$.id')) AS json returned -2147483648.

Closed.

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

Page generated in 0.052 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.