summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql-common/my_time.c18
-rw-r--r--sql/item_timefunc.cc2
-rw-r--r--sql/sql_basic_types.h6
-rw-r--r--sql/sql_time.cc15
-rw-r--r--sql/sql_time.h5
-rw-r--r--sql/sql_type.cc3
-rw-r--r--sql/sql_type.h8
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
{