From 7845f99abf1d36e972970c0fc9431956a8f4b63a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Dec 2004 03:15:06 +0300 Subject: 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. include/my_time.h: More calls are shared between client and server (libmysql now performs more intelligent date->number and number->date conversions). TODO: rename those which are not starting with 'my_' include/mysql.h: MYSQL_BIND: - more elaborated comment - some of the ex-private members were given public names - it's sometimes convenient to set bind->error to &bind->error_value. However Monty questions the idea, so it should be given more thought in future. - added new members to support data truncation. Added new return value of mysql_stmt_fetch, MYSQL_DATA_TRUNCATED. libmysql/libmysql.c: - added support for data truncation during fetch - implementation for is_binary_compatible: now conversion functions are used less frequently - we now use number_to_datetime and TIME_to_ulonglong for date->number and number->date conversions sql-common/my_time.c: - added implementation of date->number and number->date calls shared between client and server (moved from time.cc). sql/field.cc: - implemented Field_time::store_time() to better support date->time conversions in prepared mode. After-review fixes. sql/field.h: - Field::store_time now returns int sql/mysql_priv.h: - removed date->number and number->date conversion functions headers (moved to my_time.h) sql/time.cc: - removed implementation of date->number and number->date conversion functions (moved to my_time.c) tests/client_test.c: - added a test case for data truncation; other test cases adjusted. - fixed my_process_stmt_result to set STMT_ATTR_UPDATE_MAX_LENGTH (tables are now printed out prettier). --- sql/time.cc | 162 ------------------------------------------------------------ 1 file changed, 162 deletions(-) (limited to 'sql/time.cc') diff --git a/sql/time.cc b/sql/time.cc index 562f9956ccc..f1d21915c23 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -262,95 +262,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 -- cgit v1.2.1