Skip to content

Commit 72d7b12

Browse files
author
Alexander Barkov
committed
Reducing duplicate code and simplifying well formed string copying
by adding a new class String_copier. This is a pre-requisite patch for MDEV-6566 and MDEV-6572, to avoid adding more similar code.
1 parent 2d01907 commit 72d7b12

File tree

7 files changed

+164
-152
lines changed

7 files changed

+164
-152
lines changed

sql/field.cc

Lines changed: 23 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -6262,10 +6262,9 @@ bool Field_datetimef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
62626262
62636263
SYNOPSIS
62646264
check_string_copy_error()
6265-
field - Field
6266-
well_formed_error_pos - where not well formed data was first met
6267-
cannot_convert_error_pos - where a not-convertable character was first met
6268-
end - end of the string
6265+
copier - the conversion status
6266+
end - the very end of the source string
6267+
that was just copied
62696268
cs - character set of the string
62706269
62716270
NOTES
@@ -6282,30 +6281,25 @@ bool Field_datetimef::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
62826281
TRUE - If an error happened
62836282
*/
62846283

6285-
static bool
6286-
check_string_copy_error(Field_str *field,
6287-
const char *well_formed_error_pos,
6288-
const char *cannot_convert_error_pos,
6289-
const char *end,
6290-
CHARSET_INFO *cs)
6284+
bool
6285+
Field_longstr::check_string_copy_error(const String_copier *copier,
6286+
const char *end,
6287+
CHARSET_INFO *cs)
62916288
{
62926289
const char *pos;
62936290
char tmp[32];
6294-
THD *thd;
62956291

6296-
thd= field->get_thd();
6297-
6298-
if (!(pos= well_formed_error_pos) &&
6299-
!(pos= cannot_convert_error_pos))
6292+
if (!(pos= copier->most_important_error_pos()))
63006293
return FALSE;
63016294

63026295
convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6);
63036296

6297+
THD *thd= get_thd();
63046298
push_warning_printf(thd,
63056299
Sql_condition::WARN_LEVEL_WARN,
63066300
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
63076301
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
6308-
"string", tmp, field->field_name,
6302+
"string", tmp, field_name,
63096303
thd->get_stmt_da()->current_row_for_warning());
63106304
return TRUE;
63116305
}
@@ -6362,32 +6356,23 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
63626356
{
63636357
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
63646358
uint copy_length;
6365-
const char *well_formed_error_pos;
6366-
const char *cannot_convert_error_pos;
6367-
const char *from_end_pos;
6359+
String_copier copier;
63686360

63696361
/* See the comment for Field_long::store(long long) */
63706362
DBUG_ASSERT(!table || table->in_use == current_thd);
63716363

6372-
copy_length= well_formed_copy_nchars(field_charset,
6364+
copy_length= copier.well_formed_copy(field_charset,
63736365
(char*) ptr, field_length,
63746366
cs, from, length,
6375-
field_length / field_charset->mbmaxlen,
6376-
&well_formed_error_pos,
6377-
&cannot_convert_error_pos,
6378-
&from_end_pos);
6367+
field_length / field_charset->mbmaxlen);
63796368

63806369
/* Append spaces if the string was shorter than the field. */
63816370
if (copy_length < field_length)
63826371
field_charset->cset->fill(field_charset,(char*) ptr+copy_length,
63836372
field_length-copy_length,
63846373
field_charset->pad_char);
63856374

6386-
if (check_string_copy_error(this, well_formed_error_pos,
6387-
cannot_convert_error_pos, from + length, cs))
6388-
return 2;
6389-
6390-
return report_if_important_data(from_end_pos, from + length, FALSE);
6375+
return check_conversion_status(&copier, from + length, cs, false);
63916376
}
63926377

63936378

@@ -6874,29 +6859,19 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
68746859
{
68756860
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
68766861
uint copy_length;
6877-
const char *well_formed_error_pos;
6878-
const char *cannot_convert_error_pos;
6879-
const char *from_end_pos;
6862+
String_copier copier;
68806863

6881-
copy_length= well_formed_copy_nchars(field_charset,
6864+
copy_length= copier.well_formed_copy(field_charset,
68826865
(char*) ptr + length_bytes,
68836866
field_length,
68846867
cs, from, length,
6885-
field_length / field_charset->mbmaxlen,
6886-
&well_formed_error_pos,
6887-
&cannot_convert_error_pos,
6888-
&from_end_pos);
6889-
6868+
field_length / field_charset->mbmaxlen);
68906869
if (length_bytes == 1)
68916870
*ptr= (uchar) copy_length;
68926871
else
68936872
int2store(ptr, copy_length);
68946873

6895-
if (check_string_copy_error(this, well_formed_error_pos,
6896-
cannot_convert_error_pos, from + length, cs))
6897-
return 2;
6898-
6899-
return report_if_important_data(from_end_pos, from + length, TRUE);
6874+
return check_conversion_status(&copier, from + length, cs, true);
69006875
}
69016876

69026877

