Skip to content

Commit e4b302e

Browse files
committed
MDEV-27018 IF and COALESCE lose "json" property
Hybrid functions (IF, COALESCE, etc) did not preserve the JSON property from their arguments. The same problem was repeatable for single row subselects. The problem happened because the method Item::is_json_type() was inconsistently implemented across the Item hierarchy. For example, Item_hybrid_func and Item_singlerow_subselect did not override is_json_type(). Solution: - Removing Item::is_json_type() - Implementing specific JSON type handlers: Type_handler_string_json Type_handler_varchar_json Type_handler_tiny_blob_json Type_handler_blob_json Type_handler_medium_blob_json Type_handler_long_blob_json - Reusing the existing data type infrastructure to pass JSON type handlers across all item types, including classes Item_hybrid_func and Item_singlerow_subselect. Note, these two classes themselves do not need any changes! - Extending the data type infrastructure so data types can inherit their properties (e.g. aggregation rules) from their base data types. E.g. VARCHAR/JSON acts as VARCHAR, LONGTEXT/JSON acts as LONGTEXT when mixed to a non-JSON data type. This is done by: - adding virtual method Type_handler::type_handler_base() - adding a helper class Type_handler_pair - refactoring Type_handler_hybrid_field_type methods aggregate_for_result(), aggregate_for_min_max(), aggregate_for_num_op() to use Type_handler_pair. This change also fixes: MDEV-27361 Hybrid functions with JSON arguments do not send format metadata Also, adding mtr tests for JSON replication. It was not covered yet. And the current patch changes the replication code slightly.
1 parent 28e166d commit e4b302e

33 files changed

+4014
-99
lines changed

mysql-test/main/func_json.result

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,5 +1388,14 @@ id materials
13881388
DROP TABLE t1;
13891389
DROP TABLE t2;
13901390
#
1391+
# MDEV-27018 IF and COALESCE lose "json" property
1392+
#
1393+
SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f')));
1394+
json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f')))
1395+
{"a": {"b": "c"}}
1396+
SELECT json_object('a', coalesce(json_object('b', 'c')));
1397+
json_object('a', coalesce(json_object('b', 'c')))
1398+
{"a": {"b": "c"}}
1399+
#
13911400
# End of 10.5 tests
13921401
#

mysql-test/main/func_json.test

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,6 +879,14 @@ SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials
879879
DROP TABLE t1;
880880
DROP TABLE t2;
881881

882+
--echo #
883+
--echo # MDEV-27018 IF and COALESCE lose "json" property
884+
--echo #
885+
886+
SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f')));
887+
SELECT json_object('a', coalesce(json_object('b', 'c')));
888+
889+
882890
--echo #
883891
--echo # End of 10.5 tests
884892
--echo #

mysql-test/main/type_json.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,5 +126,38 @@ def JSON_COMPACT('{}') 253 (format=json) 6 0 Y 0 0 33
126126
js0 JSON_COMPACT(js0) JSON_COMPACT('{}')
127127
DROP TABLE t1;
128128
#
129+
# MDEV-27361 Hybrid functions with JSON arguments do not send format metadata
130+
#
131+
CREATE TABLE t1 (a JSON);
132+
INSERT INTO t1 VALUES ('{"a":"b"}');
133+
SELECT a, JSON_COMPACT(a), COALESCE(a) FROM t1;
134+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
135+
def test t1 t1 a a 252 (format=json) 4294967295 9 Y 144 0 33
136+
def JSON_COMPACT(a) 251 (format=json) 4294967295 9 Y 128 0 33
137+
def COALESCE(a) 251 (format=json) 4294967295 9 Y 128 39 33
138+
a JSON_COMPACT(a) COALESCE(a)
139+
{"a":"b"} {"a":"b"} {"a":"b"}
140+
SELECT JSON_ARRAYAGG(1), JSON_ARRAYAGG(a) FROM t1;
141+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
142+
def JSON_ARRAYAGG(1) 252 (format=json) 9437184 3 Y 0 0 33
143+
def JSON_ARRAYAGG(a) 252 (format=json) 12582912 11 Y 128 0 33
144+
JSON_ARRAYAGG(1) JSON_ARRAYAGG(a)
145+
[1] [{"a":"b"}]
146+
SELECT JSON_OBJECTAGG('a','b'), JSON_OBJECTAGG('a',a) FROM t1;
147+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
148+
def JSON_OBJECTAGG('a','b') 252 (format=json) 9437184 9 Y 0 0 33
149+
def JSON_OBJECTAGG('a',a) 252 (format=json) 12582912 15 Y 128 0 33
150+
JSON_OBJECTAGG('a','b') JSON_OBJECTAGG('a',a)
151+
{"a":"b"} {"a":{"a":"b"}}
152+
DROP TABLE t1;
153+
#
154+
# MDEV-27018 IF and COALESCE lose "json" property
155+
#
156+
SELECT json_object('a', (SELECT json_objectagg(b, c) FROM (SELECT 'b','c') d)) AS j FROM DUAL;
157+
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
158+
def j 250 (format=json) 9437283 16 Y 0 39 33
159+
j
160+
{"a": {"b":"c"}}
161+
#
129162
# End of 10.5 tests
130163
#

mysql-test/main/type_json.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,34 @@ SELECT js0, JSON_COMPACT(js0), JSON_COMPACT('{}') FROM t1;
8888
--enable_ps_protocol
8989
DROP TABLE t1;
9090

