mirror of
https://github.com/MariaDB/server.git
synced 2025-07-10 04:22:00 +03:00
MDEV-12559 Split Item::temporal_precision() into virtual methods in Type_handler
- Adding a new virtual method Type_handler::Item_time_precision() - Adding a new virtual method Type_handler::Item_datetime_precision() - Removing Item::temporal_precision() and adding Item::time_precision() and Item::datetime_precision() instead. - Moving Item_func_convert_tz::fix_length_and_dec() from item_timefunc.cc to item_timefunc.h. It's only two lines, and we're changing it anyway. - Removing Item_temporal_typecast::fix_length_and_dec_generic(), moving this code to Type_handler::Item_{date|time|datetime}_typecast_fix_length_and_dec(). This allows to get rid of one more field_type() call. Also, in the old reduction, Item_date_typecast::fix_length_and_dec() unnecessarily called args[0]->temporal_precision(). The new reduction does not call args[0]->datetime_precision(), as DATE does not have fractional digits.
This commit is contained in:
21
sql/item.cc
21
sql/item.cc
@ -555,27 +555,6 @@ uint Item::decimal_precision() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint Item::temporal_precision(enum_field_types type_arg)
|
|
||||||
{
|
|
||||||
if (const_item() && result_type() == STRING_RESULT &&
|
|
||||||
!is_temporal_type(field_type()))
|
|
||||||
{
|
|
||||||
MYSQL_TIME ltime;
|
|
||||||
String buf, *tmp;
|
|
||||||
MYSQL_TIME_STATUS status;
|
|
||||||
DBUG_ASSERT(fixed);
|
|
||||||
if ((tmp= val_str(&buf)) &&
|
|
||||||
!(type_arg == MYSQL_TYPE_TIME ?
|
|
||||||
str_to_time(tmp->charset(), tmp->ptr(), tmp->length(),
|
|
||||||
<ime, TIME_TIME_ONLY, &status) :
|
|
||||||
str_to_datetime(tmp->charset(), tmp->ptr(), tmp->length(),
|
|
||||||
<ime, TIME_FUZZY_DATES, &status)))
|
|
||||||
return MY_MIN(status.precision, TIME_SECOND_PART_DIGITS);
|
|
||||||
}
|
|
||||||
return MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Item::print_parenthesised(String *str, enum_query_type query_type,
|
void Item::print_parenthesised(String *str, enum_query_type query_type,
|
||||||
enum precedence parent_prec)
|
enum precedence parent_prec)
|
||||||
{
|
{
|
||||||
|
11
sql/item.h
11
sql/item.h
@ -1187,7 +1187,16 @@ public:
|
|||||||
/**
|
/**
|
||||||
TIME or DATETIME precision of the item: 0..6
|
TIME or DATETIME precision of the item: 0..6
|
||||||
*/
|
*/
|
||||||
uint temporal_precision(enum_field_types type);
|
uint time_precision()
|
||||||
|
{
|
||||||
|
return const_item() ? type_handler()->Item_time_precision(this) :
|
||||||
|
MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
|
||||||
|
}
|
||||||
|
uint datetime_precision()
|
||||||
|
{
|
||||||
|
return const_item() ? type_handler()->Item_datetime_precision(this) :
|
||||||
|
MY_MIN(decimals, TIME_SECOND_PART_DIGITS);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Returns true if this is constant (during query execution, i.e. its value
|
Returns true if this is constant (during query execution, i.e. its value
|
||||||
will not change until next fix_fields) and its value is known.
|
will not change until next fix_fields) and its value is known.
|
||||||
|
@ -2009,13 +2009,6 @@ bool Item_func_from_unixtime::get_date(MYSQL_TIME *ltime,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Item_func_convert_tz::fix_length_and_dec()
|
|
||||||
{
|
|
||||||
fix_attributes_datetime(args[0]->temporal_precision(MYSQL_TYPE_DATETIME));
|
|
||||||
maybe_null= true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
|
bool Item_func_convert_tz::get_date(MYSQL_TIME *ltime,
|
||||||
ulonglong fuzzy_date __attribute__((unused)))
|
ulonglong fuzzy_date __attribute__((unused)))
|
||||||
{
|
{
|
||||||
@ -2099,8 +2092,7 @@ void Item_date_add_interval::fix_length_and_dec()
|
|||||||
if (arg0_field_type == MYSQL_TYPE_DATETIME ||
|
if (arg0_field_type == MYSQL_TYPE_DATETIME ||
|
||||||
arg0_field_type == MYSQL_TYPE_TIMESTAMP)
|
arg0_field_type == MYSQL_TYPE_TIMESTAMP)
|
||||||
{
|
{
|
||||||
uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME),
|
uint dec= MY_MAX(args[0]->datetime_precision(), interval_dec);
|
||||||
interval_dec);
|
|
||||||
set_handler(&type_handler_datetime);
|
set_handler(&type_handler_datetime);
|
||||||
fix_attributes_datetime(dec);
|
fix_attributes_datetime(dec);
|
||||||
}
|
}
|
||||||
@ -2119,7 +2111,7 @@ void Item_date_add_interval::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
else if (arg0_field_type == MYSQL_TYPE_TIME)
|
else if (arg0_field_type == MYSQL_TYPE_TIME)
|
||||||
{
|
{
|
||||||
uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME), interval_dec);
|
uint dec= MY_MAX(args[0]->time_precision(), interval_dec);
|
||||||
if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH)
|
if (int_type >= INTERVAL_DAY && int_type != INTERVAL_YEAR_MONTH)
|
||||||
{
|
{
|
||||||
set_handler(&type_handler_time2);
|
set_handler(&type_handler_time2);
|
||||||
@ -2133,8 +2125,7 @@ void Item_date_add_interval::fix_length_and_dec()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME),
|
uint dec= MY_MAX(args[0]->datetime_precision(), interval_dec);
|
||||||
interval_dec);
|
|
||||||
set_handler(&type_handler_string);
|
set_handler(&type_handler_string);
|
||||||
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
|
collation.set(default_charset(), DERIVATION_COERCIBLE, MY_REPERTOIRE_ASCII);
|
||||||
fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec);
|
fix_char_length_temporal_not_fixed_dec(MAX_DATETIME_WIDTH, dec);
|
||||||
@ -2669,15 +2660,13 @@ void Item_func_add_time::fix_length_and_dec()
|
|||||||
arg0_field_type == MYSQL_TYPE_TIMESTAMP ||
|
arg0_field_type == MYSQL_TYPE_TIMESTAMP ||
|
||||||
is_date)
|
is_date)
|
||||||
{
|
{
|
||||||
uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_DATETIME),
|
uint dec= MY_MAX(args[0]->datetime_precision(), args[1]->time_precision());
|
||||||
args[1]->temporal_precision(MYSQL_TYPE_TIME));
|
|
||||||
set_handler(&type_handler_datetime2);
|
set_handler(&type_handler_datetime2);
|
||||||
fix_attributes_datetime(dec);
|
fix_attributes_datetime(dec);
|
||||||
}
|
}
|
||||||
else if (arg0_field_type == MYSQL_TYPE_TIME)
|
else if (arg0_field_type == MYSQL_TYPE_TIME)
|
||||||
{
|
{
|
||||||
uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
|
uint dec= MY_MAX(args[0]->time_precision(), args[1]->time_precision());
|
||||||
args[1]->temporal_precision(MYSQL_TYPE_TIME));
|
|
||||||
set_handler(&type_handler_time2);
|
set_handler(&type_handler_time2);
|
||||||
fix_attributes_time(dec);
|
fix_attributes_time(dec);
|
||||||
}
|
}
|
||||||
|
@ -443,16 +443,13 @@ class Item_func_dayname :public Item_func_weekday
|
|||||||
|
|
||||||
class Item_func_seconds_hybrid: public Item_func_numhybrid
|
class Item_func_seconds_hybrid: public Item_func_numhybrid
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
virtual enum_field_types arg0_expected_type() const = 0;
|
|
||||||
public:
|
public:
|
||||||
Item_func_seconds_hybrid(THD *thd): Item_func_numhybrid(thd) {}
|
Item_func_seconds_hybrid(THD *thd): Item_func_numhybrid(thd) {}
|
||||||
Item_func_seconds_hybrid(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
|
Item_func_seconds_hybrid(THD *thd, Item *a): Item_func_numhybrid(thd, a) {}
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec_generic(uint dec)
|
||||||
{
|
{
|
||||||
if (arg_count)
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
decimals= args[0]->temporal_precision(arg0_expected_type());
|
decimals= dec;
|
||||||
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
|
|
||||||
max_length=17 + (decimals ? decimals + 1 : 0);
|
max_length=17 + (decimals ? decimals + 1 : 0);
|
||||||
maybe_null= true;
|
maybe_null= true;
|
||||||
set_handler_by_result_type(decimals ? DECIMAL_RESULT : INT_RESULT);
|
set_handler_by_result_type(decimals ? DECIMAL_RESULT : INT_RESULT);
|
||||||
@ -466,8 +463,6 @@ public:
|
|||||||
class Item_func_unix_timestamp :public Item_func_seconds_hybrid
|
class Item_func_unix_timestamp :public Item_func_seconds_hybrid
|
||||||
{
|
{
|
||||||
bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
|
bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
|
||||||
protected:
|
|
||||||
enum_field_types arg0_expected_type() const { return MYSQL_TYPE_DATETIME; }
|
|
||||||
public:
|
public:
|
||||||
Item_func_unix_timestamp(THD *thd): Item_func_seconds_hybrid(thd) {}
|
Item_func_unix_timestamp(THD *thd): Item_func_seconds_hybrid(thd) {}
|
||||||
Item_func_unix_timestamp(THD *thd, Item *a):
|
Item_func_unix_timestamp(THD *thd, Item *a):
|
||||||
@ -491,6 +486,10 @@ public:
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC);
|
return mark_unsupported_function(func_name(), "()", arg, VCOL_TIME_FUNC);
|
||||||
}
|
}
|
||||||
|
void fix_length_and_dec()
|
||||||
|
{
|
||||||
|
fix_length_and_dec_generic(arg_count ? args[0]->datetime_precision() : 0);
|
||||||
|
}
|
||||||
longlong int_op();
|
longlong int_op();
|
||||||
my_decimal *decimal_op(my_decimal* buf);
|
my_decimal *decimal_op(my_decimal* buf);
|
||||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||||
@ -500,8 +499,6 @@ public:
|
|||||||
|
|
||||||
class Item_func_time_to_sec :public Item_func_seconds_hybrid
|
class Item_func_time_to_sec :public Item_func_seconds_hybrid
|
||||||
{
|
{
|
||||||
protected:
|
|
||||||
enum_field_types arg0_expected_type() const { return MYSQL_TYPE_TIME; }
|
|
||||||
public:
|
public:
|
||||||
Item_func_time_to_sec(THD *thd, Item *item):
|
Item_func_time_to_sec(THD *thd, Item *item):
|
||||||
Item_func_seconds_hybrid(thd, item) {}
|
Item_func_seconds_hybrid(thd, item) {}
|
||||||
@ -512,6 +509,10 @@ public:
|
|||||||
{
|
{
|
||||||
return !has_time_args();
|
return !has_time_args();
|
||||||
}
|
}
|
||||||
|
void fix_length_and_dec()
|
||||||
|
{
|
||||||
|
fix_length_and_dec_generic(args[0]->time_precision());
|
||||||
|
}
|
||||||
longlong int_op();
|
longlong int_op();
|
||||||
my_decimal *decimal_op(my_decimal* buf);
|
my_decimal *decimal_op(my_decimal* buf);
|
||||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||||
@ -864,7 +865,11 @@ class Item_func_convert_tz :public Item_datetimefunc
|
|||||||
Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c):
|
Item_func_convert_tz(THD *thd, Item *a, Item *b, Item *c):
|
||||||
Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {}
|
Item_datetimefunc(thd, a, b, c), from_tz_cached(0), to_tz_cached(0) {}
|
||||||
const char *func_name() const { return "convert_tz"; }
|
const char *func_name() const { return "convert_tz"; }
|
||||||
void fix_length_and_dec();
|
void fix_length_and_dec()
|
||||||
|
{
|
||||||
|
fix_attributes_datetime(args[0]->datetime_precision());
|
||||||
|
maybe_null= true;
|
||||||
|
}
|
||||||
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
|
||||||
void cleanup();
|
void cleanup();
|
||||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||||
@ -1059,13 +1064,6 @@ public:
|
|||||||
Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {}
|
Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {}
|
||||||
virtual const char *cast_type() const = 0;
|
virtual const char *cast_type() const = 0;
|
||||||
void print(String *str, enum_query_type query_type);
|
void print(String *str, enum_query_type query_type);
|
||||||
void fix_length_and_dec_generic(uint int_part_len)
|
|
||||||
{
|
|
||||||
if (decimals == NOT_FIXED_DEC)
|
|
||||||
decimals= args[0]->temporal_precision(field_type());
|
|
||||||
fix_attributes_temporal(int_part_len, decimals);
|
|
||||||
maybe_null= true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Item_date_typecast :public Item_temporal_typecast
|
class Item_date_typecast :public Item_temporal_typecast
|
||||||
@ -1157,8 +1155,7 @@ public:
|
|||||||
const char *func_name() const { return "timediff"; }
|
const char *func_name() const { return "timediff"; }
|
||||||
void fix_length_and_dec()
|
void fix_length_and_dec()
|
||||||
{
|
{
|
||||||
uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
|
uint dec= MY_MAX(args[0]->time_precision(), args[1]->time_precision());
|
||||||
args[1]->temporal_precision(MYSQL_TYPE_TIME));
|
|
||||||
fix_attributes_time(dec);
|
fix_attributes_time(dec);
|
||||||
maybe_null= true;
|
maybe_null= true;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "sql_type.h"
|
#include "sql_type.h"
|
||||||
#include "sql_const.h"
|
#include "sql_const.h"
|
||||||
#include "sql_class.h"
|
#include "sql_class.h"
|
||||||
|
#include "sql_time.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
@ -2689,7 +2690,11 @@ bool Type_handler_numeric::
|
|||||||
bool Type_handler::
|
bool Type_handler::
|
||||||
Item_time_typecast_fix_length_and_dec(Item_time_typecast *item) const
|
Item_time_typecast_fix_length_and_dec(Item_time_typecast *item) const
|
||||||
{
|
{
|
||||||
item->fix_length_and_dec_generic(MIN_TIME_WIDTH);
|
uint dec= item->decimals == NOT_FIXED_DEC ?
|
||||||
|
item->arguments()[0]->time_precision() :
|
||||||
|
item->decimals;
|
||||||
|
item->fix_attributes_temporal(MIN_TIME_WIDTH, dec);
|
||||||
|
item->maybe_null= true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2697,7 +2702,8 @@ bool Type_handler::
|
|||||||
bool Type_handler::
|
bool Type_handler::
|
||||||
Item_date_typecast_fix_length_and_dec(Item_date_typecast *item) const
|
Item_date_typecast_fix_length_and_dec(Item_date_typecast *item) const
|
||||||
{
|
{
|
||||||
item->fix_length_and_dec_generic(MAX_DATE_WIDTH);
|
item->fix_attributes_temporal(MAX_DATE_WIDTH, 0);
|
||||||
|
item->maybe_null= true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2706,9 +2712,12 @@ bool Type_handler::
|
|||||||
Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *item)
|
Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *item)
|
||||||
const
|
const
|
||||||
{
|
{
|
||||||
item->fix_length_and_dec_generic(MAX_DATETIME_WIDTH);
|
uint dec= item->decimals == NOT_FIXED_DEC ?
|
||||||
|
item->arguments()[0]->datetime_precision() :
|
||||||
|
item->decimals;
|
||||||
|
item->fix_attributes_temporal(MAX_DATETIME_WIDTH, dec);
|
||||||
|
item->maybe_null= true;
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3023,3 +3032,35 @@ bool Type_handler_string_result::
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
uint Type_handler::Item_time_precision(Item *item) const
|
||||||
|
{
|
||||||
|
return MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint Type_handler::Item_datetime_precision(Item *item) const
|
||||||
|
{
|
||||||
|
return MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint Type_handler_string_result::Item_temporal_precision(Item *item,
|
||||||
|
bool is_time) const
|
||||||
|
{
|
||||||
|
MYSQL_TIME ltime;
|
||||||
|
StringBuffer<64> buf;
|
||||||
|
String *tmp;
|
||||||
|
MYSQL_TIME_STATUS status;
|
||||||
|
DBUG_ASSERT(item->fixed);
|
||||||
|
if ((tmp= item->val_str(&buf)) &&
|
||||||
|
!(is_time ?
|
||||||
|
str_to_time(tmp->charset(), tmp->ptr(), tmp->length(),
|
||||||
|
<ime, TIME_TIME_ONLY, &status) :
|
||||||
|
str_to_datetime(tmp->charset(), tmp->ptr(), tmp->length(),
|
||||||
|
<ime, TIME_FUZZY_DATES, &status)))
|
||||||
|
return MY_MIN(status.precision, TIME_SECOND_PART_DIGITS);
|
||||||
|
return MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
@ -389,6 +389,8 @@ public:
|
|||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
virtual uint Item_time_precision(Item *item) const;
|
||||||
|
virtual uint Item_datetime_precision(Item *item) const;
|
||||||
/**
|
/**
|
||||||
Makes a temporary table Field to handle numeric aggregate functions,
|
Makes a temporary table Field to handle numeric aggregate functions,
|
||||||
e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc.
|
e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc.
|
||||||
@ -1040,6 +1042,7 @@ public:
|
|||||||
|
|
||||||
class Type_handler_string_result: public Type_handler
|
class Type_handler_string_result: public Type_handler
|
||||||
{
|
{
|
||||||
|
uint Item_temporal_precision(Item *item, bool is_time) const;
|
||||||
public:
|
public:
|
||||||
Item_result result_type() const { return STRING_RESULT; }
|
Item_result result_type() const { return STRING_RESULT; }
|
||||||
Item_result cmp_type() const { return STRING_RESULT; }
|
Item_result cmp_type() const { return STRING_RESULT; }
|
||||||
@ -1055,6 +1058,14 @@ public:
|
|||||||
const Type_std_attributes *item,
|
const Type_std_attributes *item,
|
||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
uint32 max_display_length(const Item *item) const;
|
uint32 max_display_length(const Item *item) const;
|
||||||
|
uint Item_time_precision(Item *item) const
|
||||||
|
{
|
||||||
|
return Item_temporal_precision(item, true);
|
||||||
|
}
|
||||||
|
uint Item_datetime_precision(Item *item) const
|
||||||
|
{
|
||||||
|
return Item_temporal_precision(item, false);
|
||||||
|
}
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
String *print_item_value(THD *thd, Item *item, String *str) const
|
String *print_item_value(THD *thd, Item *item, String *str) const
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user