summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorkonstantin@mysql.com <>2004-12-16 03:15:06 +0300
committerkonstantin@mysql.com <>2004-12-16 03:15:06 +0300
commit7216594f4f20b4f1df625cfd0f08a99d61486cc6 (patch)
tree056f73f48d150d91c8d24bee3a927dec746492bb /sql
parent24aa7e9ce7668489897bebbeac3b340e64799065 (diff)
downloadmariadb-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.cc28
-rw-r--r--sql/field.h7
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/time.cc162
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, &not_used, 1, &error);
+ nr= number_to_datetime(nr, &not_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