Commit 2e5d86f4 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-23537 Comparison with temporal columns is slow in MariaDB

Implementing methods:
- Field::val_time_packed()
- Field::val_datetime_packed()
- Item_field::val_datetime_packed(THD *thd);
- Item_field::val_time_packed(THD *thd);
to give a faster access to temporal packed longlong representation of a Field,
which is used in temporal Arg_comparator's to DATE, TIME, DATETIME data types.

The same idea is used in MySQL-5.6+.

This improves performance.
parent ae33ebe5
...@@ -2328,6 +2328,33 @@ bool Field::get_date(MYSQL_TIME *to, date_mode_t mode) ...@@ -2328,6 +2328,33 @@ bool Field::get_date(MYSQL_TIME *to, date_mode_t mode)
return !t->is_valid_temporal(); return !t->is_valid_temporal();
} }
longlong Field::val_datetime_packed(THD *thd)
{
MYSQL_TIME ltime, tmp;
if (get_date(&ltime, Datetime::Options_cmp(thd)))
return 0;
if (ltime.time_type != MYSQL_TIMESTAMP_TIME)
return pack_time(&ltime);
if (time_to_datetime_with_warn(thd, &ltime, &tmp, TIME_CONV_NONE))
return 0;
return pack_time(&tmp);
}
longlong Field::val_time_packed(THD *thd)
{
MYSQL_TIME ltime;
Time::Options_cmp opt(thd);
if (get_date(&ltime, opt))
return 0;
if (ltime.time_type == MYSQL_TIMESTAMP_TIME)
return pack_time(&ltime);
// Conversion from DATETIME or DATE to TIME is needed
return Time(thd, &ltime, opt).to_packed();
}
/** /**
This is called when storing a date in a string. This is called when storing a date in a string.
...@@ -6272,6 +6299,17 @@ bool Field_timef::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) ...@@ -6272,6 +6299,17 @@ bool Field_timef::get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
return false; return false;
} }
longlong Field_timef::val_time_packed(THD *thd)
{
DBUG_ASSERT(marked_for_read());
longlong tmp= my_time_packed_from_binary(ptr, dec);
MYSQL_TIME ltime;
TIME_from_longlong_time_packed(&ltime, tmp);
return pack_time(&ltime);
}
int Field_timef::store_native(const Native &value) int Field_timef::store_native(const Native &value)
{ {
DBUG_ASSERT(value.length() == my_time_binary_length(dec)); DBUG_ASSERT(value.length() == my_time_binary_length(dec));
...@@ -6673,6 +6711,14 @@ bool Field_newdate::get_TIME(MYSQL_TIME *ltime, const uchar *pos, ...@@ -6673,6 +6711,14 @@ bool Field_newdate::get_TIME(MYSQL_TIME *ltime, const uchar *pos,
} }
longlong Field_newdate::val_datetime_packed(THD *thd)
{
MYSQL_TIME ltime;
Field_newdate::get_date(&ltime, date_mode_t(0));
return pack_time(&ltime);
}
int Field_newdate::cmp(const uchar *a_ptr, const uchar *b_ptr) int Field_newdate::cmp(const uchar *a_ptr, const uchar *b_ptr)
{ {
uint32 a,b; uint32 a,b;
...@@ -7008,6 +7054,16 @@ bool Field_datetimef::get_TIME(MYSQL_TIME *ltime, const uchar *pos, ...@@ -7008,6 +7054,16 @@ bool Field_datetimef::get_TIME(MYSQL_TIME *ltime, const uchar *pos,
return validate_MMDD(tmp, ltime->month, ltime->day, fuzzydate); return validate_MMDD(tmp, ltime->month, ltime->day, fuzzydate);
} }
longlong Field_datetimef::val_datetime_packed(THD *thd)
{
DBUG_ASSERT(marked_for_read());
longlong tmp= my_datetime_packed_from_binary(ptr, dec);
MYSQL_TIME ltime;
TIME_from_longlong_datetime_packed(&ltime, tmp);
return pack_time(&ltime);
}
/**************************************************************************** /****************************************************************************
** string type ** string type
** A string may be varchar or binary ** A string may be varchar or binary
......
...@@ -1401,6 +1401,8 @@ class Field: public Value_source ...@@ -1401,6 +1401,8 @@ class Field: public Value_source
void copy_from_tmp(int offset); void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy); uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate); virtual bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
virtual longlong val_datetime_packed(THD *thd);
virtual longlong val_time_packed(THD *thd);
virtual TYPELIB *get_typelib() const { return NULL; } virtual TYPELIB *get_typelib() const { return NULL; }
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; } virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
virtual CHARSET_INFO *charset_for_protocol(void) const virtual CHARSET_INFO *charset_for_protocol(void) const
...@@ -3167,6 +3169,7 @@ class Field_newdate :public Field_date_common ...@@ -3167,6 +3169,7 @@ class Field_newdate :public Field_date_common
void sql_type(String &str) const; void sql_type(String &str) const;
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
{ return Field_newdate::get_TIME(ltime, ptr, fuzzydate); } { return Field_newdate::get_TIME(ltime, ptr, fuzzydate); }
longlong val_datetime_packed(THD *thd);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item); Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item);
}; };
...@@ -3336,6 +3339,7 @@ class Field_timef :public Field_time_with_dec { ...@@ -3336,6 +3339,7 @@ class Field_timef :public Field_time_with_dec {
} }
int reset(); int reset();
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate); bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
longlong val_time_packed(THD *thd);
int store_native(const Native &value); int store_native(const Native &value);
bool val_native(Native *to); bool val_native(Native *to);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
...@@ -3495,6 +3499,7 @@ class Field_datetimef :public Field_datetime_with_dec { ...@@ -3495,6 +3499,7 @@ class Field_datetimef :public Field_datetime_with_dec {
int reset(); int reset();
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate) bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate)
{ return Field_datetimef::get_TIME(ltime, ptr, fuzzydate); } { return Field_datetimef::get_TIME(ltime, ptr, fuzzydate); }
longlong val_datetime_packed(THD *thd);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
}; };
......
...@@ -3246,6 +3246,24 @@ bool Item_field::val_native_result(THD *thd, Native *to) ...@@ -3246,6 +3246,24 @@ bool Item_field::val_native_result(THD *thd, Native *to)
} }
longlong Item_field::val_datetime_packed(THD *thd)
{
DBUG_ASSERT(fixed == 1);
if ((null_value= field->is_null()))
return 0;
return field->val_datetime_packed(thd);
}
longlong Item_field::val_time_packed(THD *thd)
{
DBUG_ASSERT(fixed == 1);
if ((null_value= field->is_null()))
return 0;
return field->val_time_packed(thd);
}
void Item_field::save_result(Field *to) void Item_field::save_result(Field *to)
{ {
save_field_in_field(result_field, &null_value, to, TRUE); save_field_in_field(result_field, &null_value, to, TRUE);
......
...@@ -3418,6 +3418,8 @@ class Item_field :public Item_ident, ...@@ -3418,6 +3418,8 @@ class Item_field :public Item_ident,
longlong val_int_endpoint(bool left_endp, bool *incl_endp); longlong val_int_endpoint(bool left_endp, bool *incl_endp);
bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate); bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate);
bool get_date_result(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate); bool get_date_result(THD *thd, MYSQL_TIME *ltime,date_mode_t fuzzydate);
longlong val_datetime_packed(THD *thd);
longlong val_time_packed(THD *thd);
bool is_null() { return field->is_null(); } bool is_null() { return field->is_null(); }
void update_null_value(); void update_null_value();
void update_table_bitmaps() void update_table_bitmaps()
......
...@@ -1542,6 +1542,13 @@ class Time: public Temporal ...@@ -1542,6 +1542,13 @@ class Time: public Temporal
Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second); Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second);
Time() { time_type= MYSQL_TIMESTAMP_NONE; } Time() { time_type= MYSQL_TIMESTAMP_NONE; }
Time(const Native &native); Time(const Native &native);
Time(THD *thd, const MYSQL_TIME *ltime, const Options opt)
{
*(static_cast<MYSQL_TIME*>(this))= *ltime;
DBUG_ASSERT(is_valid_temporal());
int warn= 0;
valid_MYSQL_TIME_to_valid_value(thd, &warn, opt);
}
Time(Item *item) Time(Item *item)
:Time(current_thd, item) :Time(current_thd, item)
{ } { }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment