Commit 8ecedd19 authored by jimw@mysql.com's avatar jimw@mysql.com

Report truncation of spaces when inserting into a BINARY or VARBINARY

field. (Bug #14299)
parent 3506e1e5
...@@ -111,3 +111,25 @@ select count(distinct s1) from t1; ...@@ -111,3 +111,25 @@ select count(distinct s1) from t1;
count(distinct s1) count(distinct s1)
3 3
drop table t1; drop table t1;
create table t1 (b binary(2), vb varbinary(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
Warnings:
Warning 1265 Data truncated for column 'b' at row 1
Warning 1265 Data truncated for column 'vb' at row 1
drop table t1;
create table t1 (c char(2), vc varchar(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
Warnings:
Note 1265 Data truncated for column 'vc' at row 1
drop table t1;
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
create table t1 (b binary(2), vb varbinary(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, NULL);
ERROR 22001: Data too long for column 'b' at row 1
insert into t1 values(NULL, 0x412020);
ERROR 22001: Data too long for column 'vb' at row 1
drop table t1;
set @@sql_mode= @old_sql_mode;
...@@ -65,3 +65,27 @@ select hex(s1) from t1 where s1=0x0120; ...@@ -65,3 +65,27 @@ select hex(s1) from t1 where s1=0x0120;
select hex(s1) from t1 where s1=0x0100; select hex(s1) from t1 where s1=0x0100;
select count(distinct s1) from t1; select count(distinct s1) from t1;
drop table t1; drop table t1;
#
# Bug #14299: BINARY space truncation should cause warning or error
#
create table t1 (b binary(2), vb varbinary(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
drop table t1;
create table t1 (c char(2), vc varchar(2));
insert into t1 values(0x4120, 0x4120);
insert into t1 values(0x412020, 0x412020);
drop table t1;
set @old_sql_mode= @@sql_mode, sql_mode= 'traditional';
create table t1 (b binary(2), vb varbinary(2));
insert into t1 values(0x4120, 0x4120);
--error ER_DATA_TOO_LONG
insert into t1 values(0x412020, NULL);
--error ER_DATA_TOO_LONG
insert into t1 values(NULL, 0x412020);
drop table t1;
set @@sql_mode= @old_sql_mode;
# End of 5.0 tests
...@@ -5855,44 +5855,52 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) ...@@ -5855,44 +5855,52 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
char buff[STRING_BUFFER_USUAL_SIZE]; char buff[STRING_BUFFER_USUAL_SIZE];
String tmpstr(buff,sizeof(buff), &my_charset_bin); String tmpstr(buff,sizeof(buff), &my_charset_bin);
uint copy_length; uint copy_length;
/* See the comment for Field_long::store(long long) */ /* See the comment for Field_long::store(long long) */
DBUG_ASSERT(table->in_use == current_thd); DBUG_ASSERT(table->in_use == current_thd);
/* Convert character set if necessary */ /* Convert character set if necessary */
if (String::needs_conversion(length, cs, field_charset, &not_used)) if (String::needs_conversion(length, cs, field_charset, &not_used))
{ {
uint conv_errors; uint conv_errors;
tmpstr.copy(from, length, cs, field_charset, &conv_errors); tmpstr.copy(from, length, cs, field_charset, &conv_errors);
from= tmpstr.ptr(); from= tmpstr.ptr();
length= tmpstr.length(); length= tmpstr.length();
if (conv_errors) if (conv_errors)
error= 2; error= 2;
} }
/* /* Make sure we don't break a multibyte sequence or copy malformed data. */
Make sure we don't break a multibyte sequence
as well as don't copy a malformed data.
*/
copy_length= field_charset->cset->well_formed_len(field_charset, copy_length= field_charset->cset->well_formed_len(field_charset,
from,from+length, from,from+length,
field_length/ field_length/
field_charset->mbmaxlen, field_charset->mbmaxlen,
&well_formed_error); &well_formed_error);
memcpy(ptr,from,copy_length); memcpy(ptr,from,copy_length);
if (copy_length < field_length) // Append spaces if shorter
/* Append spaces if the string was shorter than the field. */
if (copy_length < field_length)
field_charset->cset->fill(field_charset,ptr+copy_length, field_charset->cset->fill(field_charset,ptr+copy_length,
field_length-copy_length, field_length-copy_length,
field_charset->pad_char); field_charset->pad_char);
/*
Check if we lost any important data (anything in a binary string,
or any non-space in others).
*/
if ((copy_length < length) && table->in_use->count_cuted_fields) if ((copy_length < length) && table->in_use->count_cuted_fields)
{ // Check if we loosed some info {
const char *end=from+length; if (binary())
from+= copy_length;
from+= field_charset->cset->scan(field_charset, from, end,
MY_SEQ_SPACES);
if (from != end)
error= 2; error= 2;
else
{
const char *end=from+length;
from+= copy_length;
from+= field_charset->cset->scan(field_charset, from, end,
MY_SEQ_SPACES);
if (from != end)
error= 2;
}
} }
if (error) if (error)
{ {
...@@ -6268,12 +6276,15 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) ...@@ -6268,12 +6276,15 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
if ((copy_length < length) && table->in_use->count_cuted_fields && if ((copy_length < length) && table->in_use->count_cuted_fields &&
!error_code) !error_code)
{ {
const char *end= from + length; if (!binary())
from+= copy_length; {
from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES); const char *end= from + length;
/* If we lost only spaces then produce a NOTE, not a WARNING */ from+= copy_length;
if (from == end) from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES);
level= MYSQL_ERROR::WARN_LEVEL_NOTE; /* If we lost only spaces then produce a NOTE, not a WARNING */
if (from == end)
level= MYSQL_ERROR::WARN_LEVEL_NOTE;
}
error_code= WARN_DATA_TRUNCATED; error_code= WARN_DATA_TRUNCATED;
} }
if (error_code) if (error_code)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment