summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_jsonfunc.cc65
-rw-r--r--sql/item_jsonfunc.h8
-rw-r--r--sql/item_sum.cc16
-rw-r--r--sql/item_sum.h5
4 files changed, 76 insertions, 18 deletions
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 45f57d99011..442e9b5bdca 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -1452,6 +1452,52 @@ append_null:
}
+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)
{
String *sv= item->val_str(tmp_val);
@@ -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);
- 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;
+
}
diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h
index e5676768854..0b02b8e4da2 100644
--- a/sql/item_jsonfunc.h
+++ b/sql/item_jsonfunc.h
@@ -542,10 +542,13 @@ protected:
Overrides Item_func_group_concat::skip_nulls()
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:
- 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,
bool is_distinct, List<Item> *is_select,
const SQL_I_List<ORDER> &is_order, String *is_separator,
@@ -560,7 +563,6 @@ public:
const char *func_name() const { return "json_arrayagg("; }
enum Sumfunctype sum_func() const {return JSON_ARRAYAGG_FUNC;}
- String* convert_to_json(Item *item);
String* val_str(String *str);
Item *get_copy(THD *thd)
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 510cf096575..86c0f4700bb 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -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.
*/
if ((*arg)->const_item())
- res= (*arg)->val_str(&tmp);
+ res= item->get_str_from_item(*arg, &tmp);
else
{
Field *field= (*arg)->get_tmp_table_field();
@@ -3669,19 +3669,10 @@ int dump_leaf_key(void* key_arg, element_count count __attribute__((unused)),
uint offset= (field->offset(field->table->record[0]) -
table->s->null_bytes);
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
- res= (*arg)->val_str(&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);
+ res= item->get_str_from_item(*arg, &tmp);
}
if (res)
@@ -3981,6 +3972,7 @@ bool Item_func_group_concat::repack_tree(THD *thd)
return 0;
}
+
/*
Repacking the tree is expensive. But it keeps the tree small, and
inserting into an unnecessary large tree is also waste of time.
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 7c69dea4a9a..d3c78c245d6 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1924,6 +1924,11 @@ protected:
Redefined in JSON_ARRAYAGG.
*/
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:
// Methods used by ColumnStore
bool get_distinct() const { return distinct; }