91+
92+
--echo #
93+
--echo # MDEV-27361 Hybrid functions with JSON arguments do not send format metadata
94+
--echo #
95+
96+
CREATE TABLE t1 (a JSON);
97+
INSERT INTO t1 VALUES ('{"a":"b"}');
98+
--disable_ps_protocol
99+
--enable_metadata
100+
SELECT a, JSON_COMPACT(a), COALESCE(a) FROM t1;
101+
SELECT JSON_ARRAYAGG(1), JSON_ARRAYAGG(a) FROM t1;
102+
SELECT JSON_OBJECTAGG('a','b'), JSON_OBJECTAGG('a',a) FROM t1;
103+
--disable_metadata
104+
--disable_ps_protocol
105+
DROP TABLE t1;
106+
107+
108+
--echo #
109+
--echo # MDEV-27018 IF and COALESCE lose "json" property
110+
--echo #
111+
112+
--disable_ps_protocol
113+
--enable_metadata
114+
SELECT json_object('a', (SELECT json_objectagg(b, c) FROM (SELECT 'b','c') d)) AS j FROM DUAL;
115+
--disable_metadata
116+
--disable_ps_protocol
117+
118+
91119
--echo #
92120
--echo # End of 10.5 tests
93121
--echo #
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include/master-slave.inc
2+
[connection master]
3+
#
4+
# Start of 10.5 tests
5+
#
6+
#
7+
# MDEV-27018 IF and COALESCE lose "json" property
8+
#
9+
CREATE TABLE t1 (a CHAR(100) CHECK(JSON_VALID(a)));
10+
connection slave;
11+
connection master;
12+
INSERT INTO t1 VALUES (JSON_OBJECT('a','b'));
13+
connection slave;
14+
SELECT * FROM t1 ORDER BY a;
15+
a
16+
{"a": "b"}
17+
connection master;
18+
DROP TABLE t1;
19+
#
20+
# End of 10.5 tests
21+
#
22+
include/rpl_end.inc
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include/master-slave.inc
2+
[connection master]
3+
#
4+
# Start of 10.5 tests
5+
#
6+
#
7+
# MDEV-27018 IF and COALESCE lose "json" property
8+
#
9+
CREATE TABLE t1 (a LONGTEXT CHECK(JSON_VALID(a)));
10+
connection slave;
11+
connection master;
12+
INSERT INTO t1 VALUES (JSON_OBJECT('a','b'));
13+
connection slave;
14+
SELECT * FROM t1 ORDER BY a;
15+
a
16+
{"a": "b"}
17+
connection master;
18+
DROP TABLE t1;
19+
#
20+
# End of 10.5 tests
21+
#
22+
include/rpl_end.inc
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include/master-slave.inc
2+
[connection master]
3+
#
4+
# Start of 10.5 tests
5+
#
6+
#
7+
# MDEV-27018 IF and COALESCE lose "json" property
8+
#
9+
CREATE TABLE t1 (a MEDIUMTEXT CHECK(JSON_VALID(a)));
10+
connection slave;
11+
connection master;
12+
INSERT INTO t1 VALUES (JSON_OBJECT('a','b'));
13+
connection slave;
14+
SELECT * FROM t1 ORDER BY a;
15+
a
16+
{"a": "b"}
17+
connection master;
18+
DROP TABLE t1;
19+
#
20+
# End of 10.5 tests
21+
#
22+
include/rpl_end.inc
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include/master-slave.inc
2+
[connection master]
3+
#
4+
# Start of 10.5 tests
5+
#
6+
#
7+
# MDEV-27018 IF and COALESCE lose "json" property
8+
#
9+
CREATE TABLE t1 (a TEXT CHECK(JSON_VALID(a)));
10+
connection slave;
11+
connection master;
12+
INSERT INTO t1 VALUES (JSON_OBJECT('a','b'));
13+
connection slave;
14+
SELECT * FROM t1 ORDER BY a;
15+
a
16+
{"a": "b"}
17+
connection master;
18+
DROP TABLE t1;
19+
#
20+
# End of 10.5 tests
21+
#
22+
include/rpl_end.inc
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include/master-slave.inc
2+
[connection master]
3+
#
4+
# Start of 10.5 tests
5+
#
6+
#
7+
# MDEV-27018 IF and COALESCE lose "json" property
8+
#
9+
CREATE TABLE t1 (a TINYTEXT CHECK(JSON_VALID(a)));
10+
connection slave;
11+
connection master;
12+
INSERT INTO t1 VALUES (JSON_OBJECT('a','b'));
13+
connection slave;
14+
SELECT * FROM t1 ORDER BY a;
15+
a
16+
{"a": "b"}
17+
connection master;
18+
DROP TABLE t1;
19+
#
20+
# End of 10.5 tests
21+
#
22+
include/rpl_end.inc
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
include/master-slave.inc
2+
[connection master]
3+
#
4+
# Start of 10.5 tests
5+
#
6+
#
7+
# MDEV-27018 IF and COALESCE lose "json" property
8+
#
9+
CREATE TABLE t1 (a VARCHAR(100) CHECK(JSON_VALID(a)));
10+
connection slave;
11+
connection master;
12+
INSERT INTO t1 VALUES (JSON_OBJECT('a','b'));
13+
connection slave;
14+
SELECT * FROM t1 ORDER BY a;
15+
a
16+
{"a": "b"}
17+
connection master;
18+
DROP TABLE t1;
19+
#
20+
# End of 10.5 tests
21+
#
22+
include/rpl_end.inc

0 commit comments

Comments
 (0)