diff options
author | unknown <monty@mishka.local> | 2004-09-28 20:08:00 +0300 |
---|---|---|
committer | unknown <monty@mishka.local> | 2004-09-28 20:08:00 +0300 |
commit | 2a49121590930ad9ef69718caad67304e94b9c00 (patch) | |
tree | 7f0311baaca32e6242f23dcf0a89ed38e39c9ac0 /sql/field.cc | |
parent | e74b00bbc98c1082086422dc9c8578dade9d4a11 (diff) | |
download | mariadb-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.cc | 289 |
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, ¬_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); } } |