summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2020-08-24 09:17:47 +0400
committerAlexander Barkov <bar@mariadb.com>2020-08-24 09:17:47 +0400
commit04ce29354b6053f0334ad1b8d5acaa0974b10fd8 (patch)
tree5ca7a164e985ac4f23fa006ab670162833304344
parent2e5d86f49e7ee538806fba68dc8c960d6acdd483 (diff)
downloadmariadb-git-04ce29354b6053f0334ad1b8d5acaa0974b10fd8.tar.gz
MDEV-23551 Performance degratation in temporal literals in 10.4
Problem: Queries like this showed performance degratation in 10.4 over 10.3: SELECT temporal_literal FROM t1; SELECT temporal_literal + 1 FROM t1; SELECT COUNT(*) FROM t1 WHERE temporal_column = temporal_literal; SELECT COUNT(*) FROM t1 WHERE temporal_column = string_literal; Fix: Replacing the universal member "MYSQL_TIME cached_time" in Item_temporal_literal to data type specific containers: - Date in Item_date_literal - Time in Item_time_literal - Datetime in Item_datetime_literal This restores the performance, and make it even better in some cases. See benchmark results in MDEV. Also, this change makes futher separations of Date, Time, Datetime from each other, which will make it possible not to derive them from a too heavy (40 bytes) MYSQL_TIME, and replace them to smaller data type specific containers.
-rw-r--r--sql/field.cc21
-rw-r--r--sql/item.cc27
-rw-r--r--sql/item.h143
-rw-r--r--sql/sql_select.cc9
-rw-r--r--sql/sql_show.cc8
-rw-r--r--sql/sql_type.cc14
-rw-r--r--sql/sql_type.h60
-rw-r--r--sql/table.cc3
8 files changed, 205 insertions, 80 deletions
diff --git a/sql/field.cc b/sql/field.cc
index bac5dd95b5a..4a82eae6a0e 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5818,9 +5818,7 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
See comments about truncation in the same place in
Field_time::get_equal_const_item().
*/
- return new (thd->mem_root) Item_datetime_literal(thd,
- dt.get_mysql_time(),
- decimals());
+ return new (thd->mem_root) Item_datetime_literal(thd, &dt, decimals());
}
break;
case ANY_SUBST:
@@ -5832,7 +5830,7 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
if (!dt.is_valid_datetime())
return NULL;
return new (thd->mem_root)
- Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(),
+ Item_datetime_literal_for_invalid_dates(thd, &dt,
dt.get_mysql_time()->
second_part ?
TIME_SECOND_PART_DIGITS : 0);
@@ -6183,7 +6181,7 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
(assuming CURRENT_DATE is '2015-08-30'
*/
- return new (thd->mem_root) Item_time_literal(thd, tm.get_mysql_time(),
+ return new (thd->mem_root) Item_time_literal(thd, &tm,
tm.get_mysql_time()->
second_part ?
TIME_SECOND_PART_DIGITS :
@@ -6212,8 +6210,7 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
decimals());
if (!tm.is_valid_time())
return NULL;
- return new (thd->mem_root) Item_time_literal(thd, tm.get_mysql_time(),
- decimals());
+ return new (thd->mem_root) Item_time_literal(thd, &tm, decimals());
}
break;
}
@@ -6772,12 +6769,12 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
*/
if (!dt.hhmmssff_is_zero())
return new (thd->mem_root)
- Item_datetime_literal_for_invalid_dates(thd, dt.get_mysql_time(),
+ Item_datetime_literal_for_invalid_dates(thd, &dt,
dt.get_mysql_time()->
second_part ?
TIME_SECOND_PART_DIGITS : 0);
- return new (thd->mem_root)
- Item_date_literal_for_invalid_dates(thd, Date(&dt).get_mysql_time());
+ Date d(&dt);
+ return new (thd->mem_root) Item_date_literal_for_invalid_dates(thd, &d);
}
break;
case IDENTITY_SUBST:
@@ -6792,8 +6789,8 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
Datetime dt(thd, const_item, Datetime::Options(TIME_CONV_NONE, thd));
if (!dt.is_valid_datetime())
return NULL;
- return new (thd->mem_root)
- Item_date_literal(thd, Date(&dt).get_mysql_time());
+ Date d(&dt);
+ return new (thd->mem_root) Item_date_literal(thd, &d);
}
break;
}
diff --git a/sql/item.cc b/sql/item.cc
index 22a8cb169b3..d8074dbb013 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -6998,7 +6998,7 @@ void Item_date_literal::print(String *str, enum_query_type query_type)
{
str->append("DATE'");
char buf[MAX_DATE_STRING_REP_LENGTH];
- my_date_to_str(&cached_time, buf);
+ my_date_to_str(cached_time.get_mysql_time(), buf);
str->append(buf);
str->append('\'');
}
@@ -7013,7 +7013,7 @@ Item *Item_date_literal::clone_item(THD *thd)
bool Item_date_literal::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
fuzzydate |= sql_mode_for_dates(thd);
- *ltime= cached_time;
+ cached_time.copy_to_mysql_time(ltime);
return (null_value= check_date_with_warn(thd, ltime, fuzzydate,
MYSQL_TIMESTAMP_ERROR));
}
@@ -7023,7 +7023,7 @@ void Item_datetime_literal::print(String *str, enum_query_type query_type)
{
str->append("TIMESTAMP'");
char buf[MAX_DATE_STRING_REP_LENGTH];
- my_datetime_to_str(&cached_time, buf, decimals);
+ my_datetime_to_str(cached_time.get_mysql_time(), buf, decimals);
str->append(buf);
str->append('\'');
}
@@ -7038,7 +7038,7 @@ Item *Item_datetime_literal::clone_item(THD *thd)
bool Item_datetime_literal::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
fuzzydate |= sql_mode_for_dates(thd);
- *ltime= cached_time;
+ cached_time.copy_to_mysql_time(ltime);
return (null_value= check_date_with_warn(thd, ltime, fuzzydate,
MYSQL_TIMESTAMP_ERROR));
}
@@ -7048,7 +7048,7 @@ void Item_time_literal::print(String *str, enum_query_type query_type)
{
str->append("TIME'");
char buf[MAX_DATE_STRING_REP_LENGTH];
- my_time_to_str(&cached_time, buf, decimals);
+ my_time_to_str(cached_time.get_mysql_time(), buf, decimals);
str->append(buf);
str->append('\'');
}
@@ -7062,7 +7062,7 @@ Item *Item_time_literal::clone_item(THD *thd)
bool Item_time_literal::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- *ltime= cached_time;
+ cached_time.copy_to_mysql_time(ltime);
if (fuzzydate & TIME_TIME_ONLY)
return (null_value= false);
return (null_value= check_date_with_warn(thd, ltime, fuzzydate,
@@ -9922,23 +9922,20 @@ Item *Item_cache_temporal::convert_to_basic_const_item(THD *thd)
Item *Item_cache_datetime::make_literal(THD *thd)
{
- MYSQL_TIME ltime;
- unpack_time(val_datetime_packed(thd), &ltime, MYSQL_TIMESTAMP_DATETIME);
- return new (thd->mem_root) Item_datetime_literal(thd, &ltime, decimals);
+ Datetime dt(thd, this, TIME_CONV_NONE | TIME_FRAC_NONE);
+ return new (thd->mem_root) Item_datetime_literal(thd, &dt, decimals);
}
Item *Item_cache_date::make_literal(THD *thd)
{
- MYSQL_TIME ltime;
- unpack_time(val_datetime_packed(thd), &ltime, MYSQL_TIMESTAMP_DATE);
- return new (thd->mem_root) Item_date_literal(thd, &ltime);
+ Date d(thd, this, TIME_CONV_NONE | TIME_FRAC_NONE);
+ return new (thd->mem_root) Item_date_literal(thd, &d);
}
Item *Item_cache_time::make_literal(THD *thd)
{
- MYSQL_TIME ltime;
- unpack_time(val_time_packed(thd), &ltime, MYSQL_TIMESTAMP_TIME);
- return new (thd->mem_root) Item_time_literal(thd, &ltime, decimals);
+ Time t(thd, this);
+ return new (thd->mem_root) Item_time_literal(thd, &t, decimals);
}
diff --git a/sql/item.h b/sql/item.h
index 95ca06ac211..bff60d60506 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4820,29 +4820,20 @@ public:
class Item_temporal_literal :public Item_literal
{
-protected:
- MYSQL_TIME cached_time;
public:
- /**
- Constructor for Item_date_literal.
- @param ltime DATE value.
- */
- Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime)
+ Item_temporal_literal(THD *thd)
:Item_literal(thd)
{
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
decimals= 0;
- cached_time= *ltime;
}
- Item_temporal_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
+ Item_temporal_literal(THD *thd, uint dec_arg):
Item_literal(thd)
{
collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
decimals= dec_arg;
- cached_time= *ltime;
}
- const MYSQL_TIME *const_ptr_mysql_time() const { return &cached_time; }
int save_in_field(Field *field, bool no_conversions)
{ return save_date_in_field(field, no_conversions); }
};
@@ -4853,27 +4844,62 @@ public:
*/
class Item_date_literal: public Item_temporal_literal
{
+protected:
+ Date cached_time;
+ bool update_null()
+ {
+ return maybe_null &&
+ (null_value= cached_time.check_date_with_warn(current_thd));
+ }
public:
- Item_date_literal(THD *thd, const MYSQL_TIME *ltime)
- :Item_temporal_literal(thd, ltime)
+ Item_date_literal(THD *thd, const Date *ltime)
+ :Item_temporal_literal(thd),
+ cached_time(*ltime)
{
+ DBUG_ASSERT(cached_time.is_valid_date());
max_length= MAX_DATE_WIDTH;
/*
If date has zero month or day, it can return NULL in case of
NO_ZERO_DATE or NO_ZERO_IN_DATE.
- We can't just check the current sql_mode here in constructor,
+ If date is `February 30`, it can return NULL in case if
+ no ALLOW_INVALID_DATES is set.
+ We can't set null_value using the current sql_mode here in constructor,
because sql_mode can change in case of prepared statements
between PREPARE and EXECUTE.
+ Here we only set maybe_null to true if the value has such anomalies.
+ Later (during execution time), if maybe_null is true, then the value
+ will be checked per row, according to the execution time sql_mode.
+ The check_date() below call should cover all cases mentioned.
*/
- maybe_null= !ltime->month || !ltime->day;
+ maybe_null= cached_time.check_date(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
}
const Type_handler *type_handler() const { return &type_handler_newdate; }
void print(String *str, enum_query_type query_type);
+ const MYSQL_TIME *const_ptr_mysql_time() const
+ {
+ return cached_time.get_mysql_time();
+ }
Item *clone_item(THD *thd);
- longlong val_int() { return Date(this).to_longlong(); }
- double val_real() { return Date(this).to_double(); }
- String *val_str(String *to) { return Date(this).to_string(to); }
- my_decimal *val_decimal(my_decimal *to) { return Date(this).to_decimal(to); }
+ longlong val_int()
+ {
+ return update_null() ? 0 : cached_time.to_longlong();
+ }
+ double val_real()
+ {
+ return update_null() ? 0 : cached_time.to_double();
+ }
+ String *val_str(String *to)
+ {
+ return update_null() ? 0 : cached_time.to_string(to);
+ }
+ my_decimal *val_decimal(my_decimal *to)
+ {
+ return update_null() ? 0 : cached_time.to_decimal(to);
+ }
+ longlong val_datetime_packed(THD *thd)
+ {
+ return update_null() ? 0 : cached_time.valid_date_to_packed();
+ }
bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_date_literal>(thd, this); }
@@ -4885,19 +4911,31 @@ public:
*/
class Item_time_literal: public Item_temporal_literal
{
+protected:
+ Time cached_time;
public:
- Item_time_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
- Item_temporal_literal(thd, ltime, dec_arg)
+ Item_time_literal(THD *thd, const Time *ltime, uint dec_arg):
+ Item_temporal_literal(thd, dec_arg),
+ cached_time(*ltime)
{
+ DBUG_ASSERT(cached_time.is_valid_time());
max_length= MIN_TIME_WIDTH + (decimals ? decimals + 1 : 0);
}
const Type_handler *type_handler() const { return &type_handler_time2; }
void print(String *str, enum_query_type query_type);
+ const MYSQL_TIME *const_ptr_mysql_time() const
+ {
+ return cached_time.get_mysql_time();
+ }
Item *clone_item(THD *thd);
- longlong val_int() { return Time(this).to_longlong(); }
- double val_real() { return Time(this).to_double(); }
- String *val_str(String *to) { return Time(this).to_string(to, decimals); }
- my_decimal *val_decimal(my_decimal *to) { return Time(this).to_decimal(to); }
+ longlong val_int() { return cached_time.to_longlong(); }
+ double val_real() { return cached_time.to_double(); }
+ String *val_str(String *to) { return cached_time.to_string(to, decimals); }
+ my_decimal *val_decimal(my_decimal *to) { return cached_time.to_decimal(to); }
+ longlong val_time_packed(THD *thd)
+ {
+ return cached_time.valid_time_to_packed();
+ }
bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
bool val_native(THD *thd, Native *to)
{
@@ -4913,26 +4951,49 @@ public:
*/
class Item_datetime_literal: public Item_temporal_literal
{
+protected:
+ Datetime cached_time;
+ bool update_null()
+ {
+ return maybe_null &&
+ (null_value= cached_time.check_date_with_warn(current_thd));
+ }
public:
- Item_datetime_literal(THD *thd, const MYSQL_TIME *ltime, uint dec_arg):
- Item_temporal_literal(thd, ltime, dec_arg)
+ Item_datetime_literal(THD *thd, const Datetime *ltime, uint dec_arg):
+ Item_temporal_literal(thd, dec_arg),
+ cached_time(*ltime)
{
+ DBUG_ASSERT(cached_time.is_valid_datetime());
max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0);
// See the comment on maybe_null in Item_date_literal
- maybe_null= !ltime->month || !ltime->day;
+ maybe_null= cached_time.check_date(TIME_NO_ZERO_DATE | TIME_NO_ZERO_IN_DATE);
}
const Type_handler *type_handler() const { return &type_handler_datetime2; }
void print(String *str, enum_query_type query_type);
+ const MYSQL_TIME *const_ptr_mysql_time() const
+ {
+ return cached_time.get_mysql_time();
+ }
Item *clone_item(THD *thd);
- longlong val_int() { return Datetime(this).to_longlong(); }
- double val_real() { return Datetime(this).to_double(); }
+ longlong val_int()
+ {
+ return update_null() ? 0 : cached_time.to_longlong();
+ }
+ double val_real()
+ {
+ return update_null() ? 0 : cached_time.to_double();
+ }
String *val_str(String *to)
{
- return Datetime(this).to_string(to, decimals);
+ return update_null() ? NULL : cached_time.to_string(to, decimals);
}
my_decimal *val_decimal(my_decimal *to)
{
- return Datetime(this).to_decimal(to);
+ return update_null() ? NULL : cached_time.to_decimal(to);
+ }
+ longlong val_datetime_packed(THD *thd)
+ {
+ return update_null() ? 0 : cached_time.valid_datetime_to_packed();
}
bool get_date(THD *thd, MYSQL_TIME *res, date_mode_t fuzzydate);
Item *get_copy(THD *thd)
@@ -4969,11 +5030,14 @@ class Item_date_literal_for_invalid_dates: public Item_date_literal
in sql_mode=TRADITIONAL.
*/
public:
- Item_date_literal_for_invalid_dates(THD *thd, const MYSQL_TIME *ltime)
- :Item_date_literal(thd, ltime) { }
+ Item_date_literal_for_invalid_dates(THD *thd, const Date *ltime)
+ :Item_date_literal(thd, ltime)
+ {
+ maybe_null= false;
+ }
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- *ltime= cached_time;
+ cached_time.copy_to_mysql_time(ltime);
return (null_value= false);
}
};
@@ -4987,11 +5051,14 @@ class Item_datetime_literal_for_invalid_dates: public Item_datetime_literal
{
public:
Item_datetime_literal_for_invalid_dates(THD *thd,
- const MYSQL_TIME *ltime, uint dec_arg)
- :Item_datetime_literal(thd, ltime, dec_arg) { }
+ const Datetime *ltime, uint dec_arg)
+ :Item_datetime_literal(thd, ltime, dec_arg)
+ {
+ maybe_null= false;
+ }
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate)
{
- *ltime= cached_time;
+ cached_time.copy_to_mysql_time(ltime);
return (null_value= false);
}
};
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 19e36632f0c..7091ffc2c58 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -722,8 +722,9 @@ bool vers_select_conds_t::init_from_sysvar(THD *thd)
if (type != SYSTEM_TIME_UNSPECIFIED && type != SYSTEM_TIME_ALL)
{
DBUG_ASSERT(type == SYSTEM_TIME_AS_OF);
+ Datetime dt(&in.ltime);
start.item= new (thd->mem_root)
- Item_datetime_literal(thd, &in.ltime, TIME_SECOND_PART_DIGITS);
+ Item_datetime_literal(thd, &dt, TIME_SECOND_PART_DIGITS);
if (!start.item)
return true;
}
@@ -787,15 +788,17 @@ Item* period_get_condition(THD *thd, TABLE_LIST *table, SELECT_LEX *select,
{
case SYSTEM_TIME_UNSPECIFIED:
case SYSTEM_TIME_HISTORY:
+ {
thd->variables.time_zone->gmt_sec_to_TIME(&max_time, TIMESTAMP_MAX_VALUE);
max_time.second_part= TIME_MAX_SECOND_PART;
- curr= newx Item_datetime_literal(thd, &max_time, TIME_SECOND_PART_DIGITS);
+ Datetime dt(&max_time);
+ curr= newx Item_datetime_literal(thd, &dt, TIME_SECOND_PART_DIGITS);
if (conds->type == SYSTEM_TIME_UNSPECIFIED)
cond1= newx Item_func_eq(thd, conds->field_end, curr);
else
cond1= newx Item_func_lt(thd, conds->field_end, curr);
break;
- break;
+ }
case SYSTEM_TIME_AS_OF:
cond1= newx Item_func_le(thd, conds->field_start, conds->start.item);
cond2= newx Item_func_gt(thd, conds->field_end, conds->start.item);
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 2f8de331d30..3ffb5338053 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -10082,11 +10082,6 @@ int finalize_schema_table(st_plugin_int *plugin)
DBUG_RETURN(0);
}
-/*
- This is used to create a timestamp field
-*/
-
-MYSQL_TIME zero_time={ 0,0,0,0,0,0,0,0, MYSQL_TIMESTAMP_TIME };
/**
Output trigger information (SHOW CREATE TRIGGER) to the client.
@@ -10171,8 +10166,9 @@ static bool show_create_trigger_impl(THD *thd, Trigger *trigger)
MY_CS_NAME_SIZE),
mem_root);
+ static const Datetime zero_datetime(Datetime::zero());
Item_datetime_literal *tmp= (new (mem_root)
- Item_datetime_literal(thd, &zero_time, 2));
+ Item_datetime_literal(thd, &zero_datetime, 2));
tmp->set_name(thd, STRING_WITH_LEN("Created"), system_charset_info);
fields.push_back(tmp, mem_root);
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 85052a1c1bc..0c26e947789 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -8391,7 +8391,10 @@ Type_handler_date_common::create_literal_item(THD *thd,
if (tmp.is_valid_temporal() &&
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATE &&
!have_important_literal_warnings(&st))
- item= new (thd->mem_root) Item_date_literal(thd, tmp.get_mysql_time());
+ {
+ Date d(&tmp);
+ item= new (thd->mem_root) Item_date_literal(thd, &d);
+ }
literal_warn(thd, item, str, length, cs, &st, "DATE", send_error);
return item;
}
@@ -8410,8 +8413,10 @@ Type_handler_temporal_with_date::create_literal_item(THD *thd,
if (tmp.is_valid_temporal() &&
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATETIME &&
!have_important_literal_warnings(&st))
- item= new (thd->mem_root) Item_datetime_literal(thd, tmp.get_mysql_time(),
- st.precision);
+ {
+ Datetime dt(&tmp);
+ item= new (thd->mem_root) Item_datetime_literal(thd, &dt, st.precision);
+ }
literal_warn(thd, item, str, length, cs, &st, "DATETIME", send_error);
return item;
}
@@ -8430,8 +8435,7 @@ Type_handler_time_common::create_literal_item(THD *thd,
Time tmp(thd, &st, str, length, cs, opt);
if (tmp.is_valid_time() &&
!have_important_literal_warnings(&st))
- item= new (thd->mem_root) Item_time_literal(thd, tmp.get_mysql_time(),
- st.precision);
+ item= new (thd->mem_root) Item_time_literal(thd, &tmp, st.precision);
literal_warn(thd, item, str, length, cs, &st, "TIME", send_error);
return item;
}
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 8726208b788..2064a55dc14 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -1722,6 +1722,11 @@ public:
{
return is_valid_time() ? Temporal::to_packed() : 0;
}
+ longlong valid_time_to_packed() const
+ {
+ DBUG_ASSERT(is_valid_time_slow());
+ return Temporal::to_packed();
+ }
long fraction_remainder(uint dec) const
{
DBUG_ASSERT(is_valid_time());
@@ -1896,6 +1901,11 @@ public:
{
return ::check_date_with_warn(thd, this, flags, MYSQL_TIMESTAMP_ERROR);
}
+ bool check_date_with_warn(THD *thd)
+ {
+ return ::check_date_with_warn(thd, this, Temporal::sql_mode_for_dates(thd),
+ MYSQL_TIMESTAMP_ERROR);
+ }
static date_conv_mode_t comparison_flags_for_get_date()
{ return TIME_INVALID_DATES | TIME_FUZZY_DATES; }
};
@@ -1964,11 +1974,37 @@ public:
datetime_to_date(this);
DBUG_ASSERT(is_valid_date_slow());
}
+ explicit Date(const Temporal_hybrid *from)
+ {
+ *(static_cast<MYSQL_TIME*>(this))= *from;
+ DBUG_ASSERT(is_valid_date_slow());
+ }
bool is_valid_date() const
{
DBUG_ASSERT(is_valid_value_slow());
return time_type == MYSQL_TIMESTAMP_DATE;
}
+ bool check_date(date_conv_mode_t flags, int *warnings) const
+ {
+ DBUG_ASSERT(is_valid_date_slow());
+ return ::check_date(this, (year || month || day),
+ ulonglong(flags & TIME_MODE_FOR_XXX_TO_DATE),
+ warnings);
+ }
+ bool check_date(THD *thd, int *warnings) const
+ {
+ return check_date(Temporal::sql_mode_for_dates(thd), warnings);
+ }
+ bool check_date(date_conv_mode_t flags) const
+ {
+ int dummy; /* unused */
+ return check_date(flags, &dummy);
+ }
+ bool check_date(THD *thd) const
+ {
+ int dummy;
+ return check_date(Temporal::sql_mode_for_dates(thd), &dummy);
+ }
const MYSQL_TIME *get_mysql_time() const
{
DBUG_ASSERT(is_valid_date_slow());
@@ -2011,6 +2047,11 @@ public:
return Temporal_with_date::yearweek(week_behaviour);
}
+ longlong valid_date_to_packed() const
+ {
+ DBUG_ASSERT(is_valid_date_slow());
+ return Temporal::to_packed();
+ }
longlong to_longlong() const
{
return is_valid_date() ? (longlong) TIME_to_ulonglong_date(this) : 0LL;
@@ -2197,6 +2238,16 @@ public:
{
round(thd, dec, time_round_mode_t(fuzzydate), warn);
}
+ explicit Datetime(const Temporal_hybrid *from)
+ {
+ *(static_cast<MYSQL_TIME*>(this))= *from;
+ DBUG_ASSERT(is_valid_datetime_slow());
+ }
+ explicit Datetime(const MYSQL_TIME *from)
+ {
+ *(static_cast<MYSQL_TIME*>(this))= *from;
+ DBUG_ASSERT(is_valid_datetime_slow());
+ }
bool is_valid_datetime() const
{
@@ -2219,6 +2270,10 @@ public:
int dummy; /* unused */
return check_date(flags, &dummy);
}
+ bool check_date(THD *thd) const
+ {
+ return check_date(Temporal::sql_mode_for_dates(thd));
+ }
bool hhmmssff_is_zero() const
{
DBUG_ASSERT(is_valid_datetime_slow());
@@ -2327,6 +2382,11 @@ public:
{
return is_valid_datetime() ? Temporal::to_packed() : 0;
}
+ longlong valid_datetime_to_packed() const
+ {
+ DBUG_ASSERT(is_valid_datetime_slow());
+ return Temporal::to_packed();
+ }
long fraction_remainder(uint dec) const
{
DBUG_ASSERT(is_valid_datetime());
diff --git a/sql/table.cc b/sql/table.cc
index ca0af28a79d..6fa2ef51f89 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -9365,7 +9365,8 @@ bool TR_table::query(MYSQL_TIME &commit_time, bool backwards)
SELECT_LEX &slex= *(thd->lex->first_select_lex());
Name_resolution_context_backup backup(slex.context, *this);
Item *field= newx Item_field(thd, &slex.context, (*this)[FLD_COMMIT_TS]);
- Item *value= newx Item_datetime_literal(thd, &commit_time, 6);
+ Datetime dt(&commit_time);
+ Item *value= newx Item_datetime_literal(thd, &dt, 6);
COND *conds;
if (backwards)
conds= newx Item_func_ge(thd, field, value);