Commit c3ecc18f authored by unknown's avatar unknown
Browse files

Report truncation of spaces when inserting into a BINARY or VARBINARY

field. (Bug #14299)


mysql-test/r/type_binary.result:
  Add results
mysql-test/t/type_binary.test:
  Add new regression test
sql/field.cc:
  Always report truncation of binary and varbinary strings, even if it was
  just spaces. (Plus some minor style/comment cleanups.)
parent db813bde
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -111,3 +111,25 @@ select count(distinct s1) from t1;
count(distinct s1)
3
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;
+24 −0
Original line number Diff line number Diff line
@@ -65,3 +65,27 @@ select hex(s1) from t1 where s1=0x0120;
select hex(s1) from t1 where s1=0x0100;
select count(distinct s1) from 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
+34 −23
Original line number Diff line number Diff line
@@ -5870,23 +5870,30 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
      error= 2;
  }

  /* 
    Make sure we don't break a multibyte sequence
    as well as don't copy a malformed data.
  */
  /* Make sure we don't break a multibyte sequence or copy malformed data. */
  copy_length= field_charset->cset->well_formed_len(field_charset,
                                                    from,from+length,
                                                    field_length/
                                                    field_charset->mbmaxlen,
                                                    &well_formed_error);
  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_length-copy_length,
                              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)
  {					// Check if we loosed some info
  {
    if (binary())
      error= 2;
    else
    {
      const char *end=from+length;
      from+= copy_length;
      from+= field_charset->cset->scan(field_charset, from, end,
@@ -5894,6 +5901,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
      if (from != end)
        error= 2;
    }
  }
  if (error)
  {
    if (table->in_use->abort_on_warning)
@@ -6267,6 +6275,8 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
  // Check if we lost something other than just trailing spaces
  if ((copy_length < length) && table->in_use->count_cuted_fields &&
      !error_code)
  {
    if (!binary())
    {
      const char *end= from + length;
      from+= copy_length;
@@ -6274,6 +6284,7 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
      /* 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;
  }
  if (error_code)