From cf9cc19e910f3621661de6a9384a18aacf84a8dd Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 13 Sep 2013 14:43:10 +0400 Subject: MDEV-4724 Some temporal functions do not preserve microseconds --- sql/item_timefunc.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'sql/item_timefunc.h') diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index b0245e6f743..19a9ac12985 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -361,13 +361,15 @@ class Item_func_dayname :public Item_func_weekday class Item_func_seconds_hybrid: public Item_func_numhybrid { +protected: + virtual enum_field_types arg0_expected_type() const = 0; public: Item_func_seconds_hybrid() :Item_func_numhybrid() {} Item_func_seconds_hybrid(Item *a) :Item_func_numhybrid(a) {} void fix_num_length_and_dec() { if (arg_count) - decimals= args[0]->decimals; + decimals= args[0]->temporal_precision(arg0_expected_type()); set_if_smaller(decimals, TIME_SECOND_PART_DIGITS); max_length=17 + (decimals ? decimals + 1 : 0); set_persist_maybe_null(1); @@ -383,6 +385,8 @@ public: class Item_func_unix_timestamp :public Item_func_seconds_hybrid { bool get_timestamp_value(my_time_t *seconds, ulong *second_part); +protected: + enum_field_types arg0_expected_type() const { return MYSQL_TYPE_DATETIME; } public: Item_func_unix_timestamp() :Item_func_seconds_hybrid() {} Item_func_unix_timestamp(Item *a) :Item_func_seconds_hybrid(a) {} @@ -413,6 +417,8 @@ public: class Item_func_time_to_sec :public Item_func_seconds_hybrid { +protected: + enum_field_types arg0_expected_type() const { return MYSQL_TYPE_TIME; } public: Item_func_time_to_sec(Item *item) :Item_func_seconds_hybrid(item) {} const char *func_name() const { return "time_to_sec"; } @@ -829,7 +835,7 @@ public: void fix_length_and_dec() { if (decimals == NOT_FIXED_DEC) - decimals= args[0]->decimals; + decimals= args[0]->temporal_precision(field_type()); Item_temporal_func::fix_length_and_dec(); } }; @@ -903,7 +909,8 @@ public: const char *func_name() const { return "timediff"; } void fix_length_and_dec() { - decimals= max(args[0]->decimals, args[1]->decimals); + decimals= max(args[0]->temporal_precision(MYSQL_TYPE_TIME), + args[1]->temporal_precision(MYSQL_TYPE_TIME)); Item_timefunc::fix_length_and_dec(); } bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); @@ -915,6 +922,11 @@ public: Item_func_maketime(Item *a, Item *b, Item *c) :Item_timefunc(a, b, c) {} + void fix_length_and_dec() + { + decimals= min(args[2]->decimals, TIME_SECOND_PART_DIGITS); + Item_timefunc::fix_length_and_dec(); + } const char *func_name() const { return "maketime"; } bool get_date(MYSQL_TIME *ltime, uint fuzzy_date); }; -- cgit v1.2.1