summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-04-19 05:20:19 +0400
committerAlexander Barkov <bar@mariadb.org>2017-04-19 05:20:19 +0400
commite2b03cd3b54f39e09bf20eef77effe1b53813f29 (patch)
tree4ac86a3a301c79b25ce497683d1416ecee822378 /sql/item_timefunc.h
parent634f9186922d0decb597178fda15928d2b22f062 (diff)
downloadmariadb-git-e2b03cd3b54f39e09bf20eef77effe1b53813f29.tar.gz
MDEV-12514 Split Item_temporal_func::fix_length_and_dec() + MDEV-12515
This patch implements MDEV-12514 according to the task descriptions. It automatically fixes: MDEV-12515 Wrong value when storing DATE_ADD() and ADDTIME() to a numeric field Additionally: a. Moves Item_func::set_attributes_temporal() to Type_str_attributes::fix_attributes_temporal(), which is a more proper place and name for it. b. Continues replacing calls for: set_handler_by_field_type(MYSQL_TYPE_XXX) to corresponding: set_handler(&type_handler_xxx) which is faster. Note, we should eventually get rid of almost all set_handler_by_field_type(). c. Makes type_handler_string, type_handler_time2, type_handler_newdate, type_handler_datetime2 public. (all built-in handlers will become public eventually) d. Removing Item_temporal_func::sql_mode, as it was not used.
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r--sql/item_timefunc.h57
1 files changed, 26 insertions, 31 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index f66c57e2fb5..40b8c169c80 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -31,16 +31,6 @@ enum date_time_format_types
};
-static inline uint
-mysql_temporal_int_part_length(enum enum_field_types mysql_type)
-{
- static uint max_time_type_width[5]=
- { MAX_DATETIME_WIDTH, MAX_DATETIME_WIDTH, MAX_DATE_WIDTH,
- MAX_DATETIME_WIDTH, MIN_TIME_WIDTH };
- return max_time_type_width[mysql_type_to_time_type(mysql_type)+2];
-}
-
-
bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval);
class Item_func_period_add :public Item_int_func
@@ -531,7 +521,6 @@ public:
class Item_temporal_func: public Item_func
{
- sql_mode_t sql_mode;
public:
Item_temporal_func(THD *thd): Item_func(thd) {}
Item_temporal_func(THD *thd, Item *a): Item_func(thd, a) {}
@@ -549,7 +538,6 @@ public:
{ return tmp_table_field_from_field_type(table, false, false); }
int save_in_field(Field *field, bool no_conversions)
{ return save_date_in_field(field, no_conversions); }
- void fix_length_and_dec();
};
@@ -557,22 +545,20 @@ public:
Abstract class for functions returning TIME, DATE, DATETIME or string values,
whose data type depends on parameters and is set at fix_fields time.
*/
-class Item_temporal_hybrid_func: public Item_temporal_func,
- public Type_handler_hybrid_field_type
+class Item_temporal_hybrid_func: public Item_hybrid_func
{
protected:
String ascii_buf; // Conversion buffer
public:
Item_temporal_hybrid_func(THD *thd, Item *a, Item *b):
- Item_temporal_func(thd, a, b) {}
- const Type_handler *type_handler() const
- { return Type_handler_hybrid_field_type::type_handler(); }
- enum_field_types field_type() const
- { return Type_handler_hybrid_field_type::field_type(); }
- enum Item_result result_type () const
- { return Type_handler_hybrid_field_type::result_type(); }
- enum Item_result cmp_type () const
- { return Type_handler_hybrid_field_type::cmp_type(); }
+ Item_hybrid_func(thd, a, b) {}
+
+ longlong val_int() { return val_int_from_date(); }
+ double val_real() { return val_real_from_date(); }
+ bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date)= 0;
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ { return val_decimal_from_date(decimal_value); }
+
/**
Fix the returned timestamp to match field_type(),
which is important for val_str().
@@ -599,6 +585,11 @@ public:
Item_datefunc(THD *thd, Item *a): Item_temporal_func(thd, a) { }
Item_datefunc(THD *thd, Item *a, Item *b): Item_temporal_func(thd, a, b) { }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ void fix_length_and_dec()
+ {
+ fix_attributes_date();
+ maybe_null= (arg_count > 0);
+ }
};
@@ -635,6 +626,7 @@ public:
Item_func_curtime(THD *thd, uint dec): Item_timefunc(thd), last_query_id(0)
{ decimals= dec; }
bool fix_fields(THD *, Item **);
+ void fix_length_and_dec() { fix_attributes_time(decimals); }
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
/*
Abstract method that defines which time zone is used for conversion.
@@ -722,6 +714,7 @@ public:
Item_func_now(THD *thd, uint dec): Item_datetimefunc(thd), last_query_id(0)
{ decimals= dec; }
bool fix_fields(THD *, Item **);
+ void fix_length_and_dec() { fix_attributes_datetime(decimals); }
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
virtual void store_now_in_TIME(THD *thd, MYSQL_TIME *now_time)=0;
bool check_vcol_func_processor(void *arg)
@@ -886,8 +879,8 @@ public:
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
void fix_length_and_dec()
{
- decimals= MY_MIN(args[0]->decimals, TIME_SECOND_PART_DIGITS);
- Item_timefunc::fix_length_and_dec();
+ fix_attributes_time(args[0]->decimals);
+ maybe_null= true;
}
const char *func_name() const { return "sec_to_time"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1066,11 +1059,12 @@ public:
Item_temporal_typecast(THD *thd, Item *a): Item_temporal_func(thd, a) {}
virtual const char *cast_type() const = 0;
void print(String *str, enum_query_type query_type);
- void fix_length_and_dec_generic()
+ void fix_length_and_dec_generic(uint int_part_len)
{
if (decimals == NOT_FIXED_DEC)
decimals= args[0]->temporal_precision(field_type());
- Item_temporal_func::fix_length_and_dec();
+ fix_attributes_temporal(int_part_len, decimals);
+ maybe_null= true;
}
};
@@ -1163,9 +1157,10 @@ public:
const char *func_name() const { return "timediff"; }
void fix_length_and_dec()
{
- decimals= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
+ uint dec= MY_MAX(args[0]->temporal_precision(MYSQL_TYPE_TIME),
args[1]->temporal_precision(MYSQL_TYPE_TIME));
- Item_timefunc::fix_length_and_dec();
+ fix_attributes_time(dec);
+ maybe_null= true;
}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -1180,8 +1175,8 @@ public:
{}
void fix_length_and_dec()
{
- decimals= MY_MIN(args[2]->decimals, TIME_SECOND_PART_DIGITS);
- Item_timefunc::fix_length_and_dec();
+ fix_attributes_time(args[2]->decimals);
+ maybe_null= true;
}
const char *func_name() const { return "maketime"; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);