summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.h
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2013-08-22 13:59:30 +0400
committerAlexander Barkov <bar@mariadb.org>2013-08-22 13:59:30 +0400
commit9adb6e991ec87b65d04929f115d9d0c899e4ab19 (patch)
tree92784a64dcfdf27f03ea828e5a210b8fa663869c /sql/item_timefunc.h
parent879629e6b2b9cd078f4f6b57aeee6f3c70e188cd (diff)
downloadmariadb-git-9adb6e991ec87b65d04929f115d9d0c899e4ab19.tar.gz
MDEV-4841 Wrong character set of ADDTIME() and DATE_ADD()
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r--sql/item_timefunc.h57
1 files changed, 45 insertions, 12 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 11e84cfc1cd..029e3b17cf1 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -505,6 +505,45 @@ 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; }
+ 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:
@@ -761,17 +800,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);
@@ -909,16 +946,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);
@@ -1011,18 +1046,16 @@ 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;
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)
{}
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();
};