summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_timefunc.h')
-rw-r--r--sql/item_timefunc.h159
1 files changed, 113 insertions, 46 deletions
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 396b5bbb200..ca1624c9082 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -1,3 +1,6 @@
+#ifndef ITEM_TIMEFUNC_INCLUDED
+#define ITEM_TIMEFUNC_INCLUDED
+
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
@@ -20,6 +23,8 @@
#pragma interface /* gcc class implementation */
#endif
+class MY_LOCALE;
+
enum date_time_format_types
{
TIME_ONLY= 0, TIME_MICROSECOND, DATE_ONLY, DATE_TIME, DATE_TIME_MICROSECOND
@@ -77,6 +82,39 @@ public:
};
+class Item_func_to_seconds :public Item_int_func
+{
+public:
+ Item_func_to_seconds(Item *a) :Item_int_func(a) {}
+ longlong val_int();
+ const char *func_name() const { return "to_seconds"; }
+ void fix_length_and_dec()
+ {
+ decimals=0;
+ max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
+ maybe_null=1;
+ }
+ enum_monotonicity_info get_monotonicity_info() const;
+ longlong val_int_endpoint(bool left_endp, bool *incl_endp);
+ bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
+
+ bool intro_version(uchar *int_arg)
+ {
+ int *input_version= (int*)int_arg;
+ /* This function was introduced in 5.5 */
+ int output_version= max(*input_version, 50500);
+ *input_version= output_version;
+ return 0;
+ }
+
+ /* Only meaningful with date part and optional time part */
+ bool check_valid_arguments_processor(uchar *int_arg)
+ {
+ return !has_date_args();
+ }
+};
+
+
class Item_func_dayofmonth :public Item_int_func
{
public:
@@ -100,7 +138,7 @@ public:
class Item_func_month :public Item_func
{
public:
- Item_func_month(Item *a) :Item_func(a) {}
+ Item_func_month(Item *a) :Item_func(a) { collation.set_numeric(); }
longlong val_int();
double val_real()
{ DBUG_ASSERT(fixed == 1); return (double) Item_func_month::val_int(); }
@@ -109,17 +147,16 @@ public:
longlong nr= val_int();
if (null_value)
return 0;
- str->set(nr, &my_charset_bin);
+ str->set(nr, collation.collation);
return str;
}
const char *func_name() const { return "month"; }
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ decimals= 0;
+ fix_char_length(2);
+ maybe_null= 1;
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_valid_arguments_processor(uchar *int_arg)
@@ -129,16 +166,19 @@ public:
};
-class Item_func_monthname :public Item_func_month
+class Item_func_monthname :public Item_str_func
{
MY_LOCALE *locale;
public:
- Item_func_monthname(Item *a) :Item_func_month(a) {}
+ Item_func_monthname(Item *a) :Item_str_func(a) {}
const char *func_name() const { return "monthname"; }
String *val_str(String *str);
- enum Item_result result_type () const { return STRING_RESULT; }
void fix_length_and_dec();
bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
+ bool check_valid_arguments_processor(uchar *int_arg)
+ {
+ return !has_date_args();
+ }
};
@@ -150,9 +190,9 @@ public:
const char *func_name() const { return "dayofyear"; }
void fix_length_and_dec()
{
- decimals=0;
- max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ decimals= 0;
+ fix_char_length(3);
+ maybe_null= 1;
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_valid_arguments_processor(uchar *int_arg)
@@ -303,7 +343,7 @@ class Item_func_weekday :public Item_func
bool odbc_type;
public:
Item_func_weekday(Item *a,bool type_arg)
- :Item_func(a), odbc_type(type_arg) {}
+ :Item_func(a), odbc_type(type_arg) { collation.set_numeric(); }
longlong val_int();
double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
String *val_str(String *str)
@@ -319,10 +359,9 @@ public:
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
- maybe_null=1;
+ decimals= 0;
+ fix_char_length(1);
+ maybe_null= 1;
}
bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
bool check_valid_arguments_processor(uchar *int_arg)
@@ -401,15 +440,15 @@ public:
Item_date(Item *a) :Item_func(a) {}
enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
String *val_str(String *str);
longlong val_int();
double val_real() { return val_real_from_decimal(); }
const char *func_name() const { return "date"; }
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ decimals= 0;
+ fix_length_and_charset_datetime(MAX_DATE_WIDTH);
}
Field *tmp_table_field(TABLE *table)
{
@@ -436,6 +475,7 @@ public:
Item_date_func(Item *a,Item *b) :Item_str_func(a,b) {}
Item_date_func(Item *a,Item *b, Item *c) :Item_str_func(a,b,c) {}
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
@@ -462,10 +502,11 @@ public:
Item_str_timefunc(Item *a,Item *b) :Item_str_func(a,b) {}
Item_str_timefunc(Item *a, Item *b, Item *c) :Item_str_func(a, b ,c) {}
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
void fix_length_and_dec()
{
decimals= DATETIME_DEC;
- max_length=MAX_TIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset_datetime(MAX_TIME_WIDTH);
}
Field *tmp_table_field(TABLE *table)
{
@@ -727,7 +768,6 @@ public:
void fix_length_and_dec()
{
Item_str_timefunc::fix_length_and_dec();
- collation.set(&my_charset_bin);
maybe_null=1;
}
const char *func_name() const { return "sec_to_time"; }
@@ -739,16 +779,32 @@ class Item_date_add_interval :public Item_date_func
{
String value;
enum_field_types cached_field_type;
-
+ String ascii_buf;
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_date_func(a,b),int_type(type_arg), date_sub_interval(neg_arg) {}
- String *val_str(String *);
+ String *val_str_ascii(String *str);
+ String *val_str(String *str)
+ {
+ return val_str_from_val_str_ascii(str, &ascii_buf);
+ }
const char *func_name() const { return "date_add_interval"; }
void fix_length_and_dec();
enum_field_types field_type() const { return cached_field_type; }
+ CHARSET_INFO *charset_for_protocol(void) const
+ {
+ /*
+ DATE_ADD() can return DATE, DATETIME or VARCHAR depending on arguments.
+ Send using "binary" when DATE or DATETIME,
+ or using collation.collation when VARCHAR
+ (which was 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;
+ }
longlong val_int();
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
bool eq(const Item *item, bool binary_cmp) const;
@@ -835,13 +891,7 @@ public:
class Item_typecast_maybe_null :public Item_typecast
{
public:
- Item_typecast_maybe_null(Item *a) :Item_typecast(a) {}
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length=args[0]->max_length;
- maybe_null= 1;
- }
+ Item_typecast_maybe_null(Item *a) :Item_typecast(a) { maybe_null= 1; }
};
@@ -874,16 +924,12 @@ public:
bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
- }
- void fix_length_and_dec()
- {
- collation.set(&my_charset_bin);
- max_length= 10;
- maybe_null= 1;
}
+ void fix_length_and_dec() { fix_length_and_charset_datetime(10); }
bool result_as_longlong() { return TRUE; }
longlong val_int();
double val_real() { return (double) val_int(); }
@@ -908,6 +954,7 @@ public:
bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "time"; }
enum_field_types field_type() const { return MYSQL_TYPE_TIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
@@ -924,6 +971,8 @@ public:
{
return save_time_in_field(field);
}
+ void fix_length_and_dec()
+ { fix_length_and_charset_datetime(args[0]->max_char_length()); }
};
@@ -935,15 +984,14 @@ public:
String *val_str(String *str);
const char *cast_type() const { return "datetime"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
return tmp_table_field_from_field_type(table, 0);
}
void fix_length_and_dec()
{
- collation.set(&my_charset_bin);
- maybe_null= 1;
- max_length= MAX_DATETIME_FULL_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset_datetime(MAX_DATETIME_FULL_WIDTH);
decimals= DATETIME_DEC;
}
bool result_as_longlong() { return TRUE; }
@@ -968,11 +1016,11 @@ public:
String *val_str(String *str);
const char *func_name() const { return "makedate"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
void fix_length_and_dec()
{
decimals=0;
- max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
- /* It returns NULL when the second argument is less or equal to 0 */
+ fix_length_and_charset_datetime(MAX_DATE_WIDTH);
maybe_null= 1;
}
longlong val_int();
@@ -991,6 +1039,7 @@ public:
String *val_str(String *str);
enum_field_types field_type() const { return cached_field_type; }
void fix_length_and_dec();
+ CHARSET_INFO *charset_for_protocol(void) const { return &my_charset_bin; }
Field *tmp_table_field(TABLE *table)
{
@@ -1016,6 +1065,8 @@ public:
return save_date_in_field(field);
return Item_str_func::save_in_field(field, no_conversions);
}
+ longlong val_int();
+ MYSQL_TIME *val_datetime(MYSQL_TIME *time, date_time_format_types *format);
};
class Item_func_timediff :public Item_str_timefunc
@@ -1085,20 +1136,20 @@ enum date_time_format
USA_FORMAT, JIS_FORMAT, ISO_FORMAT, EUR_FORMAT, INTERNAL_FORMAT
};
-class Item_func_get_format :public Item_str_func
+class Item_func_get_format :public Item_str_ascii_func
{
public:
const timestamp_type type; // keep it public
Item_func_get_format(timestamp_type type_arg, Item *a)
- :Item_str_func(a), type(type_arg)
+ :Item_str_ascii_func(a), type(type_arg)
{}
- String *val_str(String *str);
+ String *val_str_ascii(String *str);
const char *func_name() const { return "get_format"; }
void fix_length_and_dec()
{
maybe_null= 1;
decimals=0;
- max_length=17*MY_CHARSET_BIN_MB_MAXLEN;
+ fix_length_and_charset(17, default_charset());
}
virtual void print(String *str, enum_query_type query_type);
};
@@ -1110,6 +1161,7 @@ class Item_func_str_to_date :public Item_str_func
date_time_format_types cached_format_type;
timestamp_type cached_timestamp_type;
bool const_item;
+ ulonglong sql_mode;
public:
Item_func_str_to_date(Item *a, Item *b)
:Item_str_func(a, b), const_item(false)
@@ -1123,6 +1175,8 @@ public:
{
return tmp_table_field_from_field_type(table, 1);
}
+ longlong val_int();
+ bool result_as_longlong() { return TRUE; }
};
@@ -1132,4 +1186,17 @@ public:
Item_func_last_day(Item *a) :Item_date(a) {}
const char *func_name() const { return "last_day"; }
bool get_date(MYSQL_TIME *res, uint fuzzy_date);
+ void fix_length_and_dec()
+ {
+ Item_date::fix_length_and_dec();
+ maybe_null= 1;
+ }
};
+
+
+/* Function prototypes */
+
+bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
+ timestamp_type type, String *str);
+
+#endif /* ITEM_TIMEFUNC_INCLUDED */