diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_jsonfunc.cc | 65 | ||||
-rw-r--r-- | sql/item_jsonfunc.h | 8 | ||||
-rw-r--r-- | sql/item_sum.cc | 16 | ||||
-rw-r--r-- | sql/item_sum.h | 5 |
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; } |