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

executor: fix bug about JSON_EXTRACT fails to cast as bool #12440

Closed
wants to merge 11 commits into from
15 changes: 15 additions & 0 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1854,6 +1854,21 @@ func (s *testSuiteP1) TestGeneratedColumnRead(c *C) {
result = tk.MustQuery(`SELECT * FROM test_gc_read_m`)
result.Check(testkit.Rows(`1 2 4`, `2 3 6`))

tk.MustExec(`create table testjson(j json )`)
tk.MustExec(`insert into testjson set j='{"test":1}'`)
result = tk.MustQuery(`select j from testjson where json_extract(j, '$.test')`)
result.Check(testkit.Rows(`{"test": 1}`))

tk.MustExec(`delete from testjson`)
tk.MustExec(`insert into testjson set j='{"test":0}'`)
result = tk.MustQuery(`select j from testjson where json_extract(j, '$.test')`)
result.Check(testkit.Rows(`{"test": 0}`))

tk.MustExec(`delete from testjson`)
tk.MustExec(`insert into testjson set j='{"test1":1}'`)
result = tk.MustQuery(`select j from testjson where json_extract(j, '$.test')`)
result.Check(nil)

// Test not null generated columns.
tk.MustExec(`CREATE TABLE test_gc_read_1(a int primary key, b int, c int as (a+b) not null, d int as (a*b) stored)`)
tk.MustExec(`CREATE TABLE test_gc_read_2(a int primary key, b int, c int as (a+b), d int as (a*b) stored not null)`)
Expand Down
2 changes: 2 additions & 0 deletions types/datum.go
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,8 @@ func (d *Datum) ToBool(sc *stmtctx.StatementContext) (int64, error) {
case KindBinaryLiteral, KindMysqlBit:
val, err1 := d.GetBinaryLiteral().ToInt(sc)
isZero, err = val == 0, err1
case KindMysqlJSON:
isZero, err = d.IsNull(), nil
Copy link
Contributor

@SunRunAway SunRunAway Sep 29, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be false if $.test is zero.
Please add a test case like {"test":0} to cover it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had add testcase as follows:
a) testcase1:
insert into testjson set j='{"test":0}
select j from testjson where json_extract(j, '$.test')

b) testcase2:
insert into testjson set j='{"test1":0}
select j from testjson where json_extract(j, '$.test')

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this case in Mysql5.7, and the result is different from yours.

mysql> drop table testjson;
Query OK, 0 rows affected (0.00 sec)

mysql> create table testjson(j json );
Query OK, 0 rows affected (0.01 sec)

mysql> insert into testjson set j='{"test":0}';
Query OK, 1 row affected (0.00 sec)

mysql> select j from testjson where json_extract(j, '$.test');
Empty set (0.00 sec)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another case is different from Mysql5.7

In your branch:

mysql> create table testjson(j json);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into testjson set j='0';
Query OK, 1 row affected (0.00 sec)

mysql> insert into testjson set j='null';
Query OK, 1 row affected (0.00 sec)

mysql> insert into testjson set j='1';
Query OK, 1 row affected (0.00 sec)

mysql> select j from testjson where j;
+------+
| j    |
+------+
| 0    |
| null |
| 1    |
+------+
3 rows in set (0.00 sec)

In MySQL5.7

mysql> create table testjson(j json);
Query OK, 0 rows affected (0.02 sec)

mysql> insert into testjson set j='0';
Query OK, 1 row affected (0.01 sec)

mysql> insert into testjson set j='null';
Query OK, 1 row affected (0.00 sec)

mysql> insert into testjson set j='1';
Query OK, 1 row affected (0.00 sec)

mysql> select j from testjson where j;
+------+
| j    |
+------+
| 1    |
+------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+---------------------------------------------------------------+
| Level   | Code | Message                                                       |
+---------+------+---------------------------------------------------------------+
| Warning | 3156 | Invalid JSON value for CAST to INTEGER from column j at row 2 |
+---------+------+---------------------------------------------------------------+
1 row in set (0.00 sec)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, I will investigate it.

default:
return 0, errors.Errorf("cannot convert %v(type %T) to bool", d.GetValue(), d.GetValue())
}
Expand Down