summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2016-12-19 14:28:08 +0400
committerAlexander Barkov <bar@mariadb.org>2016-12-19 14:28:08 +0400
commit2f6fede8d5f7e98319b4b7b557bd565fdb42fac3 (patch)
treef57ad1b04932d80eb36f05a5ef55cb62dece012c /sql/item_timefunc.h
parentc4d9dc705b781bb155aab8f04cece2b87116d3c1 (diff)
downloadmariadb-git-2f6fede8d5f7e98319b4b7b557bd565fdb42fac3.tar.gz
MDEV-10524 Assertion `arg1_int >= 0' failed in Item_func_additive_op::result_precision()
This change is a backport from 10.0 to 5.5 for: 1. The full patch for: MDEV-4841 Wrong character set of ADDTIME() and DATE_ADD() 9adb6e991ec87b65d04929f115d9d0c899e4ab19 2. A small fragment of: MDEV-5298 Illegal mix of collations on timestamp 03f6778d61a74bdd7d09103a16473a2a5624cf66 which overrides Item_temporal_hybrid_func::cmp_type(), and adds a new line into cache_temporal_4265.result.
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r--sql/item_timefunc.h62
1 files changed, 50 insertions, 12 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 3a03ee4b27a..0062d500835 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -506,6 +506,50 @@ 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
+{
+protected:
+ enum_field_types cached_field_type; // TIME, DATE, DATETIME or STRING
+ String ascii_buf; // Conversion buffer
+public:
+ Item_temporal_hybrid_func(Item *a,Item *b)
+ :Item_temporal_func(a,b) {}
+ enum_field_types field_type() const { return cached_field_type; }
+ Item_result cmp_type() const
+ {
+ return cached_field_type == MYSQL_TYPE_STRING ?
+ STRING_RESULT : TIME_RESULT;
+ }
+ const CHARSET_INFO *charset_for_protocol() const
+ {
+ /*
+ Can return TIME, DATE, DATETIME or VARCHAR depending on arguments.
+ Send using "binary" when TIME, DATE or DATETIME,
+ or using collation.collation when VARCHAR
+ (which is fixed from @@collation_connection in fix_length_and_dec).
+ */
+ DBUG_ASSERT(fixed == 1);
+ return cached_field_type == MYSQL_TYPE_STRING ?
+ collation.collation : &my_charset_bin;
+ }
+ /**
+ Return string value in ASCII character set.
+ */
+ String *val_str_ascii(String *str);
+ /**
+ Return string value in @@character_set_connection.
+ */
+ String *val_str(String *str)
+ {
+ return val_str_from_val_str_ascii(str, &ascii_buf);
+ }
+};
+
+
class Item_datefunc :public Item_temporal_func
{
public:
@@ -763,17 +807,15 @@ public:
};
-class Item_date_add_interval :public Item_temporal_func
+class Item_date_add_interval :public Item_temporal_hybrid_func
{
- enum_field_types cached_field_type;
public:
const interval_type int_type; // keep it public
const bool date_sub_interval; // keep it public
Item_date_add_interval(Item *a,Item *b,interval_type type_arg,bool neg_arg)
- :Item_temporal_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
+ :Item_temporal_hybrid_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec();
- enum_field_types field_type() const { return cached_field_type; }
bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
void print(String *str, enum_query_type query_type);
@@ -911,16 +953,14 @@ public:
};
-class Item_func_add_time :public Item_temporal_func
+class Item_func_add_time :public Item_temporal_hybrid_func
{
const bool is_date;
int sign;
- enum_field_types cached_field_type;
public:
Item_func_add_time(Item *a, Item *b, bool type_arg, bool neg_arg)
- :Item_temporal_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
- enum_field_types field_type() const { return cached_field_type; }
+ :Item_temporal_hybrid_func(a, b), is_date(type_arg) { sign= neg_arg ? -1 : 1; }
void fix_length_and_dec();
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
void print(String *str, enum_query_type query_type);
@@ -1019,9 +1059,8 @@ public:
};
-class Item_func_str_to_date :public Item_temporal_func
+class Item_func_str_to_date :public Item_temporal_hybrid_func
{
- enum_field_types cached_field_type;
timestamp_type cached_timestamp_type;
bool const_item;
String subject_converter;
@@ -1029,12 +1068,11 @@ class Item_func_str_to_date :public Item_temporal_func
CHARSET_INFO *internal_charset;
public:
Item_func_str_to_date(Item *a, Item *b)
- :Item_temporal_func(a, b), const_item(false),
+ :Item_temporal_hybrid_func(a, b), const_item(false),
internal_charset(NULL)
{}
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date);
const char *func_name() const { return "str_to_date"; }
- enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
};