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

Wrong Result in Cast Blob to Json #58959

Open
curry-oss opened this issue Jan 15, 2025 · 2 comments
Open

Wrong Result in Cast Blob to Json #58959

curry-oss opened this issue Jan 15, 2025 · 2 comments
Labels
component/json severity/minor sig/execution SIG execution type/bug The issue is confirmed as a bug.

Comments

@curry-oss
Copy link

Bug Report

Please answer these questions before submitting your issue. Thanks!

1. Minimal reproduce step (Required)

DROP TABLE IF EXISTS t0;
CREATE TABLE t0(c0 BLOB);
INSERT INTO t0 VALUES ('1xx');

SELECT CAST(t0.c0 AS JSON) IS TRUE FROM t0;

2. What did you expect to see? (Required)

see the following case:

3. What did you see instead (Required)

// TiDB
mysql> SELECT CAST(t0.c0 AS JSON) IS TRUE FROM t0;
+-----------------------------+
| CAST(t0.c0 AS JSON) IS TRUE |
+-----------------------------+
|                           0 |
+-----------------------------+
1 row in set, 1 warning (0.04 sec)

// MySQL
MySQL [test]> SELECT CAST(t0.c0 AS JSON) IS TRUE FROM t0;
+-----------------------------+
| CAST(t0.c0 AS JSON) IS TRUE |
+-----------------------------+
|                           1 |
+-----------------------------+
1 row in set, 1 warning (0.01 sec)

4. What is your TiDB version? (Required)

TiDB v8.5.0

@curry-oss curry-oss added the type/bug The issue is confirmed as a bug. label Jan 15, 2025
@zanmato1984 zanmato1984 added the sig/execution SIG execution label Jan 15, 2025
@Defined2014
Copy link
Contributor

Defined2014 commented Jan 16, 2025

I think the root cause already includes in warning message. In TiDB, we will cast the json result to double, then use the istrue function to get the result.

mysql> SELECT CAST(t0.c0 AS JSON) IS TRUE FROM t0;
+-----------------------------+
| CAST(t0.c0 AS JSON) IS TRUE |
+-----------------------------+
|                           1 |
+-----------------------------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                                                                                   |
+---------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 3986 | Evaluating a JSON value in SQL boolean context does an implicit comparison against JSON integer 0; if this is not what you want, consider converting JSON to a SQL numeric type with JSON_VALUE RETURNING |
+---------+------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

@zanmato1984
Copy link
Contributor

Seems like in MySQL, when evaluated as a logical expression, a JSON type behaves differently than other types such as string. For example:

mysql> SELECT '"base64:type252:MXh4"' IS TRUE;
+---------------------------------+
| '"base64:type252:MXh4"' IS TRUE |
+---------------------------------+
|                               0 |
+---------------------------------+

mysql> SELECT cast('"base64:type252:MXh4"' as json) IS TRUE;
+-----------------------------------------------+
| cast('"base64:type252:MXh4"' as json) IS TRUE |
+-----------------------------------------------+
|                                             1 |
+-----------------------------------------------+

And I can't find official document about this behavior of MySQL.

In TiDB, when evaluated as a logical expression, a JSON type behaves the same as other non-numeric types, namely, they are first casted to FLOAT, so the results are:

tidb> SELECT '"base64:type252:MXh4"' IS TRUE;
+---------------------------------+
| '"base64:type252:MXh4"' IS TRUE |
+---------------------------------+
|                               0 |
+---------------------------------+

tidb> SELECT cast('"base64:type252:MXh4"' as json) IS TRUE;
+-----------------------------------------------+
| cast('"base64:type252:MXh4"' as json) IS TRUE |
+-----------------------------------------------+
|                                             0 |
+-----------------------------------------------+

This is a very corner usage so I'm setting severity to minor.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/json severity/minor sig/execution SIG execution type/bug The issue is confirmed as a bug.
Projects
None yet
Development

No branches or pull requests

3 participants