95
96
next week is week 1.
98
uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year)
99
uint32_t calc_week(DRIZZLE_TIME *l_time, uint32_t week_behaviour, uint32_t *year)
101
102
ulong daynr=calc_daynr(l_time->year,l_time->month,l_time->day);
102
103
ulong first_daynr=calc_daynr(l_time->year,1,1);
103
104
bool monday_first= test(week_behaviour & WEEK_MONDAY_FIRST);
104
105
bool week_year= test(week_behaviour & WEEK_YEAR);
105
106
bool first_weekday= test(week_behaviour & WEEK_FIRST_WEEKDAY);
107
uint weekday=calc_weekday(first_daynr, !monday_first);
108
uint32_t weekday=calc_weekday(first_daynr, !monday_first);
108
109
*year=l_time->year;
110
111
if (l_time->month == 1 && l_time->day <= 7-weekday)
138
139
/* Change a daynr to year, month and day */
139
140
/* Daynr 0 is returned as date 00.00.00 */
141
void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
142
void get_date_from_daynr(long daynr,uint32_t *ret_year,uint32_t *ret_month,
144
uint year,temp,leap_day,day_of_year,days_in_year;
145
uint32_t year,temp,leap_day,day_of_year,days_in_year;
146
unsigned char *month_pos;
147
148
if (daynr <= 365L || daynr >= 3652500)
148
149
{ /* Fix if wrong daynr */
212
Convert a timestamp string to a MYSQL_TIME value and produce a warning
213
Convert a timestamp string to a DRIZZLE_TIME value and produce a warning
213
214
if string was truncated during conversion.
216
217
See description of str_to_datetime() for more information.
220
str_to_datetime_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
220
enum enum_drizzle_timestamp_type
221
str_to_datetime_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
224
225
THD *thd= current_thd;
225
timestamp_type ts_type;
226
enum enum_drizzle_timestamp_type ts_type;
227
228
ts_type= str_to_datetime(str, length, l_time,
228
229
(flags | (thd->variables.sql_mode &
229
230
(MODE_INVALID_DATES |
230
231
MODE_NO_ZERO_DATE))),
232
if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
233
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
234
str, length, ts_type, NullS);
233
if (was_cut || ts_type <= DRIZZLE_TIMESTAMP_ERROR)
234
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
235
str, length, ts_type, NULL);
240
Convert a datetime from broken-down MYSQL_TIME representation to corresponding
241
Convert a datetime from broken-down DRIZZLE_TIME representation to corresponding
275
Convert a time string to a MYSQL_TIME struct and produce a warning
276
Convert a time string to a DRIZZLE_TIME struct and produce a warning
276
277
if string was cut during conversion.
279
280
See str_to_time() for more info.
282
str_to_time_with_warn(const char *str, uint length, MYSQL_TIME *l_time)
283
str_to_time_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time)
285
286
bool ret_val= str_to_time(str, length, l_time, &warning);
286
287
if (ret_val || warning)
287
make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
288
str, length, MYSQL_TIMESTAMP_TIME, NullS);
288
make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
289
str, length, DRIZZLE_TIMESTAMP_TIME, NULL);
306
307
to->second= (int) from->tm_sec;
309
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds)
310
void calc_time_from_sec(DRIZZLE_TIME *to, long seconds, long microseconds)
312
313
// to->neg is not cleared, it may already be set to a useful value
313
to->time_type= MYSQL_TIMESTAMP_TIME;
314
to->time_type= DRIZZLE_TIMESTAMP_TIME;
351
bool parse_date_time_format(timestamp_type format_type,
352
const char *format, uint format_length,
352
bool parse_date_time_format(enum enum_drizzle_timestamp_type format_type,
353
const char *format, uint32_t format_length,
353
354
DATE_TIME_FORMAT *date_time_format)
355
uint offset= 0, separators= 0;
356
uint32_t offset= 0, separators= 0;
356
357
const char *ptr= format, *format_str;
357
358
const char *end= ptr+format_length;
358
uchar *dt_pos= date_time_format->positions;
359
unsigned char *dt_pos= date_time_format->positions;
359
360
/* need_p is set if we are using AM/PM format */
360
361
bool need_p= 0, allow_separator= 0;
361
ulong part_map= 0, separator_map= 0;
362
uint32_t part_map= 0, separator_map= 0;
362
363
const char *parts[16];
364
365
date_time_format->time_separator= 0;
443
444
allow_separator= 0; // Don't allow two separators
445
446
/* Store in separator_map which parts are punct characters */
446
if (my_ispunct(&my_charset_latin1, *ptr))
447
if (my_ispunct(&my_charset_utf8_general_ci, *ptr))
447
448
separator_map|= (ulong) 1 << (offset-1);
448
else if (!my_isspace(&my_charset_latin1, *ptr))
449
else if (!my_isspace(&my_charset_utf8_general_ci, *ptr))
466
467
The last test is to ensure that %p is used if and only if
469
if ((format_type == MYSQL_TIMESTAMP_DATETIME &&
470
!test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) ||
471
(format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
472
(format_type == MYSQL_TIMESTAMP_TIME &&
473
!test_all_bits(part_map, 8 | 16 | 32)) ||
470
if ((format_type == DRIZZLE_TIMESTAMP_DATETIME &&
471
!test_all_bits(part_map, (uint32_t) (1 | 2 | 4 | 8 | 16 | 32))) ||
472
(format_type == DRIZZLE_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
473
(format_type == DRIZZLE_TIMESTAMP_TIME &&
474
!test_all_bits(part_map, (uint32_t) (8 | 16 | 32))) ||
474
475
!allow_separator || // %option should be last
475
476
(need_p && dt_pos[6] +1 != dt_pos[7]) ||
476
477
(need_p ^ (dt_pos[7] != 255)))
526
527
if (format_length == 6 && !need_p &&
527
528
!my_strnncoll(&my_charset_bin,
528
(const uchar *) format, 6,
529
(const uchar *) format_str, 6))
529
(const unsigned char *) format, 6,
530
(const unsigned char *) format_str, 6))
531
532
if (separator_map == (1 | 2))
533
if (format_type == MYSQL_TIMESTAMP_TIME)
534
if (format_type == DRIZZLE_TIMESTAMP_TIME)
535
536
if (*(format+2) != *(format+5))
549
550
if ((format_length == 12 && !need_p &&
550
551
!my_strnncoll(&my_charset_bin,
551
(const uchar *) format, 12,
552
(const uchar*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
552
(const unsigned char *) format, 12,
553
(const unsigned char*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
554
555
(separators == 5 && separator_map == (1 | 2 | 8 | 16)))
627
628
/* Put format string after current pos */
628
629
new_format->format.str= (char*) (new_format+1);
629
memcpy((char*) new_format->positions, (char*) format->positions,
630
memcpy(new_format->positions, format->positions,
630
631
sizeof(format->positions));
631
632
new_format->time_separator= format->time_separator;
632
633
/* We make the string null terminated for easy printf in SHOW VARIABLES */
633
memcpy((char*) new_format->format.str, format->format.str,
634
memcpy(new_format->format.str, format->format.str,
634
635
format->format.length);
635
636
new_format->format.str[format->format.length]= 0;
636
637
new_format->format.length= format->format.length;
658
659
const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
660
enum enum_drizzle_timestamp_type type)
662
case MYSQL_TIMESTAMP_DATE:
663
case DRIZZLE_TIMESTAMP_DATE:
663
664
return format->date_format;
664
case MYSQL_TIMESTAMP_DATETIME:
665
case DRIZZLE_TIMESTAMP_DATETIME:
665
666
return format->datetime_format;
666
case MYSQL_TIMESTAMP_TIME:
667
case DRIZZLE_TIMESTAMP_TIME:
667
668
return format->time_format;
669
670
assert(0); // Impossible
679
680
MySQL doesn't support comparing of date/time/datetime strings that
680
681
are not in arbutary order as dates are compared as strings in some
682
This functions don't check that given MYSQL_TIME structure members are
683
This functions don't check that given DRIZZLE_TIME structure members are
683
684
in valid range. If they are not, return value won't reflect any
684
685
valid date either. Additionally, make_time doesn't take into
685
686
account time->day member: it's assumed that days have been converted
687
688
****************************************************************************/
689
690
void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
690
const MYSQL_TIME *l_time, String *str)
691
const DRIZZLE_TIME *l_time, String *str)
692
uint length= (uint) my_time_to_str(l_time, (char*) str->ptr());
693
uint32_t length= (uint) my_time_to_str(l_time, (char*) str->ptr());
693
694
str->length(length);
694
695
str->set_charset(&my_charset_bin);
698
699
void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
699
const MYSQL_TIME *l_time, String *str)
700
const DRIZZLE_TIME *l_time, String *str)
701
uint length= (uint) my_date_to_str(l_time, (char*) str->ptr());
702
uint32_t length= (uint) my_date_to_str(l_time, (char*) str->ptr());
702
703
str->length(length);
703
704
str->set_charset(&my_charset_bin);
707
708
void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
708
const MYSQL_TIME *l_time, String *str)
709
const DRIZZLE_TIME *l_time, String *str)
710
uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
711
uint32_t length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
711
712
str->length(length);
712
713
str->set_charset(&my_charset_bin);
716
void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
717
void make_truncated_value_warning(THD *thd, DRIZZLE_ERROR::enum_warning_level level,
717
718
const char *str_val,
718
uint str_length, timestamp_type time_type,
720
enum enum_drizzle_timestamp_type time_type,
719
721
const char *field_name)
721
char warn_buff[MYSQL_ERRMSG_SIZE];
723
char warn_buff[DRIZZLE_ERRMSG_SIZE];
722
724
const char *type_str;
723
CHARSET_INFO *cs= &my_charset_latin1;
725
CHARSET_INFO *cs= &my_charset_utf8_general_ci;
725
String str(buff,(uint32) sizeof(buff), system_charset_info);
727
String str(buff,(uint32_t) sizeof(buff), system_charset_info);
726
728
str.copy(str_val, str_length, system_charset_info);
727
729
str[str_length]= 0; // Ensure we have end 0 for snprintf
729
731
switch (time_type) {
730
case MYSQL_TIMESTAMP_DATE:
732
case DRIZZLE_TIMESTAMP_DATE:
731
733
type_str= "date";
733
case MYSQL_TIMESTAMP_TIME:
735
case DRIZZLE_TIMESTAMP_TIME:
734
736
type_str= "time";
736
case MYSQL_TIMESTAMP_DATETIME: // FALLTHROUGH
738
case DRIZZLE_TIMESTAMP_DATETIME: // FALLTHROUGH
738
740
type_str= "datetime";
785
787
case INTERVAL_DAY_HOUR:
787
789
int64_t sec, days, daynr, microseconds, extra_sec;
788
ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
790
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME; // Return full date
789
791
microseconds= ltime->second_part + sign*interval.second_part;
790
792
extra_sec= microseconds/1000000L;
791
793
microseconds= microseconds%1000000L;
793
795
sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
795
797
sign* (int64_t) (interval.day*3600*24L +
796
interval.hour*3600LL+interval.minute*60LL+
798
interval.hour*3600L+interval.minute*60L+
797
799
interval.second))+ extra_sec;
798
800
if (microseconds < 0)
800
microseconds+= 1000000LL;
802
microseconds+= 1000000L;
803
days= sec/(3600*24LL);
804
sec-= days*3600*24LL;
805
days= sec/(3600*24L);
810
812
ltime->second_part= (uint) microseconds;
811
813
ltime->second= (uint) (sec % 60);
904
906
int64_t microseconds;
907
We suppose that if first argument is MYSQL_TIMESTAMP_TIME
909
We suppose that if first argument is DRIZZLE_TIMESTAMP_TIME
908
910
the second argument should be TIMESTAMP_TIME also.
909
911
We should check it before calc_time_diff call.
911
if (l_time1->time_type == MYSQL_TIMESTAMP_TIME) // Time value
913
if (l_time1->time_type == DRIZZLE_TIMESTAMP_TIME) // Time value
912
914
days= (long)l_time1->day - l_sign * (long)l_time2->day;
915
917
days= calc_daynr((uint) l_time1->year,
916
918
(uint) l_time1->month,
917
919
(uint) l_time1->day);
918
if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
920
if (l_time2->time_type == DRIZZLE_TIMESTAMP_TIME)
919
921
days-= l_sign * (long)l_time2->day;
921
923
days-= l_sign*calc_daynr((uint) l_time2->year,
923
925
(uint) l_time2->day);
926
microseconds= ((int64_t)days*86400LL +
928
microseconds= ((int64_t)days*86400L +
927
929
(int64_t)(l_time1->hour*3600L +
928
930
l_time1->minute*60L +
929
931
l_time1->second) -
930
932
l_sign*(int64_t)(l_time2->hour*3600L +
931
933
l_time2->minute*60L +
932
l_time2->second)) * 1000000LL +
934
l_time2->second)) * 1000000L +
933
935
(int64_t)l_time1->second_part -
934
936
l_sign*(int64_t)l_time2->second_part;