mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
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.
This commit is contained in:
56
sql/field.cc
56
sql/field.cc
@ -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(<ime, Datetime::Options_cmp(thd)))
|
||||||
|
return 0;
|
||||||
|
if (ltime.time_type != MYSQL_TIMESTAMP_TIME)
|
||||||
|
return pack_time(<ime);
|
||||||
|
if (time_to_datetime_with_warn(thd, <ime, &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(<ime, opt))
|
||||||
|
return 0;
|
||||||
|
if (ltime.time_type == MYSQL_TIMESTAMP_TIME)
|
||||||
|
return pack_time(<ime);
|
||||||
|
// Conversion from DATETIME or DATE to TIME is needed
|
||||||
|
return Time(thd, <ime, 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)
|
|||||||
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(<ime, tmp);
|
||||||
|
return pack_time(<ime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
longlong Field_newdate::val_datetime_packed(THD *thd)
|
||||||
|
{
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
Field_newdate::get_date(<ime, date_mode_t(0));
|
||||||
|
return pack_time(<ime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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,
|
|||||||
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(<ime, tmp);
|
||||||
|
return pack_time(<ime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** string type
|
** string type
|
||||||
** A string may be varchar or binary
|
** A string may be varchar or binary
|
||||||
|
@ -1401,6 +1401,8 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
}
|
}
|
||||||
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 @@ public:
|
|||||||
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); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
18
sql/item.cc
18
sql/item.cc
@ -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 @@ public:
|
|||||||
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 @@ public:
|
|||||||
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)
|
||||||
{ }
|
{ }
|
||||||
|
Reference in New Issue
Block a user