diff options
author | konstantin@mysql.com <> | 2004-12-16 03:15:06 +0300 |
---|---|---|
committer | konstantin@mysql.com <> | 2004-12-16 03:15:06 +0300 |
commit | 7216594f4f20b4f1df625cfd0f08a99d61486cc6 (patch) | |
tree | 056f73f48d150d91c8d24bee3a927dec746492bb /sql | |
parent | 24aa7e9ce7668489897bebbeac3b340e64799065 (diff) | |
download | mariadb-git-7216594f4f20b4f1df625cfd0f08a99d61486cc6.tar.gz |
Data truncation reporting implementation (libmysql) + post review
fixes. Still to do:
- deploy my_strtoll10 in limbysql.c
- add mysql_options option to switch MYSQL_DATA_TRUNCATED on and off.
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 28 | ||||
-rw-r--r-- | sql/field.h | 7 | ||||
-rw-r--r-- | sql/mysql_priv.h | 6 | ||||
-rw-r--r-- | sql/time.cc | 162 |
4 files changed, 26 insertions, 177 deletions
diff --git a/sql/field.cc b/sql/field.cc index dafb3dc25da..6f38bd3c85a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -467,11 +467,11 @@ bool Field::get_time(TIME *ltime) Needs to be changed if/when we want to support different time formats */ -void Field::store_time(TIME *ltime,timestamp_type type) +int Field::store_time(TIME *ltime, timestamp_type type) { char buff[MAX_DATE_STRING_REP_LENGTH]; uint length= (uint) my_TIME_to_str(ltime, buff); - store(buff, length, &my_charset_bin); + return store(buff, length, &my_charset_bin); } @@ -3089,7 +3089,7 @@ int Field_timestamp::store(longlong nr) bool in_dst_time_gap; THD *thd= table->in_use; - if (number_to_TIME(nr, &l_time, 0, &error)) + if (number_to_datetime(nr, &l_time, 0, &error)) { if (!(timestamp= TIME_to_timestamp(thd, &l_time, &in_dst_time_gap))) { @@ -3372,6 +3372,16 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) } +int Field_time::store_time(TIME *ltime, timestamp_type type) +{ + long tmp= ((ltime->month ? 0 : ltime->day * 24L) + ltime->hour) * 10000L + + (ltime->minute * 100 + ltime->second); + if (ltime->neg) + tmp= -tmp; + return Field_time::store((longlong) tmp); +} + + int Field_time::store(double nr) { long tmp; @@ -3953,17 +3963,20 @@ int Field_newdate::store(longlong nr) return error; } -void Field_newdate::store_time(TIME *ltime,timestamp_type type) +int Field_newdate::store_time(TIME *ltime,timestamp_type type) { long tmp; + int error= 0; if (type == MYSQL_TIMESTAMP_DATE || type == MYSQL_TIMESTAMP_DATETIME) tmp=ltime->year*16*32+ltime->month*32+ltime->day; else { tmp=0; + error= 1; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); } int3store(ptr,tmp); + return error; } bool Field_newdate::send_binary(Protocol *protocol) @@ -4112,7 +4125,7 @@ int Field_datetime::store(longlong nr) int error; longlong initial_nr= nr; - nr= number_to_TIME(nr, ¬_used, 1, &error); + nr= number_to_datetime(nr, ¬_used, 1, &error); if (error) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -4131,9 +4144,10 @@ int Field_datetime::store(longlong nr) } -void Field_datetime::store_time(TIME *ltime,timestamp_type type) +int Field_datetime::store_time(TIME *ltime,timestamp_type type) { longlong tmp; + int error= 0; /* We don't perform range checking here since values stored in TIME structure always fit into DATETIME range. @@ -4144,6 +4158,7 @@ void Field_datetime::store_time(TIME *ltime,timestamp_type type) else { tmp=0; + error= 1; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1); } #ifdef WORDS_BIGENDIAN @@ -4154,6 +4169,7 @@ void Field_datetime::store_time(TIME *ltime,timestamp_type type) else #endif longlongstore(ptr,tmp); + return error; } bool Field_datetime::send_binary(Protocol *protocol) diff --git a/sql/field.h b/sql/field.h index 4353780f9a4..e2411fb9400 100644 --- a/sql/field.h +++ b/sql/field.h @@ -96,7 +96,7 @@ public: virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0; virtual int store(double nr)=0; virtual int store(longlong nr)=0; - virtual void store_time(TIME *ltime,timestamp_type t_type); + virtual int store_time(TIME *ltime, timestamp_type t_type); virtual double val_real(void)=0; virtual longlong val_int(void)=0; inline String *val_str(String *str) { return val_str(str, str); } @@ -782,7 +782,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); - void store_time(TIME *ltime,timestamp_type type); + int store_time(TIME *ltime, timestamp_type type); void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } double val_real(void); longlong val_int(void); @@ -815,6 +815,7 @@ public: enum_field_types type() const { return FIELD_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } + int store_time(TIME *ltime, timestamp_type type); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); @@ -855,7 +856,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr); - void store_time(TIME *ltime,timestamp_type type); + int store_time(TIME *ltime, timestamp_type type); void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } double val_real(void); longlong val_int(void); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 91d15dc1125..4985a244824 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1139,8 +1139,6 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *not_exist); bool str_to_time_with_warn(const char *str,uint length,TIME *l_time); 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); void calc_time_from_sec(TIME *to, long seconds, long microseconds); @@ -1162,10 +1160,6 @@ void make_date(const DATE_TIME_FORMAT *format, const TIME *l_time, String *str); void make_time(const DATE_TIME_FORMAT *format, const TIME *l_time, String *str); -ulonglong TIME_to_ulonglong_datetime(const TIME *time); -ulonglong TIME_to_ulonglong_date(const TIME *time); -ulonglong TIME_to_ulonglong_time(const TIME *time); -ulonglong TIME_to_ulonglong(const TIME *time); int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(byte *,uint,char,char); diff --git a/sql/time.cc b/sql/time.cc index 562f9956ccc..f1d21915c23 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -263,95 +263,6 @@ str_to_time_with_warn(const char *str, uint length, TIME *l_time) /* - Convert datetime value specified as number to broken-down TIME - representation and form value of DATETIME type as side-effect. - - SYNOPSIS - number_to_TIME() - nr - datetime value as number - time_res - pointer for structure for broken-down representation - fuzzy_date - indicates whenever we allow fuzzy dates - was_cut - set ot 1 if there was some kind of error during - conversion or to 0 if everything was OK. - - DESCRIPTION - Convert a datetime value of formats YYMMDD, YYYYMMDD, YYMMDDHHMSS, - YYYYMMDDHHMMSS to broken-down TIME representation. Return value in - YYYYMMDDHHMMSS format as side-effect. - - This function also checks if datetime value fits in DATETIME range. - - RETURN VALUE - Datetime value in YYYYMMDDHHMMSS format. - If input value is not valid datetime value then 0 is returned. -*/ - -longlong number_to_TIME(longlong nr, TIME *time_res, bool fuzzy_date, - int *was_cut) -{ - long part1,part2; - - *was_cut= 0; - - if (nr == LL(0) || nr >= LL(10000101000000)) - goto ok; - if (nr < 101) - goto err; - if (nr <= (YY_PART_YEAR-1)*10000L+1231L) - { - nr= (nr+20000000L)*1000000L; // YYMMDD, year: 2000-2069 - goto ok; - } - if (nr < (YY_PART_YEAR)*10000L+101L) - goto err; - if (nr <= 991231L) - { - nr= (nr+19000000L)*1000000L; // YYMMDD, year: 1970-1999 - goto ok; - } - if (nr < 10000101L) - goto err; - if (nr <= 99991231L) - { - nr= nr*1000000L; - goto ok; - } - if (nr < 101000000L) - goto err; - if (nr <= (YY_PART_YEAR-1)*LL(10000000000)+LL(1231235959)) - { - nr= nr+LL(20000000000000); // YYMMDDHHMMSS, 2000-2069 - goto ok; - } - if (nr < YY_PART_YEAR*LL(10000000000)+ LL(101000000)) - goto err; - if (nr <= LL(991231235959)) - nr= nr+LL(19000000000000); // YYMMDDHHMMSS, 1970-1999 - - ok: - part1=(long) (nr/LL(1000000)); - part2=(long) (nr - (longlong) part1*LL(1000000)); - time_res->year= (int) (part1/10000L); part1%=10000L; - time_res->month= (int) part1 / 100; - time_res->day= (int) part1 % 100; - time_res->hour= (int) (part2/10000L); part2%=10000L; - time_res->minute=(int) part2 / 100; - time_res->second=(int) part2 % 100; - - if (time_res->year <= 9999 && time_res->month <= 12 && - time_res->day <= 31 && time_res->hour <= 23 && - time_res->minute <= 59 && time_res->second <= 59 && - (fuzzy_date || (time_res->month != 0 && time_res->day != 0) || nr==0)) - return nr; - - err: - - *was_cut= 1; - return LL(0); -} - - -/* Convert a system time structure to TIME */ @@ -807,77 +718,4 @@ void make_truncated_value_warning(THD *thd, const char *str_val, } -/* Convert time value to integer in YYYYMMDDHHMMSS format */ - -ulonglong TIME_to_ulonglong_datetime(const TIME *time) -{ - return ((ulonglong) (time->year * 10000UL + - time->month * 100UL + - time->day) * ULL(1000000) + - (ulonglong) (time->hour * 10000UL + - time->minute * 100UL + - time->second)); -} - - -/* Convert TIME value to integer in YYYYMMDD format */ - -ulonglong TIME_to_ulonglong_date(const TIME *time) -{ - return (ulonglong) (time->year * 10000UL + time->month * 100UL + time->day); -} - - -/* - Convert TIME value to integer in HHMMSS format. - This function doesn't take into account time->day member: - it's assumed that days have been converted to hours already. -*/ - -ulonglong TIME_to_ulonglong_time(const TIME *time) -{ - return (ulonglong) (time->hour * 10000UL + - time->minute * 100UL + - time->second); -} - - -/* - Convert struct TIME (date and time split into year/month/day/hour/... - to a number in format YYYYMMDDHHMMSS (DATETIME), - YYYYMMDD (DATE) or HHMMSS (TIME). - - SYNOPSIS - TIME_to_ulonglong() - - DESCRIPTION - The function is used when we need to convert value of time item - to a number if it's used in numeric context, i. e.: - SELECT NOW()+1, CURDATE()+0, CURTIMIE()+0; - SELECT ?+1; - - NOTE - This function doesn't check that given TIME structure members are - in valid range. If they are not, return value won't reflect any - valid date either. -*/ - -ulonglong TIME_to_ulonglong(const TIME *time) -{ - switch (time->time_type) { - case MYSQL_TIMESTAMP_DATETIME: - return TIME_to_ulonglong_datetime(time); - case MYSQL_TIMESTAMP_DATE: - return TIME_to_ulonglong_date(time); - case MYSQL_TIMESTAMP_TIME: - return TIME_to_ulonglong_time(time); - case MYSQL_TIMESTAMP_NONE: - case MYSQL_TIMESTAMP_ERROR: - return ULL(0); - default: - DBUG_ASSERT(0); - } - return 0; -} - #endif |