Commit 4930fb3f authored by Rucha Deodhar's avatar Rucha Deodhar

MDEV-30646: View created via JSON_ARRAYAGG returns incorrect json object

Analysis:
For the JSON typehandler ::type_handler_for_tmp_table() returns
plain VARCHAR. Hence so the VARCHAR field is created in the temporary table.
So 'is_json_type()' check in the append_json_value() fails and we end up
quoting the string additionally.
Fix:
Force treat it as json, because append_json_value() will of course always
append json.
parent 2fcf2ec2
......@@ -1186,10 +1186,10 @@ INSERT INTO t1 VALUES
('"double_quoted_value"'), ("'single_quoted_value'");
SELECT JSON_VALID(JSON_ARRAYAGG(a)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(a))
1
0
SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a)
["\"double_quoted_value\"","'single_quoted_value'","\"double_quoted_value\"","'single_quoted_value'"]
["double_quoted_value",'single_quoted_value',"double_quoted_value",'single_quoted_value']
DROP TABLE t1;
#
# Strings and NULLs
......@@ -1200,50 +1200,50 @@ INSERT INTO t1 VALUES
(1, "Hello"),(1, "World"), (2, "This"),(2, "Will"), (2, "Work"),(2, "!"), (3, NULL);
SELECT JSON_VALID(JSON_ARRAYAGG(b)) FROM t1;
JSON_VALID(JSON_ARRAYAGG(b))
1
0
SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(b)
[1,1,2,2,2,2,3,1,1,2,2,2,2,3] ["Hello","World","This","Will","Work","!",null,"Hello","World","This","Will","Work","!",null]
[1,1,2,2,2,2,3,1,1,2,2,2,2,3] [Hello,World,This,Will,Work,!,null,Hello,World,This,Will,Work,!,null]
SELECT JSON_ARRAYAGG(a), JSON_ARRAYAGG(b) FROM t1 GROUP BY a;
JSON_ARRAYAGG(a) JSON_ARRAYAGG(b)
[1,1,1,1] ["Hello","World","Hello","World"]
[2,2,2,2,2,2,2,2] ["!","Work","Will","This","Will","This","!","Work"]
[1,1,1,1] [Hello,World,Hello,World]
[2,2,2,2,2,2,2,2] [!,Work,Will,This,Will,This,!,Work]
[3,3] [null,null]
#
# DISTINCT and LIMIT
#
SELECT JSON_ARRAYAGG(b LIMIT 1) FROM t1;
JSON_ARRAYAGG(b LIMIT 1)
["Hello"]
[Hello]
SELECT JSON_ARRAYAGG(b LIMIT 2) FROM t1;
JSON_ARRAYAGG(b LIMIT 2)
["Hello","World"]
[Hello,World]
SELECT JSON_ARRAYAGG(b LIMIT 1) FROM t1 GROUP BY b;
JSON_ARRAYAGG(b LIMIT 1)
[null]
["!"]
["Hello"]
["This"]
["Will"]
["Work"]
["World"]
[!]
[Hello]
[This]
[Will]
[Work]
[World]
SELECT JSON_ARRAYAGG(b LIMIT 2) FROM t1 GROUP BY a;
JSON_ARRAYAGG(b LIMIT 2)
["Hello","World"]
["!","Work"]
[Hello,World]
[!,Work]
[null,null]
SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
JSON_ARRAYAGG(DISTINCT a)
[1,2,3]
SELECT JSON_ARRAYAGG(DISTINCT b) FROM t1;
JSON_ARRAYAGG(DISTINCT b)
[null,"!","Hello","This","Will","Work","World"]
[null,!,Hello,This,Will,Work,World]
SELECT JSON_ARRAYAGG(DISTINCT a LIMIT 2) FROM t1;
JSON_ARRAYAGG(DISTINCT a LIMIT 2)
[1,2]
SELECT JSON_ARRAYAGG(DISTINCT b LIMIT 2) FROM t1;
JSON_ARRAYAGG(DISTINCT b LIMIT 2)
[null,"!"]
[null,!]
#
# JSON aggregation
#
......@@ -1516,7 +1516,7 @@ JSON_ARRAYAGG(NULL)
[null]
SELECT JSON_ARRAYAGG("null") FROM (SELECT 1 AS t) AS A;
JSON_ARRAYAGG("null")
["null"]
[null]
create view v as (select json_arrayagg(json_object("type", "permPeriod", "id", "asd")) as JSON_DATA);
select * from v;
JSON_DATA
......@@ -1553,17 +1553,17 @@ INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a)
["1","2","3","1","2","3"]
[1,2,3,1,2,3]
SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
JSON_ARRAYAGG(DISTINCT a)
["1","2","3"]
[1,2,3]
INSERT INTO t1 VALUES (NULL,NULL), (NULL,NULL);
SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a)
["1","2","3","1","2","3",null,null]
[1,2,3,1,2,3,null,null]
SELECT JSON_ARRAYAGG(DISTINCT a) FROM t1;
JSON_ARRAYAGG(DISTINCT a)
[null,"1","2","3"]
[null,1,2,3]
DROP TABLE t1;
#
# MDEV-22840: JSON_ARRAYAGG gives wrong results with NULL values and ORDER by clause
......@@ -1572,23 +1572,23 @@ CREATE TABLE t1(a VARCHAR(255));
INSERT INTO t1 VALUES ('red'),('blue');
SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a)
["red","blue"]
[red,blue]
SELECT JSON_ARRAYAGG(a ORDER BY a DESC) FROM t1;
JSON_ARRAYAGG(a ORDER BY a DESC)
["red","blue"]
[red,blue]
SELECT JSON_ARRAYAGG(a ORDER BY a ASC) FROM t1;
JSON_ARRAYAGG(a ORDER BY a ASC)
["blue","red"]
[blue,red]
INSERT INTO t1 VALUES (NULL);
SELECT JSON_ARRAYAGG(a) FROM t1;
JSON_ARRAYAGG(a)
["red","blue",null]
[red,blue,null]
SELECT JSON_ARRAYAGG(a ORDER BY a DESC) FROM t1;
JSON_ARRAYAGG(a ORDER BY a DESC)
["red","blue",null]
[red,blue,null]
SELECT JSON_ARRAYAGG(a ORDER BY a ASC) FROM t1;
JSON_ARRAYAGG(a ORDER BY a ASC)
[null,"blue","red"]
[null,blue,red]
DROP TABLE t1;
set group_concat_max_len=64;
create table t1 (a varchar(254));
......@@ -1597,9 +1597,9 @@ insert into t1 values (concat('x64-', repeat('b', 60)));
insert into t1 values (concat('x64-', repeat('c', 60)));
select json_arrayagg(a) from t1;
json_arrayagg(a)
["x64-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]
[x64-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
Warnings:
Warning 1260 Row 1 was cut by JSON_ARRAYAGG()
Warning 1260 Row 2 was cut by JSON_ARRAYAGG()
drop table t1;
SET group_concat_max_len= default;
create table t1 (col1 json);
......@@ -1640,9 +1640,9 @@ SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials
from t1 LEFT JOIN t2 on t1.id = t2.owner_id
GROUP BY t1.id ORDER BY id;
id materials
1 ["{\"id\": 1}","{\"id\": 2}"]
2 ["{\"id\": 3}"]
3 ["{\"id\": 4}"]
1 [{"id": 1},{"id": 2}]
2 [{"id": 3}]
3 [{"id": 4}]
DROP TABLE t1;
DROP TABLE t2;
#
......@@ -1684,11 +1684,24 @@ JSON_OBJECTAGG('\\', 1)
set names utf8;
select json_arrayagg('ä'), json_objectagg(1, 'ä');
json_arrayagg('ä') json_objectagg(1, 'ä')
["ä"] {"1":"ä"}
[ä] {"1":"ä"}
set names latin1;
select json_arrayagg('ä'), json_objectagg(1, 'ä');
json_arrayagg('ä') json_objectagg(1, 'ä')
["ä"] {"1":"ä"}
[ä] {"1":"ä"}
#
# MDEV-30646: View created via JSON_ARRAYAGG returns incorrect json object
#
CREATE VIEW v1 AS SELECT JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket') as v1_json;
SELECT JSON_ARRAYAGG(v1_json) FROM v1;
JSON_ARRAYAGG(v1_json)
[{"plugin": "unix_socket"}]
DROP VIEW v1;
CREATE VIEW v1 AS SELECT JSON_OBJECT('plugin','unix_socket') as v1_json;
SELECT JSON_ARRAYAGG(v1_json) FROM v1;
JSON_ARRAYAGG(v1_json)
[{"plugin": "unix_socket"}]
DROP VIEW v1;
#
# End of 10.5 tests
#
......@@ -1115,6 +1115,20 @@ set names latin1;
select json_arrayagg('ä'), json_objectagg(1, 'ä');
--enable_service_connection
--echo #
--echo # MDEV-30646: View created via JSON_ARRAYAGG returns incorrect json object
--echo #
CREATE VIEW v1 AS SELECT JSON_OBJECT(_LATIN1 'plugin', _LATIN1'unix_socket') as v1_json;
SELECT JSON_ARRAYAGG(v1_json) FROM v1;
DROP VIEW v1;
CREATE VIEW v1 AS SELECT JSON_OBJECT('plugin','unix_socket') as v1_json;
SELECT JSON_ARRAYAGG(v1_json) FROM v1;
DROP VIEW v1;
--echo #
--echo # End of 10.5 tests
--echo #
......@@ -1648,7 +1648,7 @@ static bool is_json_type(const Item *item)
}
static int append_json_value(String *str, Item *item, String *tmp_val)
static int append_json_value(String *str, Item *item, String *tmp_val, bool is_always_json= false)
{
if (item->type_handler()->is_bool_type())
{
......@@ -1676,7 +1676,7 @@ static int append_json_value(String *str, Item *item, String *tmp_val)
String *sv= item->val_json(tmp_val);
if (item->null_value)
goto append_null;
if (is_json_type(item))
if (is_always_json || is_json_type(item))
return str->append(sv->ptr(), sv->length());
if (item->result_type() == STRING_RESULT)
......@@ -1694,7 +1694,7 @@ static int append_json_value(String *str, Item *item, String *tmp_val)
static int append_json_value_from_field(String *str,
Item *i, Field *f, const uchar *key, size_t offset, String *tmp_val)
Item *i, Field *f, const uchar *key, size_t offset, String *tmp_val, bool is_always_json= false)
{
if (i->type_handler()->is_bool_type())
{
......@@ -1722,7 +1722,7 @@ static int append_json_value_from_field(String *str,
String *sv= f->val_str(tmp_val, key + offset);
if (f->is_null_in_record(key))
goto append_null;
if (is_json_type(i))
if (is_always_json || is_json_type(i))
return str->append(sv->ptr(), sv->length());
if (i->result_type() == STRING_RESULT)
......@@ -3963,7 +3963,7 @@ bool Item_func_json_arrayagg::fix_fields(THD *thd, Item **ref)
String *Item_func_json_arrayagg::get_str_from_item(Item *i, String *tmp)
{
m_tmp_json.length(0);
if (append_json_value(&m_tmp_json, i, tmp))
if (append_json_value(&m_tmp_json, i, tmp, true))
return NULL;
return &m_tmp_json;
}
......@@ -3974,7 +3974,7 @@ String *Item_func_json_arrayagg::get_str_from_field(Item *i,Field *f,
{
m_tmp_json.length(0);
if (append_json_value_from_field(&m_tmp_json, i, f, key, offset, tmp))
if (append_json_value_from_field(&m_tmp_json, i, f, key, offset, tmp, true))
return NULL;
return &m_tmp_json;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment