diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index cba57b0853e..8e3b47e322a 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -1005,5 +1005,16 @@ JSON_VALID('{"admin\\"": null}') {"admin\"": null} 1 {"\"admin": null} 1 {"\"": null} # +# MDEV-29188: Crash in JSON_EXTRACT +# +CREATE TABLE t1 (j JSON); +INSERT INTO t1 VALUES +('{"ID": "4", "Name": "Betty", "Age": 19}'), +('[10, 20, [30, 40]]'); +SELECT * FROM t1 WHERE JSON_EXTRACT(j, '$.Age')=19; +j +{"ID": "4", "Name": "Betty", "Age": 19} +drop table t1; +# # End of 10.3 tests # diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index aa461433dfe..16f323a9a56 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -613,6 +613,20 @@ SELECT JSON_VALID('{"admin\\"": null}'), '{"admin\\"": null}' UNION SELECT JSON_VALID('{"\\"": null}'), '{"\\"": null}'; +--echo # +--echo # MDEV-29188: Crash in JSON_EXTRACT +--echo # + +CREATE TABLE t1 (j JSON); + +INSERT INTO t1 VALUES + ('{"ID": "4", "Name": "Betty", "Age": 19}'), + ('[10, 20, [30, 40]]'); + +SELECT * FROM t1 WHERE JSON_EXTRACT(j, '$.Age')=19; + +drop table t1; + --echo # --echo # End of 10.3 tests --echo # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f41414f8ae9..a3c0d4d95df 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -795,7 +795,9 @@ int Arg_comparator::compare_e_string() { String *res1,*res2; res1= (*a)->val_str(&value1); + DBUG_ASSERT((res1 == NULL) == (*a)->null_value); res2= (*b)->val_str(&value2); + DBUG_ASSERT((res2 == NULL) == (*b)->null_value); if (!res1 || !res2) return MY_TEST(res1 == res2); return MY_TEST(sortcmp(res1, res2, compare_collation()) == 0); @@ -832,10 +834,12 @@ int Arg_comparator::compare_decimal() { my_decimal decimal1; my_decimal *val1= (*a)->val_decimal(&decimal1); + DBUG_ASSERT((val1 == NULL) == (*a)->null_value); if (!(*a)->null_value) { my_decimal decimal2; my_decimal *val2= (*b)->val_decimal(&decimal2); + DBUG_ASSERT((val2 == NULL) == (*b)->null_value); if (!(*b)->null_value) { if (set_null) diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc index c0f063639bc..5166d9a78af 100644 --- a/sql/item_jsonfunc.cc +++ b/sql/item_jsonfunc.cc @@ -1109,12 +1109,14 @@ my_decimal *Item_func_json_extract::val_decimal(my_decimal *to) case JSON_VALUE_OBJECT: case JSON_VALUE_ARRAY: case JSON_VALUE_FALSE: + // TODO: fix: NULL should be NULL case JSON_VALUE_NULL: - break; + int2my_decimal(E_DEC_FATAL_ERROR, 0, false/*unsigned_flag*/, to); + return to; }; } - int2my_decimal(E_DEC_FATAL_ERROR, 0, false/*unsigned_flag*/, to); - return to; + DBUG_ASSERT(null_value); + return 0; }