MDEV-17712 Remove C_TIME_FUZZY_DATES, C_TIME_DATETIME_ONLY, C_TIME_TIME_ONLY
This commit is contained in:
parent
62bcd74712
commit
b9a9055793
@ -1893,7 +1893,7 @@ static my_time_t convert_str_to_timestamp(const char* str)
|
|||||||
uint dummy_in_dst_time_gap;
|
uint dummy_in_dst_time_gap;
|
||||||
|
|
||||||
/* We require a total specification (date AND time) */
|
/* We require a total specification (date AND time) */
|
||||||
if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &status) ||
|
if (str_to_datetime_or_date(str, (uint) strlen(str), &l_time, 0, &status) ||
|
||||||
l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings)
|
l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings)
|
||||||
{
|
{
|
||||||
error("Incorrect date and time argument: %s", str);
|
error("Incorrect date and time argument: %s", str);
|
||||||
|
@ -57,13 +57,6 @@ extern uchar days_in_month[];
|
|||||||
|
|
||||||
/* Flags to str_to_datetime */
|
/* Flags to str_to_datetime */
|
||||||
|
|
||||||
/*
|
|
||||||
TIME_FUZZY_DATES is used for the result will only be used for comparison
|
|
||||||
purposes. Conversion is as relaxed as possible.
|
|
||||||
*/
|
|
||||||
#define C_TIME_FUZZY_DATES 1U
|
|
||||||
#define C_TIME_DATETIME_ONLY 2U
|
|
||||||
#define C_TIME_TIME_ONLY 4U
|
|
||||||
#define C_TIME_NO_ZERO_IN_DATE (1UL << 23) /* == MODE_NO_ZERO_IN_DATE */
|
#define C_TIME_NO_ZERO_IN_DATE (1UL << 23) /* == MODE_NO_ZERO_IN_DATE */
|
||||||
#define C_TIME_NO_ZERO_DATE (1UL << 24) /* == MODE_NO_ZERO_DATE */
|
#define C_TIME_NO_ZERO_DATE (1UL << 24) /* == MODE_NO_ZERO_DATE */
|
||||||
#define C_TIME_INVALID_DATES (1UL << 25) /* == MODE_INVALID_DATES */
|
#define C_TIME_INVALID_DATES (1UL << 25) /* == MODE_INVALID_DATES */
|
||||||
@ -117,15 +110,18 @@ my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
|
|||||||
ulonglong flags, int *was_cut);
|
ulonglong flags, int *was_cut);
|
||||||
my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *l_time,
|
my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *l_time,
|
||||||
ulong max_hour, MYSQL_TIME_STATUS *status);
|
ulong max_hour, MYSQL_TIME_STATUS *status);
|
||||||
my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time,
|
my_bool str_to_datetime_or_date_or_time(const char *str, size_t length,
|
||||||
ulonglong flag, MYSQL_TIME_STATUS *status);
|
MYSQL_TIME *to, ulonglong flag,
|
||||||
my_bool str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time,
|
MYSQL_TIME_STATUS *status);
|
||||||
ulonglong flags, MYSQL_TIME_STATUS *status);
|
my_bool str_to_datetime_or_date(const char *str, size_t length, MYSQL_TIME *to,
|
||||||
longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
|
ulonglong flags, MYSQL_TIME_STATUS *status);
|
||||||
ulonglong flags, int *was_cut);
|
|
||||||
|
longlong number_to_datetime_or_date(longlong nr, ulong sec_part,
|
||||||
|
MYSQL_TIME *time_res,
|
||||||
|
ulonglong flags, int *was_cut);
|
||||||
|
int number_to_time_only(my_bool neg, ulonglong nr, ulong sec_part,
|
||||||
|
MYSQL_TIME *ltime, int *was_cut);
|
||||||
|
|
||||||
int number_to_time(my_bool neg, ulonglong nr, ulong sec_part,
|
|
||||||
MYSQL_TIME *ltime, int *was_cut);
|
|
||||||
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
|
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
|
||||||
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
|
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
|
||||||
ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
|
ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
|
||||||
|
@ -3215,7 +3215,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, size_t
|
|||||||
{
|
{
|
||||||
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
|
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
|
||||||
MYSQL_TIME_STATUS status;
|
MYSQL_TIME_STATUS status;
|
||||||
str_to_time(value, length, tm, 0, &status);
|
str_to_datetime_or_date_or_time(value, length, tm, 0, &status);
|
||||||
err= status.warnings;
|
err= status.warnings;
|
||||||
*param->error= MY_TEST(err);
|
*param->error= MY_TEST(err);
|
||||||
break;
|
break;
|
||||||
@ -3226,7 +3226,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value, size_t
|
|||||||
{
|
{
|
||||||
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
|
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
|
||||||
MYSQL_TIME_STATUS status;
|
MYSQL_TIME_STATUS status;
|
||||||
(void) str_to_datetime(value, length, tm, 0, &status);
|
(void) str_to_datetime_or_date(value, length, tm, 0, &status);
|
||||||
err= status.warnings;
|
err= status.warnings;
|
||||||
*param->error= MY_TEST(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
|
*param->error= MY_TEST(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
|
||||||
tm->time_type != MYSQL_TIMESTAMP_DATE);
|
tm->time_type != MYSQL_TIMESTAMP_DATE);
|
||||||
@ -3350,7 +3350,7 @@ static void fetch_long_with_conversion(MYSQL_BIND *param, MYSQL_FIELD *field,
|
|||||||
case MYSQL_TYPE_DATETIME:
|
case MYSQL_TYPE_DATETIME:
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
value= number_to_datetime(value, 0, (MYSQL_TIME *) buffer, 0, &error);
|
value= number_to_datetime_or_date(value, 0, (MYSQL_TIME *) buffer, 0, &error);
|
||||||
*param->error= MY_TEST(error);
|
*param->error= MY_TEST(error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +63,7 @@ uint calc_days_in_year(uint year)
|
|||||||
|
|
||||||
static const ulonglong C_KNOWN_FLAGS= C_TIME_NO_ZERO_IN_DATE |
|
static const ulonglong C_KNOWN_FLAGS= C_TIME_NO_ZERO_IN_DATE |
|
||||||
C_TIME_NO_ZERO_DATE |
|
C_TIME_NO_ZERO_DATE |
|
||||||
C_TIME_INVALID_DATES |
|
C_TIME_INVALID_DATES;
|
||||||
C_TIME_TIME_ONLY |
|
|
||||||
C_TIME_DATETIME_ONLY;
|
|
||||||
|
|
||||||
#define C_FLAGS_OK(flags) (((flags) & ~C_KNOWN_FLAGS) == 0)
|
#define C_FLAGS_OK(flags) (((flags) & ~C_KNOWN_FLAGS) == 0)
|
||||||
|
|
||||||
@ -161,7 +159,8 @@ static int get_punct(const char **str, const char *end)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_date_time_separator(uint *number_of_fields, ulonglong flags,
|
static int get_date_time_separator(uint *number_of_fields,
|
||||||
|
my_bool punct_is_date_time_separator,
|
||||||
const char **str, const char *end)
|
const char **str, const char *end)
|
||||||
{
|
{
|
||||||
const char *s= *str;
|
const char *s= *str;
|
||||||
@ -180,11 +179,11 @@ static int get_date_time_separator(uint *number_of_fields, ulonglong flags,
|
|||||||
but
|
but
|
||||||
cast("11:11:11.12.12.12" as time) should give 11:11:11.12
|
cast("11:11:11.12.12.12" as time) should give 11:11:11.12
|
||||||
that is, a punctuation character can be accepted as a date/time separator
|
that is, a punctuation character can be accepted as a date/time separator
|
||||||
only if TIME_DATETIME_ONLY (see str_to_time) is not set.
|
only if "punct_is_date_time_separator" is set.
|
||||||
*/
|
*/
|
||||||
if (my_ispunct(&my_charset_latin1, *s))
|
if (my_ispunct(&my_charset_latin1, *s))
|
||||||
{
|
{
|
||||||
if (flags & C_TIME_DATETIME_ONLY)
|
if (!punct_is_date_time_separator)
|
||||||
{
|
{
|
||||||
/* see above, returning 1 is not enough, we need hard abort here */
|
/* see above, returning 1 is not enough, we need hard abort here */
|
||||||
*number_of_fields= 0;
|
*number_of_fields= 0;
|
||||||
@ -414,6 +413,9 @@ str_to_DDhhmmssff_internal(my_bool neg, const char *str, size_t length,
|
|||||||
TIME_NO_ZERO_IN_DATE Don't allow partial dates
|
TIME_NO_ZERO_IN_DATE Don't allow partial dates
|
||||||
TIME_NO_ZERO_DATE Don't allow 0000-00-00 date
|
TIME_NO_ZERO_DATE Don't allow 0000-00-00 date
|
||||||
TIME_INVALID_DATES Allow 2000-02-31
|
TIME_INVALID_DATES Allow 2000-02-31
|
||||||
|
punct_is_date_time_separator
|
||||||
|
Allow punctuation as a date/time separator,
|
||||||
|
or return a hard error.
|
||||||
status Conversion status
|
status Conversion status
|
||||||
|
|
||||||
|
|
||||||
@ -448,7 +450,9 @@ str_to_DDhhmmssff_internal(my_bool neg, const char *str, size_t length,
|
|||||||
|
|
||||||
static my_bool
|
static my_bool
|
||||||
str_to_datetime_or_date_body(const char *str, size_t length, MYSQL_TIME *l_time,
|
str_to_datetime_or_date_body(const char *str, size_t length, MYSQL_TIME *l_time,
|
||||||
ulonglong flags, MYSQL_TIME_STATUS *status)
|
ulonglong flags,
|
||||||
|
my_bool punct_is_date_time_separator,
|
||||||
|
MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
const char *end=str+length, *pos;
|
const char *end=str+length, *pos;
|
||||||
uint number_of_fields= 0, digits, year_length, not_zero_date;
|
uint number_of_fields= 0, digits, year_length, not_zero_date;
|
||||||
@ -503,7 +507,8 @@ str_to_datetime_or_date_body(const char *str, size_t length, MYSQL_TIME *l_time,
|
|||||||
|| get_number(&l_time->month, &number_of_fields, &str, end)
|
|| get_number(&l_time->month, &number_of_fields, &str, end)
|
||||||
|| get_punct(&str, end)
|
|| get_punct(&str, end)
|
||||||
|| get_number(&l_time->day, &number_of_fields, &str, end)
|
|| get_number(&l_time->day, &number_of_fields, &str, end)
|
||||||
|| get_date_time_separator(&number_of_fields, flags, &str, end)
|
|| get_date_time_separator(&number_of_fields,
|
||||||
|
punct_is_date_time_separator, &str, end)
|
||||||
|| get_number(&l_time->hour, &number_of_fields, &str, end)
|
|| get_number(&l_time->hour, &number_of_fields, &str, end)
|
||||||
|| get_punct(&str, end)
|
|| get_punct(&str, end)
|
||||||
|| get_number(&l_time->minute, &number_of_fields, &str, end)
|
|| get_number(&l_time->minute, &number_of_fields, &str, end)
|
||||||
@ -587,6 +592,7 @@ err:
|
|||||||
TRUE on error
|
TRUE on error
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
my_bool str_to_datetime_or_date_or_time_body(const char *str, size_t length,
|
my_bool str_to_datetime_or_date_or_time_body(const char *str, size_t length,
|
||||||
MYSQL_TIME *l_time,
|
MYSQL_TIME *l_time,
|
||||||
ulonglong fuzzydate,
|
ulonglong fuzzydate,
|
||||||
@ -599,9 +605,7 @@ my_bool str_to_datetime_or_date_or_time_body(const char *str, size_t length,
|
|||||||
if (is_datetime_body_candidate(str, length))
|
if (is_datetime_body_candidate(str, length))
|
||||||
{ /* Probably full timestamp */
|
{ /* Probably full timestamp */
|
||||||
(void) str_to_datetime_or_date_body(str, length, l_time,
|
(void) str_to_datetime_or_date_body(str, length, l_time,
|
||||||
(fuzzydate & ~C_TIME_TIME_ONLY) |
|
fuzzydate, FALSE, status);
|
||||||
C_TIME_DATETIME_ONLY,
|
|
||||||
status);
|
|
||||||
if (l_time->time_type >= MYSQL_TIMESTAMP_ERROR)
|
if (l_time->time_type >= MYSQL_TIMESTAMP_ERROR)
|
||||||
return l_time->time_type == MYSQL_TIMESTAMP_ERROR;
|
return l_time->time_type == MYSQL_TIMESTAMP_ERROR;
|
||||||
my_time_status_init(status);
|
my_time_status_init(status);
|
||||||
@ -616,6 +620,12 @@ my_bool str_to_datetime_or_date_or_time_body(const char *str, size_t length,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Convert a string with INTERVAL DAY TO SECOND to MYSQL_TIME.
|
||||||
|
Input format: [-][DD ]hh:mm:ss.ffffff
|
||||||
|
|
||||||
|
If the input string appears to be a DATETIME, error is returned.
|
||||||
|
*/
|
||||||
my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *ltime,
|
my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *ltime,
|
||||||
ulong max_hour, MYSQL_TIME_STATUS *status)
|
ulong max_hour, MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
@ -634,7 +644,7 @@ my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *ltime,
|
|||||||
if (is_datetime_body_candidate(str, length))
|
if (is_datetime_body_candidate(str, length))
|
||||||
{
|
{
|
||||||
(void) str_to_datetime_or_date_body(str, length, ltime,
|
(void) str_to_datetime_or_date_body(str, length, ltime,
|
||||||
C_TIME_DATETIME_ONLY, status);
|
0, FALSE, status);
|
||||||
if (ltime->time_type > MYSQL_TIMESTAMP_ERROR)
|
if (ltime->time_type > MYSQL_TIMESTAMP_ERROR)
|
||||||
{
|
{
|
||||||
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
status->warnings|= MYSQL_TIME_WARN_TRUNCATED;
|
||||||
@ -650,7 +660,7 @@ my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *ltime,
|
|||||||
will scan only '2001'.
|
will scan only '2001'.
|
||||||
*/
|
*/
|
||||||
if (str_to_DDhhmmssff_internal(neg, str, length, ltime, max_hour,
|
if (str_to_DDhhmmssff_internal(neg, str, length, ltime, max_hour,
|
||||||
status, &endptr) ||
|
status, &endptr) ||
|
||||||
(endptr < str + length && endptr[0] == '-'))
|
(endptr < str + length && endptr[0] == '-'))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
status->warnings|= warn;
|
status->warnings|= warn;
|
||||||
@ -658,10 +668,13 @@ my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *ltime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time,
|
my_bool
|
||||||
ulonglong fuzzydate, MYSQL_TIME_STATUS *status)
|
str_to_datetime_or_date_or_time(const char *str, size_t length,
|
||||||
|
MYSQL_TIME *l_time,
|
||||||
|
ulonglong fuzzydate,
|
||||||
|
MYSQL_TIME_STATUS *status)
|
||||||
{
|
{
|
||||||
my_bool neg;
|
my_bool neg, rc;
|
||||||
int warn;
|
int warn;
|
||||||
DBUG_ASSERT(C_FLAGS_OK(fuzzydate));
|
DBUG_ASSERT(C_FLAGS_OK(fuzzydate));
|
||||||
my_time_status_init(status);
|
my_time_status_init(status);
|
||||||
@ -674,31 +687,8 @@ my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time,
|
|||||||
QQ: Perhaps we should modify xxx_body() to return endptr.
|
QQ: Perhaps we should modify xxx_body() to return endptr.
|
||||||
If endptr points to '-', return an error.
|
If endptr points to '-', return an error.
|
||||||
*/
|
*/
|
||||||
if (str_to_datetime_or_date_or_time_body(str, length, l_time,
|
rc= str_to_datetime_or_date_or_time_body(str, length, l_time,
|
||||||
fuzzydate, status))
|
fuzzydate, status);
|
||||||
return TRUE;
|
|
||||||
status->warnings|= warn;
|
|
||||||
l_time->neg= neg;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
my_bool
|
|
||||||
str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time,
|
|
||||||
ulonglong flags, MYSQL_TIME_STATUS *status)
|
|
||||||
{
|
|
||||||
my_bool neg, rc;
|
|
||||||
int warn;
|
|
||||||
DBUG_ASSERT(C_FLAGS_OK(flags));
|
|
||||||
my_time_status_init(status);
|
|
||||||
if (find_body(&neg, str, length, l_time, &warn, &str, &length))
|
|
||||||
{
|
|
||||||
status->warnings= warn;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
rc= (flags & C_TIME_TIME_ONLY) ?
|
|
||||||
str_to_datetime_or_date_or_time_body(str, length, l_time, flags, status) :
|
|
||||||
str_to_datetime_or_date_body(str, length, l_time, flags, status);
|
|
||||||
status->warnings|= warn;
|
status->warnings|= warn;
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
@ -711,6 +701,53 @@ str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my_bool
|
||||||
|
str_to_datetime_or_date(const char *str, size_t length, MYSQL_TIME *l_time,
|
||||||
|
ulonglong flags, MYSQL_TIME_STATUS *status)
|
||||||
|
{
|
||||||
|
my_bool neg, rc;
|
||||||
|
int warn;
|
||||||
|
DBUG_ASSERT(C_FLAGS_OK(flags));
|
||||||
|
my_time_status_init(status);
|
||||||
|
if (find_body(&neg, str, length, l_time, &warn, &str, &length))
|
||||||
|
{
|
||||||
|
status->warnings= warn;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
rc= str_to_datetime_or_date_body(str, length, l_time, flags, TRUE, status);
|
||||||
|
status->warnings|= warn;
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
if ((l_time->neg= neg))
|
||||||
|
{
|
||||||
|
status->warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Convert a string to INTERVAL DAY TO SECOND.
|
||||||
|
Input format: [DD ]hh:mm:ss.ffffff
|
||||||
|
|
||||||
|
Datetime or date formats are not understood.
|
||||||
|
|
||||||
|
Optional leading spaces and signs must be scanned by the caller.
|
||||||
|
"str" should point to the first digit.
|
||||||
|
|
||||||
|
@param neg - set the value to be negative
|
||||||
|
@param str - the input string
|
||||||
|
@param length - length of "str"
|
||||||
|
@param[OUT] l_time - write the result here
|
||||||
|
@param max_hour - if the result hour value appears to be greater than
|
||||||
|
max_hour, then cut to result to 'max_hour:59:59.999999'
|
||||||
|
@param err_hour - if the hour appears to be greater than err_hour,
|
||||||
|
return an error (without cut)
|
||||||
|
@param status
|
||||||
|
@param endptr
|
||||||
|
*/
|
||||||
static my_bool
|
static my_bool
|
||||||
str_to_DDhhmmssff_internal(my_bool neg, const char *str, size_t length,
|
str_to_DDhhmmssff_internal(my_bool neg, const char *str, size_t length,
|
||||||
MYSQL_TIME *l_time, ulong max_hour,
|
MYSQL_TIME *l_time, ulong max_hour,
|
||||||
@ -1428,7 +1465,7 @@ int my_timeval_to_str(const struct timeval *tm, char *to, uint dec)
|
|||||||
representation and form value of DATETIME type as side-effect.
|
representation and form value of DATETIME type as side-effect.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
number_to_datetime()
|
number_to_datetime_or_date()
|
||||||
nr - datetime value as number
|
nr - datetime value as number
|
||||||
time_res - pointer for structure for broken-down representation
|
time_res - pointer for structure for broken-down representation
|
||||||
flags - flags to use in validating date, as in str_to_datetime()
|
flags - flags to use in validating date, as in str_to_datetime()
|
||||||
@ -1449,8 +1486,9 @@ int my_timeval_to_str(const struct timeval *tm, char *to, uint dec)
|
|||||||
Datetime value in YYYYMMDDHHMMSS format.
|
Datetime value in YYYYMMDDHHMMSS format.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
|
longlong number_to_datetime_or_date(longlong nr, ulong sec_part,
|
||||||
ulonglong flags, int *was_cut)
|
MYSQL_TIME *time_res,
|
||||||
|
ulonglong flags, int *was_cut)
|
||||||
{
|
{
|
||||||
long part1,part2;
|
long part1,part2;
|
||||||
DBUG_ASSERT(C_FLAGS_OK(flags));
|
DBUG_ASSERT(C_FLAGS_OK(flags));
|
||||||
@ -1554,13 +1592,9 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res,
|
|||||||
0 time value is valid, but was possibly truncated
|
0 time value is valid, but was possibly truncated
|
||||||
-1 time value is invalid
|
-1 time value is invalid
|
||||||
*/
|
*/
|
||||||
int number_to_time(my_bool neg, ulonglong nr, ulong sec_part,
|
int number_to_time_only(my_bool neg, ulonglong nr, ulong sec_part,
|
||||||
MYSQL_TIME *ltime, int *was_cut)
|
MYSQL_TIME *ltime, int *was_cut)
|
||||||
{
|
{
|
||||||
if (nr > 9999999 && nr <= 99991231235959ULL && neg == 0)
|
|
||||||
return number_to_datetime(nr, sec_part, ltime,
|
|
||||||
C_TIME_INVALID_DATES, was_cut) < 0 ? -1 : 0;
|
|
||||||
|
|
||||||
*was_cut= 0;
|
*was_cut= 0;
|
||||||
ltime->year= ltime->month= ltime->day= 0;
|
ltime->year= ltime->month= ltime->day= 0;
|
||||||
ltime->time_type= MYSQL_TIMESTAMP_TIME;
|
ltime->time_type= MYSQL_TIMESTAMP_TIME;
|
||||||
|
@ -33,8 +33,12 @@ class date_mode_t
|
|||||||
public:
|
public:
|
||||||
enum value_t
|
enum value_t
|
||||||
{
|
{
|
||||||
FUZZY_DATES= 1U, // C_TIME_FUZZY_DATES
|
/*
|
||||||
TIME_ONLY= 4U, // C_TIME_TIME_ONLY
|
FUZZY_DATES is used for the result will only be used for comparison
|
||||||
|
purposes. Conversion is as relaxed as possible.
|
||||||
|
*/
|
||||||
|
FUZZY_DATES= 1U,
|
||||||
|
TIME_ONLY= 4U,
|
||||||
NO_ZERO_IN_DATE= (1UL << 23), // MODE_NO_ZERO_IN_DATE
|
NO_ZERO_IN_DATE= (1UL << 23), // MODE_NO_ZERO_IN_DATE
|
||||||
NO_ZERO_DATE= (1UL << 24), // MODE_NO_ZERO_DATE
|
NO_ZERO_DATE= (1UL << 24), // MODE_NO_ZERO_DATE
|
||||||
INVALID_DATES= (1UL << 25) // MODE_INVALID_DATES
|
INVALID_DATES= (1UL << 25) // MODE_INVALID_DATES
|
||||||
@ -98,11 +102,10 @@ const date_mode_t
|
|||||||
TIME_NO_ZERO_DATE (date_mode_t::value_t::NO_ZERO_DATE),
|
TIME_NO_ZERO_DATE (date_mode_t::value_t::NO_ZERO_DATE),
|
||||||
TIME_INVALID_DATES (date_mode_t::value_t::INVALID_DATES);
|
TIME_INVALID_DATES (date_mode_t::value_t::INVALID_DATES);
|
||||||
|
|
||||||
// Flags understood by str_to_datetime, str_to_time, number_to_time, check_date
|
// Flags understood by str_to_xxx, number_to_xxx, check_date
|
||||||
static const date_mode_t
|
static const date_mode_t
|
||||||
TIME_MODE_FOR_XXX_TO_DATE (date_mode_t::NO_ZERO_IN_DATE |
|
TIME_MODE_FOR_XXX_TO_DATE (date_mode_t::NO_ZERO_IN_DATE |
|
||||||
date_mode_t::NO_ZERO_DATE |
|
date_mode_t::NO_ZERO_DATE |
|
||||||
date_mode_t::INVALID_DATES |
|
date_mode_t::INVALID_DATES);
|
||||||
date_mode_t::TIME_ONLY);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4955,9 +4955,6 @@ my_eof(THD *thd)
|
|||||||
|
|
||||||
inline date_mode_t sql_mode_for_dates(THD *thd)
|
inline date_mode_t sql_mode_for_dates(THD *thd)
|
||||||
{
|
{
|
||||||
static_assert(C_TIME_FUZZY_DATES == date_mode_t::FUZZY_DATES &&
|
|
||||||
C_TIME_TIME_ONLY == date_mode_t::TIME_ONLY,
|
|
||||||
"sql_mode_t and pure C library date flags must be equal");
|
|
||||||
static_assert(MODE_NO_ZERO_DATE == date_mode_t::NO_ZERO_DATE &&
|
static_assert(MODE_NO_ZERO_DATE == date_mode_t::NO_ZERO_DATE &&
|
||||||
MODE_NO_ZERO_IN_DATE == date_mode_t::NO_ZERO_IN_DATE &&
|
MODE_NO_ZERO_IN_DATE == date_mode_t::NO_ZERO_IN_DATE &&
|
||||||
MODE_INVALID_DATES == date_mode_t::INVALID_DATES,
|
MODE_INVALID_DATES == date_mode_t::INVALID_DATES,
|
||||||
|
@ -7685,11 +7685,11 @@ copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
|
|||||||
sch_table->field[ISE_ON_COMPLETION]->
|
sch_table->field[ISE_ON_COMPLETION]->
|
||||||
store(STRING_WITH_LEN("PRESERVE"), scs);
|
store(STRING_WITH_LEN("PRESERVE"), scs);
|
||||||
|
|
||||||
number_to_datetime(et.created, 0, &time, 0, ¬_used);
|
number_to_datetime_or_date(et.created, 0, &time, 0, ¬_used);
|
||||||
DBUG_ASSERT(not_used==0);
|
DBUG_ASSERT(not_used==0);
|
||||||
sch_table->field[ISE_CREATED]->store_time(&time);
|
sch_table->field[ISE_CREATED]->store_time(&time);
|
||||||
|
|
||||||
number_to_datetime(et.modified, 0, &time, 0, ¬_used);
|
number_to_datetime_or_date(et.modified, 0, &time, 0, ¬_used);
|
||||||
DBUG_ASSERT(not_used==0);
|
DBUG_ASSERT(not_used==0);
|
||||||
sch_table->field[ISE_LAST_ALTERED]->store_time(&time);
|
sch_table->field[ISE_LAST_ALTERED]->store_time(&time);
|
||||||
|
|
||||||
|
@ -371,13 +371,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of str_to_time() */
|
/* Character set-aware version of str_to_datetime_or_date_or_time() */
|
||||||
bool Temporal::str_to_time(MYSQL_TIME_STATUS *status,
|
bool Temporal::str_to_datetime_or_date_or_time(MYSQL_TIME_STATUS *status,
|
||||||
const char *str, size_t length, CHARSET_INFO *cs,
|
const char *str, size_t length,
|
||||||
date_mode_t fuzzydate)
|
CHARSET_INFO *cs,
|
||||||
|
date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
TemporalAsciiBuffer tmp(str, length, cs);
|
TemporalAsciiBuffer tmp(str, length, cs);
|
||||||
bool rc= ::str_to_time(tmp.str, tmp.length, this,
|
bool rc= ::str_to_datetime_or_date_or_time(tmp.str, tmp.length, this,
|
||||||
ulonglong(fuzzydate & TIME_MODE_FOR_XXX_TO_DATE),
|
ulonglong(fuzzydate & TIME_MODE_FOR_XXX_TO_DATE),
|
||||||
status);
|
status);
|
||||||
DBUG_ASSERT(status->warnings || !rc);
|
DBUG_ASSERT(status->warnings || !rc);
|
||||||
@ -385,13 +386,14 @@ bool Temporal::str_to_time(MYSQL_TIME_STATUS *status,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Character set-aware version of str_to_datetime() */
|
/* Character set-aware version of str_to_datetime_or_date() */
|
||||||
bool Temporal::str_to_datetime(MYSQL_TIME_STATUS *status,
|
bool Temporal::str_to_datetime_or_date(MYSQL_TIME_STATUS *status,
|
||||||
const char *str, size_t length, CHARSET_INFO *cs,
|
const char *str, size_t length,
|
||||||
date_mode_t flags)
|
CHARSET_INFO *cs,
|
||||||
|
date_mode_t flags)
|
||||||
{
|
{
|
||||||
TemporalAsciiBuffer tmp(str, length, cs);
|
TemporalAsciiBuffer tmp(str, length, cs);
|
||||||
bool rc= ::str_to_datetime(tmp.str, tmp.length, this,
|
bool rc= ::str_to_datetime_or_date(tmp.str, tmp.length, this,
|
||||||
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE),
|
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE),
|
||||||
status);
|
status);
|
||||||
DBUG_ASSERT(status->warnings || !rc);
|
DBUG_ASSERT(status->warnings || !rc);
|
||||||
@ -416,7 +418,7 @@ bool Interval_DDhhmmssff::str_to_DDhhmmssff(MYSQL_TIME_STATUS *status,
|
|||||||
if string was truncated during conversion.
|
if string was truncated during conversion.
|
||||||
|
|
||||||
NOTE
|
NOTE
|
||||||
See description of str_to_datetime() for more information.
|
See description of str_to_datetime_xxx() for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -180,7 +180,10 @@ void Temporal::make_from_str(THD *thd, Warn *warn,
|
|||||||
DBUG_EXECUTE_IF("str_to_datetime_warn",
|
DBUG_EXECUTE_IF("str_to_datetime_warn",
|
||||||
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
push_warning(thd, Sql_condition::WARN_LEVEL_NOTE,
|
||||||
ER_YES, ErrConvString(str, length,cs).ptr()););
|
ER_YES, ErrConvString(str, length,cs).ptr()););
|
||||||
if (str_to_datetime(warn, str, length, cs, fuzzydate))
|
|
||||||
|
if (fuzzydate & TIME_TIME_ONLY ?
|
||||||
|
str_to_datetime_or_date_or_time(warn, str, length, cs, fuzzydate) :
|
||||||
|
str_to_datetime_or_date(warn, str, length, cs, fuzzydate))
|
||||||
make_fuzzy_date(&warn->warnings, fuzzydate);
|
make_fuzzy_date(&warn->warnings, fuzzydate);
|
||||||
if (warn->warnings)
|
if (warn->warnings)
|
||||||
warn->set_str(str, length, &my_charset_bin);
|
warn->set_str(str, length, &my_charset_bin);
|
||||||
|
@ -267,7 +267,10 @@ public:
|
|||||||
// Convert a number in format hhhmmss.ff to TIME'hhh:mm:ss.ff'
|
// Convert a number in format hhhmmss.ff to TIME'hhh:mm:ss.ff'
|
||||||
bool to_time(MYSQL_TIME *to, int *warn) const
|
bool to_time(MYSQL_TIME *to, int *warn) const
|
||||||
{
|
{
|
||||||
bool rc= number_to_time(m_neg, m_sec, m_usec, to, warn);
|
bool rc= (m_sec > 9999999 && m_sec <= 99991231235959ULL && !neg()) ?
|
||||||
|
number_to_datetime_or_date(m_sec, m_usec, to,
|
||||||
|
C_TIME_INVALID_DATES, warn) < 0 :
|
||||||
|
number_to_time_only(m_neg, m_sec, m_usec, to, warn);
|
||||||
DBUG_ASSERT(*warn || !rc);
|
DBUG_ASSERT(*warn || !rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -282,7 +285,7 @@ public:
|
|||||||
*warn= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
*warn= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool rc= number_to_datetime(m_sec, m_usec, to,
|
bool rc= number_to_datetime_or_date(m_sec, m_usec, to,
|
||||||
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE),
|
ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE),
|
||||||
warn) == -1;
|
warn) == -1;
|
||||||
DBUG_ASSERT(*warn || !rc);
|
DBUG_ASSERT(*warn || !rc);
|
||||||
@ -576,10 +579,13 @@ protected:
|
|||||||
if (warn->warnings)
|
if (warn->warnings)
|
||||||
warn->set_decimal(nr);
|
warn->set_decimal(nr);
|
||||||
}
|
}
|
||||||
bool str_to_time(MYSQL_TIME_STATUS *st, const char *str, size_t length,
|
bool str_to_datetime_or_date_or_time(MYSQL_TIME_STATUS *st,
|
||||||
CHARSET_INFO *cs, date_mode_t fuzzydate);
|
const char *str, size_t length,
|
||||||
bool str_to_datetime(MYSQL_TIME_STATUS *st, const char *str, size_t length,
|
CHARSET_INFO *cs, date_mode_t fuzzydate);
|
||||||
CHARSET_INFO *cs, date_mode_t fuzzydate);
|
bool str_to_datetime_or_date(MYSQL_TIME_STATUS *st,
|
||||||
|
const char *str, size_t length,
|
||||||
|
CHARSET_INFO *cs, date_mode_t fuzzydate);
|
||||||
|
|
||||||
bool has_valid_mmssff() const
|
bool has_valid_mmssff() const
|
||||||
{
|
{
|
||||||
return minute <= TIME_MAX_MINUTE &&
|
return minute <= TIME_MAX_MINUTE &&
|
||||||
@ -990,7 +996,7 @@ private:
|
|||||||
/*
|
/*
|
||||||
Convert a valid DATE or DATETIME to TIME.
|
Convert a valid DATE or DATETIME to TIME.
|
||||||
Before this call, "this" must be a valid DATE or DATETIME value,
|
Before this call, "this" must be a valid DATE or DATETIME value,
|
||||||
e.g. returned from Item::get_date(), str_to_time(), number_to_time().
|
e.g. returned from Item::get_date(), str_to_xxx(), number_to_xxx().
|
||||||
After this call, "this" is a valid TIME value.
|
After this call, "this" is a valid TIME value.
|
||||||
*/
|
*/
|
||||||
void valid_datetime_to_valid_time(THD *thd, int *warn, const Options opt)
|
void valid_datetime_to_valid_time(THD *thd, int *warn, const Options opt)
|
||||||
@ -999,7 +1005,7 @@ private:
|
|||||||
time_type == MYSQL_TIMESTAMP_DATETIME);
|
time_type == MYSQL_TIMESTAMP_DATETIME);
|
||||||
/*
|
/*
|
||||||
We're dealing with a DATE or DATETIME returned from
|
We're dealing with a DATE or DATETIME returned from
|
||||||
str_to_time(), number_to_time() or unpack_time().
|
str_to_xxx(), number_to_xxx() or unpack_time().
|
||||||
Do some asserts to make sure the result hour value
|
Do some asserts to make sure the result hour value
|
||||||
after mixing days to hours does not go out of the valid TIME range.
|
after mixing days to hours does not go out of the valid TIME range.
|
||||||
The maximum hour value after mixing days will be 31*24+23=767,
|
The maximum hour value after mixing days will be 31*24+23=767,
|
||||||
@ -1025,7 +1031,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
Convert valid DATE/DATETIME to valid TIME if needed.
|
Convert valid DATE/DATETIME to valid TIME if needed.
|
||||||
This method is called after Item::get_date(),
|
This method is called after Item::get_date(),
|
||||||
str_to_time(), number_to_time().
|
str_to_xxx(), number_to_xxx().
|
||||||
which can return only valid TIME/DATE/DATETIME values.
|
which can return only valid TIME/DATE/DATETIME values.
|
||||||
Before this call, "this" is:
|
Before this call, "this" is:
|
||||||
- either a valid TIME/DATE/DATETIME value
|
- either a valid TIME/DATE/DATETIME value
|
||||||
@ -1061,14 +1067,14 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This method is called after number_to_time() and str_to_time(),
|
This method is called after number_to_xxx() and str_to_xxx(),
|
||||||
which can return DATE or DATETIME values. Convert to TIME if needed.
|
which can return DATE or DATETIME values. Convert to TIME if needed.
|
||||||
We trust that xxx_to_time() returns a valid TIME/DATE/DATETIME value,
|
We trust that xxx_to_time() returns a valid TIME/DATE/DATETIME value,
|
||||||
so here we need to do only simple validation.
|
so here we need to do only simple validation.
|
||||||
*/
|
*/
|
||||||
void xxx_to_time_result_to_valid_value(THD *thd, int *warn, const Options opt)
|
void xxx_to_time_result_to_valid_value(THD *thd, int *warn, const Options opt)
|
||||||
{
|
{
|
||||||
// str_to_time(), number_to_time() never return MYSQL_TIMESTAMP_ERROR
|
// str_to_xxx(), number_to_xxx() never return MYSQL_TIMESTAMP_ERROR
|
||||||
DBUG_ASSERT(time_type != MYSQL_TIMESTAMP_ERROR);
|
DBUG_ASSERT(time_type != MYSQL_TIMESTAMP_ERROR);
|
||||||
valid_MYSQL_TIME_to_valid_value(thd, warn, opt);
|
valid_MYSQL_TIME_to_valid_value(thd, warn, opt);
|
||||||
}
|
}
|
||||||
@ -1106,7 +1112,8 @@ public:
|
|||||||
const char *str, size_t len, CHARSET_INFO *cs,
|
const char *str, size_t len, CHARSET_INFO *cs,
|
||||||
const Options opt)
|
const Options opt)
|
||||||
{
|
{
|
||||||
if (str_to_time(status, str, len, cs, opt.get_date_flags()))
|
if (str_to_datetime_or_date_or_time(status, str, len, cs,
|
||||||
|
opt.get_date_flags()))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
// The below call will optionally add notes to already collected warnings:
|
// The below call will optionally add notes to already collected warnings:
|
||||||
xxx_to_time_result_to_valid_value(thd, &status->warnings, opt);
|
xxx_to_time_result_to_valid_value(thd, &status->warnings, opt);
|
||||||
@ -1306,7 +1313,7 @@ protected:
|
|||||||
date_mode_t flags)
|
date_mode_t flags)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(bool(flags & TIME_TIME_ONLY) == false);
|
DBUG_ASSERT(bool(flags & TIME_TIME_ONLY) == false);
|
||||||
if (str_to_datetime(status, str, len, cs, flags))
|
if (str_to_datetime_or_date(status, str, len, cs, flags))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
@ -618,6 +618,15 @@ SPIDER_DB_ROW *spider_db_mysql_result::fetch_row_from_tmp_table(
|
|||||||
DBUG_RETURN((SPIDER_DB_ROW *) &row);
|
DBUG_RETURN((SPIDER_DB_ROW *) &row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static my_bool str_to_datetime(const char *str, size_t length,
|
||||||
|
MYSQL_TIME *l_time,
|
||||||
|
ulonglong flags, MYSQL_TIME_STATUS *status)
|
||||||
|
{
|
||||||
|
return str_to_datetime_or_date(str, length, l_time, flags, status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int spider_db_mysql_result::fetch_table_status(
|
int spider_db_mysql_result::fetch_table_status(
|
||||||
int mode,
|
int mode,
|
||||||
ha_rows &records,
|
ha_rows &records,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user