diff options
author | unknown <msvensson@pilot.blaudden> | 2007-05-16 10:44:59 +0200 |
---|---|---|
committer | unknown <msvensson@pilot.blaudden> | 2007-05-16 10:44:59 +0200 |
commit | b5e4f54a53d3bdb06af48956bbeabcefdb1447aa (patch) | |
tree | 890ba335add713d8bf248138165188b29e09cded /sql/field.cc | |
parent | 7703b67659aabeeed53a2b78495ded9ddee9024d (diff) | |
download | mariadb-git-b5e4f54a53d3bdb06af48956bbeabcefdb1447aa.tar.gz |
Backport of TIME->MYSQL_TIME / Y2K fixset
Made year 2000 handling more uniform
Removed year 2000 handling out from calc_days()
The above removes some bugs in date/datetimes with year between 0 and 200
Now we get a note when we insert a datetime value into a date column
For default values to CREATE, don't give errors for warning level NOTE
Fixed some compiler failures
Added library ws2_32 for windows compilation (needed if we want to compile with IOCP support)
Removed duplicate typedef TIME and replaced it with MYSQL_TIME
Better (more complete) fix for: Bug#21103 "DATE column not compared as DATE"
Fixed properly Bug#18997 "DATE_ADD and DATE_SUB perform year2K autoconversion magic on 4-digit year value"
Fixed Bug#23093 "Implicit conversion of 9912101 to date does not match cast(9912101 as date)"
include/my_time.h:
Removed not used define YY_MAGIC_BELOW
Added prototype for year_2000_handling()
mysql-test/r/date_formats.result:
Updated results (fixed bug in date_format() with year < 99
mysql-test/r/func_sapdb.result:
Added more testing of make_date()
mysql-test/r/ps_2myisam.result:
Now we get a note when we insert a datetime value into a date column
mysql-test/r/ps_3innodb.result:
Now we get a note when we insert a datetime value into a date column
mysql-test/r/ps_4heap.result:
Now we get a note when we insert a datetime value into a date column
mysql-test/r/ps_5merge.result:
Now we get a note when we insert a datetime value into a date column
mysql-test/r/ps_7ndb.result:
Now we get a note when we insert a datetime value into a date column
mysql-test/r/strict.result:
zero-year in str_to_date() throws warning in strict
mysql-test/r/type_date.result:
Added test for date conversions
mysql-test/r/type_datetime.result:
Added testcase for datetime to date conversion.
mysql-test/t/date_formats.test:
Added testing of dates < 200
mysql-test/t/func_sapdb.test:
More testing of makedate()
mysql-test/t/type_date.test:
Added test for date conversions
mysql-test/t/type_datetime.test:
Added testcase for datetime to date conversion
sql/field.cc:
Give note if we insert a datetime value in a date field
Don't give notes if we are doing internal test conversions (like from convert_constant_item())
More documentation (store functions can now return '3' to inform that the function did return a NOTE (not warning or error))
Revert some changes in Field_newdate::store() to get more optimal code
Field::set_warning() will now ignore notes if CHECK_FIELD_IGNORE is set.
New parameters to make_truncated_value_warning()
sql/field.h:
Give note if we insert a datetime value in a date field
Don't give notes if we are doing internal test conversions (like from convert_constant_item())
More documentation (store functions can now return '3' to inform that the function did return a NOTE (not warning or error))
Revert some changes in Field_newdate::store() to get more optimal code
Field::set_warning() will now ignore notes if CHECK_FIELD_IGNORE is set.
New parameters to make_truncated_value_warning()
sql/item.cc:
Give note if we insert a datetime value in a date field
Don't give notes if we are doing internal test conversions (like from convert_constant_item())
More documentation (store functions can now return '3' to inform that the function did return a NOTE (not warning or error))
Revert some changes in Field_newdate::store() to get more optimal code
Field::set_warning() will now ignore notes if CHECK_FIELD_IGNORE is set.
New parameters to make_truncated_value_warning()
sql/item.h:
TIME -> MYSQL_TIME
sql/item_cmpfunc.cc:
Don't print notes in convert_constant_item()
sql/item_func.h:
TIME -> MYSQL_TIME
sql/item_timefunc.cc:
New parameters to make_truncated_value_warning()
Moved year 2000 handling out from calc_days()
sql/item_timefunc.h:
TIME -> MYSQL_TIME
sql/my_decimal.cc:
TIME -> MYSQL_TIME
sql/my_decimal.h:
TIME -> MYSQL_TIME
sql/mysql_priv.h:
Added error level to make_truncated_value_warning()
sql/protocol.cc:
TIME -> MYSQL_TIME
sql/protocol.h:
TIME -> MYSQL_TIME
sql/sp.cc:
TIME -> MYSQL_TIME
sql/sql_base.cc:
Make testing of result value of save_in_field() uniform
sql/sql_class.h:
TIME -> MYSQL_TIME
sql/sql_show.cc:
TIME -> MYSQL_TIME
sql/structs.h:
TIME -> MYSQL_TIME
sql/time.cc:
Added error level to make_truncated_value_warning()
sql/tztime.cc:
TIME -> MYSQL_TIME
sql/tztime.h:
TIME -> MYSQL_TIME
sql/unireg.cc:
For default values to CREATE, don't give errors for warning level NOTE
(Fixed failed CREATE when we give a datetime value to a date field)
sql-common/my_time.c:
Added year_2000_handling()
Removed year 2000 handling from calc_daynr()
Diffstat (limited to 'sql/field.cc')
-rw-r--r-- | sql/field.cc | 124 |
1 files changed, 75 insertions, 49 deletions
diff --git a/sql/field.cc b/sql/field.cc index b2def4ca8d2..8467e68f987 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1550,7 +1550,7 @@ uint Field::fill_cache_field(CACHE_FIELD *copy) } -bool Field::get_date(TIME *ltime,uint fuzzydate) +bool Field::get_date(MYSQL_TIME *ltime,uint fuzzydate) { char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),*res; @@ -1561,7 +1561,7 @@ bool Field::get_date(TIME *ltime,uint fuzzydate) return 0; } -bool Field::get_time(TIME *ltime) +bool Field::get_time(MYSQL_TIME *ltime) { char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),*res; @@ -1578,7 +1578,7 @@ bool Field::get_time(TIME *ltime) Needs to be changed if/when we want to support different time formats */ -int Field::store_time(TIME *ltime, timestamp_type type_arg) +int Field::store_time(MYSQL_TIME *ltime, timestamp_type type_arg) { char buff[MAX_DATE_STRING_REP_LENGTH]; uint length= (uint) my_TIME_to_str(ltime, buff); @@ -2504,7 +2504,7 @@ int Field_new_decimal::store_decimal(const my_decimal *decimal_value) } -int Field_new_decimal::store_time(TIME *ltime, timestamp_type t_type) +int Field_new_decimal::store_time(MYSQL_TIME *ltime, timestamp_type t_type) { my_decimal decimal_value; return store_value(date2my_decimal(ltime, &decimal_value)); @@ -4359,7 +4359,8 @@ timestamp_auto_set_type Field_timestamp::get_auto_set_type() const int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { - TIME l_time; + + MYSQL_TIME l_time; my_time_t tmp= 0; int error; bool have_smth_to_conv; @@ -4429,7 +4430,7 @@ int Field_timestamp::store(double nr) int Field_timestamp::store(longlong nr, bool unsigned_val) { - TIME l_time; + MYSQL_TIME l_time; my_time_t timestamp= 0; int error; my_bool in_dst_time_gap; @@ -4486,7 +4487,7 @@ double Field_timestamp::val_real(void) longlong Field_timestamp::val_int(void) { uint32 temp; - TIME time_tmp; + MYSQL_TIME time_tmp; THD *thd= table ? table->in_use : current_thd; #ifdef WORDS_BIGENDIAN @@ -4511,7 +4512,7 @@ longlong Field_timestamp::val_int(void) String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) { uint32 temp, temp2; - TIME time_tmp; + MYSQL_TIME time_tmp; THD *thd= table ? table->in_use : current_thd; char *to; @@ -4580,7 +4581,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr) } -bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate) +bool Field_timestamp::get_date(MYSQL_TIME *ltime, uint fuzzydate) { long temp; THD *thd= table ? table->in_use : current_thd; @@ -4604,7 +4605,7 @@ bool Field_timestamp::get_date(TIME *ltime, uint fuzzydate) return 0; } -bool Field_timestamp::get_time(TIME *ltime) +bool Field_timestamp::get_time(MYSQL_TIME *ltime) { return Field_timestamp::get_date(ltime,0); } @@ -4612,7 +4613,7 @@ bool Field_timestamp::get_time(TIME *ltime) bool Field_timestamp::send_binary(Protocol *protocol) { - TIME tm; + MYSQL_TIME tm; Field_timestamp::get_date(&tm, 0); return protocol->store(&tm); } @@ -4688,7 +4689,7 @@ void Field_timestamp::set_time() int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { - TIME ltime; + MYSQL_TIME ltime; long tmp; int error= 0; int warning; @@ -4703,9 +4704,12 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) else { if (warning & MYSQL_TIME_WARN_TRUNCATED) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, + { + set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_TIME, 1); + error= 1; + } if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -4716,8 +4720,6 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) if (ltime.month) ltime.day=0; tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); - if (error > 1) - error= 2; } if (ltime.neg) @@ -4727,7 +4729,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) } -int Field_time::store_time(TIME *ltime, timestamp_type time_type) +int Field_time::store_time(MYSQL_TIME *ltime, timestamp_type time_type) { long tmp= ((ltime->month ? 0 : ltime->day * 24L) + ltime->hour) * 10000L + (ltime->minute * 100 + ltime->second); @@ -4831,7 +4833,7 @@ longlong Field_time::val_int(void) String *Field_time::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { - TIME ltime; + MYSQL_TIME ltime; val_buffer->alloc(19); long tmp=(long) sint3korr(ptr); ltime.neg= 0; @@ -4855,7 +4857,7 @@ String *Field_time::val_str(String *val_buffer, DATE_FORMAT(time, "%l.%i %p") */ -bool Field_time::get_date(TIME *ltime, uint fuzzydate) +bool Field_time::get_date(MYSQL_TIME *ltime, uint fuzzydate) { long tmp; THD *thd= table ? table->in_use : current_thd; @@ -4883,7 +4885,7 @@ bool Field_time::get_date(TIME *ltime, uint fuzzydate) } -bool Field_time::get_time(TIME *ltime) +bool Field_time::get_time(MYSQL_TIME *ltime) { long tmp=(long) sint3korr(ptr); ltime->neg=0; @@ -4905,7 +4907,7 @@ bool Field_time::get_time(TIME *ltime) bool Field_time::send_binary(Protocol *protocol) { - TIME tm; + MYSQL_TIME tm; Field_time::get_time(&tm); tm.day= tm.hour/24; // Move hours to days tm.hour-= tm.day*24; @@ -5058,7 +5060,7 @@ void Field_year::sql_type(String &res) const int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) { - TIME l_time; + MYSQL_TIME l_time; uint32 tmp; int error; THD *thd= table ? table->in_use : current_thd; @@ -5114,7 +5116,7 @@ int Field_date::store(double nr) int Field_date::store(longlong nr, bool unsigned_val) { - TIME not_used; + MYSQL_TIME not_used; int error; longlong initial_nr= nr; THD *thd= table ? table->in_use : current_thd; @@ -5155,7 +5157,7 @@ int Field_date::store(longlong nr, bool unsigned_val) bool Field_date::send_binary(Protocol *protocol) { longlong tmp= Field_date::val_int(); - TIME tm; + MYSQL_TIME tm; tm.year= (uint32) tmp/10000L % 10000; tm.month= (uint32) tmp/100 % 100; tm.day= (uint32) tmp % 100; @@ -5192,7 +5194,7 @@ longlong Field_date::val_int(void) String *Field_date::val_str(String *val_buffer, String *val_ptr __attribute__((unused))) { - TIME ltime; + MYSQL_TIME ltime; val_buffer->alloc(field_length); int32 tmp; #ifdef WORDS_BIGENDIAN @@ -5261,9 +5263,26 @@ void Field_date::sql_type(String &res) const ** In number context: YYYYMMDD ****************************************************************************/ +/* + Store string into a date field + + SYNOPSIS + Field_newdate::store() + from Date string + len Length of date field + cs Character set (not used) + + RETURN + 0 ok + 1 Value was cut during conversion + 2 Wrong date string + 3 Datetime value that was cut (warning level NOTE) +*/ + int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) { - TIME l_time; + long tmp; + MYSQL_TIME l_time; int error; THD *thd= table ? table->in_use : current_thd; enum enum_mysql_timestamp_type ret; @@ -5274,20 +5293,23 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) MODE_INVALID_DATES))), &error)) <= MYSQL_TIMESTAMP_ERROR) { - int3store(ptr,0L); + tmp= 0; error= 2; } else { - int3store(ptr, l_time.day + l_time.month*32 + l_time.year*16*32); - if(!error && (ret != MYSQL_TIMESTAMP_DATE)) - return 2; + tmp= l_time.day + l_time.month*32 + l_time.year*16*32; + if (!error && (ret != MYSQL_TIMESTAMP_DATE)) + error= 3; // Datetime was cut (note) } if (error) - set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, + set_datetime_warning(error == 3 ? MYSQL_ERROR::WARN_LEVEL_NOTE : + MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_DATE, 1); + int3store(ptr, tmp); return error; } @@ -5307,7 +5329,7 @@ int Field_newdate::store(double nr) int Field_newdate::store(longlong nr, bool unsigned_val) { - TIME l_time; + MYSQL_TIME l_time; longlong tmp; int error; THD *thd= table ? table->in_use : current_thd; @@ -5334,7 +5356,7 @@ int Field_newdate::store(longlong nr, bool unsigned_val) } -int Field_newdate::store_time(TIME *ltime, timestamp_type time_type) +int Field_newdate::store_time(MYSQL_TIME *ltime, timestamp_type time_type) { long tmp; int error= 0; @@ -5368,7 +5390,7 @@ int Field_newdate::store_time(TIME *ltime, timestamp_type time_type) bool Field_newdate::send_binary(Protocol *protocol) { - TIME tm; + MYSQL_TIME tm; Field_newdate::get_date(&tm,0); return protocol->store_date(&tm); } @@ -5416,7 +5438,7 @@ String *Field_newdate::val_str(String *val_buffer, } -bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) +bool Field_newdate::get_date(MYSQL_TIME *ltime,uint fuzzydate) { uint32 tmp=(uint32) uint3korr(ptr); ltime->day= tmp & 31; @@ -5429,7 +5451,7 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) } -bool Field_newdate::get_time(TIME *ltime) +bool Field_newdate::get_time(MYSQL_TIME *ltime) { return Field_newdate::get_date(ltime,0); } @@ -5467,7 +5489,7 @@ void Field_newdate::sql_type(String &res) const int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) { - TIME time_tmp; + MYSQL_TIME time_tmp; int error; ulonglong tmp= 0; enum enum_mysql_timestamp_type func_res; @@ -5519,7 +5541,7 @@ int Field_datetime::store(double nr) int Field_datetime::store(longlong nr, bool unsigned_val) { - TIME not_used; + MYSQL_TIME not_used; int error; longlong initial_nr= nr; THD *thd= table ? table->in_use : current_thd; @@ -5554,12 +5576,12 @@ int Field_datetime::store(longlong nr, bool unsigned_val) } -int Field_datetime::store_time(TIME *ltime,timestamp_type time_type) +int Field_datetime::store_time(MYSQL_TIME *ltime,timestamp_type time_type) { longlong tmp; int error= 0; /* - We don't perform range checking here since values stored in TIME + We don't perform range checking here since values stored in MYSQL_TIME structure always fit into DATETIME range. */ if (time_type == MYSQL_TIMESTAMP_DATE || @@ -5599,7 +5621,7 @@ int Field_datetime::store_time(TIME *ltime,timestamp_type time_type) bool Field_datetime::send_binary(Protocol *protocol) { - TIME tm; + MYSQL_TIME tm; Field_datetime::get_date(&tm, TIME_FUZZY_DATE); return protocol->store(&tm); } @@ -5671,7 +5693,7 @@ String *Field_datetime::val_str(String *val_buffer, return val_buffer; } -bool Field_datetime::get_date(TIME *ltime, uint fuzzydate) +bool Field_datetime::get_date(MYSQL_TIME *ltime, uint fuzzydate) { longlong tmp=Field_datetime::val_int(); uint32 part1,part2; @@ -5690,7 +5712,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate) return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0; } -bool Field_datetime::get_time(TIME *ltime) +bool Field_datetime::get_time(MYSQL_TIME *ltime) { return Field_datetime::get_date(ltime,0); } @@ -9060,10 +9082,13 @@ uint32 Field_blob::max_display_length() NOTE This function won't produce warning and increase cut fields counter - if count_cuted_fields == FIELD_CHECK_IGNORE for current thread. + if count_cuted_fields == CHECK_FIELD_IGNORE for current thread. + + if count_cuted_fields == CHECK_FIELD_IGNORE then we ignore notes. + This allows us to avoid notes in optimisation, like convert_constant_item(). RETURN VALUE - 1 if count_cuted_fields == FIELD_CHECK_IGNORE + 1 if count_cuted_fields == CHECK_FIELD_IGNORE and error level is not NOTE 0 otherwise */ @@ -9083,7 +9108,7 @@ Field::set_warning(MYSQL_ERROR::enum_warning_level level, uint code, thd->row_count); return 0; } - return 1; + return level >= MYSQL_ERROR::WARN_LEVEL_WARN; } @@ -9111,9 +9136,10 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, timestamp_type ts_type, int cuted_increment) { THD *thd= table ? table->in_use : current_thd; - if (thd->really_abort_on_warning() || + if ((thd->really_abort_on_warning() && + level >= MYSQL_ERROR::WARN_LEVEL_WARN) || set_warning(level, code, cuted_increment)) - make_truncated_value_warning(thd, str, str_length, ts_type, + make_truncated_value_warning(thd, level, str, str_length, ts_type, field_name); } @@ -9146,7 +9172,7 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, { char str_nr[22]; char *str_end= longlong10_to_str(nr, str_nr, -10); - make_truncated_value_warning(thd, str_nr, (uint) (str_end - str_nr), + make_truncated_value_warning(thd, level, str_nr, (uint) (str_end - str_nr), ts_type, field_name); } } @@ -9179,7 +9205,7 @@ Field::set_datetime_warning(MYSQL_ERROR::enum_warning_level level, uint code, /* 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(thd, str_nr, str_len, ts_type, + make_truncated_value_warning(thd, level, str_nr, str_len, ts_type, field_name); } } |