Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON data type does not support custom types (i.e. MySQL types) #9988

Closed
Tracked by #36993
xiekeyi98 opened this issue Apr 2, 2019 · 9 comments · Fixed by #37579
Closed
Tracked by #36993

JSON data type does not support custom types (i.e. MySQL types) #9988

xiekeyi98 opened this issue Apr 2, 2019 · 9 comments · Fixed by #37579
Assignees
Labels
challenge-program component/expression component/json help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. priority/P3 The issue has P3 priority. Assigned to backlog. sig/execution SIG execution type/compatibility type/feature-request Categorizes issue or PR as related to a new feature.

Comments

@xiekeyi98
Copy link
Contributor

xiekeyi98 commented Apr 2, 2019

Description

Bug Report

Please answer these questions before submitting your issue. Thanks!

  1. What did you do?
    If possible, provide a recipe for reproducing the error.
select json_type(cast(cast('2014-11-25 18:00' as datetime) as json));
select json_type(cast(cast('2014-11-25' as date) as json));
select json_type(cast(cast('18:00:59' as time) as json));
  1. What did you expect to see?

In MySQL

mysql> select json_type(cast(cast('2014-11-25 18:00' as datetime) as json));
+---------------------------------------------------------------+
| json_type(cast(cast('2014-11-25 18:00' as datetime) as json)) |
+---------------------------------------------------------------+
| DATETIME                                                      |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(cast('2014-11-25' as date) as json));
+-----------------------------------------------------+
| json_type(cast(cast('2014-11-25' as date) as json)) |
+-----------------------------------------------------+
| DATE                                                |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(cast('18:00:59' as time) as json));
+---------------------------------------------------+
| json_type(cast(cast('18:00:59' as time) as json)) |
+---------------------------------------------------+
| TIME                                              |
+---------------------------------------------------+
1 row in set (0.01 sec)

mysql> 
mysql> select version();
+-------------------------+
| version()               |
+-------------------------+
| 5.7.25-0ubuntu0.18.04.2 |
+-------------------------+
1 row in set (0.00 sec)

mysql> 
  1. What did you see instead?

In TiDB

mysql> select json_type(cast(cast('2014-11-25 18:00' as datetime) as json));
+---------------------------------------------------------------+
| json_type(cast(cast('2014-11-25 18:00' as datetime) as json)) |
+---------------------------------------------------------------+
| STRING                                                        |
+---------------------------------------------------------------+
1 row in set (0.01 sec)

mysql> select json_type(cast(cast('2014-11-25' as date) as json));
+-----------------------------------------------------+
| json_type(cast(cast('2014-11-25' as date) as json)) |
+-----------------------------------------------------+
| STRING                                              |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(cast('18:00:59' as time) as json));
+---------------------------------------------------+
| json_type(cast(cast('18:00:59' as time) as json)) |
+---------------------------------------------------+
| STRING                                            |
+---------------------------------------------------+
1 row in set (0.00 sec)

mysql> select tidb_version()\G
*************************** 1. row ***************************
tidb_version(): Release Version: v3.0.0-beta-321-gc6a757b24
Git Commit Hash: c6a757b2435965a72ada9d61ea8b7a367bd89b5f
Git Branch: master
UTC Build Time: 2019-04-02 02:38:04
GoVersion: go version go1.12.1 linux/amd64
Race Enabled: false
TiKV Min Version: 2.1.0-alpha.1-ff3dd160846b7d1aed9079c389fc188f7f5ea13e
Check Table Before Drop: false
1 row in set (0.00 sec)

mysql> 

SIG slack channel

#sig-exec

Score

300

Mentor

@xiekeyi98 xiekeyi98 added type/bug The issue is confirmed as a bug. type/compatibility labels Apr 2, 2019
@xiekeyi98
Copy link
Contributor Author

Others may be tested too:

