Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions mysql-test/main/mdev_39998.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#
# MDEV-39998: JSON_OVERLAPS asymmetry for ordered array comparison
#
SELECT JSON_OVERLAPS('[[1,2]]', '[[1]]') AS must_be_0;
must_be_0
0
SELECT JSON_OVERLAPS('[[1]]', '[[1,2]]') AS must_be_0_too;
must_be_0_too
0
SELECT JSON_OVERLAPS('[[1,2]]', '[[1,2]]') AS must_be_1;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

please keep the tests to the minimum required to fully cover the new functionality. This one is not needed. There's a very extensive test in func_json.test already.

must_be_1
1
SELECT JSON_OVERLAPS('[[1,2,3]]', '[[1,2]]') AS r1,
JSON_OVERLAPS('[[1,2]]', '[[1,2,3]]') AS r2;
r1 r2
0 0
SELECT JSON_OVERLAPS('[1,2,3]', '[3,4,5]') AS scalar_overlap;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is not needed too.

scalar_overlap
1
SELECT JSON_OVERLAPS('[[]]', '[[]]') AS empty_match;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

not needed. There's more that are not needed below. Please keep only the one(s) that exercise the new code in unique ways.

empty_match
1
SELECT JSON_OVERLAPS('[[1]]', '[[]]') AS r1,
JSON_OVERLAPS('[[]]', '[[1]]') AS r2;
r1 r2
0 0
SELECT JSON_OVERLAPS('[{"a":1}]', '[{"a":1}]') AS obj_match;
obj_match
1
SELECT JSON_OVERLAPS('[{"a":1,"b":2}]', '[{"a":1}]') AS r1,
JSON_OVERLAPS('[{"a":1}]', '[{"a":1,"b":2}]') AS r2;
r1 r2
0 0
SELECT JSON_OVERLAPS('[[[1,2]]]', '[[[1]]]') AS r1,
JSON_OVERLAPS('[[[1]]]', '[[[1,2]]]') AS r2;
r1 r2
0 0
SELECT JSON_OVERLAPS('[[[1,2]]]', '[[[1,2]]]') AS deep_match;
deep_match
1
SELECT JSON_OVERLAPS(NULL, '[[1]]') AS r1,
JSON_OVERLAPS('[[1]]', NULL) AS r2;
r1 r2
NULL NULL
SELECT JSON_OVERLAPS('[1,[1,2]]', '[[1,2],1]') AS mixed_match;
mixed_match
1
SELECT JSON_OVERLAPS('[1,[1,2]]', '[[1],1]') AS r1,
JSON_OVERLAPS('[[1],1]', '[1,[1,2]]') AS r2;
r1 r2
1 1
SELECT JSON_OVERLAPS('[[1]]', '[[1]]') AS single_match;
single_match
1
SELECT JSON_OVERLAPS('[["a"]]', '[["a","b"]]') AS r1,
JSON_OVERLAPS('[["a","b"]]', '[["a"]]') AS r2;
r1 r2
0 0
51 changes: 51 additions & 0 deletions mysql-test/main/mdev_39998.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#
# MDEV-39998: JSON_OVERLAPS must be symmetric for nested arrays
#

--echo #
--echo # MDEV-39998: JSON_OVERLAPS asymmetry for ordered array comparison
--echo #

# Original reported bug: prefix of nested array falsely matches
SELECT JSON_OVERLAPS('[[1,2]]', '[[1]]') AS must_be_0;
SELECT JSON_OVERLAPS('[[1]]', '[[1,2]]') AS must_be_0_too;

# Exact match must still work
SELECT JSON_OVERLAPS('[[1,2]]', '[[1,2]]') AS must_be_1;

# Both directions must agree (symmetry)
SELECT JSON_OVERLAPS('[[1,2,3]]', '[[1,2]]') AS r1,
JSON_OVERLAPS('[[1,2]]', '[[1,2,3]]') AS r2;

# Scalar overlap still works
SELECT JSON_OVERLAPS('[1,2,3]', '[3,4,5]') AS scalar_overlap;

# Empty nested arrays
SELECT JSON_OVERLAPS('[[]]', '[[]]') AS empty_match;
SELECT JSON_OVERLAPS('[[1]]', '[[]]') AS r1,
JSON_OVERLAPS('[[]]', '[[1]]') AS r2;

# Nested objects inside arrays
SELECT JSON_OVERLAPS('[{"a":1}]', '[{"a":1}]') AS obj_match;
SELECT JSON_OVERLAPS('[{"a":1,"b":2}]', '[{"a":1}]') AS r1,
JSON_OVERLAPS('[{"a":1}]', '[{"a":1,"b":2}]') AS r2;

# Deeply nested arrays
SELECT JSON_OVERLAPS('[[[1,2]]]', '[[[1]]]') AS r1,
JSON_OVERLAPS('[[[1]]]', '[[[1,2]]]') AS r2;
SELECT JSON_OVERLAPS('[[[1,2]]]', '[[[1,2]]]') AS deep_match;

# NULL handling
SELECT JSON_OVERLAPS(NULL, '[[1]]') AS r1,
JSON_OVERLAPS('[[1]]', NULL) AS r2;

# Mixed types in outer array
SELECT JSON_OVERLAPS('[1,[1,2]]', '[[1,2],1]') AS mixed_match;
SELECT JSON_OVERLAPS('[1,[1,2]]', '[[1],1]') AS r1,
JSON_OVERLAPS('[[1],1]', '[1,[1,2]]') AS r2;

# Single element arrays
SELECT JSON_OVERLAPS('[[1]]', '[[1]]') AS single_match;
SELECT JSON_OVERLAPS('[["a"]]', '[["a","b"]]') AS r1,
JSON_OVERLAPS('[["a","b"]]', '[["a"]]') AS r2;

4 changes: 2 additions & 2 deletions sql/item_jsonfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5071,8 +5071,8 @@ bool json_compare_arrays_in_order(json_engine_t *js, json_engine_t *value,
return FALSE;
}
}
res= (value->state == JST_ARRAY_END || value->state == JST_OBJ_END ?
TRUE : FALSE);
res= (value->state == JST_ARRAY_END || value->state == JST_OBJ_END) &&
(js->state == JST_ARRAY_END || js->state == JST_OBJ_END);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All of your tests are with arrays. But there's also the same issue with JST_OBJ_END. Can you maybe add few tests that exercise that? Is it at all possible that value->state is JST_OBJ_END and js->state is JST_ARRAY_END? I'd guess not. So how about comparing the two states?
And, finally, please keep TRUE : FALSE part. This is a bugfix, not a refactoring.

json_skip_current_level(js, value);
return res;
}
Expand Down
Loading