Skip to content

Commit

Permalink
cannot allocate a new String[] in the ::val_str() method
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
vuvova committed Oct 12, 2021
1 parent 8150f52 commit 513c8b4
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 12 deletions.
12 changes: 12 additions & 0 deletions mysql-test/main/func_sformat.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
8 changes: 8 additions & 0 deletions mysql-test/main/func_sformat.test
Original file line number Diff line number Diff line change
Expand Up @@ -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';
23 changes: 13 additions & 10 deletions sql/item_strfunc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand Down Expand Up @@ -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;
Expand All @@ -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++)
{
Expand All @@ -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)
Expand All @@ -1406,7 +1411,6 @@ String *Item_func_sformat::val_str(String *res)
default:
DBUG_ASSERT(0);
delete [] vargs;
delete [] val_arg;
return NULL;
}
}
Expand All @@ -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;
}

Expand Down
5 changes: 3 additions & 2 deletions sql/item_strfunc.h
Original file line number Diff line number Diff line change
Expand Up @@ -588,9 +588,10 @@ class Item_func_substr :public Item_str_func

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
Expand Down

0 comments on commit 513c8b4

Please sign in to comment.