select json_type(cast(127 as json));
select json_type(cast(255 as json));
select json_type(cast(32767 as json));
select json_type(cast(65535 as json));
select json_type(cast(8388607 as json));
select json_type(cast(16777215 as json));
select json_type(cast(2147483647 as json));
select json_type(cast(4294967295 as json));
select json_type(cast(9223372036854775807 as json));
select json_type(cast(18446744073709551615 as json));
select json_type(cast(true as json));
select json_type(cast(b'10101' as json));
select json_type(cast(cast(3.14 as decimal(5,2)) as json));
select json_type(cast(3.14 as json));
select json_type(cast(3.14E30 as json));

@ghost
Copy link

ghost commented Jul 13, 2020

Confirming this still exists in master. I've noted which values are correct:

select json_type(cast(cast('2014-11-25 18:00' as datetime) as json));
select json_type(cast(cast('2014-11-25' as date) as json));
select json_type(cast(cast('18:00:59' as time) as json));
select json_type(cast(127 as json));
select json_type(cast(255 as json));
select json_type(cast(32767 as json));
select json_type(cast(65535 as json));
select json_type(cast(8388607 as json));
select json_type(cast(16777215 as json));
select json_type(cast(2147483647 as json));
select json_type(cast(4294967295 as json));
select json_type(cast(9223372036854775807 as json));
select json_type(cast(18446744073709551615 as json));
select json_type(cast(true as json));
select json_type(cast(b'10101' as json));
select json_type(cast(cast(3.14 as decimal(5,2)) as json));
select json_type(cast(3.14 as json));
select json_type(cast(3.14E30 as json));
select tidb_version()\G


..


mysql> select json_type(cast(cast('2014-11-25 18:00' as datetime) as json));
+---------------------------------------------------------------+
| json_type(cast(cast('2014-11-25 18:00' as datetime) as json)) |
+---------------------------------------------------------------+
| STRING                                                        |
+---------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(cast('2014-11-25' as date) as json));
+-----------------------------------------------------+
| json_type(cast(cast('2014-11-25' as date) as json)) |
+-----------------------------------------------------+
| STRING                                              |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(cast('18:00:59' as time) as json));
+---------------------------------------------------+
| json_type(cast(cast('18:00:59' as time) as json)) |
+---------------------------------------------------+
| STRING                                            |
+---------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(127 as json)); # correct
+------------------------------+
| json_type(cast(127 as json)) |
+------------------------------+
| INTEGER                      |
+------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(255 as json)); # correct
+------------------------------+
| json_type(cast(255 as json)) |
+------------------------------+
| INTEGER                      |
+------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(32767 as json)); # correct
+--------------------------------+
| json_type(cast(32767 as json)) |
+--------------------------------+
| INTEGER                        |
+--------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(65535 as json)); # correct
+--------------------------------+
| json_type(cast(65535 as json)) |
+--------------------------------+
| INTEGER                        |
+--------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(8388607 as json)); # correct
+----------------------------------+
| json_type(cast(8388607 as json)) |
+----------------------------------+
| INTEGER                          |
+----------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(16777215 as json));  # correct
+-----------------------------------+
| json_type(cast(16777215 as json)) |
+-----------------------------------+
| INTEGER                           |
+-----------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(2147483647 as json));  # correct
+-------------------------------------+
| json_type(cast(2147483647 as json)) |
+-------------------------------------+
| INTEGER                             |
+-------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(4294967295 as json));  # correct
+-------------------------------------+
| json_type(cast(4294967295 as json)) |
+-------------------------------------+
| INTEGER                             |
+-------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(9223372036854775807 as json));  # correct
+----------------------------------------------+
| json_type(cast(9223372036854775807 as json)) |
+----------------------------------------------+
| INTEGER                                      |
+----------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(18446744073709551615 as json));  # correct
+-----------------------------------------------+
| json_type(cast(18446744073709551615 as json)) |
+-----------------------------------------------+
| UNSIGNED INTEGER                              |
+-----------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(true as json));  # correct
+-------------------------------+
| json_type(cast(true as json)) |
+-------------------------------+
| BOOLEAN                       |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(b'10101' as json));
ERROR 3140 (22032): Invalid JSON text: The document root must not be followed by other values.
mysql> select json_type(cast(cast(3.14 as decimal(5,2)) as json));
+-----------------------------------------------------+
| json_type(cast(cast(3.14 as decimal(5,2)) as json)) |
+-----------------------------------------------------+
| DOUBLE                                              |
+-----------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(3.14 as json));
+-------------------------------+
| json_type(cast(3.14 as json)) |
+-------------------------------+
| DOUBLE                        |
+-------------------------------+
1 row in set (0.00 sec)

