summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r--sql/item_timefunc.cc235
1 files changed, 182 insertions, 53 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index c2d1504e94a..31ce2ad9cdc 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -571,21 +571,21 @@ longlong Item_func_from_days::val_int()
void Item_func_curdate::fix_length_and_dec()
{
- struct tm tm_tmp,*start;
- time_t query_start=current_thd->query_start();
+ struct tm start;
- set_charset(default_charset());
+ collation.set(default_charset());
decimals=0;
max_length=10*default_charset()->mbmaxlen;
- localtime_r(&query_start,&tm_tmp);
- start=&tm_tmp;
- value=(longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
- ((uint) start->tm_mon+1)*100+
- (uint) start->tm_mday);
+
+ store_now_in_tm(current_thd->query_start(),&start);
+
+ value=(longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+
+ ((uint) start.tm_mon+1)*100+
+ (uint) start.tm_mday);
/* For getdate */
- ltime.year= start->tm_year+1900;
- ltime.month= start->tm_mon+1;
- ltime.day= start->tm_mday;
+ ltime.year= start.tm_year+1900;
+ ltime.month= start.tm_mon+1;
+ ltime.day= start.tm_mday;
ltime.hour= 0;
ltime.minute= 0;
ltime.second= 0;
@@ -594,6 +594,7 @@ void Item_func_curdate::fix_length_and_dec()
ltime.time_type=TIMESTAMP_DATE;
}
+
bool Item_func_curdate::get_date(TIME *res,
bool fuzzy_date __attribute__((unused)))
{
@@ -601,6 +602,27 @@ bool Item_func_curdate::get_date(TIME *res,
return 0;
}
+
+/*
+ Converts time in time_t to struct tm represenatation for local timezone.
+ Defines timezone (local) used for whole CURDATE function
+*/
+void Item_func_curdate_local::store_now_in_tm(time_t now, struct tm *now_tm)
+{
+ localtime_r(&now,now_tm);
+}
+
+
+/*
+ Converts time in time_t to struct tm represenatation for UTC
+ Defines timezone (UTC) used for whole UTC_DATE function
+*/
+void Item_func_curdate_utc::store_now_in_tm(time_t now, struct tm *now_tm)
+{
+ gmtime_r(&now,now_tm);
+}
+
+
String *Item_func_curtime::val_str(String *str)
{
str_value.set(buff,buff_length,default_charset());
@@ -609,23 +631,43 @@ String *Item_func_curtime::val_str(String *str)
void Item_func_curtime::fix_length_and_dec()
{
- struct tm tm_tmp,*start;
- time_t query_start=current_thd->query_start();
- CHARSET_INFO *cs=default_charset();
+ struct tm start;
+ CHARSET_INFO *cs= default_charset();
decimals=0;
max_length=8*cs->mbmaxlen;
- localtime_r(&query_start,&tm_tmp);
- start=&tm_tmp;
- set_charset(cs);
- value=(longlong) ((ulong) ((uint) start->tm_hour)*10000L+
- (ulong) (((uint) start->tm_min)*100L+
- (uint) start->tm_sec));
+ collation.set(cs);
+
+ store_now_in_tm(current_thd->query_start(),&start);
+
+ value=(longlong) ((ulong) ((uint) start.tm_hour)*10000L+
+ (ulong) (((uint) start.tm_min)*100L+
+ (uint) start.tm_sec));
buff_length=cs->cset->snprintf(cs,buff,sizeof(buff),"%02d:%02d:%02d",
- (int) start->tm_hour,
- (int) start->tm_min,
- (int) start->tm_sec);
+ (int) start.tm_hour,
+ (int) start.tm_min,
+ (int) start.tm_sec);
+}
+
+
+/*
+ Converts time in time_t to struct tm represenatation for local timezone.
+ Defines timezone (local) used for whole CURTIME function
+*/
+void Item_func_curtime_local::store_now_in_tm(time_t now, struct tm *now_tm)
+{
+ localtime_r(&now,now_tm);
+}
+
+
+/*
+ Converts time in time_t to struct tm represenatation for UTC.
+ Defines timezone (UTC) used for whole UTC_TIME function
+*/
+void Item_func_curtime_utc::store_now_in_tm(time_t now, struct tm *now_tm)
+{
+ gmtime_r(&now,now_tm);
}
@@ -638,37 +680,37 @@ String *Item_func_now::val_str(String *str)
void Item_func_now::fix_length_and_dec()
{
- struct tm tm_tmp,*start;
- time_t query_start=current_thd->query_start();
+ struct tm start;
CHARSET_INFO *cs= &my_charset_bin;
decimals=0;
max_length=19*cs->mbmaxlen;
- set_charset(cs);
- localtime_r(&query_start,&tm_tmp);
- start=&tm_tmp;
- value=((longlong) ((ulong) ((uint) start->tm_year+1900)*10000L+
- (((uint) start->tm_mon+1)*100+
- (uint) start->tm_mday))*(longlong) 1000000L+
- (longlong) ((ulong) ((uint) start->tm_hour)*10000L+
- (ulong) (((uint) start->tm_min)*100L+
- (uint) start->tm_sec)));
+ collation.set(cs);
+
+ store_now_in_tm(current_thd->query_start(),&start);
+
+ value=((longlong) ((ulong) ((uint) start.tm_year+1900)*10000L+
+ (((uint) start.tm_mon+1)*100+
+ (uint) start.tm_mday))*(longlong) 1000000L+
+ (longlong) ((ulong) ((uint) start.tm_hour)*10000L+
+ (ulong) (((uint) start.tm_min)*100L+
+ (uint) start.tm_sec)));
buff_length= (uint) cs->cset->snprintf(cs,buff, sizeof(buff),
"%04d-%02d-%02d %02d:%02d:%02d",
- ((int) (start->tm_year+1900)) % 10000,
- (int) start->tm_mon+1,
- (int) start->tm_mday,
- (int) start->tm_hour,
- (int) start->tm_min,
- (int) start->tm_sec);
+ ((int) (start.tm_year+1900)) % 10000,
+ (int) start.tm_mon+1,
+ (int) start.tm_mday,
+ (int) start.tm_hour,
+ (int) start.tm_min,
+ (int) start.tm_sec);
/* For getdate */
- ltime.year= start->tm_year+1900;
- ltime.month= start->tm_mon+1;
- ltime.day= start->tm_mday;
- ltime.hour= start->tm_hour;
- ltime.minute= start->tm_min;
- ltime.second= start->tm_sec;
+ ltime.year= start.tm_year+1900;
+ ltime.month= start.tm_mon+1;
+ ltime.day= start.tm_mday;
+ ltime.hour= start.tm_hour;
+ ltime.minute= start.tm_min;
+ ltime.second= start.tm_sec;
ltime.second_part=0;
ltime.neg=0;
ltime.time_type=TIMESTAMP_FULL;
@@ -690,6 +732,26 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
}
+/*
+ Converts time in time_t to struct tm represenatation for local timezone.
+ Defines timezone (local) used for whole CURRENT_TIMESTAMP function
+*/
+void Item_func_now_local::store_now_in_tm(time_t now, struct tm *now_tm)
+{
+ localtime_r(&now,now_tm);
+}
+
+
+/*
+ Converts time in time_t to struct tm represenatation for UTC.
+ Defines timezone (UTC) used for whole UTC_TIMESTAMP function
+*/
+void Item_func_now_utc::store_now_in_tm(time_t now, struct tm *now_tm)
+{
+ gmtime_r(&now,now_tm);
+}
+
+
String *Item_func_sec_to_time::val_str(String *str)
{
char buff[23*2];
@@ -1130,7 +1192,7 @@ bool Item_func_from_unixtime::get_date(TIME *ltime,
void Item_date_add_interval::fix_length_and_dec()
{
enum_field_types arg0_field_type;
- set_charset(default_charset());
+ collation.set(default_charset());
maybe_null=1;
max_length=26*MY_CHARSET_BIN_MB_MAXLEN;
value.alloc(32);
@@ -1289,14 +1351,12 @@ String *Item_date_add_interval::val_str(String *str)
longlong Item_date_add_interval::val_int()
{
TIME ltime;
+ longlong date;
if (Item_date_add_interval::get_date(&ltime,0))
return (longlong) 0;
- return ((longlong) (((ulong) ltime.year)*10000L+
- (((uint) ltime.month)*100+
- (uint) ltime.day))*(longlong) 1000000L+
- (longlong) ((ulong) ((uint) ltime.hour)*10000L+
- (ulong) (((uint)ltime.minute)*100L+
- (uint) ltime.second)));
+ date = (ltime.year*100L + ltime.month)*100L + ltime.day;
+ return ltime.time_type == TIMESTAMP_DATE ? date :
+ ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
}
void Item_extract::fix_length_and_dec()
@@ -1388,6 +1448,22 @@ longlong Item_extract::val_int()
return 0; // Impossible
}
+bool Item_extract::eq(const Item *item, bool binary_cmp) const
+{
+ if (this == item)
+ return 1;
+ if (item->type() != FUNC_ITEM ||
+ func_name() != ((Item_func*)item)->func_name())
+ return 0;
+
+ Item_extract* ie= (Item_extract*)item;
+ if (ie->int_type != int_type)
+ return 0;
+
+ if (!args[0]->eq(ie->args[0], binary_cmp))
+ return 0;
+ return 1;
+}
void Item_typecast::print(String *str)
{
@@ -1398,6 +1474,59 @@ void Item_typecast::print(String *str)
str->append(')');
}
+String *Item_char_typecast::val_str(String *str)
+{
+ String *res, *res1;
+ uint32 length;
+
+ if (!charset_conversion && !(res= args[0]->val_str(str)))
+ {
+ null_value= 1;
+ return 0;
+ }
+ else
+ {
+ // Convert character set if differ
+ if (!(res1= args[0]->val_str(&tmp_value)) ||
+ str->copy(res1->ptr(), res1->length(),res1->charset(), cast_cs))
+ {
+ null_value= 1;
+ return 0;
+ }
+ res= str;
+ }
+
+ /*
+ Cut the tail if cast with length
+ and the result is longer than cast length, e.g.
+ CAST('string' AS CHAR(1))
+ */
+ if (cast_length >= 0 &&
+ (res->length() > (length= (uint32) res->charpos(cast_length))))
+ { // Safe even if const arg
+ if (!res->alloced_length())
+ { // Don't change const str
+ str_value= *res; // Not malloced string
+ res= &str_value;
+ }
+ res->length((uint) length);
+ }
+ null_value= 0;
+ return res;
+}
+
+void Item_char_typecast::fix_length_and_dec()
+{
+ uint32 char_length;
+ charset_conversion= !my_charset_same(args[0]->collation.collation, cast_cs) &&
+ args[0]->collation.collation != &my_charset_bin &&
+ cast_cs != &my_charset_bin;
+ collation.set(cast_cs, DERIVATION_IMPLICIT);
+ char_length= (cast_length >= 0) ? cast_length :
+ args[0]->max_length/args[0]->collation.collation->mbmaxlen;
+ max_length= char_length * cast_cs->mbmaxlen;
+}
+
String *Item_datetime_typecast::val_str(String *str)
{
TIME ltime;