mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Fix for bugs
#27176: Assigning a string to an year column has unexpected results #26359: Strings becoming truncated and converted to numbers under STRICT mode Problems: 1. storing a string to an integer field we don't check if strntoull10rnd() returns MY_ERRNO_EDOM error. Fix: check for MY_ERRNO_EDOM. 2. storing a string to an year field we use my_strntol() function. Fix: use strntoull10rnd() instead.
This commit is contained in:

parent
433d3e6cf7
commit
e3c34c9cbf
@ -1352,3 +1352,44 @@ t1 CREATE TABLE `t1` (
|
|||||||
`i` int(11) default NULL
|
`i` int(11) default NULL
|
||||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*'
|
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*'
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
set sql_mode= 'traditional';
|
||||||
|
create table t1(col1 tinyint, col2 tinyint unsigned,
|
||||||
|
col3 smallint, col4 smallint unsigned,
|
||||||
|
col5 mediumint, col6 mediumint unsigned,
|
||||||
|
col7 int, col8 int unsigned,
|
||||||
|
col9 bigint, col10 bigint unsigned);
|
||||||
|
insert into t1(col1) values('-');
|
||||||
|
ERROR HY000: Incorrect integer value: '-' for column 'col1' at row 1
|
||||||
|
insert into t1(col2) values('+');
|
||||||
|
ERROR HY000: Incorrect integer value: '+' for column 'col2' at row 1
|
||||||
|
insert into t1(col3) values('-');
|
||||||
|
ERROR HY000: Incorrect integer value: '-' for column 'col3' at row 1
|
||||||
|
insert into t1(col4) values('+');
|
||||||
|
ERROR HY000: Incorrect integer value: '+' for column 'col4' at row 1
|
||||||
|
insert into t1(col5) values('-');
|
||||||
|
ERROR HY000: Incorrect integer value: '-' for column 'col5' at row 1
|
||||||
|
insert into t1(col6) values('+');
|
||||||
|
ERROR HY000: Incorrect integer value: '+' for column 'col6' at row 1
|
||||||
|
insert into t1(col7) values('-');
|
||||||
|
ERROR HY000: Incorrect integer value: '-' for column 'col7' at row 1
|
||||||
|
insert into t1(col8) values('+');
|
||||||
|
ERROR HY000: Incorrect integer value: '+' for column 'col8' at row 1
|
||||||
|
insert into t1(col9) values('-');
|
||||||
|
ERROR HY000: Incorrect integer value: '-' for column 'col9' at row 1
|
||||||
|
insert into t1(col10) values('+');
|
||||||
|
ERROR HY000: Incorrect integer value: '+' for column 'col10' at row 1
|
||||||
|
drop table t1;
|
||||||
|
set sql_mode='traditional';
|
||||||
|
create table t1(a year);
|
||||||
|
insert into t1 values ('-');
|
||||||
|
ERROR HY000: Incorrect integer value: '-' for column 'a' at row 1
|
||||||
|
insert into t1 values ('+');
|
||||||
|
ERROR HY000: Incorrect integer value: '+' for column 'a' at row 1
|
||||||
|
insert into t1 values ('');
|
||||||
|
ERROR HY000: Incorrect integer value: '' for column 'a' at row 1
|
||||||
|
insert into t1 values ('2000a');
|
||||||
|
ERROR 01000: Data truncated for column 'a' at row 1
|
||||||
|
insert into t1 values ('2E3x');
|
||||||
|
ERROR 01000: Data truncated for column 'a' at row 1
|
||||||
|
drop table t1;
|
||||||
|
End of 5.0 tests
|
||||||
|
@ -99,7 +99,7 @@ DROP TABLE t1, t2, t3;
|
|||||||
CREATE TABLE t1 (y YEAR);
|
CREATE TABLE t1 (y YEAR);
|
||||||
INSERT INTO t1 VALUES ('abc');
|
INSERT INTO t1 VALUES ('abc');
|
||||||
Warnings:
|
Warnings:
|
||||||
Warning 1264 Out of range value adjusted for column 'y' at row 1
|
Warning 1366 Incorrect integer value: 'abc' for column 'y' at row 1
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
y
|
y
|
||||||
0000
|
0000
|
||||||
|
@ -34,3 +34,15 @@ select if(y = now(), 1, 0) from t1;
|
|||||||
if(y = now(), 1, 0)
|
if(y = now(), 1, 0)
|
||||||
1
|
1
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1(a year);
|
||||||
|
insert into t1 values (2000.5), ('2000.5'), ('2001a'), ('2.001E3');
|
||||||
|
Warnings:
|
||||||
|
Warning 1265 Data truncated for column 'a' at row 3
|
||||||
|
select * from t1;
|
||||||
|
a
|
||||||
|
2001
|
||||||
|
2001
|
||||||
|
2001
|
||||||
|
2001
|
||||||
|
drop table t1;
|
||||||
|
End of 5.0 tests
|
||||||
|
@ -1208,3 +1208,53 @@ create table t1 (i int)
|
|||||||
comment '123456789*123456789*123456789*123456789*123456789*123456789*';
|
comment '123456789*123456789*123456789*123456789*123456789*123456789*';
|
||||||
show create table t1;
|
show create table t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode
|
||||||
|
#
|
||||||
|
set sql_mode= 'traditional';
|
||||||
|
create table t1(col1 tinyint, col2 tinyint unsigned,
|
||||||
|
col3 smallint, col4 smallint unsigned,
|
||||||
|
col5 mediumint, col6 mediumint unsigned,
|
||||||
|
col7 int, col8 int unsigned,
|
||||||
|
col9 bigint, col10 bigint unsigned);
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col1) values('-');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col2) values('+');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col3) values('-');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col4) values('+');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col5) values('-');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col6) values('+');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col7) values('-');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col8) values('+');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col9) values('-');
|
||||||
|
--error 1366
|
||||||
|
insert into t1(col10) values('+');
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #27176: Assigning a string to an year column has unexpected results
|
||||||
|
#
|
||||||
|
set sql_mode='traditional';
|
||||||
|
create table t1(a year);
|
||||||
|
--error 1366
|
||||||
|
insert into t1 values ('-');
|
||||||
|
--error 1366
|
||||||
|
insert into t1 values ('+');
|
||||||
|
--error 1366
|
||||||
|
insert into t1 values ('');
|
||||||
|
--error 1265
|
||||||
|
insert into t1 values ('2000a');
|
||||||
|
--error 1265
|
||||||
|
insert into t1 values ('2E3x');
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
@ -21,4 +21,12 @@ insert into t1 values (now());
|
|||||||
select if(y = now(), 1, 0) from t1;
|
select if(y = now(), 1, 0) from t1;
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
# End of 4.1 tests
|
#
|
||||||
|
# Bug #27176: Assigning a string to an year column has unexpected results
|
||||||
|
#
|
||||||
|
create table t1(a year);
|
||||||
|
insert into t1 values (2000.5), ('2000.5'), ('2001a'), ('2.001E3');
|
||||||
|
select * from t1;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
|
--echo End of 5.0 tests
|
||||||
|
371
sql/field.cc
371
sql/field.cc
@ -963,6 +963,31 @@ static Item_result field_types_result_type [FIELDTYPE_NUM]=
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Test if the given string contains important data:
|
||||||
|
not spaces for character string,
|
||||||
|
or any data for binary string.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
test_if_important_data()
|
||||||
|
cs Character set
|
||||||
|
str String to test
|
||||||
|
strend String end
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
FALSE - If string does not have important data
|
||||||
|
TRUE - If string has some important data
|
||||||
|
*/
|
||||||
|
|
||||||
|
static bool
|
||||||
|
test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend)
|
||||||
|
{
|
||||||
|
if (cs != &my_charset_bin)
|
||||||
|
str+= cs->cset->scan(cs, str, strend, MY_SEQ_SPACES);
|
||||||
|
return (str < strend);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Detect Item_result by given field type of UNION merge result
|
Detect Item_result by given field type of UNION merge result
|
||||||
|
|
||||||
@ -1051,65 +1076,114 @@ void Field_num::prepend_zeros(String *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Test if given number is a int (or a fixed format float with .000)
|
Test if given number is a int.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
test_if_int()
|
Field_num::check_int
|
||||||
|
cs Character set
|
||||||
str String to test
|
str String to test
|
||||||
end Pointer to char after last used digit
|
end Pointer to char after last used digit
|
||||||
cs Character set
|
length String length
|
||||||
|
error Error returned by strntoull10rnd()
|
||||||
|
|
||||||
NOTES
|
NOTE
|
||||||
This is called after one has called my_strntol() or similar function.
|
This is called after one has called strntoull10rnd() function.
|
||||||
This is only used to give warnings in ALTER TABLE or LOAD DATA...
|
|
||||||
|
|
||||||
TODO
|
|
||||||
Make this multi-byte-character safe
|
|
||||||
|
|
||||||
RETURN
|
RETURN
|
||||||
0 OK
|
0 ok
|
||||||
1 error. A warning is pushed if field_name != 0
|
1 error: empty string or wrong integer.
|
||||||
|
2 error: garbage at the end of string.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool Field::check_int(const char *str, int length, const char *int_end,
|
int Field_num::check_int(CHARSET_INFO *cs, const char *str, int length,
|
||||||
CHARSET_INFO *cs)
|
const char *int_end, int error)
|
||||||
{
|
{
|
||||||
const char *end;
|
/* Test if we get an empty string or wrong integer */
|
||||||
if (str == int_end)
|
if (str == int_end || error == MY_ERRNO_EDOM)
|
||||||
{
|
{
|
||||||
char buff[128];
|
char buff[128];
|
||||||
String tmp(buff,(uint32) sizeof(buff), system_charset_info);
|
String tmp(buff, (uint32) sizeof(buff), system_charset_info);
|
||||||
tmp.copy(str, length, system_charset_info);
|
tmp.copy(str, length, system_charset_info);
|
||||||
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
|
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
|
||||||
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
|
||||||
"integer", tmp.c_ptr(), field_name,
|
"integer", tmp.c_ptr(), field_name,
|
||||||
(ulong) table->in_use->row_count);
|
(ulong) table->in_use->row_count);
|
||||||
return 1; // Empty string
|
return 1;
|
||||||
}
|
}
|
||||||
end= str+length;
|
/* Test if we have garbage at the end of the given string. */
|
||||||
if ((str= int_end) == end)
|
if (test_if_important_data(cs, int_end, str + length))
|
||||||
return 0; // OK; All digits was used
|
|
||||||
|
|
||||||
/* Allow end .0000 */
|
|
||||||
if (*str == '.')
|
|
||||||
{
|
{
|
||||||
for (str++ ; str != end && *str == '0'; str++)
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
||||||
;
|
return 2;
|
||||||
}
|
|
||||||
/* Allow end space */
|
|
||||||
for ( ; str != end ; str++)
|
|
||||||
{
|
|
||||||
if (!my_isspace(cs,*str))
|
|
||||||
{
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Conver a string to an integer then check bounds.
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
Field_num::get_int
|
||||||
|
cs Character set
|
||||||
|
from String to convert
|
||||||
|
len Length of the string
|
||||||
|
rnd OUT longlong value
|
||||||
|
unsigned_max max unsigned value
|
||||||
|
signed_min min signed value
|
||||||
|
signed_max max signed value
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
The function calls strntoull10rnd() to get an integer value then
|
||||||
|
check bounds and errors returned. In case of any error a warning
|
||||||
|
is raised.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 ok
|
||||||
|
1 error
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len,
|
||||||
|
longlong *rnd, ulonglong unsigned_max,
|
||||||
|
longlong signed_min, longlong signed_max)
|
||||||
|
{
|
||||||
|
char *end;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
*rnd= (longlong) cs->cset->strntoull10rnd(cs, from, len, unsigned_flag, &end,
|
||||||
|
&error);
|
||||||
|
if (unsigned_flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max) ||
|
||||||
|
error == MY_ERRNO_ERANGE)
|
||||||
|
{
|
||||||
|
goto out_of_range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (*rnd < signed_min)
|
||||||
|
{
|
||||||
|
*rnd= signed_min;
|
||||||
|
goto out_of_range;
|
||||||
|
}
|
||||||
|
else if (*rnd > signed_max)
|
||||||
|
{
|
||||||
|
*rnd= signed_max;
|
||||||
|
goto out_of_range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (table->in_use->count_cuted_fields && check_int(cs, from, len, end, error))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out_of_range:
|
||||||
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Process decimal library return codes and issue warnings for overflow and
|
Process decimal library return codes and issue warnings for overflow and
|
||||||
truncation.
|
truncation.
|
||||||
@ -2505,45 +2579,11 @@ void Field_new_decimal::sql_type(String &str) const
|
|||||||
|
|
||||||
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
|
int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
char *end;
|
|
||||||
int error;
|
int error;
|
||||||
|
longlong rnd;
|
||||||
if (unsigned_flag)
|
|
||||||
{
|
error= get_int(cs, from, len, &rnd, 255, -128, 127);
|
||||||
ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
|
ptr[0]= unsigned_flag ? (char) (ulonglong) rnd : (char) rnd;
|
||||||
if (error == MY_ERRNO_ERANGE || tmp > 255)
|
|
||||||
{
|
|
||||||
set_if_smaller(tmp, 255);
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
ptr[0]= (char) tmp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
|
|
||||||
if (tmp < -128)
|
|
||||||
{
|
|
||||||
tmp= -128;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (tmp >= 128)
|
|
||||||
{
|
|
||||||
tmp= 127;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
ptr[0]= (char) tmp;
|
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2708,59 +2748,20 @@ void Field_tiny::sql_type(String &res) const
|
|||||||
|
|
||||||
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
|
int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
char *end;
|
int store_tmp;
|
||||||
int error;
|
int error;
|
||||||
|
longlong rnd;
|
||||||
if (unsigned_flag)
|
|
||||||
{
|
error= get_int(cs, from, len, &rnd, UINT_MAX16, INT_MIN16, INT_MAX16);
|
||||||
ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
|
store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd;
|
||||||
if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX16)
|
|
||||||
{
|
|
||||||
set_if_smaller(tmp, UINT_MAX16);
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
if (table->s->db_low_byte_first)
|
if (table->s->db_low_byte_first)
|
||||||
{
|
{
|
||||||
int2store(ptr,tmp);
|
int2store(ptr, store_tmp);
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
shortstore(ptr,(short) tmp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
|
|
||||||
if (tmp < INT_MIN16)
|
|
||||||
{
|
|
||||||
tmp= INT_MIN16;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (tmp > INT_MAX16)
|
|
||||||
{
|
|
||||||
tmp=INT_MAX16;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
if (table->s->db_low_byte_first)
|
|
||||||
{
|
|
||||||
int2store(ptr,tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
shortstore(ptr,(short) tmp);
|
shortstore(ptr, (short) store_tmp);
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2988,45 +2989,13 @@ void Field_short::sql_type(String &res) const
|
|||||||
|
|
||||||
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
|
int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
|
||||||
{
|
{
|
||||||
char *end;
|
int store_tmp;
|
||||||
int error;
|
int error;
|
||||||
|
longlong rnd;
|
||||||
if (unsigned_flag)
|
|
||||||
{
|
error= get_int(cs, from, len, &rnd, UINT_MAX24, INT_MIN24, INT_MAX24);
|
||||||
ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
|
store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd;
|
||||||
if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX24)
|
int3store(ptr, store_tmp);
|
||||||
{
|
|
||||||
set_if_smaller(tmp, UINT_MAX24);
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
int3store(ptr,tmp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
|
|
||||||
if (tmp < INT_MIN24)
|
|
||||||
{
|
|
||||||
tmp= INT_MIN24;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (tmp > INT_MAX24)
|
|
||||||
{
|
|
||||||
tmp=INT_MAX24;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
int3store(ptr,tmp);
|
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3205,45 +3174,10 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
long store_tmp;
|
long store_tmp;
|
||||||
int error;
|
int error;
|
||||||
char *end;
|
longlong rnd;
|
||||||
|
|
||||||
if (unsigned_flag)
|
error= get_int(cs, from, len, &rnd, UINT_MAX32, INT_MIN32, INT_MAX32);
|
||||||
{
|
store_tmp= unsigned_flag ? (long) (ulonglong) rnd : (long) rnd;
|
||||||
ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error);
|
|
||||||
if (error == MY_ERRNO_ERANGE || tmp > (ulonglong) UINT_MAX32)
|
|
||||||
{
|
|
||||||
set_if_smaller(tmp, (ulonglong) UINT_MAX32);
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
store_tmp= (long) tmp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
|
|
||||||
if (tmp < INT_MIN32)
|
|
||||||
{
|
|
||||||
tmp= INT_MIN32;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (tmp > INT_MAX32)
|
|
||||||
{
|
|
||||||
tmp=INT_MAX32;
|
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
|
||||||
error= 1;
|
|
||||||
}
|
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
|
||||||
error= 1;
|
|
||||||
else
|
|
||||||
error= 0;
|
|
||||||
store_tmp= (long) tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
#ifdef WORDS_BIGENDIAN
|
||||||
if (table->s->db_low_byte_first)
|
if (table->s->db_low_byte_first)
|
||||||
{
|
{
|
||||||
@ -3489,7 +3423,8 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
|
|||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
error= 1;
|
error= 1;
|
||||||
}
|
}
|
||||||
else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
else if (table->in_use->count_cuted_fields &&
|
||||||
|
check_int(cs, from, len, end, error))
|
||||||
error= 1;
|
error= 1;
|
||||||
else
|
else
|
||||||
error= 0;
|
error= 0;
|
||||||
@ -5007,16 +4942,25 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
|
|||||||
{
|
{
|
||||||
char *end;
|
char *end;
|
||||||
int error;
|
int error;
|
||||||
long nr= my_strntol(cs, from, len, 10, &end, &error);
|
longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error);
|
||||||
|
|
||||||
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || error)
|
if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 ||
|
||||||
|
error == MY_ERRNO_ERANGE)
|
||||||
{
|
{
|
||||||
*ptr=0;
|
*ptr=0;
|
||||||
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
|
if (table->in_use->count_cuted_fields &&
|
||||||
|
(error= check_int(cs, from, len, end, error)))
|
||||||
|
{
|
||||||
|
if (error == 1) /* empty or incorrect string */
|
||||||
|
{
|
||||||
|
*ptr= 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
error= 1;
|
error= 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (nr != 0 || len != 4)
|
if (nr != 0 || len != 4)
|
||||||
{
|
{
|
||||||
@ -5906,31 +5850,6 @@ report_data_too_long(Field_str *field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Test if the given string contains important data:
|
|
||||||
not spaces for character string,
|
|
||||||
or any data for binary string.
|
|
||||||
|
|
||||||
SYNOPSIS
|
|
||||||
test_if_important_data()
|
|
||||||
cs Character set
|
|
||||||
str String to test
|
|
||||||
strend String end
|
|
||||||
|
|
||||||
RETURN
|
|
||||||
FALSE - If string does not have important data
|
|
||||||
TRUE - If string has some important data
|
|
||||||
*/
|
|
||||||
|
|
||||||
static bool
|
|
||||||
test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend)
|
|
||||||
{
|
|
||||||
if (cs != &my_charset_bin)
|
|
||||||
str+= cs->cset->scan(cs, str, strend, MY_SEQ_SPACES);
|
|
||||||
return (str < strend);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Copy a string and fill with space */
|
/* Copy a string and fill with space */
|
||||||
|
|
||||||
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
|
||||||
|
@ -306,8 +306,6 @@ public:
|
|||||||
virtual void set_derivation(enum Derivation derivation_arg) { }
|
virtual void set_derivation(enum Derivation derivation_arg) { }
|
||||||
bool set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
|
bool set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code,
|
||||||
int cuted_increment);
|
int cuted_increment);
|
||||||
bool check_int(const char *str, int length, const char *int_end,
|
|
||||||
CHARSET_INFO *cs);
|
|
||||||
void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
|
void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code,
|
||||||
const char *str, uint str_len,
|
const char *str, uint str_len,
|
||||||
timestamp_type ts_type, int cuted_increment);
|
timestamp_type ts_type, int cuted_increment);
|
||||||
@ -369,6 +367,11 @@ public:
|
|||||||
bool eq_def(Field *field);
|
bool eq_def(Field *field);
|
||||||
int store_decimal(const my_decimal *);
|
int store_decimal(const my_decimal *);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
|
int check_int(CHARSET_INFO *cs, const char *str, int length,
|
||||||
|
const char *int_end, int error);
|
||||||
|
bool get_int(CHARSET_INFO *cs, const char *from, uint len,
|
||||||
|
longlong *rnd, ulonglong unsigned_max,
|
||||||
|
longlong signed_min, longlong signed_max);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user