mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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.)
This commit is contained in:
@ -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;
|
|||||||
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
|
||||||
|
57
sql/field.cc
57
sql/field.cc
@ -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, ¬_used))
|
if (String::needs_conversion(length, cs, field_charset, ¬_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)
|
|||||||
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)
|
||||||
|
Reference in New Issue
Block a user