diff options
author | Sergei Golubchik <serg@mariadb.org> | 2021-09-06 09:37:33 +0200 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2021-09-06 10:07:33 +0200 |
commit | 3866c8a541a8068c01b5369fdae9c2be961f4b53 (patch) | |
tree | 29f425cad917432e478938e92b0f8b62b7e8230f | |
parent | 2edc313837b9d35be2837756bb74d1e827e49319 (diff) | |
download | mariadb-git-bb-10.7-MDEV-25015-sformat.tar.gz |
cannot allocate a new String[] in the ::val_str() methodbb-10.7-MDEV-25015-sformat
String inherits from Sql_alloc, so it's allocated on the thd's memroot,
this cannot be done per row.
Moved String[] allocation into the Item_func_sformat constructor
(not fix_fields(), because we want it on the same memroot where the item
is).
-rw-r--r-- | mysql-test/main/func_sformat.result | 12 | ||||
-rw-r--r-- | mysql-test/main/func_sformat.test | 8 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 23 | ||||
-rw-r--r-- | sql/item_strfunc.h | 5 |
4 files changed, 36 insertions, 12 deletions
diff --git a/mysql-test/main/func_sformat.result b/mysql-test/main/func_sformat.result index f2631c32d65..fb8f89f8b4c 100644 --- a/mysql-test/main/func_sformat.result +++ b/mysql-test/main/func_sformat.result @@ -437,3 +437,15 @@ t1 CREATE TABLE `t1` ( `x` varchar(8) CHARACTER SET ucs2 DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +# +# ps parameters +# +prepare s from 'select sformat("={:d}=", ?)'; +execute s using 100; +sformat("={:d}=", ?) +=100= +execute s using 'abc'; +sformat("={:d}=", ?) +NULL +Warnings: +Warning 4183 SFORMAT error: invalid type specifier diff --git a/mysql-test/main/func_sformat.test b/mysql-test/main/func_sformat.test index 9775810148b..1c6e539f8a9 100644 --- a/mysql-test/main/func_sformat.test +++ b/mysql-test/main/func_sformat.test @@ -199,3 +199,11 @@ select hex(sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442')); create table t1 as select sformat(_ucs2 x'003D007B007D003D', _ucs2 x'0442043504410442') as x; show create table t1; drop table t1; + + +echo #; +echo # ps parameters; +echo #; +prepare s from 'select sformat("={:d}=", ?)'; +execute s using 100; +execute s using 'abc'; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index fd5e2609e0c..0d174af61d1 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1306,9 +1306,22 @@ bool Item_func_replace::fix_length_and_dec() return FALSE; } +/* + this is done in the constructor to be in the same memroot as + the item itself +*/ +Item_func_sformat::Item_func_sformat(THD *thd, List<Item> &list) + : Item_str_func(thd, list) +{ + val_arg= new (thd->mem_root) String[arg_count]; +} + bool Item_func_sformat::fix_length_and_dec() { + if (!val_arg) + return TRUE; + ulonglong char_length= 0; uint flags= MY_COLL_ALLOW_SUPERSET_CONV | @@ -1361,7 +1374,6 @@ String *Item_func_sformat::val_str(String *res) using ctx= fmt::format_context; String *fmt_arg= NULL; String *parg= NULL; - String *val_arg= NULL; fmt::format_args::format_arg *vargs= NULL; null_value= true; @@ -1371,12 +1383,6 @@ String *Item_func_sformat::val_str(String *res) if (!(vargs= new fmt::format_args::format_arg[arg_count - 1])) return NULL; - if (!(val_arg= new String[arg_count - 1])) - { - delete [] vargs; - return NULL; - } - /* Creates the array of arguments for vformat */ for (uint carg= 1; carg < arg_count; carg++) { @@ -1393,7 +1399,6 @@ String *Item_func_sformat::val_str(String *res) if (!(parg= args[carg]->val_str(&val_arg[carg-1]))) { delete [] vargs; - delete [] val_arg; return NULL; } if (parg->length() == 1) @@ -1406,7 +1411,6 @@ String *Item_func_sformat::val_str(String *res) default: DBUG_ASSERT(0); delete [] vargs; - delete [] val_arg; return NULL; } } @@ -1430,7 +1434,6 @@ String *Item_func_sformat::val_str(String *res) null_value= true; } delete [] vargs; - delete [] val_arg; return null_value ? NULL : res; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index d06f07d8c34..f28ad0f8f9f 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -588,9 +588,10 @@ public: class Item_func_sformat :public Item_str_func { + String *val_arg; public: - Item_func_sformat(THD *thd, List<Item> &list): - Item_str_func(thd, list) { } + Item_func_sformat(THD *thd, List<Item> &list); + ~Item_func_sformat() { delete val_arg; } String *val_str(String*) override; bool fix_length_and_dec() override; LEX_CSTRING func_name_cstring() const override |