1
/* Copyright (C) 2000-2003 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
21
This file defines all time functions
24
Move month and days to language files
26
#include <drizzled/server_includes.h>
28
#include <drizzled/drizzled_error_messages.h>
30
/** Day number for Dec 31st, 9999. */
31
#define MAX_DAY_NUMBER 3652424L
36
- Replace the switch with a function that should be called for each
38
- Remove sprintf and opencode the conversion, like we do in
41
The reason for this functions existence is that as we don't have a
42
way to know if a datetime/time value has microseconds in them
43
we are now only adding microseconds to the output if the
44
value has microseconds.
46
We can't use a standard make_date_time() for this as we don't know
47
if someone will use %f in the format specifier in which case we would get
48
the microseconds twice.
51
static bool make_datetime(date_time_format_types format, DRIZZLE_TIME *ltime,
55
const CHARSET_INFO * const cs= &my_charset_bin;
56
uint32_t length= MAX_DATE_STRING_REP_LENGTH;
58
if (str->alloc(length))
60
buff= (char*) str->ptr();
64
length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d",
65
ltime->neg ? "-" : "",
66
ltime->hour, ltime->minute, ltime->second);
68
case TIME_MICROSECOND:
69
length= cs->cset->snprintf(cs, buff, length, "%s%02d:%02d:%02d.%06ld",
70
ltime->neg ? "-" : "",
71
ltime->hour, ltime->minute, ltime->second,
75
length= cs->cset->snprintf(cs, buff, length, "%04d-%02d-%02d",
76
ltime->year, ltime->month, ltime->day);
79
length= cs->cset->snprintf(cs, buff, length,
80
"%04d-%02d-%02d %02d:%02d:%02d",
81
ltime->year, ltime->month, ltime->day,
82
ltime->hour, ltime->minute, ltime->second);
84
case DATE_TIME_MICROSECOND:
85
length= cs->cset->snprintf(cs, buff, length,
86
"%04d-%02d-%02d %02d:%02d:%02d.%06ld",
87
ltime->year, ltime->month, ltime->day,
88
ltime->hour, ltime->minute, ltime->second,
100
Wrapper over make_datetime() with validation of the input DRIZZLE_TIME value
103
see make_datetime() for more information
106
1 if there was an error during converion
110
static bool make_datetime_with_warn(date_time_format_types format, DRIZZLE_TIME *ltime,
115
if (make_datetime(format, ltime, str))
117
if (check_time_range(ltime, &warning))
122
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
123
str->ptr(), str->length(),
124
DRIZZLE_TIMESTAMP_TIME, NULL);
125
return make_datetime(format, ltime, str);
130
Wrapper over make_time() with validation of the input DRIZZLE_TIME value
133
see make_time() for more info
136
1 if there was an error during conversion
140
static bool make_time_with_warn(const DATE_TIME_FORMAT *format,
141
DRIZZLE_TIME *l_time, String *str)
144
make_time(format, l_time, str);
145
if (check_time_range(l_time, &warning))
149
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
150
str->ptr(), str->length(),
151
DRIZZLE_TIMESTAMP_TIME, NULL);
152
make_time(format, l_time, str);
160
Convert seconds to DRIZZLE_TIME value with overflow checking
164
seconds number of seconds
165
unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise
166
ltime output DRIZZLE_TIME value
169
If the 'seconds' argument is inside DRIZZLE_TIME data range, convert it to a
171
Otherwise, truncate the resulting value to the nearest endpoint, and
172
produce a warning message.
175
1 if the value was truncated during conversion
179
static bool sec_to_time(int64_t seconds, bool unsigned_flag, DRIZZLE_TIME *ltime)
183
memset(ltime, 0, sizeof(*ltime));
190
if (seconds < -3020399)
194
else if (seconds > 3020399)
197
sec= (uint) ((uint64_t) seconds % 3600);
198
ltime->hour= (uint) (seconds/3600);
199
ltime->minute= sec/60;
200
ltime->second= sec % 60;
205
ltime->hour= TIME_MAX_HOUR;
206
ltime->minute= TIME_MAX_MINUTE;
207
ltime->second= TIME_MAX_SECOND;
210
int len= (int)(int64_t10_to_str(seconds, buf, unsigned_flag ? 10 : -10)
212
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
213
buf, len, DRIZZLE_TIMESTAMP_TIME,
221
Date formats corresponding to compound %r and %T conversion specifiers
223
Note: We should init at least first element of "positions" array
224
(first member) or hpux11 compiler will die horribly.
226
static DATE_TIME_FORMAT time_ampm_format= {{0}, '\0', 0,
227
{(char *)"%I:%i:%S %p", 11}};
228
static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0,
229
{(char *)"%H:%i:%S", 8}};
232
Extract datetime value to DRIZZLE_TIME struct from string value
233
according to format string.
235
@param format date/time format specification
236
@param val String to decode
237
@param length Length of string
238
@param l_time Store result here
239
@param cached_timestamp_type It uses to get an appropriate warning
240
in the case when the value is truncated.
241
@param sub_pattern_end if non-zero then we are parsing string which
242
should correspond compound specifier (like %T or
243
%r) and this parameter is pointer to place where
244
pointer to end of string matching this specifier
248
Possibility to parse strings matching to patterns equivalent to compound
249
specifiers is mainly intended for use from inside of this function in
250
order to understand %T and %r conversion specifiers, so number of
251
conversion specifiers that can be used in such sub-patterns is limited.
252
Also most of checks are skipped in this case.
255
If one adds new format specifiers to this function he should also
256
consider adding them to get_date_time_result_type() function.
264
static bool extract_date_time(DATE_TIME_FORMAT *format,
265
const char *val, uint32_t length, DRIZZLE_TIME *l_time,
266
enum enum_drizzle_timestamp_type cached_timestamp_type,
267
const char **sub_pattern_end,
268
const char *date_time_type)
270
int weekday= 0, yearday= 0, daypart= 0;
273
int strict_week_number_year= -1;
276
bool sunday_first_n_first_week_non_iso= false;
277
bool strict_week_number= false;
278
bool strict_week_number_year_type= false;
279
const char *val_begin= val;
280
const char *val_end= val + length;
281
const char *ptr= format->format.str;
282
const char *end= ptr + format->format.length;
283
const CHARSET_INFO * const cs= &my_charset_bin;
285
if (!sub_pattern_end)
286
memset(l_time, 0, sizeof(*l_time));
288
for (; ptr != end && val != val_end; ptr++)
290
/* Skip pre-space between each argument */
291
while (val != val_end && my_isspace(cs, *val))
294
if (*ptr == '%' && ptr+1 != end)
301
val_len= (uint) (val_end - val);
305
tmp= (char*) val + cmin(4, val_len);
306
l_time->year= (int) my_strtoll10(val, &tmp, &error);
307
if ((int) (tmp-val) <= 2)
308
l_time->year= year_2000_handling(l_time->year);
312
tmp= (char*) val + cmin(2, val_len);
313
l_time->year= (int) my_strtoll10(val, &tmp, &error);
315
l_time->year= year_2000_handling(l_time->year);
321
tmp= (char*) val + cmin(2, val_len);
322
l_time->month= (int) my_strtoll10(val, &tmp, &error);
326
if ((l_time->month= check_word(my_locale_en_US.month_names,
327
val, val_end, &val)) <= 0)
331
if ((l_time->month= check_word(my_locale_en_US.ab_month_names,
332
val, val_end, &val)) <= 0)
338
tmp= (char*) val + cmin(2, val_len);
339
l_time->day= (int) my_strtoll10(val, &tmp, &error);
343
tmp= (char*) val + cmin(2, val_len);
344
l_time->day= (int) my_strtoll10(val, &tmp, &error);
345
/* Skip 'st, 'nd, 'th .. */
346
val= tmp + cmin((int) (val_end-tmp), 2);
357
tmp= (char*) val + cmin(2, val_len);
358
l_time->hour= (int) my_strtoll10(val, &tmp, &error);
364
tmp= (char*) val + cmin(2, val_len);
365
l_time->minute= (int) my_strtoll10(val, &tmp, &error);
372
tmp= (char*) val + cmin(2, val_len);
373
l_time->second= (int) my_strtoll10(val, &tmp, &error);
379
tmp= (char*) val_end;
381
tmp= (char*) val + 6;
382
l_time->second_part= (int) my_strtoll10(val, &tmp, &error);
383
frac_part= 6 - (tmp - val);
385
l_time->second_part*= (ulong) log_10_int[frac_part];
391
if (val_len < 2 || ! usa_time)
393
if (!my_strnncoll(&my_charset_utf8_general_ci,
394
(const unsigned char *) val, 2,
395
(const unsigned char *) "PM", 2))
397
else if (my_strnncoll(&my_charset_utf8_general_ci,
398
(const unsigned char *) val, 2,
399
(const unsigned char *) "AM", 2))
406
if ((weekday= check_word(my_locale_en_US.day_names, val, val_end, &val)) <= 0)
410
if ((weekday= check_word(my_locale_en_US.ab_day_names, val, val_end, &val)) <= 0)
414
tmp= (char*) val + 1;
415
if ((weekday= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
418
/* We should use the same 1 - 7 scale for %w as for %W */
424
tmp= (char*) val + cmin(val_len, 3);
425
yearday= (int) my_strtoll10(val, &tmp, &error);
434
sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
435
strict_week_number= (*ptr=='V' || *ptr=='v');
436
tmp= (char*) val + cmin(val_len, 2);
437
if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
438
(strict_week_number && !week_number) ||
444
/* Year used with 'strict' %V and %v week numbers */
447
strict_week_number_year_type= (*ptr=='X');
448
tmp= (char*) val + cmin(4, val_len);
449
strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
453
/* Time in AM/PM notation */
456
We can't just set error here, as we don't want to generate two
457
warnings in case of errors
459
if (extract_date_time(&time_ampm_format, val,
460
(uint)(val_end - val), l_time,
461
cached_timestamp_type, &val, "time"))
465
/* Time in 24-hour notation */
467
if (extract_date_time(&time_24hrs_format, val,
468
(uint)(val_end - val), l_time,
469
cached_timestamp_type, &val, "time"))
473
/* Conversion specifiers that match classes of characters */
475
while (my_ispunct(cs, *val) && val != val_end)
479
while (my_isalpha(cs, *val) && val != val_end)
483
while (my_isdigit(cs, *val) && val != val_end)
489
if (error) // Error from my_strtoll10
492
else if (!my_isspace(cs, *ptr))
501
if (l_time->hour > 12 || l_time->hour < 1)
503
l_time->hour= l_time->hour%12+daypart;
507
If we are recursively called for parsing string matching compound
508
specifiers we are already done.
512
*sub_pattern_end= val;
519
days= calc_daynr(l_time->year,1,1) + yearday - 1;
520
if (days <= 0 || days > MAX_DAY_NUMBER)
522
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
525
if (week_number >= 0 && weekday)
531
%V,%v require %X,%x resprectively,
532
%U,%u should be used with %Y and not %X or %x
534
if ((strict_week_number &&
535
(strict_week_number_year < 0 || (strict_week_number_year_type != sunday_first_n_first_week_non_iso))) ||
536
(!strict_week_number && strict_week_number_year >= 0))
539
/* Number of days since year 0 till 1st Jan of this year */
540
days= calc_daynr((strict_week_number ? strict_week_number_year :
543
/* Which day of week is 1st Jan of this year */
544
weekday_b= calc_weekday(days, sunday_first_n_first_week_non_iso);
547
Below we are going to sum:
548
1) number of days since year 0 till 1st day of 1st week of this year
549
2) number of days between 1st week and our week
550
3) and position of our day in the week
552
if (sunday_first_n_first_week_non_iso)
554
days+= ((weekday_b == 0) ? 0 : 7) - weekday_b +
555
(week_number - 1) * 7 +
560
days+= ((weekday_b <= 3) ? 0 : 7) - weekday_b +
561
(week_number - 1) * 7 +
565
if (days <= 0 || days > MAX_DAY_NUMBER)
567
get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day);
570
if (l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 ||
571
l_time->minute > 59 || l_time->second > 59)
578
if (!my_isspace(&my_charset_utf8_general_ci,*val))
580
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
582
cached_timestamp_type, NULL);
585
} while (++val != val_end);
592
strmake(buff, val_begin, cmin(length, (uint)sizeof(buff)-1));
593
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
594
ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
595
date_time_type, buff, "str_to_date");
602
Create a formated date/time value in a string.
605
bool make_date_time(DATE_TIME_FORMAT *format, DRIZZLE_TIME *l_time,
606
enum enum_drizzle_timestamp_type type, String *str)
612
const char *ptr, *end;
613
THD *thd= current_thd;
614
MY_LOCALE *locale= thd->variables.lc_time_names;
621
end= (ptr= format->format.str) + format->format.length;
622
for (; ptr != end ; ptr++)
624
if (*ptr != '%' || ptr+1 == end)
632
str->append(locale->month_names->type_names[l_time->month-1],
633
strlen(locale->month_names->type_names[l_time->month-1]),
634
system_charset_info);
639
str->append(locale->ab_month_names->type_names[l_time->month-1],
640
strlen(locale->ab_month_names->type_names[l_time->month-1]),
641
system_charset_info);
644
if (type == DRIZZLE_TIMESTAMP_TIME)
646
weekday= calc_weekday(calc_daynr(l_time->year,l_time->month,
648
str->append(locale->day_names->type_names[weekday],
649
strlen(locale->day_names->type_names[weekday]),
650
system_charset_info);
653
if (type == DRIZZLE_TIMESTAMP_TIME)
655
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
657
str->append(locale->ab_day_names->type_names[weekday],
658
strlen(locale->ab_day_names->type_names[weekday]),
659
system_charset_info);
662
if (type == DRIZZLE_TIMESTAMP_TIME)
664
length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
665
str->append_with_prefill(intbuff, length, 1, '0');
666
if (l_time->day >= 10 && l_time->day <= 19)
667
str->append(STRING_WITH_LEN("th"));
670
switch (l_time->day %10) {
672
str->append(STRING_WITH_LEN("st"));
675
str->append(STRING_WITH_LEN("nd"));
678
str->append(STRING_WITH_LEN("rd"));
681
str->append(STRING_WITH_LEN("th"));
687
length= int10_to_str(l_time->year, intbuff, 10) - intbuff;
688
str->append_with_prefill(intbuff, length, 4, '0');
691
length= int10_to_str(l_time->year%100, intbuff, 10) - intbuff;
692
str->append_with_prefill(intbuff, length, 2, '0');
695
length= int10_to_str(l_time->month, intbuff, 10) - intbuff;
696
str->append_with_prefill(intbuff, length, 2, '0');
699
length= int10_to_str(l_time->month, intbuff, 10) - intbuff;
700
str->append_with_prefill(intbuff, length, 1, '0');
703
length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
704
str->append_with_prefill(intbuff, length, 2, '0');
707
length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
708
str->append_with_prefill(intbuff, length, 1, '0');
711
length= int10_to_str(l_time->second_part, intbuff, 10) - intbuff;
712
str->append_with_prefill(intbuff, length, 6, '0');
715
length= int10_to_str(l_time->hour, intbuff, 10) - intbuff;
716
str->append_with_prefill(intbuff, length, 2, '0');
720
hours_i= (l_time->hour%24 + 11)%12+1;
721
length= int10_to_str(hours_i, intbuff, 10) - intbuff;
722
str->append_with_prefill(intbuff, length, 2, '0');
724
case 'i': /* minutes */
725
length= int10_to_str(l_time->minute, intbuff, 10) - intbuff;
726
str->append_with_prefill(intbuff, length, 2, '0');
729
if (type == DRIZZLE_TIMESTAMP_TIME)
731
length= int10_to_str(calc_daynr(l_time->year,l_time->month,
733
calc_daynr(l_time->year,1,1) + 1, intbuff, 10) - intbuff;
734
str->append_with_prefill(intbuff, length, 3, '0');
737
length= int10_to_str(l_time->hour, intbuff, 10) - intbuff;
738
str->append_with_prefill(intbuff, length, 1, '0');
741
hours_i= (l_time->hour%24 + 11)%12+1;
742
length= int10_to_str(hours_i, intbuff, 10) - intbuff;
743
str->append_with_prefill(intbuff, length, 1, '0');
746
hours_i= l_time->hour%24;
747
str->append(hours_i < 12 ? "AM" : "PM",2);
750
length= sprintf(intbuff,
751
((l_time->hour % 24) < 12) ?
752
"%02d:%02d:%02d AM" : "%02d:%02d:%02d PM",
753
(l_time->hour+11)%12+1,
756
str->append(intbuff, length);
760
length= int10_to_str(l_time->second, intbuff, 10) - intbuff;
761
str->append_with_prefill(intbuff, length, 2, '0');
764
length= sprintf(intbuff,
769
str->append(intbuff, length);
775
if (type == DRIZZLE_TIMESTAMP_TIME)
777
length= int10_to_str(calc_week(l_time,
779
WEEK_FIRST_WEEKDAY : WEEK_MONDAY_FIRST,
781
intbuff, 10) - intbuff;
782
str->append_with_prefill(intbuff, length, 2, '0');
789
if (type == DRIZZLE_TIMESTAMP_TIME)
791
length= int10_to_str(calc_week(l_time,
793
(WEEK_YEAR | WEEK_FIRST_WEEKDAY) :
794
(WEEK_YEAR | WEEK_MONDAY_FIRST)),
796
intbuff, 10) - intbuff;
797
str->append_with_prefill(intbuff, length, 2, '0');
804
if (type == DRIZZLE_TIMESTAMP_TIME)
806
(void) calc_week(l_time,
808
WEEK_YEAR | WEEK_FIRST_WEEKDAY :
809
WEEK_YEAR | WEEK_MONDAY_FIRST),
811
length= int10_to_str(year, intbuff, 10) - intbuff;
812
str->append_with_prefill(intbuff, length, 4, '0');
816
if (type == DRIZZLE_TIMESTAMP_TIME)
818
weekday=calc_weekday(calc_daynr(l_time->year,l_time->month,
820
length= int10_to_str(weekday, intbuff, 10) - intbuff;
821
str->append_with_prefill(intbuff, length, 1, '0');
836
Get a array of positive numbers from a string object.
837
Each number is separated by 1 non digit character
838
Return error if there is too many numbers.
839
If there is too few numbers, assume that the numbers are left out
840
from the high end. This allows one to give:
841
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
843
@param length: length of str
844
@param cs: charset of str
845
@param values: array of results
846
@param count: count of elements in result array
847
@param transform_msec: if value is true we suppose
848
that the last part of string value is microseconds
849
and we should transform value to six digit value.
850
For example, '1.1' -> '1.100000'
853
static bool get_interval_info(const char *str,uint32_t length, const CHARSET_INFO * const cs,
854
uint32_t count, uint64_t *values,
857
const char *end=str+length;
859
while (str != end && !my_isdigit(cs,*str))
862
for (i=0 ; i < count ; i++)
865
const char *start= str;
866
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
867
value= value * 10L + (int64_t) (*str - '0');
868
if (transform_msec && i == count - 1) // microseconds always last
870
long msec_length= 6 - (str - start);
872
value*= (long) log_10_int[msec_length];
875
while (str != end && !my_isdigit(cs,*str))
877
if (str == end && i != count-1)
880
/* Change values[0...i-1] -> values[0...count-1] */
881
bmove_upp((unsigned char*) (values+count), (unsigned char*) (values+i),
883
memset(values, 0, sizeof(*values)*(count-i));
891
int64_t Item_func_period_add::val_int()
894
ulong period=(ulong) args[0]->val_int();
895
int months=(int) args[1]->val_int();
897
if ((null_value=args[0]->null_value || args[1]->null_value) ||
899
return 0; /* purecov: inspected */
901
convert_month_to_period((uint) ((int) convert_period_to_month(period)+
906
int64_t Item_func_period_diff::val_int()
909
ulong period1=(ulong) args[0]->val_int();
910
ulong period2=(ulong) args[1]->val_int();
912
if ((null_value=args[0]->null_value || args[1]->null_value))
913
return 0; /* purecov: inspected */
914
return (int64_t) ((long) convert_period_to_month(period1)-
915
(long) convert_period_to_month(period2));
920
int64_t Item_func_to_days::val_int()
924
if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
926
return (int64_t) calc_daynr(ltime.year,ltime.month,ltime.day);
931
Get information about this Item tree monotonicity
934
Item_func_to_days::get_monotonicity_info()
937
Get information about monotonicity of the function represented by this item
941
See enum_monotonicity_info.
944
enum_monotonicity_info Item_func_to_days::get_monotonicity_info() const
946
if (args[0]->type() == Item::FIELD_ITEM)
948
if (args[0]->field_type() == DRIZZLE_TYPE_NEWDATE)
949
return MONOTONIC_STRICT_INCREASING;
950
if (args[0]->field_type() == DRIZZLE_TYPE_DATETIME)
951
return MONOTONIC_INCREASING;
953
return NON_MONOTONIC;
957
int64_t Item_func_to_days::val_int_endpoint(bool left_endp, bool *incl_endp)
962
if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
964
/* got NULL, leave the incl_endp intact */
967
res=(int64_t) calc_daynr(ltime.year,ltime.month,ltime.day);
969
if (args[0]->field_type() == DRIZZLE_TYPE_NEWDATE)
971
// TO_DAYS() is strictly monotonic for dates, leave incl_endp intact
976
Handle the special but practically useful case of datetime values that
977
point to day bound ("strictly less" comparison stays intact):
979
col < '2007-09-15 00:00:00' -> TO_DAYS(col) < TO_DAYS('2007-09-15')
981
which is different from the general case ("strictly less" changes to
984
col < '2007-09-15 12:34:56' -> TO_DAYS(col) <= TO_DAYS('2007-09-15')
986
if (!left_endp && !(ltime.hour || ltime.minute || ltime.second ||
995
int64_t Item_func_dayofyear::val_int()
999
if (get_arg0_date(<ime,TIME_NO_ZERO_DATE))
1001
return (int64_t) calc_daynr(ltime.year,ltime.month,ltime.day) -
1002
calc_daynr(ltime.year,1,1) + 1;
1005
int64_t Item_func_dayofmonth::val_int()
1009
(void) get_arg0_date(<ime, TIME_FUZZY_DATE);
1010
return (int64_t) ltime.day;
1013
int64_t Item_func_month::val_int()
1017
(void) get_arg0_date(<ime, TIME_FUZZY_DATE);
1018
return (int64_t) ltime.month;
1022
String* Item_func_monthname::val_str(String* str)
1025
const char *month_name;
1026
uint32_t month= (uint) val_int();
1027
THD *thd= current_thd;
1029
if (null_value || !month)
1035
month_name= thd->variables.lc_time_names->month_names->type_names[month-1];
1036
str->set(month_name, strlen(month_name), system_charset_info);
1042
Returns the quarter of the year.
1045
int64_t Item_func_quarter::val_int()
1049
if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1051
return (int64_t) ((ltime.month+2)/3);
1054
int64_t Item_func_hour::val_int()
1058
(void) get_arg0_time(<ime);
1062
int64_t Item_func_minute::val_int()
1066
(void) get_arg0_time(<ime);
1067
return ltime.minute;
1071
Returns the second in time_exp in the range of 0 - 59.
1073
int64_t Item_func_second::val_int()
1077
(void) get_arg0_time(<ime);
1078
return ltime.second;
1082
uint32_t week_mode(uint32_t mode)
1084
uint32_t week_format= (mode & 7);
1085
if (!(week_format & WEEK_MONDAY_FIRST))
1086
week_format^= WEEK_FIRST_WEEKDAY;
1092
The bits in week_format(for calc_week() function) has the following meaning:
1093
WEEK_MONDAY_FIRST (0) If not set Sunday is first day of week
1094
If set Monday is first day of week
1095
WEEK_YEAR (1) If not set Week is in range 0-53
1097
Week 0 is returned for the the last week of the previous year (for
1098
a date at start of january) In this case one can get 53 for the
1099
first week of next year. This flag ensures that the week is
1100
relevant for the given year. Note that this flag is only
1101
releveant if WEEK_JANUARY is not set.
1103
If set Week is in range 1-53.
1105
In this case one may get week 53 for a date in January (when
1106
the week is that last week of previous year) and week 1 for a
1109
WEEK_FIRST_WEEKDAY (2) If not set Weeks are numbered according
1111
If set The week that contains the first
1112
'first-day-of-week' is week 1.
1114
ISO 8601:1988 means that if the week containing January 1 has
1115
four or more days in the new year, then it is week 1;
1116
Otherwise it is the last week of the previous year, and the
1117
next week is week 1.
1121
int64_t Item_func_week::val_int()
1126
if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1128
return (int64_t) calc_week(<ime,
1129
week_mode((uint) args[1]->val_int()),
1134
int64_t Item_func_yearweek::val_int()
1139
if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1141
week= calc_week(<ime,
1142
(week_mode((uint) args[1]->val_int()) | WEEK_YEAR),
1144
return week+year*100;
1148
int64_t Item_func_weekday::val_int()
1153
if (get_arg0_date(<ime, TIME_NO_ZERO_DATE))
1156
return (int64_t) calc_weekday(calc_daynr(ltime.year, ltime.month,
1158
odbc_type) + test(odbc_type);
1162
String* Item_func_dayname::val_str(String* str)
1165
uint32_t weekday=(uint) val_int(); // Always Item_func_daynr()
1166
const char *day_name;
1167
THD *thd= current_thd;
1172
day_name= thd->variables.lc_time_names->day_names->type_names[weekday];
1173
str->set(day_name, strlen(day_name), system_charset_info);
1178
int64_t Item_func_year::val_int()
1182
(void) get_arg0_date(<ime, TIME_FUZZY_DATE);
1183
return (int64_t) ltime.year;
1188
Get information about this Item tree monotonicity
1191
Item_func_year::get_monotonicity_info()
1194
Get information about monotonicity of the function represented by this item
1198
See enum_monotonicity_info.
1201
enum_monotonicity_info Item_func_year::get_monotonicity_info() const
1203
if (args[0]->type() == Item::FIELD_ITEM &&
1204
(args[0]->field_type() == DRIZZLE_TYPE_NEWDATE ||
1205
args[0]->field_type() == DRIZZLE_TYPE_DATETIME))
1206
return MONOTONIC_INCREASING;
1207
return NON_MONOTONIC;
1211
int64_t Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
1215
if (get_arg0_date(<ime, TIME_FUZZY_DATE))
1217
/* got NULL, leave the incl_endp intact */
1222
Handle the special but practically useful case of datetime values that
1223
point to year bound ("strictly less" comparison stays intact) :
1225
col < '2007-01-01 00:00:00' -> YEAR(col) < 2007
1227
which is different from the general case ("strictly less" changes to
1230
col < '2007-09-15 23:00:00' -> YEAR(col) <= 2007
1232
if (!left_endp && ltime.day == 1 && ltime.month == 1 &&
1233
!(ltime.hour || ltime.minute || ltime.second || ltime.second_part))
1241
int64_t Item_func_unix_timestamp::val_int()
1248
return (int64_t) current_thd->query_start();
1249
if (args[0]->type() == FIELD_ITEM)
1250
{ // Optimize timestamp field
1251
Field *field=((Item_field*) args[0])->field;
1252
if (field->type() == DRIZZLE_TYPE_TIMESTAMP)
1253
return ((Field_timestamp*) field)->get_timestamp(&null_value);
1256
if (get_arg0_date(<ime, 0))
1259
We have to set null_value again because get_arg0_date will also set it
1260
to true if we have wrong datetime parameter (and we should return 0 in
1263
null_value= args[0]->null_value;
1267
return (int64_t) TIME_to_timestamp(current_thd, <ime, ¬_used);
1271
int64_t Item_func_time_to_sec::val_int()
1276
(void) get_arg0_time(<ime);
1277
seconds=ltime.hour*3600L+ltime.minute*60+ltime.second;
1278
return ltime.neg ? -seconds : seconds;
1283
Convert a string to a interval value.
1285
To make code easy, allow interval objects without separators.
1288
bool get_interval_value(Item *args,interval_type int_type,
1289
String *str_value, INTERVAL *interval)
1293
const char *str= NULL;
1295
const CHARSET_INFO * const cs= str_value->charset();
1297
memset(interval, 0, sizeof(*interval));
1298
if ((int) int_type <= INTERVAL_MICROSECOND)
1300
value= args->val_int();
1301
if (args->null_value)
1312
if (!(res=args->val_str(str_value)))
1315
/* record negative intervalls in interval->neg */
1317
const char *end=str+res->length();
1318
while (str != end && my_isspace(cs,*str))
1320
if (str != end && *str == '-')
1325
length= (size_t) (end-str); // Set up pointers to new str
1330
interval->year= (ulong) value;
1332
case INTERVAL_QUARTER:
1333
interval->month= (ulong)(value*3);
1335
case INTERVAL_MONTH:
1336
interval->month= (ulong) value;
1339
interval->day= (ulong)(value*7);
1342
interval->day= (ulong) value;
1345
interval->hour= (ulong) value;
1347
case INTERVAL_MICROSECOND:
1348
interval->second_part=value;
1350
case INTERVAL_MINUTE:
1351
interval->minute=value;
1353
case INTERVAL_SECOND:
1354
interval->second=value;
1356
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
1357
if (get_interval_info(str,length,cs,2,array,0))
1359
interval->year= (ulong) array[0];
1360
interval->month= (ulong) array[1];
1362
case INTERVAL_DAY_HOUR:
1363
if (get_interval_info(str,length,cs,2,array,0))
1365
interval->day= (ulong) array[0];
1366
interval->hour= (ulong) array[1];
1368
case INTERVAL_DAY_MICROSECOND:
1369
if (get_interval_info(str,length,cs,5,array,1))
1371
interval->day= (ulong) array[0];
1372
interval->hour= (ulong) array[1];
1373
interval->minute= array[2];
1374
interval->second= array[3];
1375
interval->second_part= array[4];
1377
case INTERVAL_DAY_MINUTE:
1378
if (get_interval_info(str,length,cs,3,array,0))
1380
interval->day= (ulong) array[0];
1381
interval->hour= (ulong) array[1];
1382
interval->minute= array[2];
1384
case INTERVAL_DAY_SECOND:
1385
if (get_interval_info(str,length,cs,4,array,0))
1387
interval->day= (ulong) array[0];
1388
interval->hour= (ulong) array[1];
1389
interval->minute= array[2];
1390
interval->second= array[3];
1392
case INTERVAL_HOUR_MICROSECOND:
1393
if (get_interval_info(str,length,cs,4,array,1))
1395
interval->hour= (ulong) array[0];
1396
interval->minute= array[1];
1397
interval->second= array[2];
1398
interval->second_part= array[3];
1400
case INTERVAL_HOUR_MINUTE:
1401
if (get_interval_info(str,length,cs,2,array,0))
1403
interval->hour= (ulong) array[0];
1404
interval->minute= array[1];
1406
case INTERVAL_HOUR_SECOND:
1407
if (get_interval_info(str,length,cs,3,array,0))
1409
interval->hour= (ulong) array[0];
1410
interval->minute= array[1];
1411
interval->second= array[2];
1413
case INTERVAL_MINUTE_MICROSECOND:
1414
if (get_interval_info(str,length,cs,3,array,1))
1416
interval->minute= array[0];
1417
interval->second= array[1];
1418
interval->second_part= array[2];
1420
case INTERVAL_MINUTE_SECOND:
1421
if (get_interval_info(str,length,cs,2,array,0))
1423
interval->minute= array[0];
1424
interval->second= array[1];
1426
case INTERVAL_SECOND_MICROSECOND:
1427
if (get_interval_info(str,length,cs,2,array,1))
1429
interval->second= array[0];
1430
interval->second_part= array[1];
1432
case INTERVAL_LAST: /* purecov: begin deadcode */
1434
break; /* purecov: end */
1440
String *Item_date::val_str(String *str)
1444
if (get_date(<ime, TIME_FUZZY_DATE))
1445
return (String *) 0;
1446
if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
1449
return (String *) 0;
1451
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
1456
int64_t Item_date::val_int()
1460
if (get_date(<ime, TIME_FUZZY_DATE))
1462
return (int64_t) (ltime.year*10000L+ltime.month*100+ltime.day);
1466
bool Item_func_from_days::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
1468
int64_t value=args[0]->val_int();
1469
if ((null_value=args[0]->null_value))
1471
memset(ltime, 0, sizeof(DRIZZLE_TIME));
1472
get_date_from_daynr((long) value, <ime->year, <ime->month, <ime->day);
1473
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
1478
void Item_func_curdate::fix_length_and_dec()
1480
collation.set(&my_charset_bin);
1482
max_length=MAX_DATE_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
1484
store_now_in_TIME(<ime);
1486
/* We don't need to set second_part and neg because they already 0 */
1487
ltime.hour= ltime.minute= ltime.second= 0;
1488
ltime.time_type= DRIZZLE_TIMESTAMP_DATE;
1489
value= (int64_t) TIME_to_uint64_t_date(<ime);
1492
String *Item_func_curdate::val_str(String *str)
1495
if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
1498
return (String *) 0;
1500
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
1505
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1506
time zone. Defines time zone (local) used for whole CURDATE function.
1508
void Item_func_curdate_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1510
THD *thd= current_thd;
1511
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1512
(my_time_t)thd->query_start());
1513
thd->time_zone_used= 1;
1518
Converts current time in my_time_t to DRIZZLE_TIME represenatation for UTC
1519
time zone. Defines time zone (UTC) used for whole UTC_DATE function.
1521
void Item_func_curdate_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1523
my_tz_UTC->gmt_sec_to_TIME(now_time,
1524
(my_time_t)(current_thd->query_start()));
1526
We are not flagging this query as using time zone, since it uses fixed
1527
UTC-SYSTEM time-zone.
1532
bool Item_func_curdate::get_date(DRIZZLE_TIME *res,
1533
uint32_t fuzzy_date __attribute__((unused)))
1540
String *Item_func_curtime::val_str(String *str __attribute__((unused)))
1543
str_value.set(buff, buff_length, &my_charset_bin);
1548
void Item_func_curtime::fix_length_and_dec()
1552
decimals= DATETIME_DEC;
1553
collation.set(&my_charset_bin);
1554
store_now_in_TIME(<ime);
1555
value= TIME_to_uint64_t_time(<ime);
1556
buff_length= (uint) my_time_to_str(<ime, buff);
1557
max_length= buff_length;
1562
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1563
time zone. Defines time zone (local) used for whole CURTIME function.
1565
void Item_func_curtime_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1567
THD *thd= current_thd;
1568
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1569
(my_time_t)thd->query_start());
1570
thd->time_zone_used= 1;
1575
Converts current time in my_time_t to DRIZZLE_TIME represenatation for UTC
1576
time zone. Defines time zone (UTC) used for whole UTC_TIME function.
1578
void Item_func_curtime_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1580
my_tz_UTC->gmt_sec_to_TIME(now_time,
1581
(my_time_t)(current_thd->query_start()));
1583
We are not flagging this query as using time zone, since it uses fixed
1584
UTC-SYSTEM time-zone.
1589
String *Item_func_now::val_str(String *str __attribute__((unused)))
1592
str_value.set(buff,buff_length, &my_charset_bin);
1597
void Item_func_now::fix_length_and_dec()
1599
decimals= DATETIME_DEC;
1600
collation.set(&my_charset_bin);
1602
store_now_in_TIME(<ime);
1603
value= (int64_t) TIME_to_uint64_t_datetime(<ime);
1605
buff_length= (uint) my_datetime_to_str(<ime, buff);
1606
max_length= buff_length;
1611
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1612
time zone. Defines time zone (local) used for whole NOW function.
1614
void Item_func_now_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1616
THD *thd= current_thd;
1617
thd->variables.time_zone->gmt_sec_to_TIME(now_time,
1618
(my_time_t)thd->query_start());
1619
thd->time_zone_used= 1;
1624
Converts current time in my_time_t to DRIZZLE_TIME represenatation for UTC
1625
time zone. Defines time zone (UTC) used for whole UTC_TIMESTAMP function.
1627
void Item_func_now_utc::store_now_in_TIME(DRIZZLE_TIME *now_time)
1629
my_tz_UTC->gmt_sec_to_TIME(now_time,
1630
(my_time_t)(current_thd->query_start()));
1632
We are not flagging this query as using time zone, since it uses fixed
1633
UTC-SYSTEM time-zone.
1638
bool Item_func_now::get_date(DRIZZLE_TIME *res,
1639
uint32_t fuzzy_date __attribute__((unused)))
1646
int Item_func_now::save_in_field(Field *to, bool no_conversions __attribute__((unused)))
1649
return to->store_time(<ime, DRIZZLE_TIMESTAMP_DATETIME);
1654
Converts current time in my_time_t to DRIZZLE_TIME represenatation for local
1655
time zone. Defines time zone (local) used for whole SYSDATE function.
1657
void Item_func_sysdate_local::store_now_in_TIME(DRIZZLE_TIME *now_time)
1659
THD *thd= current_thd;
1660
thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0));
1661
thd->time_zone_used= 1;
1665
String *Item_func_sysdate_local::val_str(String *str __attribute__((unused)))
1668
store_now_in_TIME(<ime);
1669
buff_length= (uint) my_datetime_to_str(<ime, buff);
1670
str_value.set(buff, buff_length, &my_charset_bin);
1675
int64_t Item_func_sysdate_local::val_int()
1678
store_now_in_TIME(<ime);
1679
return (int64_t) TIME_to_uint64_t_datetime(<ime);
1683
double Item_func_sysdate_local::val_real()
1686
store_now_in_TIME(<ime);
1687
return uint64_t2double(TIME_to_uint64_t_datetime(<ime));
1691
void Item_func_sysdate_local::fix_length_and_dec()
1694
collation.set(&my_charset_bin);
1695
max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
1699
bool Item_func_sysdate_local::get_date(DRIZZLE_TIME *res,
1700
uint32_t fuzzy_date __attribute__((unused)))
1702
store_now_in_TIME(<ime);
1708
int Item_func_sysdate_local::save_in_field(Field *to, bool no_conversions __attribute__((unused)))
1710
store_now_in_TIME(<ime);
1712
to->store_time(<ime, DRIZZLE_TIMESTAMP_DATETIME);
1717
String *Item_func_sec_to_time::val_str(String *str)
1721
int64_t arg_val= args[0]->val_int();
1723
if ((null_value=args[0]->null_value) ||
1724
str->alloc(MAX_DATE_STRING_REP_LENGTH))
1730
sec_to_time(arg_val, args[0]->unsigned_flag, <ime);
1732
make_time((DATE_TIME_FORMAT *) 0, <ime, str);
1737
int64_t Item_func_sec_to_time::val_int()
1741
int64_t arg_val= args[0]->val_int();
1743
if ((null_value=args[0]->null_value))
1746
sec_to_time(arg_val, args[0]->unsigned_flag, <ime);
1748
return (ltime.neg ? -1 : 1) *
1749
((ltime.hour)*10000 + ltime.minute*100 + ltime.second);
1753
void Item_func_date_format::fix_length_and_dec()
1755
THD* thd= current_thd;
1757
Must use this_item() in case it's a local SP variable
1758
(for ->max_length and ->str_value)
1760
Item *arg1= args[1]->this_item();
1763
const CHARSET_INFO * const cs= thd->variables.collation_connection;
1764
uint32_t repertoire= arg1->collation.repertoire;
1765
if (!thd->variables.lc_time_names->is_ascii)
1766
repertoire|= MY_REPERTOIRE_EXTENDED;
1767
collation.set(cs, arg1->collation.derivation, repertoire);
1768
if (arg1->type() == STRING_ITEM)
1769
{ // Optimize the normal case
1771
max_length= format_length(&arg1->str_value) *
1772
collation.collation->mbmaxlen;
1777
max_length=cmin(arg1->max_length,(uint32_t) MAX_BLOB_WIDTH) * 10 *
1778
collation.collation->mbmaxlen;
1779
set_if_smaller(max_length,MAX_BLOB_WIDTH);
1781
maybe_null=1; // If wrong date
1785
bool Item_func_date_format::eq(const Item *item, bool binary_cmp) const
1787
Item_func_date_format *item_func;
1789
if (item->type() != FUNC_ITEM)
1791
if (func_name() != ((Item_func*) item)->func_name())
1795
item_func= (Item_func_date_format*) item;
1796
if (!args[0]->eq(item_func->args[0], binary_cmp))
1799
We must compare format string case sensitive.
1800
This needed because format modifiers with different case,
1801
for example %m and %M, have different meaning.
1803
if (!args[1]->eq(item_func->args[1], 1))
1810
uint32_t Item_func_date_format::format_length(const String *format)
1813
const char *ptr=format->ptr();
1814
const char *end=ptr+format->length();
1816
for (; ptr != end ; ptr++)
1818
if (*ptr != '%' || ptr == end-1)
1823
case 'M': /* month, textual */
1824
case 'W': /* day (of the week), textual */
1825
size += 64; /* large for UTF8 locale data */
1827
case 'D': /* day (of the month), numeric plus english suffix */
1828
case 'Y': /* year, numeric, 4 digits */
1829
case 'x': /* Year, used with 'v' */
1830
case 'X': /* Year, used with 'v, where week starts with Monday' */
1833
case 'a': /* locale's abbreviated weekday name (Sun..Sat) */
1834
case 'b': /* locale's abbreviated month name (Jan.Dec) */
1835
size += 32; /* large for UTF8 locale data */
1837
case 'j': /* day of year (001..366) */
1840
case 'U': /* week (00..52) */
1841
case 'u': /* week (00..52), where week starts with Monday */
1842
case 'V': /* week 1..53 used with 'x' */
1843
case 'v': /* week 1..53 used with 'x', where week starts with Monday */
1844
case 'y': /* year, numeric, 2 digits */
1845
case 'm': /* month, numeric */
1846
case 'd': /* day (of the month), numeric */
1847
case 'h': /* hour (01..12) */
1848
case 'I': /* --||-- */
1849
case 'i': /* minutes, numeric */
1850
case 'l': /* hour ( 1..12) */
1851
case 'p': /* locale's AM or PM */
1852
case 'S': /* second (00..61) */
1853
case 's': /* seconds, numeric */
1854
case 'c': /* month (0..12) */
1855
case 'e': /* day (0..31) */
1858
case 'k': /* hour ( 0..23) */
1859
case 'H': /* hour (00..23; value > 23 OK, padding always 2-digit) */
1860
size += 7; /* docs allow > 23, range depends on sizeof(unsigned int) */
1862
case 'r': /* time, 12-hour (hh:mm:ss [AP]M) */
1865
case 'T': /* time, 24-hour (hh:mm:ss) */
1868
case 'f': /* microseconds */
1871
case 'w': /* day (of the week), numeric */
1883
String *Item_func_date_format::val_str(String *str)
1886
DRIZZLE_TIME l_time;
1890
if (!is_time_format)
1892
if (get_arg0_date(&l_time, TIME_FUZZY_DATE))
1898
if (!(res=args[0]->val_str(str)) ||
1899
(str_to_time_with_warn(res->ptr(), res->length(), &l_time)))
1902
l_time.year=l_time.month=l_time.day=0;
1906
if (!(format = args[1]->val_str(str)) || !format->length())
1912
size=format_length(format);
1914
if (size < MAX_DATE_STRING_REP_LENGTH)
1915
size= MAX_DATE_STRING_REP_LENGTH;
1918
str= &value; // Save result here
1919
if (str->alloc(size))
1922
DATE_TIME_FORMAT date_time_format;
1923
date_time_format.format.str= (char*) format->ptr();
1924
date_time_format.format.length= format->length();
1926
/* Create the result string */
1927
str->set_charset(collation.collation);
1928
if (!make_date_time(&date_time_format, &l_time,
1929
is_time_format ? DRIZZLE_TIMESTAMP_TIME :
1930
DRIZZLE_TIMESTAMP_DATE,
1940
void Item_func_from_unixtime::fix_length_and_dec()
1943
collation.set(&my_charset_bin);
1944
decimals= DATETIME_DEC;
1945
max_length=MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
1947
thd->time_zone_used= 1;
1951
String *Item_func_from_unixtime::val_str(String *str)
1953
DRIZZLE_TIME time_tmp;
1957
if (get_date(&time_tmp, 0))
1960
if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
1966
make_datetime((DATE_TIME_FORMAT *) 0, &time_tmp, str);
1972
int64_t Item_func_from_unixtime::val_int()
1974
DRIZZLE_TIME time_tmp;
1978
if (get_date(&time_tmp, 0))
1981
return (int64_t) TIME_to_uint64_t_datetime(&time_tmp);
1984
bool Item_func_from_unixtime::get_date(DRIZZLE_TIME *ltime,
1985
uint32_t fuzzy_date __attribute__((unused)))
1987
uint64_t tmp= (uint64_t)(args[0]->val_int());
1989
"tmp > TIMESTAMP_MAX_VALUE" check also covers case of negative
1990
from_unixtime() argument since tmp is unsigned.
1992
if ((null_value= (args[0]->null_value || tmp > TIMESTAMP_MAX_VALUE)))
1995
thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)tmp);
2001
void Item_date_add_interval::fix_length_and_dec()
2003
enum_field_types arg0_field_type;
2005
collation.set(&my_charset_bin);
2007
max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
2008
value.alloc(max_length);
2011
The field type for the result of an Item_date function is defined as
2014
- If first arg is a DRIZZLE_TYPE_DATETIME result is DRIZZLE_TYPE_DATETIME
2015
- If first arg is a DRIZZLE_TYPE_NEWDATE and the interval type uses hours,
2016
minutes or seconds then type is DRIZZLE_TYPE_DATETIME.
2017
- Otherwise the result is DRIZZLE_TYPE_VARCHAR
2018
(This is because you can't know if the string contains a DATE, DRIZZLE_TIME or
2021
cached_field_type= DRIZZLE_TYPE_VARCHAR;
2022
arg0_field_type= args[0]->field_type();
2023
if (arg0_field_type == DRIZZLE_TYPE_DATETIME ||
2024
arg0_field_type == DRIZZLE_TYPE_TIMESTAMP)
2025
cached_field_type= DRIZZLE_TYPE_DATETIME;
2026
else if (arg0_field_type == DRIZZLE_TYPE_NEWDATE)
2028
if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH)
2029
cached_field_type= arg0_field_type;
2031
cached_field_type= DRIZZLE_TYPE_DATETIME;
2036
/* Here arg[1] is a Item_interval object */
2038
bool Item_date_add_interval::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
2042
if (args[0]->get_date(ltime, TIME_NO_ZERO_DATE) ||
2043
get_interval_value(args[1], int_type, &value, &interval))
2044
return (null_value=1);
2046
if (date_sub_interval)
2047
interval.neg = !interval.neg;
2049
if ((null_value= date_add_interval(ltime, int_type, interval)))
2055
String *Item_date_add_interval::val_str(String *str)
2059
enum date_time_format_types format;
2061
if (Item_date_add_interval::get_date(<ime, TIME_NO_ZERO_DATE))
2064
if (ltime.time_type == DRIZZLE_TIMESTAMP_DATE)
2066
else if (ltime.second_part)
2067
format= DATE_TIME_MICROSECOND;
2071
if (!make_datetime(format, <ime, str))
2079
int64_t Item_date_add_interval::val_int()
2084
if (Item_date_add_interval::get_date(<ime, TIME_NO_ZERO_DATE))
2086
date = (ltime.year*100L + ltime.month)*100L + ltime.day;
2087
return ltime.time_type == DRIZZLE_TIMESTAMP_DATE ? date :
2088
((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second;
2093
bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
2095
Item_date_add_interval *other= (Item_date_add_interval*) item;
2096
if (!Item_func::eq(item, binary_cmp))
2098
return ((int_type == other->int_type) &&
2099
(date_sub_interval == other->date_sub_interval));
2103
'interval_names' reflects the order of the enumeration interval_type.
2107
static const char *interval_names[]=
2109
"year", "quarter", "month", "week", "day",
2110
"hour", "minute", "second", "microsecond",
2111
"year_month", "day_hour", "day_minute",
2112
"day_second", "hour_minute", "hour_second",
2113
"minute_second", "day_microsecond",
2114
"hour_microsecond", "minute_microsecond",
2115
"second_microsecond"
2118
void Item_date_add_interval::print(String *str, enum_query_type query_type)
2121
args[0]->print(str, query_type);
2122
str->append(date_sub_interval?" - interval ":" + interval ");
2123
args[1]->print(str, query_type);
2125
str->append(interval_names[int_type]);
2129
void Item_extract::print(String *str, enum_query_type query_type)
2131
str->append(STRING_WITH_LEN("extract("));
2132
str->append(interval_names[int_type]);
2133
str->append(STRING_WITH_LEN(" from "));
2134
args[0]->print(str, query_type);
2138
void Item_extract::fix_length_and_dec()
2140
value.alloc(32); // alloc buffer
2142
maybe_null=1; // If wrong date
2144
case INTERVAL_YEAR: max_length=4; date_value=1; break;
2145
case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break;
2146
case INTERVAL_QUARTER: max_length=2; date_value=1; break;
2147
case INTERVAL_MONTH: max_length=2; date_value=1; break;
2148
case INTERVAL_WEEK: max_length=2; date_value=1; break;
2149
case INTERVAL_DAY: max_length=2; date_value=1; break;
2150
case INTERVAL_DAY_HOUR: max_length=9; date_value=0; break;
2151
case INTERVAL_DAY_MINUTE: max_length=11; date_value=0; break;
2152
case INTERVAL_DAY_SECOND: max_length=13; date_value=0; break;
2153
case INTERVAL_HOUR: max_length=2; date_value=0; break;
2154
case INTERVAL_HOUR_MINUTE: max_length=4; date_value=0; break;
2155
case INTERVAL_HOUR_SECOND: max_length=6; date_value=0; break;
2156
case INTERVAL_MINUTE: max_length=2; date_value=0; break;
2157
case INTERVAL_MINUTE_SECOND: max_length=4; date_value=0; break;
2158
case INTERVAL_SECOND: max_length=2; date_value=0; break;
2159
case INTERVAL_MICROSECOND: max_length=2; date_value=0; break;
2160
case INTERVAL_DAY_MICROSECOND: max_length=20; date_value=0; break;
2161
case INTERVAL_HOUR_MICROSECOND: max_length=13; date_value=0; break;
2162
case INTERVAL_MINUTE_MICROSECOND: max_length=11; date_value=0; break;
2163
case INTERVAL_SECOND_MICROSECOND: max_length=9; date_value=0; break;
2164
case INTERVAL_LAST: assert(0); break; /* purecov: deadcode */
2169
int64_t Item_extract::val_int()
2178
if (get_arg0_date(<ime, TIME_FUZZY_DATE))
2184
String *res= args[0]->val_str(&value);
2185
if (!res || str_to_time_with_warn(res->ptr(), res->length(), <ime))
2190
neg= ltime.neg ? -1 : 1;
2194
case INTERVAL_YEAR: return ltime.year;
2195
case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month;
2196
case INTERVAL_QUARTER: return (ltime.month+2)/3;
2197
case INTERVAL_MONTH: return ltime.month;
2200
week_format= current_thd->variables.default_week_format;
2201
return calc_week(<ime, week_mode(week_format), &year);
2203
case INTERVAL_DAY: return ltime.day;
2204
case INTERVAL_DAY_HOUR: return (long) (ltime.day*100L+ltime.hour)*neg;
2205
case INTERVAL_DAY_MINUTE: return (long) (ltime.day*10000L+
2208
case INTERVAL_DAY_SECOND: return ((int64_t) ltime.day*1000000L+
2209
(int64_t) (ltime.hour*10000L+
2212
case INTERVAL_HOUR: return (long) ltime.hour*neg;
2213
case INTERVAL_HOUR_MINUTE: return (long) (ltime.hour*100+ltime.minute)*neg;
2214
case INTERVAL_HOUR_SECOND: return (long) (ltime.hour*10000+ltime.minute*100+
2216
case INTERVAL_MINUTE: return (long) ltime.minute*neg;
2217
case INTERVAL_MINUTE_SECOND: return (long) (ltime.minute*100+ltime.second)*neg;
2218
case INTERVAL_SECOND: return (long) ltime.second*neg;
2219
case INTERVAL_MICROSECOND: return (long) ltime.second_part*neg;
2220
case INTERVAL_DAY_MICROSECOND: return (((int64_t)ltime.day*1000000L +
2221
(int64_t)ltime.hour*10000L +
2223
ltime.second)*1000000L +
2224
ltime.second_part)*neg;
2225
case INTERVAL_HOUR_MICROSECOND: return (((int64_t)ltime.hour*10000L +
2227
ltime.second)*1000000L +
2228
ltime.second_part)*neg;
2229
case INTERVAL_MINUTE_MICROSECOND: return (((int64_t)(ltime.minute*100+
2230
ltime.second))*1000000L+
2231
ltime.second_part)*neg;
2232
case INTERVAL_SECOND_MICROSECOND: return ((int64_t)ltime.second*1000000L+
2233
ltime.second_part)*neg;
2234
case INTERVAL_LAST: assert(0); break; /* purecov: deadcode */
2236
return 0; // Impossible
2239
bool Item_extract::eq(const Item *item, bool binary_cmp) const
2243
if (item->type() != FUNC_ITEM ||
2244
functype() != ((Item_func*)item)->functype())
2247
Item_extract* ie= (Item_extract*)item;
2248
if (ie->int_type != int_type)
2251
if (!args[0]->eq(ie->args[0], binary_cmp))
2257
bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
2261
if (item->type() != FUNC_ITEM ||
2262
functype() != ((Item_func*)item)->functype())
2265
Item_char_typecast *cast= (Item_char_typecast*)item;
2266
if (cast_length != cast->cast_length ||
2267
cast_cs != cast->cast_cs)
2270
if (!args[0]->eq(cast->args[0], binary_cmp))
2275
void Item_typecast::print(String *str, enum_query_type query_type)
2277
str->append(STRING_WITH_LEN("cast("));
2278
args[0]->print(str, query_type);
2279
str->append(STRING_WITH_LEN(" as "));
2280
str->append(cast_type());
2285
void Item_char_typecast::print(String *str, enum_query_type query_type)
2287
str->append(STRING_WITH_LEN("cast("));
2288
args[0]->print(str, query_type);
2289
str->append(STRING_WITH_LEN(" as char"));
2290
if (cast_length >= 0)
2294
// my_charset_bin is good enough for numbers
2295
String st(buffer, sizeof(buffer), &my_charset_bin);
2296
st.set((uint64_t)cast_length, &my_charset_bin);
2302
str->append(STRING_WITH_LEN(" charset "));
2303
str->append(cast_cs->csname);
2308
String *Item_char_typecast::val_str(String *str)
2314
if (!charset_conversion)
2316
if (!(res= args[0]->val_str(str)))
2324
// Convert character set if differ
2325
uint32_t dummy_errors;
2326
if (!(res= args[0]->val_str(&tmp_value)) ||
2327
str->copy(res->ptr(), res->length(), from_cs,
2328
cast_cs, &dummy_errors))
2336
res->set_charset(cast_cs);
2339
Cut the tail if cast with length
2340
and the result is longer than cast length, e.g.
2341
CAST('string' AS CHAR(1))
2343
if (cast_length >= 0)
2345
if (res->length() > (length= (uint32_t) res->charpos(cast_length)))
2346
{ // Safe even if const arg
2348
snprintf(char_type, sizeof(char_type), "%s(%lu)",
2349
cast_cs == &my_charset_bin ? "BINARY" : "CHAR",
2352
if (!res->alloced_length())
2353
{ // Don't change const str
2354
str_value= *res; // Not malloced string
2357
push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2358
ER_TRUNCATED_WRONG_VALUE,
2359
ER(ER_TRUNCATED_WRONG_VALUE), char_type,
2361
res->length((uint) length);
2363
else if (cast_cs == &my_charset_bin && res->length() < (uint) cast_length)
2365
if (res->alloced_length() < (uint) cast_length)
2367
str->alloc(cast_length);
2371
memset(res->ptr() + res->length(), 0,
2372
(uint) cast_length - res->length());
2373
res->length(cast_length);
2381
void Item_char_typecast::fix_length_and_dec()
2383
uint32_t char_length;
2385
We always force character set conversion if cast_cs
2386
is a multi-byte character set. It garantees that the
2387
result of CAST is a well-formed string.
2388
For single-byte character sets we allow just to copy
2389
from the argument. A single-byte character sets string
2390
is always well-formed.
2392
There is a special trick to convert form a number to ucs2.
2393
As numbers have my_charset_bin as their character set,
2394
it wouldn't do conversion to ucs2 without an additional action.
2395
To force conversion, we should pretend to be non-binary.
2396
Let's choose from_cs this way:
2397
- If the argument in a number and cast_cs is ucs2 (i.e. mbminlen > 1),
2398
then from_cs is set to latin1, to perform latin1 -> ucs2 conversion.
2399
- If the argument is a number and cast_cs is ASCII-compatible
2400
(i.e. mbminlen == 1), then from_cs is set to cast_cs,
2401
which allows just to take over the args[0]->val_str() result
2402
and thus avoid unnecessary character set conversion.
2403
- If the argument is not a number, then from_cs is set to
2404
the argument's charset.
2406
from_cs= (args[0]->result_type() == INT_RESULT ||
2407
args[0]->result_type() == DECIMAL_RESULT ||
2408
args[0]->result_type() == REAL_RESULT) ?
2409
(cast_cs->mbminlen == 1 ? cast_cs : &my_charset_utf8_general_ci) :
2410
args[0]->collation.collation;
2411
charset_conversion= (cast_cs->mbmaxlen > 1) ||
2412
(!my_charset_same(from_cs, cast_cs) && from_cs != &my_charset_bin && cast_cs != &my_charset_bin);
2413
collation.set(cast_cs, DERIVATION_IMPLICIT);
2414
char_length= (cast_length >= 0) ? cast_length :
2415
args[0]->max_length/from_cs->mbmaxlen;
2416
max_length= char_length * cast_cs->mbmaxlen;
2420
String *Item_datetime_typecast::val_str(String *str)
2425
if (!get_arg0_date(<ime, TIME_FUZZY_DATE) &&
2426
!make_datetime(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME,
2435
int64_t Item_datetime_typecast::val_int()
2439
if (get_arg0_date(<ime,1))
2445
return TIME_to_uint64_t_datetime(<ime);
2449
bool Item_time_typecast::get_time(DRIZZLE_TIME *ltime)
2451
bool res= get_arg0_time(ltime);
2453
For DRIZZLE_TIMESTAMP_TIME value we can have non-zero day part,
2454
which we should not lose.
2456
if (ltime->time_type == DRIZZLE_TIMESTAMP_DATETIME)
2457
ltime->year= ltime->month= ltime->day= 0;
2458
ltime->time_type= DRIZZLE_TIMESTAMP_TIME;
2463
int64_t Item_time_typecast::val_int()
2466
if (get_time(<ime))
2471
return ltime.hour * 10000L + ltime.minute * 100 + ltime.second;
2474
String *Item_time_typecast::val_str(String *str)
2479
if (!get_arg0_time(<ime) &&
2480
!make_datetime(ltime.second_part ? TIME_MICROSECOND : TIME_ONLY,
2489
bool Item_date_typecast::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date __attribute__((unused)))
2491
bool res= get_arg0_date(ltime, TIME_FUZZY_DATE);
2492
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
2493
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
2498
bool Item_date_typecast::get_time(DRIZZLE_TIME *ltime)
2500
memset(ltime, 0, sizeof(DRIZZLE_TIME));
2501
return args[0]->null_value;
2505
String *Item_date_typecast::val_str(String *str)
2510
if (!get_arg0_date(<ime, TIME_FUZZY_DATE) &&
2511
!str->alloc(MAX_DATE_STRING_REP_LENGTH))
2513
make_date((DATE_TIME_FORMAT *) 0, <ime, str);
2521
int64_t Item_date_typecast::val_int()
2525
if ((null_value= args[0]->get_date(<ime, TIME_FUZZY_DATE)))
2527
return (int64_t) (ltime.year * 10000L + ltime.month * 100 + ltime.day);
2531
MAKEDATE(a,b) is a date function that creates a date value
2532
from a year and day value.
2535
As arguments are integers, we can't know if the year is a 2 digit or 4 digit year.
2536
In this case we treat all years < 100 as 2 digit years. Ie, this is not safe
2537
for dates between 0000-01-01 and 0099-12-31
2540
String *Item_func_makedate::val_str(String *str)
2543
DRIZZLE_TIME l_time;
2544
long daynr= (long) args[1]->val_int();
2545
long year= (long) args[0]->val_int();
2548
if (args[0]->null_value || args[1]->null_value ||
2549
year < 0 || daynr <= 0)
2553
year= year_2000_handling(year);
2555
days= calc_daynr(year,1,1) + daynr - 1;
2556
/* Day number from year 0 to 9999-12-31 */
2557
if (days >= 0 && days <= MAX_DAY_NUMBER)
2560
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
2561
if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
2563
make_date((DATE_TIME_FORMAT *) 0, &l_time, str);
2574
MAKEDATE(a,b) is a date function that creates a date value
2575
from a year and day value.
2578
As arguments are integers, we can't know if the year is a 2 digit or 4 digit year.
2579
In this case we treat all years < 100 as 2 digit years. Ie, this is not safe
2580
for dates between 0000-01-01 and 0099-12-31
2583
int64_t Item_func_makedate::val_int()
2586
DRIZZLE_TIME l_time;
2587
long daynr= (long) args[1]->val_int();
2588
long year= (long) args[0]->val_int();
2591
if (args[0]->null_value || args[1]->null_value ||
2592
year < 0 || daynr <= 0)
2596
year= year_2000_handling(year);
2598
days= calc_daynr(year,1,1) + daynr - 1;
2599
/* Day number from year 0 to 9999-12-31 */
2600
if (days >= 0 && days < MAX_DAY_NUMBER)
2603
get_date_from_daynr(days,&l_time.year,&l_time.month,&l_time.day);
2604
return (int64_t) (l_time.year * 10000L + l_time.month * 100 + l_time.day);
2613
void Item_func_add_time::fix_length_and_dec()
2615
enum_field_types arg0_field_type;
2617
max_length=MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
2621
The field type for the result of an Item_func_add_time function is defined
2624
- If first arg is a DRIZZLE_TYPE_DATETIME or DRIZZLE_TYPE_TIMESTAMP
2625
result is DRIZZLE_TYPE_DATETIME
2626
- If first arg is a DRIZZLE_TYPE_TIME result is DRIZZLE_TYPE_TIME
2627
- Otherwise the result is DRIZZLE_TYPE_VARCHAR
2630
cached_field_type= DRIZZLE_TYPE_VARCHAR;
2631
arg0_field_type= args[0]->field_type();
2632
if (arg0_field_type == DRIZZLE_TYPE_NEWDATE ||
2633
arg0_field_type == DRIZZLE_TYPE_DATETIME ||
2634
arg0_field_type == DRIZZLE_TYPE_TIMESTAMP)
2635
cached_field_type= DRIZZLE_TYPE_DATETIME;
2636
else if (arg0_field_type == DRIZZLE_TYPE_TIME)
2637
cached_field_type= DRIZZLE_TYPE_TIME;
2641
ADDTIME(t,a) and SUBTIME(t,a) are time functions that calculate a
2644
t: time_or_datetime_expression
2647
Result: Time value or datetime value
2650
String *Item_func_add_time::val_str(String *str)
2653
DRIZZLE_TIME l_time1, l_time2, l_time3;
2655
long days, microseconds;
2660
if (is_date) // TIMESTAMP function
2662
if (get_arg0_date(&l_time1, TIME_FUZZY_DATE) ||
2663
args[1]->get_time(&l_time2) ||
2664
l_time1.time_type == DRIZZLE_TIMESTAMP_TIME ||
2665
l_time2.time_type != DRIZZLE_TIMESTAMP_TIME)
2668
else // ADDTIME function
2670
if (args[0]->get_time(&l_time1) ||
2671
args[1]->get_time(&l_time2) ||
2672
l_time2.time_type == DRIZZLE_TIMESTAMP_DATETIME)
2674
is_time= (l_time1.time_type == DRIZZLE_TIMESTAMP_TIME);
2676
if (l_time1.neg != l_time2.neg)
2679
memset(&l_time3, 0, sizeof(l_time3));
2681
l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign,
2682
&seconds, µseconds);
2685
If first argument was negative and diff between arguments
2686
is non-zero we need to swap sign to get proper result.
2688
if (l_time1.neg && (seconds || microseconds))
2689
l_time3.neg= 1-l_time3.neg; // Swap sign of result
2691
if (!is_time && l_time3.neg)
2694
days= (long)(seconds/86400L);
2696
calc_time_from_sec(&l_time3, (long)(seconds%86400L), microseconds);
2700
get_date_from_daynr(days,&l_time3.year,&l_time3.month,&l_time3.day);
2702
!make_datetime(l_time1.second_part || l_time2.second_part ?
2703
DATE_TIME_MICROSECOND : DATE_TIME,
2709
l_time3.hour+= days*24;
2710
if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
2711
TIME_MICROSECOND : TIME_ONLY,
2721
void Item_func_add_time::print(String *str, enum_query_type query_type)
2726
str->append(STRING_WITH_LEN("timestamp("));
2731
str->append(STRING_WITH_LEN("addtime("));
2733
str->append(STRING_WITH_LEN("subtime("));
2735
args[0]->print(str, query_type);
2737
args[1]->print(str, query_type);
2743
TIMEDIFF(t,s) is a time function that calculates the
2744
time value between a start and end time.
2746
t and s: time_or_datetime_expression
2750
String *Item_func_timediff::val_str(String *str)
2756
DRIZZLE_TIME l_time1 ,l_time2, l_time3;
2759
if (args[0]->get_time(&l_time1) ||
2760
args[1]->get_time(&l_time2) ||
2761
l_time1.time_type != l_time2.time_type)
2764
if (l_time1.neg != l_time2.neg)
2767
memset(&l_time3, 0, sizeof(l_time3));
2769
l_time3.neg= calc_time_diff(&l_time1, &l_time2, l_sign,
2770
&seconds, µseconds);
2773
For DRIZZLE_TIMESTAMP_TIME only:
2774
If first argument was negative and diff between arguments
2775
is non-zero we need to swap sign to get proper result.
2777
if (l_time1.neg && (seconds || microseconds))
2778
l_time3.neg= 1-l_time3.neg; // Swap sign of result
2780
calc_time_from_sec(&l_time3, (long) seconds, microseconds);
2782
if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ?
2783
TIME_MICROSECOND : TIME_ONLY,
2793
MAKETIME(h,m,s) is a time function that calculates a time value
2794
from the total number of hours, minutes, and seconds.
2798
String *Item_func_maketime::val_str(String *str)
2804
int64_t hour= args[0]->val_int();
2805
int64_t minute= args[1]->val_int();
2806
int64_t second= args[2]->val_int();
2808
if ((null_value=(args[0]->null_value ||
2809
args[1]->null_value ||
2810
args[2]->null_value ||
2811
minute < 0 || minute > 59 ||
2812
second < 0 || second > 59 ||
2813
str->alloc(MAX_DATE_STRING_REP_LENGTH))))
2816
memset(<ime, 0, sizeof(ltime));
2819
/* Check for integer overflows */
2822
if (args[0]->unsigned_flag)
2827
if (-hour > UINT_MAX || hour > UINT_MAX)
2832
ltime.hour= (uint) ((hour < 0 ? -hour : hour));
2833
ltime.minute= (uint) minute;
2834
ltime.second= (uint) second;
2838
ltime.hour= TIME_MAX_HOUR;
2839
ltime.minute= TIME_MAX_MINUTE;
2840
ltime.second= TIME_MAX_SECOND;
2842
char *ptr= int64_t10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10);
2843
int len = (int)(ptr - buf) +
2844
sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second);
2845
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2846
buf, len, DRIZZLE_TIMESTAMP_TIME,
2850
if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str))
2860
MICROSECOND(a) is a function ( extraction) that extracts the microseconds
2863
a: Datetime or time value
2867
int64_t Item_func_microsecond::val_int()
2871
if (!get_arg0_time(<ime))
2872
return ltime.second_part;
2877
int64_t Item_func_timestamp_diff::val_int()
2879
DRIZZLE_TIME ltime1, ltime2;
2886
if (args[0]->get_date(<ime1, TIME_NO_ZERO_DATE) ||
2887
args[1]->get_date(<ime2, TIME_NO_ZERO_DATE))
2890
if (calc_time_diff(<ime2,<ime1, 1,
2891
&seconds, µseconds))
2894
if (int_type == INTERVAL_YEAR ||
2895
int_type == INTERVAL_QUARTER ||
2896
int_type == INTERVAL_MONTH)
2898
uint32_t year_beg, year_end, month_beg, month_end, day_beg, day_end;
2900
uint32_t second_beg, second_end, microsecond_beg, microsecond_end;
2904
year_beg= ltime2.year;
2905
year_end= ltime1.year;
2906
month_beg= ltime2.month;
2907
month_end= ltime1.month;
2908
day_beg= ltime2.day;
2909
day_end= ltime1.day;
2910
second_beg= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second;
2911
second_end= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second;
2912
microsecond_beg= ltime2.second_part;
2913
microsecond_end= ltime1.second_part;
2917
year_beg= ltime1.year;
2918
year_end= ltime2.year;
2919
month_beg= ltime1.month;
2920
month_end= ltime2.month;
2921
day_beg= ltime1.day;
2922
day_end= ltime2.day;
2923
second_beg= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second;
2924
second_end= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second;
2925
microsecond_beg= ltime1.second_part;
2926
microsecond_end= ltime2.second_part;
2930
years= year_end - year_beg;
2931
if (month_end < month_beg || (month_end == month_beg && day_end < day_beg))
2936
if (month_end < month_beg || (month_end == month_beg && day_end < day_beg))
2937
months+= 12 - (month_beg - month_end);
2939
months+= (month_end - month_beg);
2941
if (day_end < day_beg)
2943
else if ((day_end == day_beg) &&
2944
((second_end < second_beg) ||
2945
(second_end == second_beg && microsecond_end < microsecond_beg)))
2951
return months/12*neg;
2952
case INTERVAL_QUARTER:
2953
return months/3*neg;
2954
case INTERVAL_MONTH:
2957
return seconds/86400L/7L*neg;
2959
return seconds/86400L*neg;
2961
return seconds/3600L*neg;
2962
case INTERVAL_MINUTE:
2963
return seconds/60L*neg;
2964
case INTERVAL_SECOND:
2966
case INTERVAL_MICROSECOND:
2968
In MySQL difference between any two valid datetime values
2969
in microseconds fits into int64_t.
2971
return (seconds*1000000L+microseconds)*neg;
2982
void Item_func_timestamp_diff::print(String *str, enum_query_type query_type)
2984
str->append(func_name());
2989
str->append(STRING_WITH_LEN("YEAR"));
2991
case INTERVAL_QUARTER:
2992
str->append(STRING_WITH_LEN("QUARTER"));
2994
case INTERVAL_MONTH:
2995
str->append(STRING_WITH_LEN("MONTH"));
2998
str->append(STRING_WITH_LEN("WEEK"));
3001
str->append(STRING_WITH_LEN("DAY"));
3004
str->append(STRING_WITH_LEN("HOUR"));
3006
case INTERVAL_MINUTE:
3007
str->append(STRING_WITH_LEN("MINUTE"));
3009
case INTERVAL_SECOND:
3010
str->append(STRING_WITH_LEN("SECOND"));
3012
case INTERVAL_MICROSECOND:
3013
str->append(STRING_WITH_LEN("SECOND_FRAC"));
3019
for (uint32_t i=0 ; i < 2 ; i++)
3022
args[i]->print(str, query_type);
3028
String *Item_func_get_format::val_str(String *str)
3031
const char *format_name;
3032
KNOWN_DATE_TIME_FORMAT *format;
3033
String *val= args[0]->val_str(str);
3036
if ((null_value= args[0]->null_value))
3039
val_len= val->length();
3040
for (format= &known_date_time_formats[0];
3041
(format_name= format->format_name);
3044
uint32_t format_name_len;
3045
format_name_len= strlen(format_name);
3046
if (val_len == format_name_len &&
3047
!my_strnncoll(&my_charset_utf8_general_ci,
3048
(const unsigned char *) val->ptr(), val_len,
3049
(const unsigned char *) format_name, val_len))
3051
const char *format_str= get_date_time_format_str(format, type);
3052
str->set(format_str, strlen(format_str), &my_charset_bin);
3062
void Item_func_get_format::print(String *str, enum_query_type query_type)
3064
str->append(func_name());
3068
case DRIZZLE_TIMESTAMP_DATE:
3069
str->append(STRING_WITH_LEN("DATE, "));
3071
case DRIZZLE_TIMESTAMP_DATETIME:
3072
str->append(STRING_WITH_LEN("DATETIME, "));
3074
case DRIZZLE_TIMESTAMP_TIME:
3075
str->append(STRING_WITH_LEN("TIME, "));
3080
args[0]->print(str, query_type);
3086
Get type of datetime value (DATE/TIME/...) which will be produced
3087
according to format string.
3089
@param format format string
3090
@param length length of format string
3093
We don't process day format's characters('D', 'd', 'e') because day
3094
may be a member of all date/time types.
3097
Format specifiers supported by this function should be in sync with
3098
specifiers supported by extract_date_time() function.
3101
One of date_time_format_types values:
3102
- DATE_TIME_MICROSECOND
3109
static date_time_format_types
3110
get_date_time_result_type(const char *format, uint32_t length)
3112
const char *time_part_frms= "HISThiklrs";
3113
const char *date_part_frms= "MVUXYWabcjmvuxyw";
3114
bool date_part_used= 0, time_part_used= 0, frac_second_used= 0;
3116
const char *val= format;
3117
const char *end= format + length;
3119
for (; val != end && val != end; val++)
3121
if (*val == '%' && val+1 != end)
3125
frac_second_used= time_part_used= 1;
3126
else if (!time_part_used && strchr(time_part_frms, *val))
3128
else if (!date_part_used && strchr(date_part_frms, *val))
3130
if (date_part_used && frac_second_used)
3133
frac_second_used implies time_part_used, and thus we already
3134
have all types of date-time components and can end our search.
3136
return DATE_TIME_MICROSECOND;
3141
/* We don't have all three types of date-time components */
3142
if (frac_second_used)
3143
return TIME_MICROSECOND;
3154
void Item_func_str_to_date::fix_length_and_dec()
3158
cached_field_type= DRIZZLE_TYPE_DATETIME;
3159
max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
3160
cached_timestamp_type= DRIZZLE_TIMESTAMP_NONE;
3161
if ((const_item= args[1]->const_item()))
3163
char format_buff[64];
3164
String format_str(format_buff, sizeof(format_buff), &my_charset_bin);
3165
String *format= args[1]->val_str(&format_str);
3166
if (!args[1]->null_value)
3168
cached_format_type= get_date_time_result_type(format->ptr(),
3170
switch (cached_format_type) {
3172
cached_timestamp_type= DRIZZLE_TIMESTAMP_DATE;
3173
cached_field_type= DRIZZLE_TYPE_NEWDATE;
3174
max_length= MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
3177
case TIME_MICROSECOND:
3178
cached_timestamp_type= DRIZZLE_TIMESTAMP_TIME;
3179
cached_field_type= DRIZZLE_TYPE_TIME;
3180
max_length= MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN;
3183
cached_timestamp_type= DRIZZLE_TIMESTAMP_DATETIME;
3184
cached_field_type= DRIZZLE_TYPE_DATETIME;
3192
bool Item_func_str_to_date::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
3194
DATE_TIME_FORMAT date_time_format;
3195
char val_buff[64], format_buff[64];
3196
String val_string(val_buff, sizeof(val_buff), &my_charset_bin), *val;
3197
String format_str(format_buff, sizeof(format_buff), &my_charset_bin), *format;
3199
val= args[0]->val_str(&val_string);
3200
format= args[1]->val_str(&format_str);
3201
if (args[0]->null_value || args[1]->null_value)
3205
memset(ltime, 0, sizeof(*ltime));
3206
date_time_format.format.str= (char*) format->ptr();
3207
date_time_format.format.length= format->length();
3208
if (extract_date_time(&date_time_format, val->ptr(), val->length(),
3209
ltime, cached_timestamp_type, 0, "datetime") ||
3210
((fuzzy_date & TIME_NO_ZERO_DATE) &&
3211
(ltime->year == 0 || ltime->month == 0 || ltime->day == 0)))
3213
if (cached_timestamp_type == DRIZZLE_TIMESTAMP_TIME && ltime->day)
3216
Day part for time type can be nonzero value and so
3217
we should add hours from day part to hour part to
3218
keep valid time value.
3220
ltime->hour+= ltime->day*24;
3226
return (null_value=1);
3230
String *Item_func_str_to_date::val_str(String *str)
3235
if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE))
3238
if (!make_datetime((const_item ? cached_format_type :
3239
(ltime.second_part ? DATE_TIME_MICROSECOND : DATE_TIME)),
3246
bool Item_func_last_day::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
3248
if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
3249
(ltime->month == 0))
3255
uint32_t month_idx= ltime->month-1;
3256
ltime->day= days_in_month[month_idx];
3257
if ( month_idx == 1 && calc_days_in_year(ltime->year) == 366)
3259
ltime->hour= ltime->minute= ltime->second= 0;
3260
ltime->second_part= 0;
3261
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;