The problem is that sformat does not assign the enough space for the
result string. The result string is allocated with the max_length of
argument, but the correst max_length should be based on the format
string.
The patch fixes the problem by using MAX_BLOB_WIDTH to assign length
If charset aggregation decides to convert arguments to some specific
charset and some arguments are numbers, they'll be wrapped into a
Item_func_conv_charset(), that changes result_type() to STRING_RESULT.
Fix: don't convert numbers, sformat needs their numerical value only.
1. it is against sql way, auto-detection should use metadata, not data,
consider:
create table t1 (qwe varchar(10)) as values ('qwe'),('qw'),('q'),('werty');
select sformat('{:*>5s}', qwe) from t1;
this will auto-break on the third row.
2. using max_char_length() instead of length() fixes that, but
there's a second big issue, fmt < 8.0 doesn't natively support unicode,
so {:c} would only work for one-byte strings, for 'a', not for 'я'
because of all that let's always format strings as strings.
{:c} will only now work for numbers and still only in the ascii range.
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).
* comment - use the standard style
* no need to reimplement for with while
* TODO comments for not implemented types
* rename the error not to refer to the underlying library, it's
the implementation detail
* use res->length(0) to set length to 0, but preserve the already
allocated buffer
* rename main.sformat -> main.func_sformat
* removed a duplicated part of the test
2021-10-12 13:28:10 +02:00
Renamed from mysql-test/main/sformat.result (Browse further)