diff options
-rw-r--r-- | sql-common/my_time.c | 18 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 2 | ||||
-rw-r--r-- | sql/sql_basic_types.h | 6 | ||||
-rw-r--r-- | sql/sql_time.cc | 15 | ||||
-rw-r--r-- | sql/sql_time.h | 5 | ||||
-rw-r--r-- | sql/sql_type.cc | 3 | ||||
-rw-r--r-- | sql/sql_type.h | 8 |
7 files changed, 46 insertions, 11 deletions
diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 0ad6d64a1b9..2841d33f7fd 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -58,6 +58,20 @@ uint calc_days_in_year(uint year) 366 : 365); } + +#ifndef DBUG_OFF + +static const ulonglong C_KNOWN_FLAGS= C_TIME_NO_ZERO_IN_DATE | + C_TIME_NO_ZERO_DATE | + C_TIME_INVALID_DATES | + C_TIME_TIME_ONLY | + C_TIME_DATETIME_ONLY; + +#define C_FLAGS_OK(flags) (((flags) & ~C_KNOWN_FLAGS) == 0) + +#endif + + /** @brief Check datetime value for validity according to flags. @@ -82,6 +96,7 @@ uint calc_days_in_year(uint year) my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date, ulonglong flags, int *was_cut) { + DBUG_ASSERT(C_FLAGS_OK(flags)); if (ltime->time_type == MYSQL_TIMESTAMP_TIME) return FALSE; if (not_zero_date) @@ -298,6 +313,7 @@ str_to_datetime(const char *str, size_t length, MYSQL_TIME *l_time, const char *end=str+length, *pos; uint number_of_fields= 0, digits, year_length, not_zero_date; DBUG_ENTER("str_to_datetime"); + DBUG_ASSERT(C_FLAGS_OK(flags)); bzero(l_time, sizeof(*l_time)); if (flags & C_TIME_TIME_ONLY) @@ -464,6 +480,7 @@ my_bool str_to_time(const char *str, size_t length, MYSQL_TIME *l_time, const char *end=str+length, *end_of_days; my_bool found_days,found_hours, neg= 0; uint UNINIT_VAR(state); + DBUG_ASSERT(C_FLAGS_OK(fuzzydate)); my_time_status_init(status); for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) @@ -1209,6 +1226,7 @@ longlong number_to_datetime(longlong nr, ulong sec_part, MYSQL_TIME *time_res, ulonglong flags, int *was_cut) { long part1,part2; + DBUG_ASSERT(C_FLAGS_OK(flags)); *was_cut= 0; time_res->time_type=MYSQL_TIMESTAMP_DATE; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 94757e16d41..6d88ef2185a 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -441,7 +441,7 @@ static bool extract_date_time(THD *thd, DATE_TIME_FORMAT *format, goto err; int was_cut; - if (check_date(l_time, ulonglong(fuzzydate | TIME_INVALID_DATES), &was_cut)) + if (check_date(l_time, fuzzydate | TIME_INVALID_DATES, &was_cut)) goto err; if (val != val_end) diff --git a/sql/sql_basic_types.h b/sql/sql_basic_types.h index 132393c1b29..362ab0f1259 100644 --- a/sql/sql_basic_types.h +++ b/sql/sql_basic_types.h @@ -98,5 +98,11 @@ const date_mode_t TIME_NO_ZERO_DATE (date_mode_t::value_t::NO_ZERO_DATE), TIME_INVALID_DATES (date_mode_t::value_t::INVALID_DATES); +// Flags understood by str_to_datetime, str_to_time, number_to_time, check_date +static const date_mode_t + TIME_MODE_FOR_XXX_TO_DATE (date_mode_t::NO_ZERO_IN_DATE | + date_mode_t::NO_ZERO_DATE | + date_mode_t::INVALID_DATES | + date_mode_t::TIME_ONLY); #endif diff --git a/sql/sql_time.cc b/sql/sql_time.cc index 469096ffa52..01e4cdff332 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -293,7 +293,7 @@ check_date_with_warn(THD *thd, const MYSQL_TIME *ltime, date_mode_t fuzzydate, timestamp_type ts_type) { int unused; - if (check_date(ltime, ulonglong(fuzzydate), &unused)) + if (check_date(ltime, fuzzydate, &unused)) { ErrConvTime str(ltime); make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, @@ -377,7 +377,9 @@ bool Temporal::str_to_time(MYSQL_TIME_STATUS *status, date_mode_t fuzzydate) { TemporalAsciiBuffer tmp(str, length, cs); - return ::str_to_time(tmp.str, tmp.length, this, ulonglong(fuzzydate), status); + return ::str_to_time(tmp.str, tmp.length, this, + ulonglong(fuzzydate & TIME_MODE_FOR_XXX_TO_DATE), + status); } @@ -387,7 +389,9 @@ bool Temporal::str_to_datetime(MYSQL_TIME_STATUS *status, date_mode_t flags) { TemporalAsciiBuffer tmp(str, length, cs); - return ::str_to_datetime(tmp.str, tmp.length, this, ulonglong(flags), status); + return ::str_to_datetime(tmp.str, tmp.length, this, + ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), + status); } @@ -407,7 +411,8 @@ str_to_datetime_with_warn(THD *thd, CHARSET_INFO *cs, MYSQL_TIME_STATUS status; TemporalAsciiBuffer tmp(str, length, cs); bool ret_val= str_to_datetime(tmp.str, tmp.length, l_time, - ulonglong(flags), &status); + ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), + &status); if (ret_val || status.warnings) { const ErrConvString err(str, length, &my_charset_bin); @@ -1339,7 +1344,7 @@ time_to_datetime_with_warn(THD *thd, */ if (time_to_datetime(thd, from, to) || ((thd->variables.old_behavior & OLD_MODE_ZERO_DATE_TIME_CAST) && - check_date(to, ulonglong(fuzzydate), &warn))) + check_date(to, fuzzydate, &warn))) { ErrConvTime str(from); thd->push_warning_truncated_wrong_value("datetime", str.ptr()); diff --git a/sql/sql_time.h b/sql/sql_time.h index f9edf661240..f113962b596 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -167,9 +167,10 @@ non_zero_date(const MYSQL_TIME *ltime) non_zero_hhmmssuu(ltime)); } static inline bool -check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut) +check_date(const MYSQL_TIME *ltime, date_mode_t flags, int *was_cut) { - return check_date(ltime, non_zero_date(ltime), flags, was_cut); + return check_date(ltime, non_zero_date(ltime), + ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), was_cut); } bool check_date_with_warn(THD *thd, const MYSQL_TIME *ltime, date_mode_t fuzzy_date, timestamp_type ts_type); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index e051b9efc4c..869c3a1cc2e 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -480,7 +480,8 @@ void Temporal_with_date::make_from_item(THD *thd, Item *item) void Temporal_with_date::check_date_or_invalidate(int *warn, date_mode_t flags) { - if (check_date(this, pack_time(this) != 0, ulonglong(flags), warn)) + if (check_date(this, pack_time(this) != 0, + ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), warn)) time_type= MYSQL_TIMESTAMP_NONE; } diff --git a/sql/sql_type.h b/sql/sql_type.h index e0d3aa5a1f3..7e29f7d53a7 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -285,7 +285,9 @@ public: *warn= MYSQL_TIME_WARN_OUT_OF_RANGE; return true; } - return number_to_datetime(m_sec, m_usec, to, ulonglong(flags), warn) == -1; + return number_to_datetime(m_sec, m_usec, to, + ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), + warn) == -1; } // Convert elapsed seconds to TIME bool sec_to_time(MYSQL_TIME *ltime, uint dec) const @@ -1230,7 +1232,9 @@ public: bool check_date(date_mode_t flags, int *warnings) const { DBUG_ASSERT(is_valid_datetime_slow()); - return ::check_date(this, (year || month || day), ulonglong(flags), warnings); + return ::check_date(this, (year || month || day), + ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE), + warnings); } bool check_date(date_mode_t flags) const { |