34 #include "sql_class.h"
36 #include "sql_locale.h"
49 #include "sql_class.h"
57 #define MAX_DAY_NUMBER 3652424L
68 adjust_time_range_with_warn(
MYSQL_TIME *ltime, uint8 decimals)
71 if (check_time_range_quick(ltime))
75 MYSQL_TIMESTAMP_TIME);
76 adjust_time_range(ltime, &warning);
103 static bool sec_to_time(lldiv_t seconds,
MYSQL_TIME *ltime)
107 set_zero_time(ltime, MYSQL_TIMESTAMP_TIME);
109 if (seconds.quot < 0 || seconds.rem < 0)
112 seconds.quot= -seconds.quot;
113 seconds.rem= -seconds.rem;
116 if (seconds.quot > TIME_MAX_VALUE_SECONDS)
118 set_max_hhmmss(ltime);
122 ltime->hour= (uint) (seconds.quot / 3600);
123 uint sec= (uint) (seconds.quot % 3600);
124 ltime->minute= sec / 60;
125 ltime->second= sec % 60;
126 time_add_nanoseconds_with_round(ltime, seconds.rem, &warning);
128 adjust_time_range(ltime, &warning);
130 return warning ?
true :
false;
141 {(
char *)
"%I:%i:%S %p", 11}};
143 {(
char *)
"%H:%i:%S", 8}};
179 const char *val, uint length,
MYSQL_TIME *l_time,
180 timestamp_type cached_timestamp_type,
181 const char **sub_pattern_end,
182 const char *date_time_type)
184 int weekday= 0, yearday= 0, daypart= 0;
187 int strict_week_number_year= -1;
190 bool UNINIT_VAR(sunday_first_n_first_week_non_iso);
191 bool UNINIT_VAR(strict_week_number);
192 bool UNINIT_VAR(strict_week_number_year_type);
193 const char *val_begin= val;
194 const char *val_end= val + length;
195 const char *ptr= format->format.str;
196 const char *end= ptr + format->format.length;
198 DBUG_ENTER(
"extract_date_time");
200 if (!sub_pattern_end)
201 memset(l_time, 0,
sizeof(*l_time));
203 for (; ptr != end && val != val_end; ptr++)
206 if ((val+= cs->cset->scan(cs, val, val_end, MY_SEQ_SPACES)) >= val_end)
209 if (*ptr ==
'%' && ptr+1 != end)
216 val_len= (uint) (val_end - val);
220 tmp= (
char*) val + MY_MIN(4, val_len);
221 l_time->year= (int) my_strtoll10(val, &tmp, &error);
222 if ((
int) (tmp-val) <= 2)
223 l_time->year= year_2000_handling(l_time->year);
227 tmp= (
char*) val + MY_MIN(2, val_len);
228 l_time->year= (int) my_strtoll10(val, &tmp, &error);
230 l_time->year= year_2000_handling(l_time->year);
236 tmp= (
char*) val + MY_MIN(2, val_len);
237 l_time->month= (int) my_strtoll10(val, &tmp, &error);
241 if ((l_time->month= check_word(my_locale_en_US.month_names,
242 val, val_end, &val)) <= 0)
246 if ((l_time->month= check_word(my_locale_en_US.ab_month_names,
247 val, val_end, &val)) <= 0)
253 tmp= (
char*) val + MY_MIN(2, val_len);
254 l_time->day= (int) my_strtoll10(val, &tmp, &error);
258 tmp= (
char*) val + MY_MIN(2, val_len);
259 l_time->day= (int) my_strtoll10(val, &tmp, &error);
261 val= tmp + MY_MIN((
int) (val_end-tmp), 2);
272 tmp= (
char*) val + MY_MIN(2, val_len);
273 l_time->hour= (int) my_strtoll10(val, &tmp, &error);
279 tmp= (
char*) val + MY_MIN(2, val_len);
280 l_time->minute= (int) my_strtoll10(val, &tmp, &error);
287 tmp= (
char*) val + MY_MIN(2, val_len);
288 l_time->second= (int) my_strtoll10(val, &tmp, &error);
294 tmp= (
char*) val_end;
296 tmp= (
char*) val + 6;
297 l_time->
second_part= (int) my_strtoll10(val, &tmp, &error);
298 frac_part= 6 - (int) (tmp - val);
300 l_time->
second_part*= (ulong) log_10_int[frac_part];
306 if (val_len < 2 || ! usa_time)
308 if (!my_strnncoll(&my_charset_latin1,
309 (
const uchar *) val, 2,
310 (
const uchar *)
"PM", 2))
312 else if (my_strnncoll(&my_charset_latin1,
313 (
const uchar *) val, 2,
314 (
const uchar *)
"AM", 2))
321 if ((weekday= check_word(my_locale_en_US.day_names, val, val_end, &val)) <= 0)
325 if ((weekday= check_word(my_locale_en_US.ab_day_names, val, val_end, &val)) <= 0)
329 tmp= (
char*) val + 1;
330 if ((weekday= (
int) my_strtoll10(val, &tmp, &error)) < 0 ||
339 tmp= (
char*) val + MY_MIN(val_len, 3);
340 yearday= (int) my_strtoll10(val, &tmp, &error);
349 sunday_first_n_first_week_non_iso= (*ptr==
'U' || *ptr==
'V');
350 strict_week_number= (*ptr==
'V' || *ptr==
'v');
351 tmp= (
char*) val + MY_MIN(val_len, 2);
352 if ((week_number= (
int) my_strtoll10(val, &tmp, &error)) < 0 ||
353 (strict_week_number && !week_number) ||
362 strict_week_number_year_type= (*ptr==
'X');
363 tmp= (
char*) val + MY_MIN(4, val_len);
364 strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
374 if (extract_date_time(&time_ampm_format, val,
375 (uint)(val_end - val), l_time,
376 cached_timestamp_type, &val,
"time"))
382 if (extract_date_time(&time_24hrs_format, val,
383 (uint)(val_end - val), l_time,
384 cached_timestamp_type, &val,
"time"))
390 while (my_ispunct(cs, *val) && val != val_end)
394 while (my_isalpha(cs, *val) && val != val_end)
398 while (my_isdigit(cs, *val) && val != val_end)
407 else if (!my_isspace(cs, *ptr))
416 if (l_time->hour > 12 || l_time->hour < 1)
418 l_time->hour= l_time->hour%12+daypart;
427 *sub_pattern_end= val;
434 days= calc_daynr(l_time->year,1,1) + yearday - 1;
437 get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
440 if (week_number >= 0 && weekday)
449 if ((strict_week_number &&
450 (strict_week_number_year < 0 ||
451 strict_week_number_year_type != sunday_first_n_first_week_non_iso)) ||
452 (!strict_week_number && strict_week_number_year >= 0))
456 days= calc_daynr((strict_week_number ? strict_week_number_year :
460 weekday_b= calc_weekday(days, sunday_first_n_first_week_non_iso);
468 if (sunday_first_n_first_week_non_iso)
470 days+= ((weekday_b == 0) ? 0 : 7) - weekday_b +
471 (week_number - 1) * 7 +
476 days+= ((weekday_b <= 3) ? 0 : 7) - weekday_b +
477 (week_number - 1) * 7 +
483 get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
486 if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 ||
487 l_time->minute > 59 || l_time->second > 59)
494 if (!my_isspace(&my_charset_latin1,*val))
497 make_truncated_value_warning(
ErrConvString(val_begin, length),
498 cached_timestamp_type);
501 }
while (++val != val_end);
508 strmake(buff, val_begin, min<size_t>(length,
sizeof(buff)-1));
509 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
510 ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
511 date_time_type, buff,
"str_to_date");
528 const char *ptr, *end;
529 THD *thd= current_thd;
530 MY_LOCALE *locale= thd->variables.lc_time_names;
537 end= (ptr= format->format.str) + format->format.length;
538 for (; ptr != end ; ptr++)
540 if (*ptr !=
'%' || ptr+1 == end)
548 str->append(locale->month_names->type_names[l_time->month-1],
549 (uint) strlen(locale->month_names->type_names[l_time->month-1]),
550 system_charset_info);
555 str->append(locale->ab_month_names->type_names[l_time->month-1],
556 (uint) strlen(locale->ab_month_names->type_names[l_time->month-1]),
557 system_charset_info);
560 if (type == MYSQL_TIMESTAMP_TIME || !(l_time->month || l_time->year))
562 weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
564 str->append(locale->day_names->type_names[weekday],
565 (uint) strlen(locale->day_names->type_names[weekday]),
566 system_charset_info);
569 if (type == MYSQL_TIMESTAMP_TIME || !(l_time->month || l_time->year))
571 weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
573 str->append(locale->ab_day_names->type_names[weekday],
574 (uint) strlen(locale->ab_day_names->type_names[weekday]),
575 system_charset_info);
578 if (type == MYSQL_TIMESTAMP_TIME)
580 length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff);
581 str->append_with_prefill(intbuff, length, 1,
'0');
582 if (l_time->day >= 10 && l_time->day <= 19)
583 str->append(STRING_WITH_LEN(
"th"));
586 switch (l_time->day %10) {
588 str->append(STRING_WITH_LEN(
"st"));
591 str->append(STRING_WITH_LEN(
"nd"));
594 str->append(STRING_WITH_LEN(
"rd"));
597 str->append(STRING_WITH_LEN(
"th"));
603 length= (uint) (int10_to_str(l_time->year, intbuff, 10) - intbuff);
604 str->append_with_prefill(intbuff, length, 4,
'0');
607 length= (uint) (int10_to_str(l_time->year%100, intbuff, 10) - intbuff);
608 str->append_with_prefill(intbuff, length, 2,
'0');
611 length= (uint) (int10_to_str(l_time->month, intbuff, 10) - intbuff);
612 str->append_with_prefill(intbuff, length, 2,
'0');
615 length= (uint) (int10_to_str(l_time->month, intbuff, 10) - intbuff);
616 str->append_with_prefill(intbuff, length, 1,
'0');
619 length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff);
620 str->append_with_prefill(intbuff, length, 2,
'0');
623 length= (uint) (int10_to_str(l_time->day, intbuff, 10) - intbuff);
624 str->append_with_prefill(intbuff, length, 1,
'0');
627 length= (uint) (int10_to_str(l_time->
second_part, intbuff, 10) - intbuff);
628 str->append_with_prefill(intbuff, length, 6,
'0');
631 length= (uint) (int10_to_str(l_time->hour, intbuff, 10) - intbuff);
632 str->append_with_prefill(intbuff, length, 2,
'0');
636 hours_i= (l_time->hour%24 + 11)%12+1;
637 length= (uint) (int10_to_str(hours_i, intbuff, 10) - intbuff);
638 str->append_with_prefill(intbuff, length, 2,
'0');
641 length= (uint) (int10_to_str(l_time->minute, intbuff, 10) - intbuff);
642 str->append_with_prefill(intbuff, length, 2,
'0');
645 if (type == MYSQL_TIMESTAMP_TIME)
647 length= (uint) (int10_to_str(calc_daynr(l_time->year,l_time->month,
649 calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff);
650 str->append_with_prefill(intbuff, length, 3,
'0');
653 length= (uint) (int10_to_str(l_time->hour, intbuff, 10) - intbuff);
654 str->append_with_prefill(intbuff, length, 1,
'0');
657 hours_i= (l_time->hour%24 + 11)%12+1;
658 length= (uint) (int10_to_str(hours_i, intbuff, 10) - intbuff);
659 str->append_with_prefill(intbuff, length, 1,
'0');
662 hours_i= l_time->hour%24;
663 str->append(hours_i < 12 ?
"AM" :
"PM",2);
666 length= sprintf(intbuff, ((l_time->hour % 24) < 12) ?
667 "%02d:%02d:%02d AM" :
"%02d:%02d:%02d PM",
668 (l_time->hour+11)%12+1,
671 str->append(intbuff, length);
675 length= (uint) (int10_to_str(l_time->second, intbuff, 10) - intbuff);
676 str->append_with_prefill(intbuff, length, 2,
'0');
679 length= sprintf(intbuff,
"%02d:%02d:%02d",
680 l_time->hour, l_time->minute, l_time->second);
681 str->append(intbuff, length);
687 if (type == MYSQL_TIMESTAMP_TIME)
689 length= (uint) (int10_to_str(calc_week(l_time,
691 WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST,
693 intbuff, 10) - intbuff);
694 str->append_with_prefill(intbuff, length, 2,
'0');
701 if (type == MYSQL_TIMESTAMP_TIME)
703 length= (uint) (int10_to_str(calc_week(l_time,
705 (WEEK_YEAR | WEEK_FIRST_WEEKDAY) :
706 (WEEK_YEAR | WEEK_MONDAY_FIRST)),
708 intbuff, 10) - intbuff);
709 str->append_with_prefill(intbuff, length, 2,
'0');
716 if (type == MYSQL_TIMESTAMP_TIME)
718 (void) calc_week(l_time,
720 WEEK_YEAR | WEEK_FIRST_WEEKDAY :
721 WEEK_YEAR | WEEK_MONDAY_FIRST),
723 length= (uint) (int10_to_str(year, intbuff, 10) - intbuff);
724 str->append_with_prefill(intbuff, length, 4,
'0');
728 if (type == MYSQL_TIMESTAMP_TIME || !(l_time->month || l_time->year))
730 weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
732 length= (uint) (int10_to_str(weekday, intbuff, 10) - intbuff);
733 str->append_with_prefill(intbuff, length, 1,
'0');
766 static bool get_interval_info(
Item *args,
769 uint count, ulonglong *values,
773 if (!(res= args->val_str_ascii(str_value)))
777 const char *str= res->ptr();
778 const char *end= str + res->length();
780 str+= cs->cset->scan(cs, str, end, MY_SEQ_SPACES);
781 if (str < end && *str ==
'-')
787 while (str < end && !my_isdigit(cs,*str))
791 for (uint
i=0 ;
i < count ;
i++)
794 const char *start= str;
795 for (value=0; str != end && my_isdigit(cs,*str) ; str++)
796 value= value*LL(10) + (longlong) (*str -
'0');
797 msec_length= 6 - (str - start);
799 while (str != end && !my_isdigit(cs,*str))
801 if (str == end &&
i != count-1)
805 bmove_upp((uchar*) (values+count), (uchar*) (values+
i),
807 memset(values, 0,
sizeof(*values)*(count-
i));
812 if (transform_msec && msec_length > 0)
813 values[count - 1] *= (long) log_10_int[msec_length];
821 bool Item_temporal_func::check_precision()
823 if (decimals > DATETIME_MAX_DECIMALS)
825 my_error(ER_TOO_BIG_PRECISION, MYF(0),
826 (
int) decimals, func_name(), DATETIME_MAX_DECIMALS);
833 type_conversion_status
836 if (cached_field_type == MYSQL_TYPE_TIME)
837 return save_time_in_field(field);
838 if (is_temporal_type_with_date(cached_field_type))
839 return save_date_in_field(field);
846 DBUG_ASSERT(fixed == 1);
847 if (cached_field_type == MYSQL_TYPE_TIME)
848 return val_decimal_from_time(decimal_value);
849 else if (cached_field_type == MYSQL_TYPE_DATETIME)
850 return val_decimal_from_date(decimal_value);
855 return null_value ? 0:
856 ltime.time_type == MYSQL_TIMESTAMP_TIME ?
857 time2my_decimal(<ime, decimal_value) :
858 date2my_decimal(<ime, decimal_value);
863 bool Item_temporal_hybrid_func::get_date(
MYSQL_TIME *ltime, uint fuzzy_date)
868 DBUG_ASSERT(null_value ==
true);
871 if (cached_field_type == MYSQL_TYPE_TIME ||
872 tm.time_type == MYSQL_TIMESTAMP_TIME)
873 time_to_datetime(current_thd, &tm, ltime);
880 bool Item_temporal_hybrid_func::get_time(
MYSQL_TIME *ltime)
884 DBUG_ASSERT(null_value ==
true);
887 if (cached_field_type == MYSQL_TYPE_TIME &&
888 ltime->time_type != MYSQL_TIMESTAMP_TIME)
889 datetime_to_time(ltime);
896 DBUG_ASSERT(fixed == 1);
900 (null_value= my_TIME_to_str(<ime, str,
901 cached_field_type == MYSQL_TYPE_STRING ?
903 DATETIME_MAX_DECIMALS : 0) :
908 DBUG_ASSERT((cached_field_type == MYSQL_TYPE_TIME &&
909 ltime.time_type == MYSQL_TIMESTAMP_TIME) ||
910 (cached_field_type == MYSQL_TYPE_DATE &&
911 ltime.time_type == MYSQL_TIMESTAMP_DATE) ||
912 (cached_field_type == MYSQL_TYPE_DATETIME &&
913 ltime.time_type == MYSQL_TIMESTAMP_DATETIME) ||
914 cached_field_type == MYSQL_TYPE_STRING ||
915 ltime.time_type == MYSQL_TIMESTAMP_NONE);
922 DBUG_ASSERT(fixed == 1);
924 return get_time(<ime) ? 0LL : TIME_to_longlong_time_packed(<ime);
930 DBUG_ASSERT(fixed == 1);
932 return get_date(<ime, TIME_FUZZY_DATE) ?
933 0LL : TIME_to_longlong_date_packed(<ime);
939 DBUG_ASSERT(fixed == 1);
941 return get_date(<ime, TIME_FUZZY_DATE) ?
942 0LL : TIME_to_longlong_datetime_packed(<ime);
949 item->basic_const_item() && type() == item->type() &&
950 func_name() == ((
Item_func *) item)->func_name() &&
957 str->append(
"DATE'");
958 str->append(cached_time.
cptr());
966 item->basic_const_item() && type() == item->type() &&
967 func_name() == ((
Item_func *) item)->func_name() &&
974 str->append(
"TIMESTAMP'");
975 str->append(cached_time.
cptr());
983 item->basic_const_item() && type() == item->type() &&
984 func_name() == ((
Item_func *) item)->func_name() &&
991 str->append(
"TIME'");
992 str->append(cached_time.
cptr());
997 longlong Item_func_period_add::val_int()
999 DBUG_ASSERT(fixed == 1);
1000 ulong period=(ulong) args[0]->val_int();
1001 int months=(int) args[1]->val_int();
1003 if ((null_value=args[0]->null_value || args[1]->null_value) ||
1007 convert_month_to_period((uint) ((
int) convert_period_to_month(period)+
1012 longlong Item_func_period_diff::val_int()
1014 DBUG_ASSERT(fixed == 1);
1015 ulong period1=(ulong) args[0]->val_int();
1016 ulong period2=(ulong) args[1]->val_int();
1018 if ((null_value=args[0]->null_value || args[1]->null_value))
1020 return (longlong) ((long) convert_period_to_month(period1)-
1021 (long) convert_period_to_month(period2));
1026 longlong Item_func_to_days::val_int()
1028 DBUG_ASSERT(fixed == 1);
1030 if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1032 return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
1036 longlong Item_func_to_seconds::val_int_endpoint(
bool left_endp,
1039 DBUG_ASSERT(fixed == 1);
1044 if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1047 return LONGLONG_MIN;
1049 seconds= ltime.hour * 3600L + ltime.minute * 60 + ltime.second;
1050 seconds= ltime.neg ? -seconds : seconds;
1051 days= (longlong) calc_daynr(ltime.year, ltime.month, ltime.day);
1052 seconds+= days * 24L * 3600L;
1054 null_value= check_date(<ime, non_zero_date(<ime),
1055 (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE),
1063 longlong Item_func_to_seconds::val_int()
1065 DBUG_ASSERT(fixed == 1);
1069 if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1071 seconds= ltime.hour * 3600L + ltime.minute * 60 + ltime.second;
1072 seconds=ltime.neg ? -seconds : seconds;
1073 days= (longlong) calc_daynr(ltime.year, ltime.month, ltime.day);
1074 return seconds + days * 24L * 3600L;
1091 enum_monotonicity_info Item_func_to_days::get_monotonicity_info()
const
1093 if (args[0]->type() == Item::FIELD_ITEM)
1095 if (args[0]->field_type() == MYSQL_TYPE_DATE)
1096 return MONOTONIC_STRICT_INCREASING_NOT_NULL;
1097 if (args[0]->field_type() == MYSQL_TYPE_DATETIME)
1098 return MONOTONIC_INCREASING_NOT_NULL;
1100 return NON_MONOTONIC;
1103 enum_monotonicity_info Item_func_to_seconds::get_monotonicity_info()
const
1105 if (args[0]->type() == Item::FIELD_ITEM)
1107 if (args[0]->field_type() == MYSQL_TYPE_DATE ||
1108 args[0]->field_type() == MYSQL_TYPE_DATETIME)
1109 return MONOTONIC_STRICT_INCREASING_NOT_NULL;
1111 return NON_MONOTONIC;
1115 longlong Item_func_to_days::val_int_endpoint(
bool left_endp,
bool *incl_endp)
1117 DBUG_ASSERT(fixed == 1);
1121 if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1124 return LONGLONG_MIN;
1126 res=(longlong) calc_daynr(ltime.year,ltime.month,ltime.day);
1128 null_value= check_date(<ime, non_zero_date(<ime),
1129 (TIME_NO_ZERO_IN_DATE | TIME_NO_ZERO_DATE),
1136 if (args[0]->field_type() != MYSQL_TYPE_DATE)
1141 if (args[0]->field_type() == MYSQL_TYPE_DATE)
1159 if ((!left_endp && !(ltime.hour || ltime.minute || ltime.second ||
1161 (left_endp && ltime.hour == 23 && ltime.minute == 59 &&
1162 ltime.second == 59))
1171 longlong Item_func_dayofyear::val_int()
1173 DBUG_ASSERT(fixed == 1);
1175 if (get_arg0_date(<ime,TIME_NO_ZERO_DATE))
1177 return (longlong) calc_daynr(ltime.year,ltime.month,ltime.day) -
1178 calc_daynr(ltime.year,1,1) + 1;
1181 longlong Item_func_dayofmonth::val_int()
1183 DBUG_ASSERT(fixed == 1);
1185 return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.day;
1188 longlong Item_func_month::val_int()
1190 DBUG_ASSERT(fixed == 1);
1192 return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.month;
1196 void Item_func_monthname::fix_length_and_dec()
1198 THD* thd= current_thd;
1199 const CHARSET_INFO *cs= thd->variables.collation_connection;
1200 uint32 repertoire= my_charset_repertoire(cs);
1201 locale= thd->variables.lc_time_names;
1202 collation.set(cs, DERIVATION_COERCIBLE, repertoire);
1204 max_length= locale->max_month_name_length * collation.collation->mbmaxlen;
1211 DBUG_ASSERT(fixed == 1);
1212 const char *month_name;
1216 if ((null_value= (get_arg0_date(<ime, TIME_FUZZY_DATE) || !ltime.month)))
1219 month_name= locale->month_names->type_names[ltime.month - 1];
1220 str->copy(month_name, (uint) strlen(month_name), &my_charset_utf8_bin,
1221 collation.collation, &err);
1232 DBUG_ASSERT(fixed == 1);
1234 if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1236 return (longlong) ((ltime.month+2)/3);
1239 longlong Item_func_hour::val_int()
1241 DBUG_ASSERT(fixed == 1);
1243 return get_arg0_time(<ime) ? 0 : ltime.hour;
1246 longlong Item_func_minute::val_int()
1248 DBUG_ASSERT(fixed == 1);
1250 return get_arg0_time(<ime) ? 0 : ltime.minute;
1258 DBUG_ASSERT(fixed == 1);
1260 return get_arg0_time(<ime) ? 0 : ltime.second;
1264 uint week_mode(uint
mode)
1266 uint week_format= (mode & 7);
1267 if (!(week_format & WEEK_MONDAY_FIRST))
1268 week_format^= WEEK_FIRST_WEEKDAY;
1305 DBUG_ASSERT(fixed == 1);
1308 if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1310 return (longlong) calc_week(<ime,
1311 week_mode((uint) args[1]->
val_int()),
1316 longlong Item_func_yearweek::val_int()
1318 DBUG_ASSERT(fixed == 1);
1321 if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1323 week= calc_week(<ime,
1324 (week_mode((uint) args[1]->val_int()) | WEEK_YEAR),
1326 return week+year*100;
1330 longlong Item_func_weekday::val_int()
1332 DBUG_ASSERT(fixed == 1);
1335 if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1338 return (longlong) calc_weekday(calc_daynr(ltime.year, ltime.month,
1340 odbc_type) +
test(odbc_type);
1343 void Item_func_dayname::fix_length_and_dec()
1345 THD* thd= current_thd;
1346 const CHARSET_INFO *cs= thd->variables.collation_connection;
1347 uint32 repertoire= my_charset_repertoire(cs);
1348 locale= thd->variables.lc_time_names;
1349 collation.set(cs, DERIVATION_COERCIBLE, repertoire);
1351 max_length= locale->max_day_name_length * collation.collation->mbmaxlen;
1358 DBUG_ASSERT(fixed == 1);
1359 uint weekday=(uint) val_int();
1360 const char *day_name;
1366 day_name= locale->day_names->type_names[weekday];
1367 str->copy(day_name, (uint) strlen(day_name), &my_charset_utf8_bin,
1368 collation.collation, &err);
1373 longlong Item_func_year::val_int()
1375 DBUG_ASSERT(fixed == 1);
1377 return get_arg0_date(<ime, TIME_FUZZY_DATE) ? 0 : (longlong) ltime.year;
1395 enum_monotonicity_info Item_func_year::get_monotonicity_info()
const
1397 if (args[0]->type() == Item::FIELD_ITEM &&
1398 (args[0]->field_type() == MYSQL_TYPE_DATE ||
1399 args[0]->field_type() == MYSQL_TYPE_DATETIME))
1400 return MONOTONIC_INCREASING;
1401 return NON_MONOTONIC;
1405 longlong Item_func_year::val_int_endpoint(
bool left_endp,
bool *incl_endp)
1407 DBUG_ASSERT(fixed == 1);
1409 if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1412 return LONGLONG_MIN;
1426 if (!left_endp && ltime.day == 1 && ltime.month == 1 &&
1427 !(ltime.hour || ltime.minute || ltime.second || ltime.
second_part))
1435 longlong Item_timeval_func::val_int()
1445 return val_timeval(&tm) ? NULL : timeval2my_decimal(&tm, decimal_value);
1449 double Item_timeval_func::val_real()
1453 (double) tm.tv_sec + (
double) tm.tv_usec / (double) 1000000;
1460 if (
val_timeval(&tm) || (null_value= str->alloc(MAX_DATE_STRING_REP_LENGTH)))
1462 str->length(my_timeval_to_str(&tm, (
char*) str->ptr(), decimals));
1463 str->set_charset(collation.collation);
1470 DBUG_ASSERT(fixed == 1);
1473 tm->tv_sec= current_thd->query_start();
1478 return (null_value= args[0]->
get_timeval(tm, &warnings));
1482 enum_monotonicity_info Item_func_unix_timestamp::get_monotonicity_info()
const
1484 if (args[0]->
type() == Item::FIELD_ITEM &&
1485 (args[0]->field_type() == MYSQL_TYPE_TIMESTAMP))
1486 return MONOTONIC_INCREASING;
1487 return NON_MONOTONIC;
1491 longlong Item_func_unix_timestamp::val_int_endpoint(
bool left_endp,
bool *incl_endp)
1493 DBUG_ASSERT(fixed == 1);
1494 DBUG_ASSERT(arg_count == 1 &&
1495 args[0]->
type() == Item::FIELD_ITEM &&
1496 args[0]->field_type() == MYSQL_TYPE_TIMESTAMP);
1503 longlong Item_func_time_to_sec::val_int()
1505 DBUG_ASSERT(fixed == 1);
1508 if (get_arg0_time(<ime))
1510 seconds= ltime.hour * 3600L + ltime.minute * 60 + ltime.second;
1511 return ltime.neg ? -seconds : seconds;
1525 longlong UNINIT_VAR(value);
1527 memset(interval, 0,
sizeof(*interval));
1528 if (int_type == INTERVAL_SECOND && args->decimals)
1532 if (!(val= args->val_decimal(&decimal_value)) ||
1533 my_decimal2lldiv_t(E_DEC_FATAL_ERROR, val, &tmp))
1536 if (tmp.quot >= 0 && tmp.rem >= 0)
1538 interval->neg=
false;
1539 interval->second= tmp.quot;
1540 interval->second_part= tmp.rem / 1000;
1544 interval->neg=
true;
1545 interval->second= -tmp.quot;
1546 interval->second_part= -tmp.rem / 1000;
1550 else if (int_type <= INTERVAL_MICROSECOND)
1552 value= args->val_int();
1553 if (args->null_value)
1557 interval->neg=
true;
1564 interval->year= (ulong) value;
1566 case INTERVAL_QUARTER:
1567 interval->month= (ulong)(value*3);
1569 case INTERVAL_MONTH:
1570 interval->month= (ulong) value;
1573 interval->day= (ulong)(value*7);
1576 interval->day= (ulong) value;
1579 interval->hour= (ulong) value;
1581 case INTERVAL_MINUTE:
1582 interval->minute=value;
1584 case INTERVAL_SECOND:
1585 interval->second=value;
1587 case INTERVAL_MICROSECOND:
1588 interval->second_part=value;
1590 case INTERVAL_YEAR_MONTH:
1591 if (get_interval_info(args, str_value, &interval->neg, 2, array,
false))
1593 interval->year= (ulong) array[0];
1594 interval->month= (ulong) array[1];
1596 case INTERVAL_DAY_HOUR:
1597 if (get_interval_info(args, str_value, &interval->neg, 2, array,
false))
1599 interval->day= (ulong) array[0];
1600 interval->hour= (ulong) array[1];
1602 case INTERVAL_DAY_MINUTE:
1603 if (get_interval_info(args, str_value, &interval->neg, 3, array,
false))
1605 interval->day= (ulong) array[0];
1606 interval->hour= (ulong) array[1];
1607 interval->minute= array[2];
1609 case INTERVAL_DAY_SECOND:
1610 if (get_interval_info(args, str_value, &interval->neg, 4, array,
false))
1612 interval->day= (ulong) array[0];
1613 interval->hour= (ulong) array[1];
1614 interval->minute= array[2];
1615 interval->second= array[3];
1617 case INTERVAL_HOUR_MINUTE:
1618 if (get_interval_info(args, str_value, &interval->neg, 2, array,
false))
1620 interval->hour= (ulong) array[0];
1621 interval->minute= array[1];
1623 case INTERVAL_HOUR_SECOND:
1624 if (get_interval_info(args, str_value, &interval->neg, 3, array,
false))
1626 interval->hour= (ulong) array[0];
1627 interval->minute= array[1];
1628 interval->second= array[2];
1630 case INTERVAL_MINUTE_SECOND:
1631 if (get_interval_info(args, str_value, &interval->neg, 2, array,
false))
1633 interval->minute= array[0];
1634 interval->second= array[1];
1636 case INTERVAL_DAY_MICROSECOND:
1637 if (get_interval_info(args, str_value, &interval->neg, 5, array,
true))
1639 interval->day= (ulong) array[0];
1640 interval->hour= (ulong) array[1];
1641 interval->minute= array[2];
1642 interval->second= array[3];
1643 interval->second_part= array[4];
1645 case INTERVAL_HOUR_MICROSECOND:
1646 if (get_interval_info(args, str_value, &interval->neg, 4, array,
true))
1648 interval->hour= (ulong) array[0];
1649 interval->minute= array[1];
1650 interval->second= array[2];
1651 interval->second_part= array[3];
1653 case INTERVAL_MINUTE_MICROSECOND:
1654 if (get_interval_info(args, str_value, &interval->neg, 3, array,
true))
1656 interval->minute= array[0];
1657 interval->second= array[1];
1658 interval->second_part= array[2];
1660 case INTERVAL_SECOND_MICROSECOND:
1661 if (get_interval_info(args, str_value, &interval->neg, 2, array,
true))
1663 interval->second= array[0];
1664 interval->second_part= array[1];
1674 bool Item_func_from_days::get_date(
MYSQL_TIME *ltime, uint fuzzy_date)
1676 longlong value=args[0]->val_int();
1677 if ((null_value=args[0]->null_value))
1680 get_date_from_daynr((
long) value, <ime->year, <ime->month, <ime->day);
1682 if ((null_value= (fuzzy_date & TIME_NO_ZERO_DATE) &&
1683 (ltime->year == 0 || ltime->month == 0 || ltime->day == 0)))
1686 ltime->time_type= MYSQL_TIMESTAMP_DATE;
1693 DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_TIME);
1695 time_packed= TIME_to_longlong_time_packed(&time);
1703 DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_DATE);
1705 time_packed= TIME_to_longlong_date_packed(&time);
1713 DBUG_ASSERT(ltime->time_type == MYSQL_TIMESTAMP_DATETIME);
1715 time_packed= TIME_to_longlong_datetime_packed(&time);
1725 time_packed= TIME_to_longlong_datetime_packed(&time);
1734 time.time_type= MYSQL_TIMESTAMP_DATE;
1736 time.hour= time.minute= time.second= 0;
1737 time_packed= TIME_to_longlong_date_packed(&time);
1747 datetime_to_time(&time);
1748 time_packed= TIME_to_longlong_time_packed(&time);
1754 void MYSQL_TIME_cache::cache_string()
1756 DBUG_ASSERT(time.time_type != MYSQL_TIMESTAMP_NONE);
1757 if (string_length == 0)
1758 string_length= my_TIME_to_str(&time, string_buff,
decimals());
1773 return check_date(ltime, non_zero_date(ltime), fuzzydate, &warnings);
1780 str->set(string_buff, string_length, &my_charset_latin1);
1786 void Item_func_curdate::fix_length_and_dec()
1788 THD *thd= current_thd;
1789 Item_date_func::fix_length_and_dec();
1790 cached_time.
set_date(thd->query_start_timeval_trunc(decimals), time_zone());
1794 Time_zone *Item_func_curdate_local::time_zone()
1796 return current_thd->time_zone();
1800 Time_zone *Item_func_curdate_utc::time_zone()
1807 void Item_func_curtime::fix_length_and_dec()
1809 if (check_precision())
1811 THD *thd= current_thd;
1812 cached_time.
set_time(thd->query_start_timeval_trunc(decimals), decimals,
1819 fix_length_and_dec_and_charset_datetime(8, decimals);
1823 Time_zone *Item_func_curtime_local::time_zone()
1825 return current_thd->time_zone();
1829 Time_zone *Item_func_curtime_utc::time_zone()
1837 void Item_func_now::fix_length_and_dec()
1839 if (check_precision())
1841 THD *thd= current_thd;
1842 cached_time.
set_datetime(thd->query_start_timeval_trunc(decimals), decimals,
1844 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, decimals);
1850 THD *thd= field->table != NULL ? field->table->in_use : current_thd;
1851 const timeval tm= thd->query_start_timeval_trunc(field->decimals());
1852 field->set_notnull();
1857 Time_zone *Item_func_now_local::time_zone()
1859 return current_thd->time_zone();
1863 Time_zone *Item_func_now_utc::time_zone()
1869 type_conversion_status
1882 uint fuzzy_date __attribute__((unused)))
1884 THD *thd= current_thd;
1885 ulonglong tmp= my_micro_time();
1886 thd->time_zone()->gmt_sec_to_TIME(now_time,
1887 (my_time_t) (tmp / 1000000));
1891 my_datetime_trunc(now_time, decimals);
1897 void Item_func_sysdate_local::fix_length_and_dec()
1899 if (check_precision())
1901 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, decimals);
1905 bool Item_func_sec_to_time::get_time(
MYSQL_TIME *ltime)
1907 my_decimal tmp, *val= args[0]->val_decimal(&tmp);
1909 if ((null_value= args[0]->null_value))
1911 if (my_decimal2lldiv_t(0, val, &seconds))
1913 set_max_time(ltime, val->sign());
1914 make_truncated_value_warning(
ErrConvString(val), MYSQL_TIMESTAMP_TIME);
1917 if (sec_to_time(seconds, ltime))
1919 MYSQL_TIMESTAMP_TIME);
1924 void Item_func_date_format::fix_length_and_dec()
1926 THD* thd= current_thd;
1931 Item *arg1= args[1]->this_item();
1934 const CHARSET_INFO *cs= thd->variables.collation_connection;
1935 uint32 repertoire= arg1->collation.repertoire;
1936 if (!thd->variables.lc_time_names->is_ascii)
1937 repertoire|= MY_REPERTOIRE_EXTENDED;
1938 collation.set(cs, arg1->collation.derivation, repertoire);
1939 if (arg1->type() == STRING_ITEM)
1942 max_length= format_length(&arg1->str_value) *
1943 collation.collation->mbmaxlen;
1948 max_length= min<uint32>(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
1949 collation.collation->mbmaxlen;
1950 set_if_smaller(max_length,MAX_BLOB_WIDTH);
1960 if (item->type() != FUNC_ITEM)
1962 if (func_name() != ((
Item_func*) item)->func_name())
1967 if (!args[0]->
eq(item_func->args[0], binary_cmp))
1974 if (!args[1]->
eq(item_func->args[1], 1))
1981 uint Item_func_date_format::format_length(
const String *format)
1984 const char *ptr=format->ptr();
1985 const char *end=ptr+format->length();
1987 for (; ptr != end ; ptr++)
1989 if (*ptr !=
'%' || ptr == end-1)
2059 DBUG_ASSERT(fixed == 1);
2061 if (!is_time_format)
2063 if (get_arg0_date(&l_time, TIME_FUZZY_DATE))
2068 if (get_arg0_time(&l_time))
2070 l_time.year=l_time.month=l_time.day=0;
2073 if (!(format = args[1]->val_str(str)) || !format->length())
2079 size=format_length(format);
2081 if (size < MAX_DATE_STRING_REP_LENGTH)
2082 size= MAX_DATE_STRING_REP_LENGTH;
2086 if (str->alloc(size))
2090 date_time_format.format.str= (
char*) format->ptr();
2091 date_time_format.format.length= format->length();
2094 str->set_charset(collation.collation);
2096 is_time_format ? MYSQL_TIMESTAMP_TIME :
2097 MYSQL_TIMESTAMP_DATE,
2107 void Item_func_from_unixtime::fix_length_and_dec()
2110 uint8 dec= MY_MIN(args[0]->decimals, DATETIME_MAX_DECIMALS);
2111 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, dec);
2113 thd->time_zone_used= 1;
2117 bool Item_func_from_unixtime::get_date(
MYSQL_TIME *ltime,
2118 uint fuzzy_date __attribute__((unused)))
2124 if (!(val= args[0]->val_decimal(&decimal_value)) ||
2125 my_decimal2lldiv_t(E_DEC_FATAL_ERROR, val, &lld))
2133 lld.quot= args[0]->val_int();
2137 if ((null_value= (args[0]->null_value ||
2138 lld.quot > TIMESTAMP_MAX_VALUE) || lld.quot < 0 || lld.rem < 0))
2141 thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t) lld.quot);
2143 ltime->
second_part= decimals ? lld.rem / 1000 : 0;
2144 return datetime_add_nanoseconds_with_round(ltime, lld.rem % 1000, &warnings);
2148 void Item_func_convert_tz::fix_length_and_dec()
2150 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH,
2156 bool Item_func_convert_tz::get_date(
MYSQL_TIME *ltime,
2157 uint fuzzy_date __attribute__((unused)))
2159 my_time_t my_time_tmp;
2161 THD *thd= current_thd;
2163 if (!from_tz_cached)
2165 from_tz= my_tz_find(thd, args[1]->val_str_ascii(&str));
2166 from_tz_cached= args[1]->const_item();
2171 to_tz= my_tz_find(thd, args[2]->val_str_ascii(&str));
2172 to_tz_cached= args[2]->const_item();
2175 if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, TIME_NO_ZERO_DATE))
2198 void Item_func_convert_tz::cleanup()
2200 from_tz_cached= to_tz_cached= 0;
2201 Item_datetime_func::cleanup();
2205 void Item_date_add_interval::fix_length_and_dec()
2207 enum_field_types arg0_field_type;
2222 arg0_field_type= args[0]->field_type();
2223 uint8 interval_dec= 0;
2224 if (int_type == INTERVAL_MICROSECOND ||
2225 (int_type >= INTERVAL_DAY_MICROSECOND &&
2226 int_type <= INTERVAL_SECOND_MICROSECOND))
2227 interval_dec= DATETIME_MAX_DECIMALS;
2228 else if (int_type == INTERVAL_SECOND && args[1]->decimals > 0)
2229 interval_dec= MY_MIN(args[1]->decimals, DATETIME_MAX_DECIMALS);
2231 if (arg0_field_type == MYSQL_TYPE_DATETIME ||
2232 arg0_field_type == MYSQL_TYPE_TIMESTAMP)
2235 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, dec);
2236 cached_field_type= MYSQL_TYPE_DATETIME;
2238 else if (arg0_field_type == MYSQL_TYPE_DATE)
2240 if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
2242 cached_field_type= MYSQL_TYPE_DATE;
2243 fix_length_and_dec_and_charset_datetime(MAX_DATE_WIDTH, 0);
2247 cached_field_type= MYSQL_TYPE_DATETIME;
2248 fix_length_and_dec_and_charset_datetime(MAX_DATE_WIDTH, interval_dec);
2251 else if (arg0_field_type == MYSQL_TYPE_TIME)
2254 cached_field_type= MYSQL_TYPE_TIME;
2255 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, dec);
2259 cached_field_type= MYSQL_TYPE_STRING;
2261 fix_length_and_charset(MAX_DATETIME_FULL_WIDTH, default_charset());
2263 value.alloc(max_length);
2268 bool Item_date_add_interval::get_date_internal(
MYSQL_TIME *ltime,
2273 if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) ||
2275 return (null_value=
true);
2277 if (date_sub_interval)
2278 interval.neg = !interval.neg;
2284 if (cached_field_type == MYSQL_TYPE_DATE &&
2285 ltime->time_type == MYSQL_TIMESTAMP_DATETIME)
2286 datetime_to_date(ltime);
2287 else if (cached_field_type == MYSQL_TYPE_DATETIME &&
2288 ltime->time_type == MYSQL_TIMESTAMP_DATE)
2289 date_to_datetime(ltime);
2291 if ((null_value= date_add_interval(ltime, int_type, interval)))
2297 bool Item_date_add_interval::get_time_internal(
MYSQL_TIME *ltime)
2301 if ((null_value= args[0]->get_time(ltime) ||
2305 if (date_sub_interval)
2306 interval.neg= !interval.neg;
2308 DBUG_ASSERT(!check_time_range_quick(ltime));
2310 longlong usec1= ((((ltime->day * 24 + ltime->hour) * 60 +
2311 ltime->minute) * 60 + ltime->second) * 1000000LL +
2313 (ltime->neg ? -1 : 1);
2314 longlong usec2= ((((interval.day * 24 + interval.hour) * 60 +
2315 interval.minute) * 60 + interval.second) * 1000000LL +
2316 interval.second_part) *
2317 (interval.neg ? -1 : 1);
2318 longlong diff= usec1 + usec2;
2320 seconds.quot= diff / 1000000;
2321 seconds.rem= diff % 1000000 * 1000;
2322 if ((null_value= (interval.year || interval.month ||
2323 sec_to_time(seconds, ltime))))
2325 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
2326 ER_DATETIME_FUNCTION_OVERFLOW,
2327 ER(ER_DATETIME_FUNCTION_OVERFLOW),
2337 if (cached_field_type != MYSQL_TYPE_TIME)
2338 return get_date_internal(ltime, fuzzy_date | TIME_NO_ZERO_DATE);
2339 return get_time_internal(ltime);
2348 return ((int_type == other->int_type) &&
2349 (date_sub_interval == other->date_sub_interval));
2357 static const char *interval_names[]=
2359 "year",
"quarter",
"month",
"week",
"day",
2360 "hour",
"minute",
"second",
"microsecond",
2361 "year_month",
"day_hour",
"day_minute",
2362 "day_second",
"hour_minute",
"hour_second",
2363 "minute_second",
"day_microsecond",
2364 "hour_microsecond",
"minute_microsecond",
2365 "second_microsecond"
2371 args[0]->
print(str, query_type);
2372 str->append(date_sub_interval?
" - interval ":
" + interval ");
2373 args[1]->
print(str, query_type);
2375 str->append(interval_names[int_type]);
2381 str->append(STRING_WITH_LEN(
"extract("));
2382 str->append(interval_names[int_type]);
2383 str->append(STRING_WITH_LEN(
" from "));
2384 args[0]->
print(str, query_type);
2388 void Item_extract::fix_length_and_dec()
2392 case INTERVAL_YEAR: max_length=4; date_value=1;
break;
2393 case INTERVAL_YEAR_MONTH: max_length=6; date_value=1;
break;
2394 case INTERVAL_QUARTER: max_length=2; date_value=1;
break;
2395 case INTERVAL_MONTH: max_length=2; date_value=1;
break;
2396 case INTERVAL_WEEK: max_length=2; date_value=1;
break;
2397 case INTERVAL_DAY: max_length=2; date_value=1;
break;
2398 case INTERVAL_DAY_HOUR: max_length=9; date_value=0;
break;
2399 case INTERVAL_DAY_MINUTE: max_length=11; date_value=0;
break;
2400 case INTERVAL_DAY_SECOND: max_length=13; date_value=0;
break;
2401 case INTERVAL_HOUR: max_length=2; date_value=0;
break;
2402 case INTERVAL_HOUR_MINUTE: max_length=4; date_value=0;
break;
2403 case INTERVAL_HOUR_SECOND: max_length=6; date_value=0;
break;
2404 case INTERVAL_MINUTE: max_length=2; date_value=0;
break;
2405 case INTERVAL_MINUTE_SECOND: max_length=4; date_value=0;
break;
2406 case INTERVAL_SECOND: max_length=2; date_value=0;
break;
2407 case INTERVAL_MICROSECOND: max_length=2; date_value=0;
break;
2408 case INTERVAL_DAY_MICROSECOND: max_length=20; date_value=0;
break;
2409 case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0;
break;
2410 case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0;
break;
2411 case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0;
break;
2412 case INTERVAL_LAST: DBUG_ASSERT(0);
break;
2417 longlong Item_extract::val_int()
2419 DBUG_ASSERT(fixed == 1);
2426 if (get_arg0_date(<ime, TIME_FUZZY_DATE))
2432 if (get_arg0_time(<ime))
2434 neg= ltime.neg ? -1 : 1;
2437 case INTERVAL_YEAR:
return ltime.year;
2438 case INTERVAL_YEAR_MONTH:
return ltime.year*100L+ltime.month;
2439 case INTERVAL_QUARTER:
return (ltime.month+2)/3;
2440 case INTERVAL_MONTH:
return ltime.month;
2443 week_format= current_thd->variables.default_week_format;
2444 return calc_week(<ime, week_mode(week_format), &year);
2446 case INTERVAL_DAY:
return ltime.day;
2447 case INTERVAL_DAY_HOUR:
return (
long) (ltime.day*100L+ltime.hour)*neg;
2448 case INTERVAL_DAY_MINUTE:
return (
long) (ltime.day*10000L+
2451 case INTERVAL_DAY_SECOND:
return ((longlong) ltime.day*1000000L+
2452 (longlong) (ltime.hour*10000L+
2455 case INTERVAL_HOUR:
return (
long) ltime.hour*neg;
2456 case INTERVAL_HOUR_MINUTE:
return (
long) (ltime.hour*100+ltime.minute)*neg;
2457 case INTERVAL_HOUR_SECOND:
return (
long) (ltime.hour*10000+ltime.minute*100+
2459 case INTERVAL_MINUTE:
return (
long) ltime.minute*neg;
2460 case INTERVAL_MINUTE_SECOND:
return (
long) (ltime.minute*100+ltime.second)*neg;
2461 case INTERVAL_SECOND:
return (
long) ltime.second*neg;
2462 case INTERVAL_MICROSECOND:
return (
long) ltime.
second_part*neg;
2463 case INTERVAL_DAY_MICROSECOND:
return (((longlong)ltime.day*1000000L +
2464 (longlong)ltime.hour*10000L +
2466 ltime.second)*1000000L +
2468 case INTERVAL_HOUR_MICROSECOND:
return (((longlong)ltime.hour*10000L +
2470 ltime.second)*1000000L +
2472 case INTERVAL_MINUTE_MICROSECOND:
return (((longlong)(ltime.minute*100+
2473 ltime.second))*1000000L+
2475 case INTERVAL_SECOND_MICROSECOND:
return ((longlong)ltime.second*1000000L+
2477 case INTERVAL_LAST: DBUG_ASSERT(0);
break;
2486 if (item->type() != FUNC_ITEM ||
2487 functype() != ((
Item_func*)item)->functype())
2491 if (ie->int_type != int_type)
2494 if (!args[0]->
eq(ie->args[0], binary_cmp))
2502 str->append(STRING_WITH_LEN(
"cast("));
2503 args[0]->
print(str, query_type);
2504 str->append(STRING_WITH_LEN(
" as "));
2505 str->append(cast_type());
2512 bool Item_datetime_typecast::get_date(
MYSQL_TIME *ltime, uint fuzzy_date)
2514 if ((null_value= args[0]->get_date(ltime, fuzzy_date | TIME_NO_DATE_FRAC_WARN)))
2516 DBUG_ASSERT(ltime->time_type != MYSQL_TIMESTAMP_TIME);
2517 ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
2519 return (null_value= my_datetime_round(ltime, decimals, &warnings));
2525 str->append(STRING_WITH_LEN(
"cast("));
2526 args[0]->
print(str, query_type);
2527 str->append(STRING_WITH_LEN(
" as "));
2528 str->append(cast_type());
2535 bool Item_time_typecast::get_time(
MYSQL_TIME *ltime)
2537 if (get_arg0_time(ltime))
2539 my_time_round(ltime, decimals);
2544 if (ltime->time_type != MYSQL_TIMESTAMP_TIME)
2545 datetime_to_time(ltime);
2552 str->append(STRING_WITH_LEN(
"cast("));
2553 args[0]->
print(str, query_type);
2554 str->append(STRING_WITH_LEN(
" as "));
2555 str->append(cast_type());
2560 bool Item_date_typecast::get_date(
MYSQL_TIME *ltime, uint fuzzy_date)
2562 bool res= get_arg0_date(ltime, fuzzy_date | TIME_NO_DATE_FRAC_WARN);
2563 ltime->hour= ltime->minute= ltime->second= ltime->
second_part= 0;
2564 ltime->time_type= MYSQL_TIMESTAMP_DATE;
2581 DBUG_ASSERT(fixed == 1);
2582 long daynr= (long) args[1]->val_int();
2583 long year= (long) args[0]->val_int();
2586 if (args[0]->null_value || args[1]->null_value ||
2587 year < 0 || year > 9999 || daynr <= 0)
2591 year= year_2000_handling(year);
2593 days= calc_daynr(year, 1, 1) + daynr - 1;
2598 get_date_from_daynr(days, <ime->year, <ime->month, <ime->day);
2600 ltime->hour= ltime->minute= ltime->second= ltime->
second_part= 0;
2601 ltime->time_type= MYSQL_TIMESTAMP_DATE;
2611 void Item_func_add_time::fix_length_and_dec()
2625 if (args[0]->field_type() == MYSQL_TYPE_TIME && !is_date)
2627 cached_field_type= MYSQL_TYPE_TIME;
2629 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, dec);
2631 else if (args[0]->is_temporal_with_date_and_time() || is_date)
2633 cached_field_type= MYSQL_TYPE_DATETIME;
2635 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, dec);
2639 cached_field_type= MYSQL_TYPE_STRING;
2640 fix_length_and_charset(MAX_DATETIME_FULL_WIDTH, default_charset());
2657 bool Item_func_add_time::val_datetime(
MYSQL_TIME *time, uint fuzzy_date)
2659 DBUG_ASSERT(fixed == 1);
2662 long days, microseconds;
2667 if (cached_field_type == MYSQL_TYPE_DATETIME)
2669 if (get_arg0_date(&l_time1, fuzzy_date) ||
2670 args[1]->get_time(&l_time2) ||
2671 l_time1.time_type == MYSQL_TIMESTAMP_TIME ||
2672 l_time2.time_type != MYSQL_TIMESTAMP_TIME)
2677 if (args[0]->get_time(&l_time1) ||
2678 args[1]->get_time(&l_time2) ||
2679 l_time2.time_type == MYSQL_TIMESTAMP_DATETIME)
2681 is_time= (l_time1.time_type == MYSQL_TIMESTAMP_TIME);
2683 if (l_time1.neg != l_time2.neg)
2688 time->neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
2689 &seconds, µseconds);
2695 if (l_time1.neg && (seconds || microseconds))
2696 time->neg= 1 - time->neg;
2698 if (!is_time && time->neg)
2701 days= (long) (seconds / SECONDS_IN_24H);
2703 calc_time_from_sec(time, seconds % SECONDS_IN_24H, microseconds);
2707 get_date_from_daynr(days, &time->year, &time->month, &time->day);
2708 time->time_type= MYSQL_TIMESTAMP_DATETIME;
2713 time->time_type= MYSQL_TIMESTAMP_TIME;
2714 time->hour+= days*24;
2715 adjust_time_range_with_warn(time, 0);
2728 DBUG_ASSERT(sign > 0);
2729 str->append(STRING_WITH_LEN(
"timestamp("));
2734 str->append(STRING_WITH_LEN(
"addtime("));
2736 str->append(STRING_WITH_LEN(
"subtime("));
2738 args[0]->
print(str, query_type);
2740 args[1]->
print(str, query_type);
2760 DBUG_ASSERT(fixed == 1);
2768 if ((args[0]->is_temporal_with_date() &&
2769 args[1]->field_type() == MYSQL_TYPE_TIME) ||
2770 (args[1]->is_temporal_with_date() &&
2771 args[0]->field_type() == MYSQL_TYPE_TIME))
2774 if (args[0]->is_temporal_with_date() ||
2775 args[1]->is_temporal_with_date())
2777 if (args[0]->get_date(&l_time1, TIME_FUZZY_DATE) ||
2778 args[1]->get_date(&l_time2, TIME_FUZZY_DATE))
2788 if (l_time1.time_type != l_time2.time_type)
2791 if (l_time1.neg != l_time2.neg)
2794 memset(l_time3, 0,
sizeof(*l_time3));
2796 l_time3->neg= calc_time_diff(&l_time1, &l_time2, l_sign,
2797 &seconds, µseconds);
2804 if (l_time1.neg && (seconds || microseconds))
2805 l_time3->neg= 1 - l_time3->neg;
2807 calc_time_from_sec(l_time3, seconds, microseconds);
2808 adjust_time_range_with_warn(l_time3, decimals);
2812 return (null_value= 1);
2824 DBUG_ASSERT(fixed == 1);
2826 longlong hour= args[0]->val_int();
2827 longlong minute= args[1]->val_int();
2828 my_decimal tmp, *sec= args[2]->val_decimal(&tmp);
2831 if ((null_value= (args[0]->null_value ||
2832 args[1]->null_value ||
2833 args[2]->null_value ||
2834 my_decimal2lldiv_t(E_DEC_FATAL_ERROR, sec, &second) ||
2835 minute < 0 || minute > 59 ||
2836 second.quot < 0 || second.quot > 59 || second.rem < 0)))
2839 set_zero_time(ltime, MYSQL_TIMESTAMP_TIME);
2844 if (args[0]->unsigned_flag)
2849 if (-hour > UINT_MAX || hour > UINT_MAX)
2854 ltime->hour= (uint) ((hour < 0 ? -hour : hour));
2855 ltime->minute= (uint) minute;
2856 ltime->second= (uint) second.quot;
2859 adjust_time_range_with_warn(ltime, decimals);
2860 time_add_nanoseconds_with_round(ltime, second.rem % 1000, &warnings);
2866 set_max_hhmmss(ltime);
2867 char buf[MAX_BIGINT_WIDTH + 6 + 10 +1];
2868 char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
2869 int len = (int)(ptr - buf) +
2870 sprintf(ptr,
":%02u:%02u", (uint) minute, (uint) second.quot);
2877 int dec= MY_MIN(args[2]->decimals, 9);
2878 len+= sprintf(buf + len,
".%0*lld", dec,
2879 second.rem / (ulong) log_10_int[9 - dec]);
2881 DBUG_ASSERT(strlen(buf) <
sizeof(buf));
2882 make_truncated_value_warning(
ErrConvString(buf, len), MYSQL_TIMESTAMP_TIME);
2897 DBUG_ASSERT(fixed == 1);
2899 return get_arg0_time(<ime) ? 0 : ltime.
second_part;
2903 longlong Item_func_timestamp_diff::val_int()
2912 if (args[0]->get_date(<ime1, TIME_NO_ZERO_DATE) ||
2913 args[1]->get_date(<ime2, TIME_NO_ZERO_DATE))
2916 if (calc_time_diff(<ime2,<ime1, 1,
2917 &seconds, µseconds))
2920 if (int_type == INTERVAL_YEAR ||
2921 int_type == INTERVAL_QUARTER ||
2922 int_type == INTERVAL_MONTH)
2924 uint year_beg, year_end, month_beg, month_end, day_beg, day_end;
2926 uint second_beg, second_end, microsecond_beg, microsecond_end;
2930 year_beg= ltime2.year;
2931 year_end= ltime1.year;
2932 month_beg= ltime2.month;
2933 month_end= ltime1.month;
2934 day_beg= ltime2.day;
2935 day_end= ltime1.day;
2936 second_beg= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second;
2937 second_end= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second;
2943 year_beg= ltime1.year;
2944 year_end= ltime2.year;
2945 month_beg= ltime1.month;
2946 month_end= ltime2.month;
2947 day_beg= ltime1.day;
2948 day_end= ltime2.day;
2949 second_beg= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second;
2950 second_end= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second;
2956 years= year_end - year_beg;
2957 if (month_end < month_beg || (month_end == month_beg && day_end < day_beg))
2962 if (month_end < month_beg || (month_end == month_beg && day_end < day_beg))
2963 months+= 12 - (month_beg - month_end);
2965 months+= (month_end - month_beg);
2967 if (day_end < day_beg)
2969 else if ((day_end == day_beg) &&
2970 ((second_end < second_beg) ||
2971 (second_end == second_beg && microsecond_end < microsecond_beg)))
2977 return months/12*neg;
2978 case INTERVAL_QUARTER:
2979 return months/3*neg;
2980 case INTERVAL_MONTH:
2983 return seconds / SECONDS_IN_24H / 7L * neg;
2985 return seconds / SECONDS_IN_24H * neg;
2987 return seconds/3600L*neg;
2988 case INTERVAL_MINUTE:
2989 return seconds/60L*neg;
2990 case INTERVAL_SECOND:
2992 case INTERVAL_MICROSECOND:
2997 return (seconds*1000000L+microseconds)*neg;
3010 str->append(func_name());
3015 str->append(STRING_WITH_LEN(
"YEAR"));
3017 case INTERVAL_QUARTER:
3018 str->append(STRING_WITH_LEN(
"QUARTER"));
3020 case INTERVAL_MONTH:
3021 str->append(STRING_WITH_LEN(
"MONTH"));
3024 str->append(STRING_WITH_LEN(
"WEEK"));
3027 str->append(STRING_WITH_LEN(
"DAY"));
3030 str->append(STRING_WITH_LEN(
"HOUR"));
3032 case INTERVAL_MINUTE:
3033 str->append(STRING_WITH_LEN(
"MINUTE"));
3035 case INTERVAL_SECOND:
3036 str->append(STRING_WITH_LEN(
"SECOND"));
3038 case INTERVAL_MICROSECOND:
3039 str->append(STRING_WITH_LEN(
"SECOND_FRAC"));
3045 for (uint
i=0 ;
i < 2 ;
i++)
3048 args[
i]->
print(str, query_type);
3054 String *Item_func_get_format::val_str_ascii(
String *str)
3056 DBUG_ASSERT(fixed == 1);
3057 const char *format_name;
3059 String *val= args[0]->val_str_ascii(str);
3062 if ((null_value= args[0]->null_value))
3065 val_len= val->length();
3066 for (format= &known_date_time_formats[0];
3067 (format_name= format->format_name);
3070 uint format_name_len;
3071 format_name_len= (uint) strlen(format_name);
3072 if (val_len == format_name_len &&
3073 !my_strnncoll(&my_charset_latin1,
3074 (
const uchar *) val->ptr(), val_len,
3075 (
const uchar *) format_name, val_len))
3077 const char *format_str= get_date_time_format_str(format,
type);
3078 str->set(format_str, (uint) strlen(format_str), &my_charset_numeric);
3090 str->append(func_name());
3094 case MYSQL_TIMESTAMP_DATE:
3095 str->append(STRING_WITH_LEN(
"DATE, "));
3097 case MYSQL_TIMESTAMP_DATETIME:
3098 str->append(STRING_WITH_LEN(
"DATETIME, "));
3100 case MYSQL_TIMESTAMP_TIME:
3101 str->append(STRING_WITH_LEN(
"TIME, "));
3106 args[0]->
print(str, query_type);
3126 void Item_func_str_to_date::fix_from_format(
const char *format, uint length)
3128 const char *time_part_frms=
"HISThiklrs";
3129 const char *date_part_frms=
"MVUXYWabcjmvuxyw";
3130 bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
3131 const char *val= format;
3132 const char *end= format + length;
3134 for (; val != end && val != end; val++)
3136 if (*val ==
'%' && val + 1 != end)
3140 frac_second_used= time_part_used= 1;
3141 else if (!time_part_used && strchr(time_part_frms, *val))
3143 else if (!date_part_used && strchr(date_part_frms, *val))
3145 if (date_part_used && frac_second_used)
3151 cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
3152 cached_field_type= MYSQL_TYPE_DATETIME;
3153 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH,
3154 DATETIME_MAX_DECIMALS);
3161 if (frac_second_used)
3163 cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
3164 cached_field_type= MYSQL_TYPE_TIME;
3165 fix_length_and_dec_and_charset_datetime(MAX_TIME_FULL_WIDTH,
3166 DATETIME_MAX_DECIMALS);
3168 else if (time_part_used)
3172 cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
3173 cached_field_type= MYSQL_TYPE_DATETIME;
3174 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH, 0);
3178 cached_timestamp_type= MYSQL_TIMESTAMP_TIME;
3179 cached_field_type= MYSQL_TYPE_TIME;
3180 fix_length_and_dec_and_charset_datetime(MAX_TIME_WIDTH, 0);
3185 cached_timestamp_type= MYSQL_TIMESTAMP_DATE;
3186 cached_field_type= MYSQL_TYPE_DATE;
3187 fix_length_and_dec_and_charset_datetime(MAX_DATE_WIDTH, 0);
3192 void Item_func_str_to_date::fix_length_and_dec()
3195 cached_field_type= MYSQL_TYPE_DATETIME;
3196 cached_timestamp_type= MYSQL_TIMESTAMP_DATETIME;
3197 fix_length_and_dec_and_charset_datetime(MAX_DATETIME_WIDTH,
3198 DATETIME_MAX_DECIMALS);
3199 sql_mode= current_thd->datetime_flags();
3200 if ((const_item= args[1]->const_item()))
3202 char format_buff[64];
3203 String format_str(format_buff,
sizeof(format_buff), &my_charset_bin);
3204 String *format= args[1]->val_str(&format_str);
3205 if (!args[1]->null_value)
3206 fix_from_format(format->ptr(), format->length());
3214 char val_buff[64], format_buff[64];
3215 String val_string(val_buff,
sizeof(val_buff), &my_charset_bin), *val;
3216 String format_str(format_buff,
sizeof(format_buff), &my_charset_bin), *format;
3218 fuzzy_date|= sql_mode;
3219 val= args[0]->val_str(&val_string);
3220 format= args[1]->val_str(&format_str);
3221 if (args[0]->null_value || args[1]->null_value)
3225 memset(ltime, 0,
sizeof(*ltime));
3226 date_time_format.format.str= (
char*) format->ptr();
3227 date_time_format.format.length= format->length();
3228 if (extract_date_time(&date_time_format, val->ptr(), val->length(),
3229 ltime, cached_timestamp_type, 0,
"datetime") ||
3230 ((fuzzy_date & TIME_NO_ZERO_DATE) &&
3231 (ltime->year == 0 || ltime->month == 0 || ltime->day == 0)))
3233 ltime->time_type= cached_timestamp_type;
3234 if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day)
3241 ltime->hour+= ltime->day*24;
3247 if (val && (fuzzy_date & TIME_NO_ZERO_DATE) )
3250 strmake(buff, val->ptr(), min<size_t>(val->length(),
sizeof(buff)-1));
3251 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
3252 ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
3253 "datetime", buff,
"str_to_date");
3255 return (null_value= 1);
3259 bool Item_func_last_day::get_date(
MYSQL_TIME *ltime, uint fuzzy_date)
3261 if ((null_value= get_arg0_date(ltime, fuzzy_date)))
3264 if (ltime->month == 0)
3270 ltime->time_type= MYSQL_TIMESTAMP_DATE;
3272 make_truncated_value_warning(
ErrConvString(str), MYSQL_TIMESTAMP_ERROR);
3273 return (null_value=
true);
3276 uint month_idx= ltime->month - 1;
3277 ltime->day= days_in_month[month_idx];
3278 if (month_idx == 1 && calc_days_in_year(ltime->year) == 366)
3280 datetime_to_date(ltime);