mirror of
https://github.com/MariaDB/server.git
synced 2026-05-07 15:45:33 +02:00
Fixed bug#30059.
Server handles truncation for assignment of too-long values
into CHAR/VARCHAR/TEXT columns in a different ways when the
truncated characters are spaces:
1. CHAR(N) columns silently ignore end-space truncation;
2. TEXT columns post a truncation warning/error in the
non-strict/strict mode.
3. VARCHAR columns always post a truncation note in
any mode.
Space truncation processing has been synchronised over
CHAR/VARCHAR/TEXT columns: current behavior of VARCHAR
columns has been propagated as standard.
Binary-encoded string/BLOB columns are not affected.
mysql-test/r/heap.result:
Updated test case for bug#30059.
mysql-test/r/innodb.result:
Updated test case for bug#30059.
mysql-test/r/myisam.result:
Updated test case for bug#30059.
mysql-test/r/strict.result:
Updated test case for bug#30059.
mysql-test/r/type_binary.result:
Updated test case for bug#30059.
mysql-test/r/warnings.result:
Added test case for bug#30059.
mysql-test/t/warnings.test:
Added test case for bug#30059.
sql/field.cc:
Fixed bug#30059.
The report_data_too_long function was replaced with the
Field_longstr::report_if_important_data method.
The Field_string::store and the Field_blob::store
methods was synchronized with the Field_varstring::store
method.
Changes:
1. to CHAR(N): posting of space truncation note has been added
in both (strict and non-strict) modes;
2. to BLOBs: a check for space truncation has been added,
a warning in the non-strict mode and an error message in
the strict mode have been replaced with a truncation note.
Similar parts of Field_string::store, Field_blob::store and
Field_varstring::store have been moved to the
Field_longstr::report_if_important_data method.
sql/field.h:
Fixed bug#30059.
The Field_longstr::report_if_important_data method has been declared.
This commit is contained in:
parent
1919d238e5
commit
3891d43617
9 changed files with 110 additions and 43 deletions
74
sql/field.cc
74
sql/field.cc
|
|
@ -5861,26 +5861,41 @@ check_string_copy_error(Field_str *field,
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Send a truncation warning or a truncation error
|
||||
after storing a too long character string info a field.
|
||||
Check if we lost any important data and send a truncation error/warning
|
||||
|
||||
SYNOPSIS
|
||||
report_data_too_long()
|
||||
field - Field
|
||||
Field_longstr::report_if_important_data()
|
||||
ptr - Truncated rest of string
|
||||
end - End of truncated string
|
||||
|
||||
RETURN
|
||||
N/A
|
||||
RETURN VALUES
|
||||
0 - None was truncated (or we don't count cut fields)
|
||||
2 - Some bytes was truncated
|
||||
|
||||
NOTE
|
||||
Check if we lost any important data (anything in a binary string,
|
||||
or any non-space in others). If only trailing spaces was lost,
|
||||
send a truncation note, otherwise send a truncation error.
|
||||
*/
|
||||
|
||||
inline void
|
||||
report_data_too_long(Field_str *field)
|
||||
int
|
||||
Field_longstr::report_if_important_data(const char *ptr, const char *end)
|
||||
{
|
||||
if (field->table->in_use->abort_on_warning)
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
|
||||
else
|
||||
field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
if ((ptr < end) && table->in_use->count_cuted_fields)
|
||||
{
|
||||
if (test_if_important_data(field_charset, ptr, end))
|
||||
{
|
||||
if (table->in_use->abort_on_warning)
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DATA_TOO_LONG, 1);
|
||||
else
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||
}
|
||||
else /* If we lost only spaces then produce a NOTE, not a WARNING */
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -5914,19 +5929,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
cannot_convert_error_pos, from + length))
|
||||
return 2;
|
||||
|
||||
/*
|
||||
Check if we lost any important data (anything in a binary string,
|
||||
or any non-space in others).
|
||||
*/
|
||||
if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
|
||||
{
|
||||
if (test_if_important_data(field_charset, from_end_pos, from + length))
|
||||
{
|
||||
report_data_too_long(this);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return report_if_important_data(from_end_pos, from + length);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -6385,16 +6388,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
cannot_convert_error_pos, from + length))
|
||||
return 2;
|
||||
|
||||
// Check if we lost something other than just trailing spaces
|
||||
if ((from_end_pos < from + length) && table->in_use->count_cuted_fields)
|
||||
{
|
||||
if (test_if_important_data(field_charset, from_end_pos, from + length))
|
||||
report_data_too_long(this);
|
||||
else /* If we lost only spaces then produce a NOTE, not a WARNING */
|
||||
set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED, 1);
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
return report_if_important_data(from_end_pos, from + length);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -7030,13 +7024,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
|
|||
cannot_convert_error_pos, from + length))
|
||||
return 2;
|
||||
|
||||
if (from_end_pos < from + length)
|
||||
{
|
||||
report_data_too_long(this);
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return report_if_important_data(from_end_pos, from + length);
|
||||
|
||||
oom_error:
|
||||
/* Fatal OOM error */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue