diff options
author | unknown <konstantin@mysql.com> | 2004-06-24 19:08:36 +0400 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2004-06-24 19:08:36 +0400 |
commit | 9dde418895f2d236234b975c4ada88ad624e8ba4 (patch) | |
tree | 51efbaacdacd9dad5c2745e3ccb58a3614f4f608 /sql | |
parent | 85e9258b05b2490e35aa60adecf48a3f65245eb0 (diff) | |
download | mariadb-git-9dde418895f2d236234b975c4ada88ad624e8ba4.tar.gz |
Fix for Bug#4030 "Client side conversion string -> date type doesn't
work (prepared statements)" and after-review fixes:
- str_to_TIME renamed to str_to_datetime to pair with str_to_time
- functions str_to_time and str_to_TIME moved to sql-common
- send_data_str now supports MYSQL_TYPE_TIME, MYSQL_TIME_DATE,
MYSQL_TIME_DATETIME types of user input buffers.
- few more comments in the client library
- a test case added.
VC++Files/libmysql/libmysql.dsp:
new file: my_time.c
VC++Files/libmysqld/libmysqld.dsp:
new file: my_time.c
VC++Files/sql/mysqld.dsp:
new file: my_time.c
include/Makefile.am:
- mysql_time.h added to the list of installed client library headers
include/mysql.h:
- declarations for MYSQL_TIME and enum_mysql_timestamp_type moved to
mysql_time.h, which is in shared use of client library and mysys.
libmysql/Makefile.shared:
- my_time.lo added to the list of libmysql objects
libmysql/libmysql.c:
Fix for bug#4030 "Client side conversion string -> date type doesn't work
(prepared statements)" and cleanup.
- added case labels for TIME/DATE/DATETIME types to send_data_str
- comments for read_binary_{date,time,datetime}, fetch_result_*, fetch_results.
libmysqld/Makefile.am:
- my_time.c added
sql-common/Makefile.am:
- my_time.c added to the list of files included into source distribution.
sql/Makefile.am:
my_time.c added to the list of mysqld sources.
sql/field.cc:
- TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to
MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/item.cc:
- TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to
MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/item_timefunc.cc:
- TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to
MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/mysql_priv.h:
- added typedefs for TIME and timestamp_type
- removed declarations for str_to_time and str_to_TIME (now this functions
reside in mysys)
sql/mysqld.cc:
- log_10_int moved to mysys (it's used by str_to_TIME and str_to_time)
- enum values TIMESTAMP_{TIME,DATE,DATETIME} were renamed to
MYSQL_TIMESTAMP_{TIME,DATE,DATETIME}
sql/set_var.cc:
- TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to
MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
sql/set_var.h:
- fixed timestamp_type usage to be compatible with typedef.
sql/sql_prepare.cc:
- TIMESTAMP_{TIME,DATE,DATETIME} were renamed to
MYSQL_TIMESTAMP_{TIME,DATE,DATETIME}
- embedded library implementation of set_param_{time,date,datetime} is
much simplier now, as MYSQL_TIME is the same as TIME.
sql/sql_yacc.yy:
- s/\<TIMESTAMP_/MYSQL_TIMESTAMP/gc
sql/structs.h:
- declarations for TIME and timestamp_type replaced with typedefs
- str_to_datetime arguments moved to mysys headers
sql/time.cc:
- str_to_time and str_to_TIME moved to mysys
- TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to
MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...} as these names are now
exported to client.
- str_to_TIME renamed to str_to_datetime to pair with str_to_time
- str_to_TIME_with_warn renamed accordingly
sql/tztime.cc:
- TIMESTAMP_{TIME,DATE,DATETIME,...} renamed to
MYSQL_TIMESTAMP_{TIME,DATETIME,DATE,...}
tests/client_test.c:
- a test case for Bug#4030 "Client side conversion string -> date type
doesn't work (prepared statements)"
Diffstat (limited to 'sql')
-rw-r--r-- | sql/Makefile.am | 5 | ||||
-rw-r--r-- | sql/field.cc | 85 | ||||
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 66 | ||||
-rw-r--r-- | sql/mysql_priv.h | 8 | ||||
-rw-r--r-- | sql/mysqld.cc | 27 | ||||
-rw-r--r-- | sql/set_var.cc | 6 | ||||
-rw-r--r-- | sql/set_var.h | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 45 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 6 | ||||
-rw-r--r-- | sql/structs.h | 25 | ||||
-rw-r--r-- | sql/time.cc | 585 | ||||
-rw-r--r-- | sql/tztime.cc | 6 |
13 files changed, 148 insertions, 722 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index 9fecf6a0d8f..9777e1b8533 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -89,7 +89,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ client.c sql_client.cc mini_client_errors.c pack.c\ stacktrace.c repl_failsafe.h repl_failsafe.cc \ gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \ - tztime.cc examples/ha_example.cc examples/ha_archive.cc + tztime.cc my_time.c \ + examples/ha_example.cc examples/ha_archive.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) @@ -114,6 +115,8 @@ link_sources: @LN_CP_F@ ../sql-common/pack.c pack.c rm -f client.c @LN_CP_F@ ../sql-common/client.c client.c + rm -f my_time.c + @LN_CP_F@ ../sql-common/my_time.c my_time.c gen_lex_hash.o: gen_lex_hash.cc lex.h $(CXXCOMPILE) -c $(INCLUDES) $< diff --git a/sql/field.cc b/sql/field.cc index f113b98cccd..8368b18e78a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -398,8 +398,8 @@ bool Field::get_date(TIME *ltime,uint fuzzydate) char buff[40]; String tmp(buff,sizeof(buff),&my_charset_bin),*res; if (!(res=val_str(&tmp)) || - str_to_TIME_with_warn(res->ptr(), res->length(), ltime, fuzzydate) <= - TIMESTAMP_DATETIME_ERROR) + str_to_datetime_with_warn(res->ptr(), res->length(), + ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR) return 1; return 0; } @@ -2918,12 +2918,12 @@ 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_TIME(from, len, &l_time, 0, &error) > - TIMESTAMP_DATETIME_ERROR); + have_smth_to_conv= (str_to_datetime(from, len, &l_time, 0, &error) > + MYSQL_TIMESTAMP_ERROR); if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - from, len, TIMESTAMP_DATETIME, 1); + from, len, MYSQL_TIMESTAMP_DATETIME, 1); if (have_smth_to_conv) { @@ -2931,7 +2931,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - from, len, TIMESTAMP_DATETIME, !error); + from, len, MYSQL_TIMESTAMP_DATETIME, !error); error= 1; } @@ -2939,7 +2939,7 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_INVALID_TIMESTAMP, - from, len, TIMESTAMP_DATETIME, !error); + from, len, MYSQL_TIMESTAMP_DATETIME, !error); error= 1; } } @@ -2962,7 +2962,7 @@ int Field_timestamp::store(double nr) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - nr, TIMESTAMP_DATETIME); + nr, MYSQL_TIMESTAMP_DATETIME); nr= 0; // Avoid overflow on buff error= 1; } @@ -2985,7 +2985,7 @@ int Field_timestamp::store(longlong nr) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - nr, TIMESTAMP_DATETIME, 1); + nr, MYSQL_TIMESTAMP_DATETIME, 1); error= 1; } @@ -2993,14 +2993,14 @@ int Field_timestamp::store(longlong nr) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_INVALID_TIMESTAMP, - nr, TIMESTAMP_DATETIME, !error); + nr, MYSQL_TIMESTAMP_DATETIME, !error); error= 1; } } else if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - nr, TIMESTAMP_DATETIME, 1); + nr, MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -3232,14 +3232,14 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) tmp=0L; error= 1; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - from, len, TIMESTAMP_TIME, 1); + from, len, MYSQL_TIMESTAMP_TIME, 1); } else { if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - from, len, TIMESTAMP_TIME, 1); + from, len, MYSQL_TIMESTAMP_TIME, 1); if (ltime.month) ltime.day=0; @@ -3249,7 +3249,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) tmp=8385959; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - from, len, TIMESTAMP_TIME, !error); + from, len, MYSQL_TIMESTAMP_TIME, !error); error= 1; } } @@ -3269,14 +3269,14 @@ int Field_time::store(double nr) { tmp=8385959L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME); + ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; } else if (nr < -8385959.0) { tmp= -8385959L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME); + ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; } else @@ -3288,7 +3288,8 @@ int Field_time::store(double nr) { tmp=0; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME); + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_TIME); error= 1; } } @@ -3305,14 +3306,16 @@ int Field_time::store(longlong nr) { tmp=8385959L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME, 1); + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_TIME, 1); error= 1; } else if (nr < (longlong) -8385959L) { tmp= -8385959L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME, 1); + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_TIME, 1); error= 1; } else @@ -3322,7 +3325,8 @@ int Field_time::store(longlong nr) { tmp=0; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_TIME, 1); + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_TIME, 1); error= 1; } } @@ -3417,7 +3421,7 @@ bool Field_time::get_time(TIME *ltime) ltime->minute= (int) tmp/100; ltime->second= (int) tmp % 100; ltime->second_part=0; - ltime->time_type= TIMESTAMP_TIME; + ltime->time_type= MYSQL_TIMESTAMP_TIME; return 0; } @@ -3566,8 +3570,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) uint32 tmp; int error; - if (str_to_TIME(from, len, &l_time, 1, &error) <= - TIMESTAMP_DATETIME_ERROR) + if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR) { tmp=0; error= 1; @@ -3577,7 +3580,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs) if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - from, len, TIMESTAMP_DATE, 1); + from, len, MYSQL_TIMESTAMP_DATE, 1); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -3602,7 +3605,7 @@ int Field_date::store(double nr) tmp=0L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - nr, TIMESTAMP_DATE); + nr, MYSQL_TIMESTAMP_DATE); error= 1; } else @@ -3630,7 +3633,7 @@ int Field_date::store(longlong nr) tmp=0L; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - nr, TIMESTAMP_DATE, 0); + nr, MYSQL_TIMESTAMP_DATE, 0); error= 1; } else @@ -3758,8 +3761,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) TIME l_time; long tmp; int error; - if (str_to_TIME(from, len, &l_time, 1, &error) <= - TIMESTAMP_DATETIME_ERROR) + if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR) { tmp=0L; error= 1; @@ -3769,7 +3771,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs) if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, - from, len, TIMESTAMP_DATE, 1); + from, len, MYSQL_TIMESTAMP_DATE, 1); int3store(ptr,tmp); return error; @@ -3781,7 +3783,7 @@ int Field_newdate::store(double nr) { (void) Field_newdate::store((longlong) -1); set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_TRUNCATED, nr, TIMESTAMP_DATE); + ER_WARN_DATA_TRUNCATED, nr, MYSQL_TIMESTAMP_DATE); return 1; } else @@ -3799,7 +3801,8 @@ int Field_newdate::store(longlong nr) { tmp=0; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_DATE, 1); + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_DATE, 1); error= 1; } else @@ -3818,7 +3821,8 @@ int Field_newdate::store(longlong nr) { tmp=0L; // Don't allow date to change set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_OUT_OF_RANGE, nr, TIMESTAMP_DATE, 1); + ER_WARN_DATA_OUT_OF_RANGE, nr, + MYSQL_TIMESTAMP_DATE, 1); error= 1; } else @@ -3831,7 +3835,7 @@ int Field_newdate::store(longlong nr) void Field_newdate::store_time(TIME *ltime,timestamp_type type) { long tmp; - if (type == TIMESTAMP_DATE || type == TIMESTAMP_DATETIME) + if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME) tmp=ltime->year*16*32+ltime->month*32+ltime->day; else { @@ -3895,7 +3899,7 @@ bool Field_newdate::get_date(TIME *ltime,uint fuzzydate) ltime->day= tmp & 31; ltime->month= (tmp >> 5) & 15; ltime->year= (tmp >> 9); - ltime->time_type=TIMESTAMP_DATE; + 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; } @@ -3939,14 +3943,13 @@ int Field_datetime::store(const char *from,uint len,CHARSET_INFO *cs) int error; ulonglong tmp= 0; - if (str_to_TIME(from, len, &time_tmp, 1, &error) > - TIMESTAMP_DATETIME_ERROR) + if (str_to_datetime(from, len, &time_tmp, 1, &error) > MYSQL_TIMESTAMP_ERROR) tmp= TIME_to_ulonglong_datetime(&time_tmp); if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - from, len, TIMESTAMP_DATETIME, 1); + from, len, MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -3967,7 +3970,7 @@ int Field_datetime::store(double nr) { set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, - nr, TIMESTAMP_DATETIME); + nr, MYSQL_TIMESTAMP_DATETIME); nr=0.0; error= 1; } @@ -3987,7 +3990,7 @@ int Field_datetime::store(longlong nr) if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, initial_nr, - TIMESTAMP_DATETIME, 1); + MYSQL_TIMESTAMP_DATETIME, 1); #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) @@ -4004,7 +4007,7 @@ int Field_datetime::store(longlong nr) void Field_datetime::store_time(TIME *ltime,timestamp_type type) { longlong tmp; - if (type == TIMESTAMP_DATE || type == TIMESTAMP_DATETIME) + if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME) tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*LL(1000000)+ (ltime->hour*10000L+ltime->minute*100+ltime->second)); else @@ -4103,7 +4106,7 @@ bool Field_datetime::get_date(TIME *ltime, uint fuzzydate) part1=(uint32) (tmp/LL(1000000)); part2=(uint32) (tmp - (ulonglong) part1*LL(1000000)); - ltime->time_type= TIMESTAMP_DATETIME; + ltime->time_type= MYSQL_TIMESTAMP_DATETIME; ltime->neg= 0; ltime->second_part= 0; ltime->second= (int) (part2%100); diff --git a/sql/item.cc b/sql/item.cc index 35e1312b540..0e9a73aacb2 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -228,8 +228,8 @@ bool Item::get_date(TIME *ltime,uint fuzzydate) char buff[40]; String tmp(buff,sizeof(buff), &my_charset_bin),*res; if (!(res=val_str(&tmp)) || - str_to_TIME_with_warn(res->ptr(),res->length(),ltime,fuzzydate) <= - TIMESTAMP_DATETIME_ERROR) + str_to_datetime_with_warn(res->ptr(), res->length(), + ltime, fuzzydate) <= MYSQL_TIMESTAMP_ERROR) { bzero((char*) ltime,sizeof(*ltime)); return 1; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index a5ea72374c1..786bcf434ed 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -425,21 +425,21 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, str->append(month_names[l_time->month-1],3); break; case 'W': - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; weekday= calc_weekday(calc_daynr(l_time->year,l_time->month, l_time->day),0); str->append(day_names[weekday]); break; case 'a': - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; weekday=calc_weekday(calc_daynr(l_time->year,l_time->month, l_time->day),0); str->append(day_names[weekday],3); break; case 'D': - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; length= int10_to_str(l_time->day, intbuff, 10) - intbuff; str->append_with_prefill(intbuff, length, 1, '0'); @@ -507,7 +507,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, str->append_with_prefill(intbuff, length, 2, '0'); break; case 'j': - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; length= int10_to_str(calc_daynr(l_time->year,l_time->month, l_time->day) - @@ -555,7 +555,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, case 'u': { uint year; - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; length= int10_to_str(calc_week(l_time, (*ptr) == 'U' ? @@ -569,7 +569,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, case 'V': { uint year; - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; length= int10_to_str(calc_week(l_time, ((*ptr) == 'V' ? @@ -584,7 +584,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, case 'X': { uint year; - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; (void) calc_week(l_time, ((*ptr) == 'X' ? @@ -596,7 +596,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time, } break; case 'w': - if (type == TIMESTAMP_TIME) + if (type == MYSQL_TIMESTAMP_TIME) return 1; weekday=calc_weekday(calc_daynr(l_time->year,l_time->month, l_time->day),1); @@ -1107,7 +1107,7 @@ int Item_date::save_in_field(Field *field, bool no_conversions) if (get_date(<ime, TIME_FUZZY_DATE)) return set_field_to_null(field); field->set_notnull(); - field->store_time(<ime, TIMESTAMP_DATE); + field->store_time(<ime, MYSQL_TIMESTAMP_DATE); return 0; } @@ -1129,7 +1129,7 @@ bool Item_func_from_days::get_date(TIME *ltime, uint fuzzy_date) return 1; bzero(ltime, sizeof(TIME)); get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day); - ltime->time_type= TIMESTAMP_DATE; + ltime->time_type= MYSQL_TIMESTAMP_DATE; return 0; } @@ -1144,7 +1144,7 @@ void Item_func_curdate::fix_length_and_dec() /* We don't need to set second_part and neg because they already 0 */ ltime.hour= ltime.minute= ltime.second= 0; - ltime.time_type=TIMESTAMP_DATE; + ltime.time_type= MYSQL_TIMESTAMP_DATE; value= (longlong) TIME_to_ulonglong_date(<ime); } @@ -1308,7 +1308,7 @@ bool Item_func_now::get_date(TIME *res, int Item_func_now::save_in_field(Field *to, bool no_conversions) { to->set_notnull(); - to->store_time(<ime,TIMESTAMP_DATETIME); + to->store_time(<ime, MYSQL_TIMESTAMP_DATETIME); return 0; } @@ -1494,7 +1494,9 @@ String *Item_func_date_format::val_str(String *str) /* Create the result string */ if (!make_date_time(&date_time_format, &l_time, - is_time_format ? TIMESTAMP_TIME : TIMESTAMP_DATE, str)) + is_time_format ? MYSQL_TIMESTAMP_TIME : + MYSQL_TIMESTAMP_DATE, + str)) return str; null_date: @@ -1713,7 +1715,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date) case INTERVAL_DAY_HOUR: { longlong sec, days, daynr, microseconds, extra_sec; - ltime->time_type=TIMESTAMP_DATETIME; // Return full date + ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date microseconds= ltime->second_part + sign*interval.second_part; extra_sec= microseconds/1000000L; microseconds= microseconds%1000000L; @@ -1798,7 +1800,7 @@ String *Item_date_add_interval::val_str(String *str) if (Item_date_add_interval::get_date(<ime,0)) return 0; - if (ltime.time_type == TIMESTAMP_DATE) + if (ltime.time_type == MYSQL_TIMESTAMP_DATE) format= DATE_ONLY; else if (ltime.second_part) format= DATE_TIME_MICROSECOND; @@ -1821,7 +1823,7 @@ longlong Item_date_add_interval::val_int() if (Item_date_add_interval::get_date(<ime,0)) return (longlong) 0; date = (ltime.year*100L + ltime.month)*100L + ltime.day; - return ltime.time_type == TIMESTAMP_DATE ? date : + return ltime.time_type == MYSQL_TIMESTAMP_DATE ? date : ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second; } @@ -2069,7 +2071,7 @@ String *Item_datetime_typecast::val_str(String *str) bool Item_time_typecast::get_time(TIME *ltime) { bool res= get_arg0_time(ltime); - ltime->time_type= TIMESTAMP_TIME; + ltime->time_type= MYSQL_TIMESTAMP_TIME; return res; } @@ -2092,7 +2094,7 @@ String *Item_time_typecast::val_str(String *str) bool Item_date_typecast::get_date(TIME *ltime, uint fuzzy_date) { bool res= get_arg0_date(ltime,1); - ltime->time_type= TIMESTAMP_DATE; + ltime->time_type= MYSQL_TIMESTAMP_DATE; return res; } @@ -2198,17 +2200,17 @@ String *Item_func_add_time::val_str(String *str) { if (get_arg0_date(&l_time1,1) || args[1]->get_time(&l_time2) || - l_time1.time_type == TIMESTAMP_TIME || - l_time2.time_type != TIMESTAMP_TIME) + l_time1.time_type == MYSQL_TIMESTAMP_TIME || + l_time2.time_type != MYSQL_TIMESTAMP_TIME) goto null_date; } else // ADDTIME function { if (args[0]->get_time(&l_time1) || args[1]->get_time(&l_time2) || - l_time2.time_type == TIMESTAMP_DATETIME) + l_time2.time_type == MYSQL_TIMESTAMP_DATETIME) goto null_date; - is_time= (l_time1.time_type == TIMESTAMP_TIME); + is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME); if (is_time && (l_time2.neg == l_time1.neg && l_time1.neg)) l_time3.neg= 1; } @@ -2324,7 +2326,7 @@ String *Item_func_timediff::val_str(String *str) if (l_time1.neg != l_time2.neg) l_sign= -l_sign; - if (l_time1.time_type == TIMESTAMP_TIME) // Time value + if (l_time1.time_type == MYSQL_TIMESTAMP_TIME) // Time value days= l_time1.day - l_sign*l_time2.day; else // DateTime value days= (calc_daynr((uint) l_time1.year, @@ -2466,13 +2468,13 @@ void Item_func_get_format::print(String *str) str->append('('); switch (type) { - case TIMESTAMP_DATE: + case MYSQL_TIMESTAMP_DATE: str->append("DATE, "); break; - case TIMESTAMP_DATETIME: + case MYSQL_TIMESTAMP_DATETIME: str->append("DATETIME, "); break; - case TIMESTAMP_TIME: + case MYSQL_TIMESTAMP_TIME: str->append("TIME, "); break; default: @@ -2555,25 +2557,25 @@ void Item_func_str_to_date::fix_length_and_dec() decimals=0; cached_field_type= MYSQL_TYPE_STRING; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; - cached_timestamp_type= TIMESTAMP_NONE; + cached_timestamp_type= MYSQL_TIMESTAMP_NONE; if ((const_item= args[1]->const_item())) { format= args[1]->val_str(&format_str); cached_format_type= check_result_type(format->ptr(), format->length()); switch (cached_format_type) { case DATE_ONLY: - cached_timestamp_type= TIMESTAMP_DATE; + cached_timestamp_type= MYSQL_TIMESTAMP_DATE; cached_field_type= MYSQL_TYPE_DATE; max_length= MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; break; case TIME_ONLY: case TIME_MICROSECOND: - cached_timestamp_type= TIMESTAMP_TIME; + cached_timestamp_type= MYSQL_TIMESTAMP_TIME; cached_field_type= MYSQL_TYPE_TIME; max_length= MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; break; default: - cached_timestamp_type= TIMESTAMP_DATETIME; + cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME; cached_field_type= MYSQL_TYPE_DATETIME; break; } @@ -2599,7 +2601,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) if (extract_date_time(&date_time_format, val->ptr(), val->length(), ltime, cached_timestamp_type)) goto null_date; - if (cached_timestamp_type == TIMESTAMP_TIME && ltime->day) + if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day) { /* Day part for time type can be nonzero value and so @@ -2640,6 +2642,6 @@ bool Item_func_last_day::get_date(TIME *ltime, uint fuzzy_date) ltime->day= days_in_month[month_idx]; if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366) ltime->day= 29; - ltime->time_type= TIMESTAMP_DATE; + ltime->time_type= MYSQL_TIMESTAMP_DATE; return 0; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index db8d534064d..b4431089fa1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -18,6 +18,7 @@ #include <mysql_version.h> #include <mysql_embed.h> #include <my_sys.h> +#include <my_time.h> #include <m_string.h> #include <hash.h> #include <signal.h> @@ -1001,12 +1002,9 @@ void get_date_from_daynr(long daynr,uint *year, uint *month, void init_time(void); my_time_t my_system_gmt_sec(const TIME *, long *current_timezone, bool *not_exist); my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *not_exist); -bool str_to_time(const char *str,uint length,TIME *l_time, int *was_cut); bool str_to_time_with_warn(const char *str,uint length,TIME *l_time); -timestamp_type str_to_TIME(const char *str, uint length, TIME *l_time, - uint flags, int *was_cut); -timestamp_type str_to_TIME_with_warn(const char *str, uint length, - TIME *l_time, uint flags); +timestamp_type str_to_datetime_with_warn(const char *str, uint length, + TIME *l_time, uint flags); longlong number_to_TIME(longlong nr, TIME *time_res, bool fuzzy_date, int *was_cut); void localtime_to_TIME(TIME *to, struct tm *from); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3c23ecd3c3d..71c6bac4500 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -309,15 +309,6 @@ ulong my_bind_addr; /* the address we bind to */ volatile ulong cached_thread_count= 0; double log_10[32]; /* 10 potences */ -ulonglong log_10_int[20]= -{ - 1, 10, 100, 1000, 10000UL, 100000UL, 1000000UL, 10000000UL, - ULL(100000000), ULL(1000000000), ULL(10000000000), ULL(100000000000), - ULL(1000000000000), ULL(10000000000000), ULL(100000000000000), - ULL(1000000000000000), ULL(10000000000000000), ULL(100000000000000000), - ULL(1000000000000000000), ULL(10000000000000000000) -}; - time_t start_time; char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30]; @@ -4928,18 +4919,18 @@ The minimum value for this variable is 4096.", 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0}, { "date-format", OPT_DATE_FORMAT, "The DATE format (For future).", - (gptr*) &opt_date_time_formats[TIMESTAMP_DATE], - (gptr*) &opt_date_time_formats[TIMESTAMP_DATE], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "datetime-format", OPT_DATETIME_FORMAT, "The DATETIME/TIMESTAMP format (for future).", - (gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME], - (gptr*) &opt_date_time_formats[TIMESTAMP_DATETIME], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME], 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, { "time-format", OPT_TIME_FORMAT, "The TIME format (for future).", - (gptr*) &opt_date_time_formats[TIMESTAMP_TIME], - (gptr*) &opt_date_time_formats[TIMESTAMP_TIME], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -6045,11 +6036,11 @@ static void get_options(int argc,char **argv) if (opt_log_queries_not_using_indexes) opt_specialflag|= SPECIAL_LOG_QUERIES_NOT_USING_INDEXES; - if (init_global_datetime_format(TIMESTAMP_DATE, + if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE, &global_system_variables.date_format) || - init_global_datetime_format(TIMESTAMP_TIME, + init_global_datetime_format(MYSQL_TIMESTAMP_TIME, &global_system_variables.time_format) || - init_global_datetime_format(TIMESTAMP_DATETIME, + init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME, &global_system_variables.datetime_format)) exit(1); } diff --git a/sql/set_var.cc b/sql/set_var.cc index aa45afc3c30..840a7ae075a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -351,13 +351,13 @@ sys_var_long_ptr sys_innodb_max_dirty_pages_pct("innodb_max_dirty_pages_p sys_var_thd_date_time_format sys_time_format("time_format", &SV::time_format, - TIMESTAMP_TIME); + MYSQL_TIMESTAMP_TIME); sys_var_thd_date_time_format sys_date_format("date_format", &SV::date_format, - TIMESTAMP_DATE); + MYSQL_TIMESTAMP_DATE); sys_var_thd_date_time_format sys_datetime_format("datetime_format", &SV::datetime_format, - TIMESTAMP_DATETIME); + MYSQL_TIMESTAMP_DATETIME); /* Variables that are bits in THD */ diff --git a/sql/set_var.h b/sql/set_var.h index c2b4ca34b2d..a51e44285d6 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -669,7 +669,7 @@ public: class sys_var_thd_date_time_format :public sys_var_thd { DATE_TIME_FORMAT *SV::*offset; - enum timestamp_type date_time_type; + timestamp_type date_time_type; public: sys_var_thd_date_time_format(const char *name_arg, DATE_TIME_FORMAT *SV::*offset_arg, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 09b442f8dfc..3e88a2ecd4f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -361,7 +361,7 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len) } tm.day= tm.year= tm.month= 0; - param->set_time(&tm, TIMESTAMP_TIME, + param->set_time(&tm, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } *pos+= length; @@ -396,7 +396,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0; - param->set_time(&tm, TIMESTAMP_DATETIME, + param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } *pos+= length; @@ -423,7 +423,7 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) tm.second_part= 0; tm.neg= 0; - param->set_time(&tm, TIMESTAMP_DATE, + param->set_time(&tm, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } *pos+= length; @@ -432,58 +432,25 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) #else/*!EMBEDDED_LIBRARY*/ void set_param_time(Item_param *param, uchar **pos, ulong len) { - TIME tm; MYSQL_TIME *to= (MYSQL_TIME*)*pos; - - tm.second_part= to->second_part; - - tm.day= to->day; - tm.hour= to->hour; - tm.minute= to->minute; - tm.second= to->second; - - tm.year= tm.month= 0; - tm.neg= to->neg; - param->set_time(&tm, TIMESTAMP_TIME, + param->set_time(to, MYSQL_TIMESTAMP_TIME, MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } void set_param_datetime(Item_param *param, uchar **pos, ulong len) { - TIME tm; MYSQL_TIME *to= (MYSQL_TIME*)*pos; - tm.second_part= to->second_part; - - tm.day= to->day; - tm.hour= to->hour; - tm.minute= to->minute; - tm.second= to->second; - tm.year= to->year; - tm.month= to->month; - tm.neg= 0; - - param->set_time(&tm, TIMESTAMP_DATETIME, + param->set_time(to, MYSQL_TIMESTAMP_DATETIME, MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } void set_param_date(Item_param *param, uchar **pos, ulong len) { - TIME tm; MYSQL_TIME *to= (MYSQL_TIME*)*pos; - - tm.second_part= to->second_part; - - tm.day= to->day; - tm.year= to->year; - tm.month= to->month; - tm.neg= 0; - tm.hour= tm.minute= tm.second= 0; - tm.second_part= 0; - tm.neg= 0; - param->set_time(&tm, TIMESTAMP_DATE, + param->set_time(to, MYSQL_TIMESTAMP_DATE, MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } #endif /*!EMBEDDED_LIBRARY*/ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 49ef2f29dfc..5fbb84d202e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3530,9 +3530,9 @@ interval: | YEAR_SYM { $$=INTERVAL_YEAR; }; date_time_type: - DATE_SYM {$$=TIMESTAMP_DATE;} - | TIME_SYM {$$=TIMESTAMP_TIME;} - | DATETIME {$$=TIMESTAMP_DATETIME;}; + DATE_SYM {$$=MYSQL_TIMESTAMP_DATE;} + | TIME_SYM {$$=MYSQL_TIMESTAMP_TIME;} + | DATETIME {$$=MYSQL_TIMESTAMP_DATETIME;}; table_alias: /* empty */ diff --git a/sql/structs.h b/sql/structs.h index ee231186e1a..c30d85f59cb 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -130,23 +130,14 @@ typedef struct st_read_record { /* Parameter to read_record */ } READ_RECORD; -enum timestamp_type -{ - TIMESTAMP_NONE= -2, TIMESTAMP_DATETIME_ERROR= -1, - TIMESTAMP_DATE= 0, TIMESTAMP_DATETIME= 1, TIMESTAMP_TIME= 2 -}; - -/* Parameters to str_to_TIME */ -#define TIME_FUZZY_DATE 1 -#define TIME_DATETIME_ONLY 2 - - -typedef struct st_time { - uint year,month,day,hour,minute,second; - ulong second_part; - bool neg; - timestamp_type time_type; -} TIME; +/* + Originally MySQL used TIME structure inside server only, but since + 4.1 it's exported to user in the new client API. Define aliases for + new names to keep existing code simple. +*/ + +typedef struct st_mysql_time TIME; +typedef enum enum_mysql_timestamp_type timestamp_type; typedef struct { diff --git a/sql/time.cc b/sql/time.cc index b5550b98e8c..132612e53c5 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -345,364 +345,19 @@ ulong convert_month_to_period(ulong month) } -/* Position for YYYY-DD-MM HH-MM-DD.FFFFFF AM in default format */ - -static uchar internal_format_positions[]= -{0, 1, 2, 3, 4, 5, 6, (uchar) 255}; - -static char time_separator=':'; - -/* - Convert a timestamp string to a TIME value. - - SYNOPSIS - str_to_TIME() - str String to parse - length Length of string - l_time Date is stored here - flags Bitmap of following items - TIME_FUZZY_DATE Set if we should allow partial dates - TIME_DATETIME_ONLY Set if we only allow full datetimes. - was_cut Set to 1 if value was cut during conversion or to 0 - otherwise. - - DESCRIPTION - At least the following formats are recogniced (based on number of digits) - YYMMDD, YYYYMMDD, YYMMDDHHMMSS, YYYYMMDDHHMMSS - YY-MM-DD, YYYY-MM-DD, YY-MM-DD HH.MM.SS - YYYYMMDDTHHMMSS where T is a the character T (ISO8601) - Also dates where all parts are zero are allowed - - The second part may have an optional .###### fraction part. - - NOTES - This function should work with a format position vector as long as the - following things holds: - - All date are kept together and all time parts are kept together - - Date and time parts must be separated by blank - - Second fractions must come after second part and be separated - by a '.'. (The second fractions are optional) - - AM/PM must come after second fractions (or after seconds if no fractions) - - Year must always been specified. - - If time is before date, then we will use datetime format only if - the argument consist of two parts, separated by space. - Otherwise we will assume the argument is a date. - - The hour part must be specified in hour-minute-second order. - - RETURN VALUES - TIMESTAMP_NONE String wasn't a timestamp, like - [DD [HH:[MM:[SS]]]].fraction. - l_time is not changed. - TIMESTAMP_DATE DATE string (YY MM and DD parts ok) - TIMESTAMP_DATETIME Full timestamp - TIMESTAMP_DATETIME_ERROR Timestamp with wrong values. - All elements in l_time is set to 0 -*/ - -#define MAX_DATE_PARTS 8 - -timestamp_type -str_to_TIME(const char *str, uint length, TIME *l_time, uint flags, - int *was_cut) -{ - uint field_length, year_length, digits, i, number_of_fields; - uint date[MAX_DATE_PARTS], date_len[MAX_DATE_PARTS]; - uint add_hours= 0, start_loop; - ulong not_zero_date, allow_space; - bool is_internal_format; - const char *pos, *last_field_pos; - const char *end=str+length; - const uchar *format_position; - bool found_delimitier= 0, found_space= 0; - uint frac_pos, frac_len; - DBUG_ENTER("str_to_TIME"); - DBUG_PRINT("ENTER",("str: %.*s",length,str)); - - LINT_INIT(field_length); - LINT_INIT(year_length); - LINT_INIT(last_field_pos); - - *was_cut= 0; - - // Skip space at start - for (; str != end && my_isspace(&my_charset_latin1, *str) ; str++) - ; - if (str == end || ! my_isdigit(&my_charset_latin1, *str)) - { - *was_cut= 1; - DBUG_RETURN(TIMESTAMP_NONE); - } - - is_internal_format= 0; - /* This has to be changed if want to activate different timestamp formats */ - format_position= internal_format_positions; - - /* - Calculate number of digits in first part. - If length= 8 or >= 14 then year is of format YYYY. - (YYYY-MM-DD, YYYYMMDD, YYYYYMMDDHHMMSS) - */ - for (pos=str; pos != end && my_isdigit(&my_charset_latin1,*pos) ; pos++) - ; - - digits= (uint) (pos-str); - start_loop= 0; // Start of scan loop - date_len[format_position[0]]= 0; // Length of year field - if (pos == end) - { - /* Found date in internal format (only numbers like YYYYMMDD) */ - year_length= (digits == 4 || digits == 8 || digits >= 14) ? 4 : 2; - field_length=year_length-1; - is_internal_format= 1; - format_position= internal_format_positions; - } - else - { - if (format_position[0] >= 3) // If year is after HHMMDD - { - /* - If year is not in first part then we have to determinate if we got - a date field or a datetime field. - We do this by checking if there is two numbers separated by - space in the input. - */ - while (pos < end && !my_isspace(&my_charset_latin1, *pos)) - pos++; - while (pos < end && !my_isdigit(&my_charset_latin1, *pos)) - pos++; - if (pos == end) - { - if (flags & TIME_DATETIME_ONLY) - { - *was_cut= 1; - DBUG_RETURN(TIMESTAMP_NONE); // Can't be a full datetime - } - /* Date field. Set hour, minutes and seconds to 0 */ - date[0]= date[1]= date[2]= date[3]= date[4]= 0; - start_loop= 5; // Start with first date part - } - } - } - - /* - Only allow space in the first "part" of the datetime field and: - - after days, part seconds - - before and after AM/PM (handled by code later) - - 2003-03-03 20:00:20 AM - 20:00:20.000000 AM 03-03-2000 - */ - i= max((uint) format_position[0], (uint) format_position[1]); - set_if_bigger(i, (uint) format_position[2]); - allow_space= ((1 << i) | (1 << format_position[6])); - allow_space&= (1 | 2 | 4 | 8); - - not_zero_date= 0; - for (i = start_loop; - i < MAX_DATE_PARTS-1 && str != end && - my_isdigit(&my_charset_latin1,*str); - i++) - { - const char *start= str; - ulong tmp_value= (uint) (uchar) (*str++ - '0'); - while (str != end && my_isdigit(&my_charset_latin1,str[0]) && - (!is_internal_format || field_length--)) - { - tmp_value=tmp_value*10 + (ulong) (uchar) (*str - '0'); - str++; - } - date_len[i]= (uint) (str - start); - if (tmp_value > 999999) // Impossible date part - { - *was_cut= 1; - DBUG_RETURN(TIMESTAMP_NONE); - } - date[i]=tmp_value; - not_zero_date|= tmp_value; - - /* Length-1 of next field */ - field_length= format_position[i+1] == 0 ? 3 : 1; - - if ((last_field_pos= str) == end) - { - i++; // Register last found part - break; - } - /* Allow a 'T' after day to allow CCYYMMDDT type of fields */ - if (i == format_position[2] && *str == 'T') - { - str++; // ISO8601: CCYYMMDDThhmmss - continue; - } - if (i == format_position[5]) // Seconds - { - if (*str == '.') // Followed by part seconds - { - str++; - field_length= 5; // 5 digits after first (=6) - } - continue; - - /* No part seconds */ - date[++i]= 0; - } - while (str != end && - (my_ispunct(&my_charset_latin1,*str) || - my_isspace(&my_charset_latin1,*str))) - { - if (my_isspace(&my_charset_latin1,*str)) - { - if (!(allow_space & (1 << i))) - { - *was_cut= 1; - DBUG_RETURN(TIMESTAMP_NONE); - } - found_space= 1; - } - str++; - found_delimitier= 1; // Should be a 'normal' date - } - /* Check if next position is AM/PM */ - if (i == format_position[6]) // Seconds, time for AM/PM - { - i++; // Skip AM/PM part - if (format_position[7] != 255) // If using AM/PM - { - if (str+2 <= end && (str[1] == 'M' || str[1] == 'm')) - { - if (str[0] == 'p' || str[0] == 'P') - add_hours= 12; - else if (str[0] != 'a' || str[0] != 'A') - continue; // Not AM/PM - str+= 2; // Skip AM/PM - /* Skip space after AM/PM */ - while (str != end && my_isspace(&my_charset_latin1,*str)) - str++; - } - } - } - last_field_pos= str; - } - if (found_delimitier && !found_space && (flags & TIME_DATETIME_ONLY)) - { - *was_cut= 1; - DBUG_RETURN(TIMESTAMP_NONE); // Can't be a datetime - } - - str= last_field_pos; - - number_of_fields= i - start_loop; - while (i < MAX_DATE_PARTS) - { - date_len[i]= 0; - date[i++]= 0; - } - - if (!is_internal_format) - { - year_length= date_len[(uint) format_position[0]]; - if (!year_length) // Year must be specified - { - *was_cut= 1; - DBUG_RETURN(TIMESTAMP_NONE); - } - - l_time->year= date[(uint) format_position[0]]; - l_time->month= date[(uint) format_position[1]]; - l_time->day= date[(uint) format_position[2]]; - l_time->hour= date[(uint) format_position[3]]; - l_time->minute= date[(uint) format_position[4]]; - l_time->second= date[(uint) format_position[5]]; - - frac_pos= (uint) format_position[6]; - frac_len= date_len[frac_pos]; - if (frac_len < 6) - date[frac_pos]*= (uint) log_10_int[6 - frac_len]; - l_time->second_part= date[frac_pos]; - - if (format_position[7] != (uchar) 255) - { - if (l_time->hour > 12) - { - *was_cut= 1; - goto err; - } - l_time->hour= l_time->hour%12 + add_hours; - } - } - else - { - l_time->year= date[0]; - l_time->month= date[1]; - l_time->day= date[2]; - l_time->hour= date[3]; - l_time->minute= date[4]; - l_time->second= date[5]; - if (date_len[6] < 6) - date[6]*= (uint) log_10_int[6 - date_len[6]]; - l_time->second_part=date[6]; - } - l_time->neg= 0; - - if (year_length == 2 && i >= format_position[1] && i >=format_position[2] && - (l_time->month || l_time->day)) - l_time->year+= (l_time->year < YY_PART_YEAR ? 2000 : 1900); - - if (number_of_fields < 3 || l_time->month > 12 || - l_time->day > 31 || l_time->hour > 23 || - l_time->minute > 59 || l_time->second > 59 || - (!(flags & TIME_FUZZY_DATE) && (l_time->month == 0 || l_time->day == 0))) - { - /* Only give warning for a zero date if there is some garbage after */ - if (!not_zero_date) // If zero date - { - for (; str != end ; str++) - { - if (!my_isspace(&my_charset_latin1, *str)) - { - not_zero_date= 1; // Give warning - break; - } - } - } - if (not_zero_date) - *was_cut= 1; - goto err; - } - - l_time->time_type= (number_of_fields <= 3 ? - TIMESTAMP_DATE : TIMESTAMP_DATETIME); - - for (; str != end ; str++) - { - if (!my_isspace(&my_charset_latin1,*str)) - { - *was_cut= 1; - break; - } - } - - DBUG_RETURN(l_time->time_type= - (number_of_fields <= 3 ? TIMESTAMP_DATE : TIMESTAMP_DATETIME)); - -err: - bzero((char*) l_time, sizeof(*l_time)); - DBUG_RETURN(TIMESTAMP_DATETIME_ERROR); -} - - /* Convert a timestamp string to a TIME value and produce a warning if string was truncated during conversion. NOTE - See description of str_to_TIME() for more information. + See description of str_to_datetime() for more information. */ timestamp_type -str_to_TIME_with_warn(const char *str, uint length, TIME *l_time, uint flags) +str_to_datetime_with_warn(const char *str, uint length, TIME *l_time, + uint flags) { int was_cut; - timestamp_type ts_type= str_to_TIME(str, length, l_time, flags, &was_cut); + timestamp_type ts_type= str_to_datetime(str, length, l_time, flags, &was_cut); if (was_cut) make_truncated_value_warning(current_thd, str, length, ts_type); return ts_type; @@ -748,190 +403,6 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *in_dst_time_gap) /* - Convert a time string to a TIME struct. - - SYNOPSIS - str_to_time() - str A string in full TIMESTAMP format or - [-] DAYS [H]H:MM:SS, [H]H:MM:SS, [M]M:SS, [H]HMMSS, - [M]MSS or [S]S - There may be an optional [.second_part] after seconds - length Length of str - l_time Store result here - was_cut Set to 1 if value was cut during conversion or to 0 - otherwise. - - NOTES - Because of the extra days argument, this function can only - work with times where the time arguments are in the above order. - - RETURN - 0 ok - 1 error -*/ - -bool str_to_time(const char *str, uint length, TIME *l_time, int *was_cut) -{ - long date[5],value; - const char *end=str+length, *end_of_days; - bool found_days,found_hours; - uint state; - - l_time->neg=0; - *was_cut= 0; - for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) - length--; - if (str != end && *str == '-') - { - l_time->neg=1; - str++; - length--; - } - if (str == end) - return 1; - - /* Check first if this is a full TIMESTAMP */ - if (length >= 12) - { // Probably full timestamp - enum timestamp_type res= str_to_TIME(str,length,l_time, - (TIME_FUZZY_DATE | - TIME_DATETIME_ONLY), - was_cut); - if ((int) res >= (int) TIMESTAMP_DATETIME_ERROR) - return res == TIMESTAMP_DATETIME_ERROR; - /* We need to restore was_cut flag since str_to_TIME can modify it */ - *was_cut= 0; - } - - /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ - for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++) - value=value*10L + (long) (*str - '0'); - - /* Skip all space after 'days' */ - end_of_days= str; - for (; str != end && my_isspace(&my_charset_latin1, str[0]) ; str++) - ; - - LINT_INIT(state); - found_days=found_hours=0; - if ((uint) (end-str) > 1 && str != end_of_days && - my_isdigit(&my_charset_latin1, *str)) - { // Found days part - date[0]= value; - state= 1; // Assume next is hours - found_days= 1; - } - else if ((end-str) > 1 && *str == time_separator && - my_isdigit(&my_charset_latin1, str[1])) - { - date[0]=0; // Assume we found hours - date[1]=value; - state=2; - found_hours=1; - str++; // skip ':' - } - else - { - /* String given as one number; assume HHMMSS format */ - date[0]= 0; - date[1]= value/10000; - date[2]= value/100 % 100; - date[3]= value % 100; - state=4; - goto fractional; - } - - /* Read hours, minutes and seconds */ - for (;;) - { - for (value=0; str != end && my_isdigit(&my_charset_latin1,*str) ; str++) - value=value*10L + (long) (*str - '0'); - date[state++]=value; - if (state == 4 || (end-str) < 2 || *str != time_separator || - !my_isdigit(&my_charset_latin1,str[1])) - break; - str++; // Skip time_separator (':') - } - - if (state != 4) - { // Not HH:MM:SS - /* Fix the date to assume that seconds was given */ - if (!found_hours && !found_days) - { - bmove_upp((char*) (date+4), (char*) (date+state), - sizeof(long)*(state-1)); - bzero((char*) date, sizeof(long)*(4-state)); - } - else - bzero((char*) (date+state), sizeof(long)*(4-state)); - } - -fractional: - /* Get fractional second part */ - if ((end-str) >= 2 && *str == '.' && my_isdigit(&my_charset_latin1,str[1])) - { - uint field_length=5; - str++; value=(uint) (uchar) (*str - '0'); - while (++str != end && - my_isdigit(&my_charset_latin1,str[0]) && - field_length--) - value=value*10 + (uint) (uchar) (*str - '0'); - if (field_length) - value*= (long) log_10_int[field_length]; - date[4]=value; - } - else - date[4]=0; - - if (internal_format_positions[7] != 255) - { - /* Read a possible AM/PM */ - while (str != end && my_isspace(&my_charset_latin1, *str)) - str++; - if (str+2 <= end && (str[1] == 'M' || str[1] == 'm')) - { - if (str[0] == 'p' || str[0] == 'P') - { - str+= 2; - date[1]= date[1]%12 + 12; - } - else if (str[0] == 'a' || str[0] == 'A') - str+=2; - } - } - - /* Some simple checks */ - if (date[2] >= 60 || date[3] >= 60) - { - *was_cut= 1; - return 1; - } - l_time->year= 0; // For protocol::store_time - l_time->month= 0; - l_time->day= date[0]; - l_time->hour= date[1]; - l_time->minute= date[2]; - l_time->second= date[3]; - l_time->second_part= date[4]; - l_time->time_type= TIMESTAMP_TIME; - - /* Check if there is garbage at end of the TIME specification */ - if (str != end) - { - do - { - if (!my_isspace(&my_charset_latin1,*str)) - { - *was_cut= 1; - break; - } - } while (++str != end); - } - return 0; -} - - -/* Convert a time string to a TIME struct and produce a warning if string was cut during conversion. @@ -944,7 +415,7 @@ str_to_time_with_warn(const char *str, uint length, TIME *l_time) int was_cut; bool ret_val= str_to_time(str, length, l_time, &was_cut); if (was_cut) - make_truncated_value_warning(current_thd, str, length, TIMESTAMP_TIME); + make_truncated_value_warning(current_thd, str, length, MYSQL_TIMESTAMP_TIME); return ret_val; } @@ -1210,10 +681,10 @@ bool parse_date_time_format(timestamp_type format_type, The last test is to ensure that %p is used if and only if it's needed. */ - if ((format_type == TIMESTAMP_DATETIME && + if ((format_type == MYSQL_TIMESTAMP_DATETIME && !test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) || - (format_type == TIMESTAMP_DATE && part_map != (1 | 2 | 4)) || - (format_type == TIMESTAMP_TIME && + (format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) || + (format_type == MYSQL_TIMESTAMP_TIME && !test_all_bits(part_map, 8 | 16 | 32)) || !allow_separator || // %option should be last (need_p && dt_pos[6] +1 != dt_pos[7]) || @@ -1256,10 +727,10 @@ bool parse_date_time_format(timestamp_type format_type, format_str= 0; switch (format_type) { - case TIMESTAMP_DATE: + case MYSQL_TIMESTAMP_DATE: format_str= known_date_time_formats[INTERNAL_FORMAT].date_format; /* fall through */ - case TIMESTAMP_TIME: + case MYSQL_TIMESTAMP_TIME: if (!format_str) format_str=known_date_time_formats[INTERNAL_FORMAT].time_format; @@ -1274,7 +745,7 @@ bool parse_date_time_format(timestamp_type format_type, return 0; if (separator_map == (1 | 2)) { - if (format_type == TIMESTAMP_TIME) + if (format_type == MYSQL_TIMESTAMP_TIME) { if (*(format+2) != *(format+5)) break; // Error @@ -1284,7 +755,7 @@ bool parse_date_time_format(timestamp_type format_type, return 0; } break; - case TIMESTAMP_DATETIME: + case MYSQL_TIMESTAMP_DATETIME: /* If there is no separators, allow the internal format as we can read this. If separators are used, they must be between each part. @@ -1403,11 +874,11 @@ const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format, timestamp_type type) { switch (type) { - case TIMESTAMP_DATE: + case MYSQL_TIMESTAMP_DATE: return format->date_format; - case TIMESTAMP_DATETIME: + case MYSQL_TIMESTAMP_DATETIME: return format->datetime_format; - case TIMESTAMP_TIME: + case MYSQL_TIMESTAMP_TIME: return format->time_format; default: DBUG_ASSERT(0); // Impossible @@ -1489,13 +960,13 @@ void make_truncated_value_warning(THD *thd, const char *str_val, str.append('\0'); switch (time_type) { - case TIMESTAMP_DATE: + case MYSQL_TIMESTAMP_DATE: type_str= "date"; break; - case TIMESTAMP_TIME: + case MYSQL_TIMESTAMP_TIME: type_str= "time"; break; - case TIMESTAMP_DATETIME: // FALLTHROUGH + case MYSQL_TIMESTAMP_DATETIME: // FALLTHROUGH default: type_str= "datetime"; break; @@ -1565,14 +1036,14 @@ ulonglong TIME_to_ulonglong_time(const TIME *time) ulonglong TIME_to_ulonglong(const TIME *time) { switch (time->time_type) { - case TIMESTAMP_DATETIME: + case MYSQL_TIMESTAMP_DATETIME: return TIME_to_ulonglong_datetime(time); - case TIMESTAMP_DATE: + case MYSQL_TIMESTAMP_DATE: return TIME_to_ulonglong_date(time); - case TIMESTAMP_TIME: + case MYSQL_TIMESTAMP_TIME: return TIME_to_ulonglong_time(time); - case TIMESTAMP_NONE: - case TIMESTAMP_DATETIME_ERROR: + case MYSQL_TIMESTAMP_NONE: + case MYSQL_TIMESTAMP_ERROR: return ULL(0); default: DBUG_ASSERT(0); @@ -1595,17 +1066,17 @@ ulonglong TIME_to_ulonglong(const TIME *time) void TIME_to_string(const TIME *time, String *str) { switch (time->time_type) { - case TIMESTAMP_DATETIME: + case MYSQL_TIMESTAMP_DATETIME: make_datetime((DATE_TIME_FORMAT*) 0, time, str); break; - case TIMESTAMP_DATE: + case MYSQL_TIMESTAMP_DATE: make_date((DATE_TIME_FORMAT*) 0, time, str); break; - case TIMESTAMP_TIME: + case MYSQL_TIMESTAMP_TIME: make_time((DATE_TIME_FORMAT*) 0, time, str); break; - case TIMESTAMP_NONE: - case TIMESTAMP_DATETIME_ERROR: + case MYSQL_TIMESTAMP_NONE: + case MYSQL_TIMESTAMP_ERROR: str->length(0); str->set_charset(&my_charset_bin); break; diff --git a/sql/tztime.cc b/sql/tztime.cc index 0b0ae2839df..a62720f2eeb 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -584,7 +584,7 @@ sec_to_TIME(TIME * tmp, my_time_t t, long offset) /* filling MySQL specific TIME members */ tmp->neg= 0; tmp->second_part= 0; - tmp->time_type= TIMESTAMP_DATETIME; + tmp->time_type= MYSQL_TIMESTAMP_DATETIME; } @@ -1011,7 +1011,7 @@ Time_zone_system::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const localtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); - tmp->time_type= TIMESTAMP_DATETIME; + tmp->time_type= MYSQL_TIMESTAMP_DATETIME; } @@ -1094,7 +1094,7 @@ Time_zone_utc::gmt_sec_to_TIME(TIME *tmp, my_time_t t) const time_t tmp_t= (time_t)t; gmtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); - tmp->time_type= TIMESTAMP_DATETIME; + tmp->time_type= MYSQL_TIMESTAMP_DATETIME; } |