mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-30646 View created via JSON_ARRAYAGG returns incorrect json object
Backporting add782a13e
from 10.6, this fixes the problem.
This commit is contained in:
@@ -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
|
from t1 LEFT JOIN t2 on t1.id = t2.owner_id
|
||||||
GROUP BY t1.id ORDER BY id;
|
GROUP BY t1.id ORDER BY id;
|
||||||
id materials
|
id materials
|
||||||
1 ["{\"id\": 1}","{\"id\": 2}"]
|
1 [{"id": 1},{"id": 2}]
|
||||||
2 ["{\"id\": 3}"]
|
2 [{"id": 3}]
|
||||||
3 ["{\"id\": 4}"]
|
3 [{"id": 4}]
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
#
|
#
|
||||||
|
@@ -2880,5 +2880,13 @@ DROP PROCEDURE p1;
|
|||||||
DROP PROCEDURE p2;
|
DROP PROCEDURE p2;
|
||||||
DROP TABLE t1, t1c, t2;
|
DROP TABLE t1, t1c, t2;
|
||||||
#
|
#
|
||||||
|
# MDEV-30646 View created via JSON_ARRAYAGG returns incorrect json object
|
||||||
|
#
|
||||||
|
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
|
# End of 10.5 tests
|
||||||
#
|
#
|
||||||
|
@@ -138,6 +138,15 @@ DROP PROCEDURE p2;
|
|||||||
|
|
||||||
DROP TABLE t1, t1c, t2;
|
DROP TABLE t1, t1c, t2;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-30646 View created via JSON_ARRAYAGG returns incorrect json object
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
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 #
|
||||||
--echo # End of 10.5 tests
|
--echo # End of 10.5 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@@ -1633,7 +1633,7 @@ null_return:
|
|||||||
`CONVERT(arg USING charset)` is actually a general purpose string
|
`CONVERT(arg USING charset)` is actually a general purpose string
|
||||||
expression, not a JSON expression.
|
expression, not a JSON expression.
|
||||||
*/
|
*/
|
||||||
static bool is_json_type(const Item *item)
|
bool is_json_type(const Item *item)
|
||||||
{
|
{
|
||||||
for ( ; ; )
|
for ( ; ; )
|
||||||
{
|
{
|
||||||
|
@@ -640,5 +640,6 @@ public:
|
|||||||
{ return get_item_copy<Item_func_json_objectagg>(thd, this); }
|
{ return get_item_copy<Item_func_json_objectagg>(thd, this); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern bool is_json_type(const Item *item);
|
||||||
|
|
||||||
#endif /* ITEM_JSONFUNC_INCLUDED */
|
#endif /* ITEM_JSONFUNC_INCLUDED */
|
||||||
|
@@ -18569,6 +18569,25 @@ Field *Item_func_sp::create_tmp_field_ex(MEM_ROOT *root, TABLE *table,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool make_json_valid_expr(TABLE *table, Field *field)
|
||||||
|
{
|
||||||
|
THD *thd= table->in_use;
|
||||||
|
Query_arena backup_arena;
|
||||||
|
Item *expr, *item_field;
|
||||||
|
|
||||||
|
if (!table->expr_arena && table->init_expr_arena(thd->mem_root))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
thd->set_n_backup_active_arena(table->expr_arena, &backup_arena);
|
||||||
|
if ((item_field= new (thd->mem_root) Item_field(thd, field)) &&
|
||||||
|
(expr= new (thd->mem_root) Item_func_json_valid(thd, item_field)))
|
||||||
|
field->check_constraint= add_virtual_expression(thd, expr);
|
||||||
|
thd->restore_active_arena(table->expr_arena, &backup_arena);
|
||||||
|
return field->check_constraint == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create field for temporary table.
|
Create field for temporary table.
|
||||||
|
|
||||||
@@ -18614,6 +18633,9 @@ Field *create_tmp_field(TABLE *table, Item *item,
|
|||||||
make_copy_field);
|
make_copy_field);
|
||||||
Field *result= item->create_tmp_field_ex(table->in_use->mem_root,
|
Field *result= item->create_tmp_field_ex(table->in_use->mem_root,
|
||||||
table, &src, &prm);
|
table, &src, &prm);
|
||||||
|
if (is_json_type(item) && make_json_valid_expr(table, result))
|
||||||
|
result= NULL;
|
||||||
|
|
||||||
*from_field= src.field();
|
*from_field= src.field();
|
||||||
*default_field= src.default_field();
|
*default_field= src.default_field();
|
||||||
if (src.item_result_field())
|
if (src.item_result_field())
|
||||||
|
21
sql/table.cc
21
sql/table.cc
@@ -53,6 +53,17 @@
|
|||||||
#define MYSQL57_GENERATED_FIELD 128
|
#define MYSQL57_GENERATED_FIELD 128
|
||||||
#define MYSQL57_GCOL_HEADER_SIZE 4
|
#define MYSQL57_GCOL_HEADER_SIZE 4
|
||||||
|
|
||||||
|
bool TABLE::init_expr_arena(MEM_ROOT *mem_root)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
We need to use CONVENTIONAL_EXECUTION here to ensure that
|
||||||
|
any new items created by fix_fields() are not reverted.
|
||||||
|
*/
|
||||||
|
expr_arena= new (alloc_root(mem_root, sizeof(Query_arena)))
|
||||||
|
Query_arena(mem_root, Query_arena::STMT_CONVENTIONAL_EXECUTION);
|
||||||
|
return expr_arena == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct extra2_fields
|
struct extra2_fields
|
||||||
{
|
{
|
||||||
LEX_CUSTRING version;
|
LEX_CUSTRING version;
|
||||||
@@ -1145,14 +1156,8 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
|
|||||||
table->s->table_check_constraints * sizeof(Virtual_column_info*));
|
table->s->table_check_constraints * sizeof(Virtual_column_info*));
|
||||||
|
|
||||||
DBUG_ASSERT(table->expr_arena == NULL);
|
DBUG_ASSERT(table->expr_arena == NULL);
|
||||||
/*
|
|
||||||
We need to use CONVENTIONAL_EXECUTION here to ensure that
|
if (table->init_expr_arena(mem_root))
|
||||||
any new items created by fix_fields() are not reverted.
|
|
||||||
*/
|
|
||||||
table->expr_arena= new (alloc_root(mem_root, sizeof(Query_arena)))
|
|
||||||
Query_arena(mem_root,
|
|
||||||
Query_arena::STMT_CONVENTIONAL_EXECUTION);
|
|
||||||
if (!table->expr_arena)
|
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
|
|
||||||
thd->set_n_backup_active_arena(table->expr_arena, &backup_arena);
|
thd->set_n_backup_active_arena(table->expr_arena, &backup_arena);
|
||||||
|
@@ -1645,6 +1645,8 @@ public:
|
|||||||
m_needs_reopen= value;
|
m_needs_reopen= value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool init_expr_arena(MEM_ROOT *mem_root);
|
||||||
|
|
||||||
bool alloc_keys(uint key_count);
|
bool alloc_keys(uint key_count);
|
||||||
bool check_tmp_key(uint key, uint key_parts,
|
bool check_tmp_key(uint key, uint key_parts,
|
||||||
uint (*next_field_no) (uchar *), uchar *arg);
|
uint (*next_field_no) (uchar *), uchar *arg);
|
||||||
|
Reference in New Issue
Block a user