summaryrefslogtreecommitdiff
path: root/sql/field.cc
diff options
context:
space:
mode:
authorunknown <monty@mishka.local>2004-09-28 20:08:00 +0300
committerunknown <monty@mishka.local>2004-09-28 20:08:00 +0300
commit2a49121590930ad9ef69718caad67304e94b9c00 (patch)
tree7f0311baaca32e6242f23dcf0a89ed38e39c9ac0 /sql/field.cc
parente74b00bbc98c1082086422dc9c8578dade9d4a11 (diff)
downloadmariadb-git-2a49121590930ad9ef69718caad67304e94b9c00.tar.gz
Strict mode & better warnings
Under strict mode MySQL will generate an error message if there was any conversion when assigning data to a field. Added checking of date/datetime fields. If strict mode, give error if we have not given value to field without a default value (for INSERT) client/mysqltest.c: Added --exit as an option to abort a test in a middle (good for debugging) include/my_time.h: Added flags to allow checking of dates in strict mode include/mysql_com.h: Added flag to check if field has a default value or not include/mysqld_error.h: New error messages for strict mode include/sql_state.h: Fixed SQL states (for strict mode tests) mysql-test/r/auto_increment.result: Updated error messages mysql-test/r/func_sapdb.result: Added test for ALLOW_INVALID_DATES mysql-test/r/func_str.result: Updated error messages mysql-test/r/func_time.result: Updated error messages mysql-test/r/insert.result: Updated error messages mysql-test/r/loaddata.result: Updated error messages mysql-test/r/select.result: Updated error messages mysql-test/r/sp.result: Updated error messages mysql-test/r/timezone2.result: Updated error messages mysql-test/r/type_datetime.result: Updated error messages mysql-test/r/type_decimal.result: Updated error messages mysql-test/r/type_float.result: Updated error messages mysql-test/r/type_ranges.result: Updated error messages mysql-test/r/type_time.result: Updated error messages mysql-test/r/type_uint.result: Updated error messages mysql-test/r/warnings.result: Updated error messages mysql-test/t/func_sapdb.test: Aded test sql-common/my_time.c: Added checking of dates sql/field.cc: Better error messages Optimization of warning handling (by introducing of check_int()) Changed to use my_strtoll10() sql/field.h: Added check_int() sql/item_func.cc: Warnings when dividing by NULL sql/item_func.h: Warnings when dividing by NULL sql/item_timefunc.cc: Testing of date/datetime Use macros instead of constants sql/mysql_priv.h: New modes (part of strict mode) sql/mysqld.cc: New modes (part of strict mode) sql/opt_range.cc: Simple optimizations sql/protocol.cc: Add note/warning level to find_handler() sql/set_var.cc: Added mode 'traditional' sql/share/czech/errmsg.txt: New error messages for strict mode sql/share/danish/errmsg.txt: New error messages for strict mode sql/share/dutch/errmsg.txt: New error messages for strict mode sql/share/english/errmsg.txt: New error messages for strict mode sql/share/estonian/errmsg.txt: New error messages for strict mode sql/share/french/errmsg.txt: New error messages for strict mode sql/share/german/errmsg.txt: New error messages for strict mode sql/share/greek/errmsg.txt: New error messages for strict mode sql/share/hungarian/errmsg.txt: New error messages for strict mode sql/share/italian/errmsg.txt: New error messages for strict mode sql/share/japanese/errmsg.txt: New error messages for strict mode sql/share/korean/errmsg.txt: New error messages for strict mode sql/share/norwegian-ny/errmsg.txt: New error messages for strict mode sql/share/norwegian/errmsg.txt: New error messages for strict mode sql/share/polish/errmsg.txt: New error messages for strict mode sql/share/portuguese/errmsg.txt: New error messages for strict mode sql/share/romanian/errmsg.txt: New error messages for strict mode sql/share/russian/errmsg.txt: New error messages for strict mode sql/share/serbian/errmsg.txt: New error messages for strict mode sql/share/slovak/errmsg.txt: New error messages for strict mode sql/share/spanish/errmsg.txt: New error messages for strict mode sql/share/swedish/errmsg.txt: New error messages for strict mode sql/share/ukrainian/errmsg.txt: New error messages for strict mode sql/sp_rcontext.cc: Add note/warning level to find_handler() sql/sp_rcontext.h: Add note/warning level to find_handler() sql/sql_base.cc: Fix bug for detecting crashed table sql/sql_class.cc: Variables for strct mode sql/sql_class.h: Variables for strct mode sql/sql_error.cc: In strict mode, convert warnings to errors sql/sql_insert.cc: Strict mode If strict mode, give error if we have not given value to field without a default value sql/sql_load.cc: Strict mode sql/sql_parse.cc: Strict mode. Add flag to field if it doesn't have a default value sql/sql_select.cc: Added comment Prepare for upper level handling of table->status sql/sql_union.cc: Added THD to write_record() sql/sql_update.cc: Strict mode sql/table.cc: Handling of default values sql/time.cc: Checking of dates
Diffstat (limited to 'sql/field.cc')
-rw-r--r--sql/field.cc289
1 files changed, 158 insertions, 131 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 5356fbc773a..ada8381653b 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -83,32 +83,48 @@ void Field_num::prepend_zeros(String *value)
RETURN
0 ok
- 1 error
+ 1 error. A warning is pushed if field_name != 0
*/
-bool test_if_int(const char *str, int length, const char *int_end,
- CHARSET_INFO *cs)
+bool Field::check_int(const char *str, int length, const char *int_end,
+ CHARSET_INFO *cs)
{
+ const char *end;
if (str == int_end)
- return 0; // Empty string
- const char *end=str+length;
+ {
+ char buff[128];
+ String tmp(buff,(uint32) sizeof(buff), system_charset_info);
+ tmp.copy(str, length, system_charset_info);
+ push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
+ ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
+ "integer", tmp.c_ptr(), field_name,
+ (ulong) table->in_use->row_count);
+ return 1; // Empty string
+ }
+ end= str+length;
if ((str= int_end) == end)
- return 1; // All digits was used
+ return 0; // ok; All digits was used
/* Allow end .0000 */
if (*str == '.')
{
- for (str++ ; str != end && *str == '0'; str++) ;
+ for (str++ ; str != end && *str == '0'; str++)
+ ;
}
/* Allow end space */
- for (str++ ; str != end ; str++)
+ for ( ; str != end ; str++)
{
if (!my_isspace(cs,*str))
- return 0;
+ {
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ return 1;
+ }
}
- return 1;
+ return 0;
}
+
#ifdef NOT_USED
static bool test_if_real(const char *str,int length, CHARSET_INFO *cs)
{
@@ -846,7 +862,13 @@ int Field_decimal::store(const char *from, uint len, CHARSET_INFO *cs)
if (tmp_char != '0') // Losing a non zero digit ?
{
if (!is_cuted_fields_incr)
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ {
+ /*
+ This is a note, not a warning, as we don't want to abort
+ when we cut decimals in strict mode
+ */
+ set_warning(MYSQL_ERROR::WARN_LEVEL_NOTE, ER_WARN_DATA_TRUNCATED, 1);
+ }
return 0;
}
continue;
@@ -1073,11 +1095,8 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
}
else
{
@@ -1093,11 +1112,8 @@ int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
}
ptr[0]= (char) tmp;
return error;
@@ -1277,11 +1293,8 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
}
else
{
@@ -1297,11 +1310,8 @@ int Field_short::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
}
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -1552,11 +1562,8 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
}
else
{
@@ -1572,11 +1579,8 @@ int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
- else if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- {
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
error= 1;
- }
}
int3store(ptr,tmp);
@@ -1752,71 +1756,72 @@ void Field_medium::sql_type(String &res) const
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
{
- long tmp;
- int error= 0;
+ longlong tmp;
+ long store_tmp;
+ int error;
+ bool warning_given= 0;
char *end;
tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
len-= tmp;
from+= tmp;
- my_errno=0;
- if (unsigned_flag)
+ end= (char*) from+len;
+ tmp= my_strtoll10(from, &end, &error);
+
+ if (error != MY_ERRNO_EDOM)
{
- if (!len || *from == '-')
+ if (unsigned_flag)
{
- tmp=0; // Set negative to 0
- my_errno=ERANGE;
- error= 1;
+ if (error < 0)
+ {
+ error= 1;
+ tmp= 0;
+ }
+ else if ((ulonglong) tmp > (ulonglong) UINT_MAX32)
+ {
+ tmp= UINT_MAX32;
+ error= 1;
+ }
+ else
+ error= 0;
}
else
- tmp=(long) my_strntoul(cs,from,len,10,&end,&error);
- }
- else
- tmp=my_strntol(cs,from,len,10,&end,&error);
- if (error ||
- (from+len != end && table->in_use->count_cuted_fields &&
- !test_if_int(from,len,end,cs)))
- error= 1;
-#if SIZEOF_LONG > 4
- if (unsigned_flag)
- {
- if ((ulong) tmp > UINT_MAX32)
- {
- tmp= UINT_MAX32;
- error= 1;
- my_errno=ERANGE;
- }
- }
- else
- {
- if (tmp > INT_MAX32)
- {
- tmp= INT_MAX32;
- error= 1;
- my_errno=ERANGE;
- }
- else if (tmp < INT_MIN32)
{
- tmp= INT_MIN32;
- error= 1;
- my_errno=ERANGE;
+ if (error < 0)
+ {
+ error= 0;
+ if (tmp < INT_MIN32)
+ {
+ tmp= INT_MIN32;
+ error= 1;
+ }
+ }
+ else if (tmp > INT_MAX32)
+ {
+ tmp= INT_MAX32;
+ error= 1;
+ }
}
}
-#endif
if (error)
{
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
error= 1;
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
}
+ else if (from+len != end && table->in_use->count_cuted_fields &&
+ check_int(from,len,end,cs))
+ error= 1;
+
+ store_tmp= (long) tmp;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
- int4store(ptr,tmp);
+ int4store(ptr, store_tmp);
}
else
#endif
- longstore(ptr,tmp);
+ longstore(ptr, store_tmp);
return error;
}
@@ -1831,13 +1836,11 @@ int Field_long::store(double nr)
if (nr < 0)
{
res=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr > (double) (ulong) ~0L)
{
res=(int32) (uint32) ~0L;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
@@ -1848,18 +1851,19 @@ int Field_long::store(double nr)
if (nr < (double) INT_MIN32)
{
res=(int32) INT_MIN32;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr > (double) INT_MAX32)
{
res=(int32) INT_MAX32;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
res=(int32) nr;
}
+ if (error)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -1876,26 +1880,18 @@ int Field_long::store(longlong nr)
{
int error= 0;
int32 res;
-
- /*
- This assert has nothing to do with this method per se, it was put here
- only because it is one of the best places for catching places there its
- condition is broken.
- */
- DBUG_ASSERT(table->in_use == current_thd);
+ DBUG_ASSERT(table->in_use == current_thd); // General safety
if (unsigned_flag)
{
if (nr < 0)
{
res=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr >= (LL(1) << 32))
{
res=(int32) (uint32) ~0L;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
@@ -1906,18 +1902,19 @@ int Field_long::store(longlong nr)
if (nr < (longlong) INT_MIN32)
{
res=(int32) INT_MIN32;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr > (longlong) INT_MAX32)
{
res=(int32) INT_MAX32;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
res=(int32) nr;
}
+ if (error)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2052,17 +2049,16 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
longlong tmp;
int error= 0;
char *end;
+ bool warning_given;
tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES);
len-= (uint)tmp;
from+= tmp;
- my_errno=0;
if (unsigned_flag)
{
if (!len || *from == '-')
{
tmp=0; // Set negative to 0
- my_errno= ERANGE;
error= 1;
}
else
@@ -2070,13 +2066,14 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
}
else
tmp=my_strntoll(cs,from,len,10,&end,&error);
- if (error ||
- (from+len != end && table->in_use->count_cuted_fields &&
- !test_if_int(from,len,end,cs)))
+ if (error)
{
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
+ else if (from+len != end && table->in_use->count_cuted_fields &&
+ check_int(from,len,end,cs))
+ error= 1;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2093,19 +2090,18 @@ int Field_longlong::store(double nr)
{
int error= 0;
longlong res;
- nr=rint(nr);
+
+ nr= rint(nr);
if (unsigned_flag)
{
if (nr < 0)
{
res=0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else if (nr >= (double) ~ (ulonglong) 0)
{
res= ~(longlong) 0;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
error= 1;
}
else
@@ -2113,21 +2109,22 @@ int Field_longlong::store(double nr)
}
else
{
- if (nr <= (double) LONGLONG_MIN)
+ if (nr < (double) LONGLONG_MIN)
{
- res=(longlong) LONGLONG_MIN;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ res= LONGLONG_MIN;
error= 1;
}
- else if (nr >= (double) LONGLONG_MAX)
+ else if (nr > (double) LONGLONG_MAX)
{
- res=(longlong) LONGLONG_MAX;
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+ res= LONGLONG_MAX;
error= 1;
}
else
res=(longlong) nr;
}
+ if (error)
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
+
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2951,14 +2948,22 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
bool in_dst_time_gap;
THD *thd= table->in_use;
- have_smth_to_conv= (str_to_datetime(from, len, &l_time, 0, &error) >
+ have_smth_to_conv= (str_to_datetime(from, len, &l_time,
+ ((table->in_use->variables.sql_mode &
+ MODE_NO_ZERO_DATE) |
+ MODE_NO_ZERO_IN_DATE),
+ &error) >
MYSQL_TIMESTAMP_ERROR);
- if (error)
+ if (error || !have_smth_to_conv)
+ {
+ error= 1;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, MYSQL_TIMESTAMP_DATETIME, 1);
+ }
- if (have_smth_to_conv)
+ /* Only convert a correct date (not a zero date) */
+ if (have_smth_to_conv && l_time.month)
{
if (!(tmp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap)))
{
@@ -2988,6 +2993,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
return error;
}
+
int Field_timestamp::store(double nr)
{
int error= 0;
@@ -3162,7 +3168,7 @@ bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate)
longget(temp,ptr);
if (temp == 0L)
{ /* Zero time is "000000" */
- if (!fuzzydate)
+ if (fuzzydate & TIME_NO_ZERO_DATE)
return 1;
bzero((char*) ltime,sizeof(*ltime));
}
@@ -3183,7 +3189,7 @@ bool Field_timestamp::get_time(TIME *ltime)
bool Field_timestamp::send_binary(Protocol *protocol)
{
TIME tm;
- Field_timestamp::get_date(&tm, TIME_FUZZY_DATE);
+ Field_timestamp::get_date(&tm, 0);
return protocol->store(&tm);
}
@@ -3415,7 +3421,7 @@ String *Field_time::val_str(String *val_buffer,
bool Field_time::get_date(TIME *ltime, uint fuzzydate)
{
long tmp;
- if (!fuzzydate)
+ if (!(fuzzydate & TIME_FUZZY_DATE))
{
push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_WARN_DATA_OUT_OF_RANGE,
@@ -3497,18 +3503,19 @@ void Field_time::sql_type(String &res) const
int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
{
- int not_used; // We can ignore result from str2int
char *end;
- long nr= my_strntol(cs, from, len, 10, &end, &not_used);
+ int error;
+ long nr= my_strntol(cs, from, len, 10, &end, &error);
- if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155)
+ if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || error)
{
*ptr=0;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
return 1;
}
- if (table->in_use->count_cuted_fields && !test_if_int(from,len,end,cs))
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ if (table->in_use->count_cuted_fields && check_int(from,len,end,cs))
+ error= 1;
+
if (nr != 0 || len != 4)
{
if (nr < YY_PART_YEAR)
@@ -3517,7 +3524,7 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs)
nr-= 1900;
}
*ptr= (char) (unsigned char) nr;
- return 0;
+ return error;
}
@@ -3603,7 +3610,11 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
uint32 tmp;
int error;
- if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
+ if (str_to_datetime(from, len, &l_time, TIME_FUZZY_DATE |
+ (table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES)),
+ &error) <= MYSQL_TIMESTAMP_ERROR)
{
tmp=0;
error= 1;
@@ -3794,7 +3805,12 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
TIME l_time;
long tmp;
int error;
- if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
+ if (str_to_datetime(from, len, &l_time,
+ (TIME_FUZZY_DATE |
+ (table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))),
+ &error) <= MYSQL_TIMESTAMP_ERROR)
{
tmp=0L;
error= 1;
@@ -3934,7 +3950,8 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate)
ltime->year= (tmp >> 9);
ltime->time_type= MYSQL_TIMESTAMP_DATE;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
- return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
+ return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
+ 1 : 0);
}
bool Field_newdate::get_time(TIME *ltime)
@@ -3976,7 +3993,12 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs)
int error;
ulonglong tmp= 0;
- if (str_to_datetime(from, len, &time_tmp, 1, &error) > MYSQL_TIMESTAMP_ERROR)
+ if (str_to_datetime(from, len, &time_tmp,
+ (TIME_FUZZY_DATE |
+ (table->in_use->variables.sql_mode &
+ (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
+ MODE_INVALID_DATES))),
+ &error) > MYSQL_TIMESTAMP_ERROR)
tmp= TIME_to_ulonglong_datetime(&time_tmp);
if (error)
@@ -4148,7 +4170,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate)
ltime->day= (int) (part1%100);
ltime->month= (int) (part1/100%100);
ltime->year= (int) (part1/10000);
- return (!fuzzydate && (!ltime->month || !ltime->day)) ? 1 : 0;
+ return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
}
bool Field_datetime::get_time(TIME *ltime)
@@ -6059,7 +6081,7 @@ Field::set_warning(const uint level, const uint code, int cuted_increment)
Produce warning or note about datetime string data saved into field
SYNOPSYS
- set_warning()
+ set_datime_warning()
level - level of message (Note/Warning/Error)
code - error code of message to be produced
str - string value which we tried to save
@@ -6077,8 +6099,10 @@ Field::set_datetime_warning(const uint level, const uint code,
const char *str, uint str_length,
timestamp_type ts_type, int cuted_increment)
{
- if (set_warning(level, code, cuted_increment))
- make_truncated_value_warning(table->in_use, str, str_length, ts_type);
+ if (table->in_use->really_abort_on_warning() ||
+ set_warning(level, code, cuted_increment))
+ make_truncated_value_warning(table->in_use, str, str_length, ts_type,
+ field_name);
}
@@ -6103,12 +6127,13 @@ Field::set_datetime_warning(const uint level, const uint code,
longlong nr, timestamp_type ts_type,
int cuted_increment)
{
- if (set_warning(level, code, cuted_increment))
+ if (table->in_use->really_abort_on_warning() ||
+ set_warning(level, code, cuted_increment))
{
char str_nr[22];
char *str_end= longlong10_to_str(nr, str_nr, -10);
make_truncated_value_warning(table->in_use, str_nr, str_end - str_nr,
- ts_type);
+ ts_type, field_name);
}
}
@@ -6132,12 +6157,14 @@ void
Field::set_datetime_warning(const uint level, const uint code,
double nr, timestamp_type ts_type)
{
- if (set_warning(level, code, 1))
+ if (table->in_use->really_abort_on_warning() ||
+ set_warning(level, code, 1))
{
/* DBL_DIG is enough to print '-[digits].E+###' */
char str_nr[DBL_DIG + 8];
uint str_len= my_sprintf(str_nr, (str_nr, "%g", nr));
- make_truncated_value_warning(table->in_use, str_nr, str_len, ts_type);
+ make_truncated_value_warning(table->in_use, str_nr, str_len, ts_type,
+ field_name);
}
}