@@ -7351,9 +7326,8 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
73517326
{
73527327
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
73537328
uint copy_length, new_length;
7354-
const char *well_formed_error_pos;
7355-
const char *cannot_convert_error_pos;
7356-
const char *from_end_pos, *tmp;
7329+
String_copier copier;
7330+
const char *tmp;
73577331
char buff[STRING_BUFFER_USUAL_SIZE];
73587332
String tmpstr(buff,sizeof(buff), &my_charset_bin);
73597333

@@ -7401,28 +7375,14 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
74017375
bmove(ptr + packlength, (uchar*) &tmp, sizeof(char*));
74027376
return 0;
74037377
}
7404-
/*
7405-
"length" is OK as "nchars" argument to well_formed_copy_nchars as this
7406-
is never used to limit the length of the data. The cut of long data
7407-
is done with the new_length value.
7408-
*/
7409-
copy_length= well_formed_copy_nchars(field_charset,
7378+
copy_length= copier.well_formed_copy(field_charset,
74107379
(char*) value.ptr(), new_length,
7411-
cs, from, length,
7412-
length,
7413-
&well_formed_error_pos,
7414-
&cannot_convert_error_pos,
7415-
&from_end_pos);
7416-
7380+
cs, from, length);
74177381
Field_blob::store_length(copy_length);
74187382
tmp= value.ptr();
74197383
bmove(ptr+packlength,(uchar*) &tmp,sizeof(char*));
74207384

7421-
if (check_string_copy_error(this, well_formed_error_pos,
7422-
cannot_convert_error_pos, from + length, cs))
7423-
return 2;
7424-
7425-
return report_if_important_data(from_end_pos, from + length, TRUE);
7385+
return check_conversion_status(&copier, from + length, cs, true);
74267386

74277387
oom_error:
74287388
/* Fatal OOM error */

sql/field.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1132,6 +1132,17 @@ class Field_longstr :public Field_str
11321132
protected:
11331133
int report_if_important_data(const char *ptr, const char *end,
11341134
bool count_spaces);
1135+
bool check_string_copy_error(const String_copier *copier,
1136+
const char *end, CHARSET_INFO *cs);
1137+
int check_conversion_status(const String_copier *copier,
1138+
const char *end, CHARSET_INFO *cs,
1139+
bool count_spaces)
1140+
{
1141+
if (check_string_copy_error(copier, end, cs))
1142+
return 2;
1143+
return report_if_important_data(copier->source_end_pos(),
1144+
end, count_spaces);
1145+
}
11351146
public:
11361147
Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
11371148
uchar null_bit_arg, utype unireg_check_arg,

sql/sql_class.cc

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2986,9 +2986,7 @@ int select_export::send_data(List<Item> &items)
29862986
if (res && !my_charset_same(write_cs, res->charset()) &&
29872987
!my_charset_same(write_cs, &my_charset_bin))
29882988
{
2989-
const char *well_formed_error_pos;
2990-
const char *cannot_convert_error_pos;
2991-
const char *from_end_pos;
2989+
String_copier copier;
29922990
const char *error_pos;
29932991
uint32 bytes;
29942992
uint64 estimated_bytes=
@@ -3001,16 +2999,11 @@ int select_export::send_data(List<Item> &items)
30012999
goto err;
30023000
}
30033001

3004-
bytes= well_formed_copy_nchars(write_cs, (char *) cvt_str.ptr(),
3002+
bytes= copier.well_formed_copy(write_cs, (char *) cvt_str.ptr(),
30053003
cvt_str.alloced_length(),
3006-
res->charset(), res->ptr(), res->length(),
3007-
UINT_MAX32, // copy all input chars,
3008-
// i.e. ignore nchars parameter
3009-
&well_formed_error_pos,
3010-
&cannot_convert_error_pos,
3011-
&from_end_pos);
3012-
error_pos= well_formed_error_pos ? well_formed_error_pos
3013-
: cannot_convert_error_pos;
3004+
res->charset(),
3005+
res->ptr(), res->length());
3006+
error_pos= copier.most_important_error_pos();
30143007
if (error_pos)
30153008
{
30163009
char printable_buff[32];
@@ -3023,7 +3016,7 @@ int select_export::send_data(List<Item> &items)
30233016
"string", printable_buff,
30243017
item->name, static_cast<long>(row_count));
30253018
}
3026-
else if (from_end_pos < res->ptr() + res->length())
3019+
else if (copier.source_end_pos() < res->ptr() + res->length())
30273020
{
30283021
/*
30293022
result is longer than UINT_MAX32 and doesn't fit into String

sql/sql_signal.cc

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,16 +195,9 @@ static bool assign_fixed_string(MEM_ROOT *mem_root,
195195
dst_str= (char*) alloc_root(mem_root, dst_len + 1);
196196
if (dst_str)
197197
{
198-
const char* well_formed_error_pos;
199-
const char* cannot_convert_error_pos;
200-
const char* from_end_pos;
201-
202-
dst_copied= well_formed_copy_nchars(dst_cs, dst_str, dst_len,
203-
src_cs, src_str, src_len,
204-
numchars,
205-
& well_formed_error_pos,
206-
& cannot_convert_error_pos,
207-
& from_end_pos);
198+
dst_copied= String_copier().well_formed_copy(dst_cs, dst_str, dst_len,
199+
src_cs, src_str, src_len,
200+
numchars);
208201
DBUG_ASSERT(dst_copied <= dst_len);
209202
dst_len= dst_copied; /* In case the copy truncated the data */
210203
dst_str[dst_copied]= '\0';

0 commit comments

Comments
 (0)