Commit 74198384 authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-21914 JSON_ARRAYAGG doesn't reject ORDER BY clause, but doesn't work either.

ORDER BY fixed for JSON_ARRAYAGG.
parent 07daf735
...@@ -1240,6 +1240,9 @@ select * from v; ...@@ -1240,6 +1240,9 @@ select * from v;
JSON_DATA JSON_DATA
[{"type": "permPeriod", "id": "asd"}] [{"type": "permPeriod", "id": "asd"}]
drop view v; drop view v;
select json_arrayagg(a order by a asc) from (select 1 a union select 2 a) t;
json_arrayagg(a order by a asc)
[1,2]
# #
# End of 10.5 tests # End of 10.5 tests
# #
...@@ -759,6 +759,8 @@ create view v as (select json_arrayagg(json_object("type", "permPeriod", "id", " ...@@ -759,6 +759,8 @@ create view v as (select json_arrayagg(json_object("type", "permPeriod", "id", "
select * from v; select * from v;
drop view v; drop view v;
select json_arrayagg(a order by a asc) from (select 1 a union select 2 a) t;
--echo # --echo #
--echo # End of 10.5 tests --echo # End of 10.5 tests
--echo # --echo #
......
...@@ -1452,6 +1452,52 @@ static int append_json_value(String *str, Item *item, String *tmp_val) ...@@ -1452,6 +1452,52 @@ 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)
{
if (i->type_handler()->is_bool_type())
{
longlong v_int= f->val_int(key + offset);
const char *t_f;
int t_f_len;
if (f->is_null(offset))
goto append_null;
if (v_int)
{
t_f= "true";
t_f_len= 4;
}
else
{
t_f= "false";
t_f_len= 5;
}
return str->append(t_f, t_f_len);
}
{
String *sv= f->val_str(tmp_val, key + offset);
if (f->is_null(offset))
goto append_null;
if (i->is_json_type())
return str->append(sv->ptr(), sv->length());
if (i->result_type() == STRING_RESULT)
{
return str->append("\"", 1) ||
st_append_escaped(str, sv) ||
str->append("\"", 1);
}
return st_append_escaped(str, sv);
}
append_null:
return str->append("null", 4);
}
static int append_json_keyname(String *str, Item *item, String *tmp_val) static int append_json_keyname(String *str, Item *item, String *tmp_val)
{ {
String *sv= item->val_str(tmp_val); String *sv= item->val_str(tmp_val);
...@@ -3621,12 +3667,25 @@ int Arg_comparator::compare_e_json_str_basic(Item *j, Item *s) ...@@ -3621,12 +3667,25 @@ int Arg_comparator::compare_e_json_str_basic(Item *j, Item *s)
} }
String* Item_func_json_arrayagg::convert_to_json(Item *item) 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))
return NULL;
return &m_tmp_json;
}
String *Item_func_json_arrayagg::get_str_from_field(Item *i,Field *f,
String *tmp, const uchar *key, size_t offset)
{ {
String tmp;
m_tmp_json.length(0); m_tmp_json.length(0);
append_json_value(&m_tmp_json, item, &tmp);
if (append_json_value_from_field(&m_tmp_json, i, f, key, offset, tmp))
return NULL;
return &m_tmp_json; return &m_tmp_json;
} }
......
...@@ -542,10 +542,13 @@ class Item_func_json_arrayagg : public Item_func_group_concat ...@@ -542,10 +542,13 @@ class Item_func_json_arrayagg : public Item_func_group_concat
Overrides Item_func_group_concat::skip_nulls() Overrides Item_func_group_concat::skip_nulls()
NULL-s should be added to the result as JSON null value. NULL-s should be added to the result as JSON null value.
*/ */
virtual bool skip_nulls() const { return false; } bool skip_nulls() const { return false; }
String *get_str_from_item(Item *i, String *tmp);
String *get_str_from_field(Item *i, Field *f, String *tmp,
const uchar *key, size_t offset);
public: public:
String m_tmp_json; /* Used in convert_to_json. */ String m_tmp_json; /* Used in get_str_from_*.. */
Item_func_json_arrayagg(THD *thd, Name_resolution_context *context_arg, Item_func_json_arrayagg(THD *thd, Name_resolution_context *context_arg,
bool is_distinct, List<Item> *is_select, bool is_distinct, List<Item> *is_select,
const SQL_I_List<ORDER> &is_order, String *is_separator, const SQL_I_List<ORDER> &is_order, String *is_separator,
...@@ -560,7 +563,6 @@ class Item_func_json_arrayagg : public Item_func_group_concat ...@@ -560,7 +563,6 @@ class Item_func_json_arrayagg : public Item_func_group_concat
const char *func_name() const { return "json_arrayagg("; } const char *func_name() const { return "json_arrayagg("; }
enum Sumfunctype sum_func() const {return JSON_ARRAYAGG_FUNC;} enum Sumfunctype sum_func() const {return JSON_ARRAYAGG_FUNC;}
String* convert_to_json(Item *item);
String* val_str(String *str); String* val_str(String *str);
Item *get_copy(THD *thd) Item *get_copy(THD *thd)
......
...@@ -3660,7 +3660,7 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), ...@@ -3660,7 +3660,7 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
because it contains both order and arg list fields. because it contains both order and arg list fields.
*/ */
if ((*arg)->const_item()) if ((*arg)->const_item())
res= (*arg)->val_str(&tmp); res= item->get_str_from_item(*arg, &tmp);
else else
{ {
Field *field= (*arg)->get_tmp_table_field(); Field *field= (*arg)->get_tmp_table_field();
...@@ -3669,19 +3669,10 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)), ...@@ -3669,19 +3669,10 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
uint offset= (field->offset(field->table->record[0]) - uint offset= (field->offset(field->table->record[0]) -
table->s->null_bytes); table->s->null_bytes);
DBUG_ASSERT(offset < table->s->reclength); DBUG_ASSERT(offset < table->s->reclength);
res= field->val_str(&tmp, key + offset); res= item->get_str_from_field(*arg, field, &tmp, key, offset);
} }
else else
res= (*arg)->val_str(&tmp); res= item->get_str_from_item(*arg, &tmp);
}
if (item->sum_func() == Item_sum::JSON_ARRAYAGG_FUNC)
{
/*
JSON_ARRAYAGG needs to convert the type into valid JSON before
appending it to the result
*/
Item_func_json_arrayagg *arrayagg= (Item_func_json_arrayagg *) item_arg;
res= arrayagg->convert_to_json(*arg);
} }
if (res) if (res)
...@@ -3981,6 +3972,7 @@ bool Item_func_group_concat::repack_tree(THD *thd) ...@@ -3981,6 +3972,7 @@ bool Item_func_group_concat::repack_tree(THD *thd)
return 0; return 0;
} }
/* /*
Repacking the tree is expensive. But it keeps the tree small, and Repacking the tree is expensive. But it keeps the tree small, and
inserting into an unnecessary large tree is also waste of time. inserting into an unnecessary large tree is also waste of time.
......
...@@ -1924,6 +1924,11 @@ class Item_func_group_concat : public Item_sum ...@@ -1924,6 +1924,11 @@ class Item_func_group_concat : public Item_sum
Redefined in JSON_ARRAYAGG. Redefined in JSON_ARRAYAGG.
*/ */
virtual bool skip_nulls() const { return true; } virtual bool skip_nulls() const { return true; }
virtual String *get_str_from_item(Item *i, String *tmp)
{ return i->val_str(tmp); }
virtual String *get_str_from_field(Item *i, Field *f, String *tmp,
const uchar *key, size_t offset)
{ return f->val_str(tmp, key + offset); }
public: public:
// Methods used by ColumnStore // Methods used by ColumnStore
bool get_distinct() const { return distinct; } bool get_distinct() const { return distinct; }
......
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