mysql> select json_type(cast(3.14E30 as json)); # correct
+----------------------------------+
| json_type(cast(3.14E30 as json)) |
+----------------------------------+
| DOUBLE                           |
+----------------------------------+
1 row in set (0.00 sec)

mysql> select tidb_version()\G
*************************** 1. row ***************************
tidb_version(): Release Version: v4.0.0-beta.2-750-g8a661044c
Edition: Community
Git Commit Hash: 8a661044cedf8daad1de4fbf79a390962b6f6c3b
Git Branch: master
UTC Build Time: 2020-07-10 10:52:37
GoVersion: go1.13
Race Enabled: false
TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306
Check Table Before Drop: false
1 row in set (0.00 sec)

@ghost ghost added the component/json label Jul 24, 2020
@ghost ghost added the priority/P3 The issue has P3 priority. Assigned to backlog. label Aug 12, 2020
@jebter jebter added the sig/execution SIG execution label Nov 11, 2020
@lzmhhh123 lzmhhh123 added challenge-program help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. labels Dec 4, 2020
@lzmhhh123
Copy link
Contributor

We didn't fully support json type. I convert the issue to type/feature.

@lzmhhh123 lzmhhh123 added type/feature-request Categorizes issue or PR as related to a new feature. and removed type/bug The issue is confirmed as a bug. labels Dec 8, 2020
@lzmhhh123
Copy link
Contributor

lzmhhh123 commented Dec 8, 2020

image
image

The difference json type between MySQL 8 and TiDB.

@morgo morgo changed the title json_type and cast cannot keep same with MySQL JSON data type does not support custom types (i.e. MySQL types) Dec 11, 2020
@jianzhiyao
Copy link
Contributor

jianzhiyao commented May 18, 2021

reference:

@morgo morgo assigned morgo and unassigned lzmhhh123 Aug 9, 2021
@morgo
Copy link
Contributor

morgo commented Aug 9, 2021

I am assigning this to myself. We have an intern looking into it.

@morgo morgo removed their assignment Nov 18, 2021
@xiongjiwei xiongjiwei self-assigned this Aug 10, 2022
@xiongjiwei xiongjiwei mentioned this issue Aug 30, 2022
34 tasks
@YangKeao
Copy link
Member

YangKeao commented Sep 1, 2022

This behavior has further influence:


drop table t;
create table t(
    i INT, j JSON, da DATE
    );
insert into t values (0, '"1596-03-31"', '1596-03-31');
select i from t where cast(json_unquote(j) as DATE) = da; -- should output 0
select i from t where cast(da as json) != j; -- should output 0

In TiDB, cast(da as json) is equal with the j, which in MySQL it's not.

@YangKeao
Copy link
Member

YangKeao commented Sep 1, 2022

It's quite amazing that it doesn't have the problem for #37443, the json_type keeps to be DATETIME even after saving to disk.

@YangKeao
Copy link
Member

YangKeao commented Sep 2, 2022

I'm working on this issue. It can be split into two problems:

  • Merge the json and types pkg, so that the json pkg can use the types.Time and types.Duration.
  • Implement the json time and duration types, and the cast between the json and Date/Datetime/Timestamp/Time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
challenge-program component/expression component/json help wanted Denotes an issue that needs help from a contributor. Must meet "help wanted" guidelines. priority/P3 The issue has P3 priority. Assigned to backlog. sig/execution SIG execution type/compatibility type/feature-request Categorizes issue or PR as related to a new feature.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants