~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/time.cc

  • Committer: Monty Taylor
  • Date: 2008-07-05 11:20:18 UTC
  • mto: This revision was merged to the branch mainline in revision 62.
  • Revision ID: monty@inaugust.com-20080705112018-fr12kkmgphtu7m29
Changes so that removal of duplicate curr_dir from my_sys.h work.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
/* Functions to handle date and time */
18
18
 
19
 
#include <drizzled/server_includes.h>
20
 
#include <drizzled/drizzled_error_messages.h>
 
19
#include "mysql_priv.h"
 
20
#include <m_ctype.h>
21
21
 
22
22
 
23
23
        /* Some functions to calculate dates */
63
63
 
64
64
int calc_weekday(long daynr,bool sunday_first_day_of_week)
65
65
{
66
 
  return ((int) ((daynr + 5L + (sunday_first_day_of_week ? 1L : 0L)) % 7));
 
66
  DBUG_ENTER("calc_weekday");
 
67
  DBUG_RETURN ((int) ((daynr + 5L + (sunday_first_day_of_week ? 1L : 0L)) % 7));
67
68
}
68
69
 
69
70
/*
95
96
        next week is week 1.
96
97
*/
97
98
 
98
 
uint32_t calc_week(DRIZZLE_TIME *l_time, uint32_t week_behaviour, uint32_t *year)
 
99
uint calc_week(MYSQL_TIME *l_time, uint week_behaviour, uint *year)
99
100
{
100
 
  uint32_t days;
 
101
  uint days;
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);
106
107
 
107
 
  uint32_t weekday=calc_weekday(first_daynr, !monday_first);
 
108
  uint weekday=calc_weekday(first_daynr, !monday_first);
108
109
  *year=l_time->year;
109
110
 
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 */
140
141
 
141
 
void get_date_from_daynr(long daynr,uint32_t *ret_year,uint32_t *ret_month,
142
 
                         uint32_t *ret_day)
 
142
void get_date_from_daynr(long daynr,uint *ret_year,uint *ret_month,
 
143
                         uint *ret_day)
143
144
{
144
 
  uint32_t year,temp,leap_day,day_of_year,days_in_year;
145
 
  unsigned char *month_pos;
 
145
  uint year,temp,leap_day,day_of_year,days_in_year;
 
146
  uchar *month_pos;
 
147
  DBUG_ENTER("get_date_from_daynr");
146
148
 
147
149
  if (daynr <= 365L || daynr >= 3652500)
148
150
  {                                             /* Fix if wrong daynr */
176
178
    *ret_year=year;
177
179
    *ret_day=day_of_year+leap_day;
178
180
  }
179
 
  return;
 
181
  DBUG_VOID_RETURN;
180
182
}
181
183
 
182
184
        /* Functions to handle periods */
209
211
 
210
212
 
211
213
/*
212
 
  Convert a timestamp string to a DRIZZLE_TIME value and produce a warning 
 
214
  Convert a timestamp string to a MYSQL_TIME value and produce a warning 
213
215
  if string was truncated during conversion.
214
216
 
215
217
  NOTE
216
218
    See description of str_to_datetime() for more information.
217
219
*/
218
220
 
219
 
enum enum_drizzle_timestamp_type
220
 
str_to_datetime_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time,
221
 
                          uint32_t flags)
 
221
timestamp_type
 
222
str_to_datetime_with_warn(const char *str, uint length, MYSQL_TIME *l_time,
 
223
                          uint flags)
222
224
{
223
225
  int was_cut;
224
226
  THD *thd= current_thd;
225
 
  enum enum_drizzle_timestamp_type ts_type;
 
227
  timestamp_type ts_type;
226
228
  
227
229
  ts_type= str_to_datetime(str, length, l_time,
228
230
                           (flags | (thd->variables.sql_mode &
229
231
                                     (MODE_INVALID_DATES |
230
232
                                      MODE_NO_ZERO_DATE))),
231
233
                           &was_cut);
232
 
  if (was_cut || ts_type <= DRIZZLE_TIMESTAMP_ERROR)
233
 
    make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
234
 
                                 str, length, ts_type,  NULL);
 
234
  if (was_cut || ts_type <= MYSQL_TIMESTAMP_ERROR)
 
235
    make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
236
                                 str, length, ts_type,  NullS);
235
237
  return ts_type;
236
238
}
237
239
 
238
240
 
239
241
/*
240
 
  Convert a datetime from broken-down DRIZZLE_TIME representation to corresponding 
 
242
  Convert a datetime from broken-down MYSQL_TIME representation to corresponding 
241
243
  TIMESTAMP value.
242
244
 
243
245
  SYNOPSIS
253
255
     0 - t contains datetime value which is out of TIMESTAMP range.
254
256
     
255
257
*/
256
 
my_time_t TIME_to_timestamp(THD *thd, const DRIZZLE_TIME *t, bool *in_dst_time_gap)
 
258
my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *in_dst_time_gap)
257
259
{
258
260
  my_time_t timestamp;
259
261
 
272
274
 
273
275
 
274
276
/*
275
 
  Convert a time string to a DRIZZLE_TIME struct and produce a warning
 
277
  Convert a time string to a MYSQL_TIME struct and produce a warning
276
278
  if string was cut during conversion.
277
279
 
278
280
  NOTE
279
281
    See str_to_time() for more info.
280
282
*/
281
283
bool
282
 
str_to_time_with_warn(const char *str, uint32_t length, DRIZZLE_TIME *l_time)
 
284
str_to_time_with_warn(const char *str, uint length, MYSQL_TIME *l_time)
283
285
{
284
286
  int warning;
285
287
  bool ret_val= str_to_time(str, length, l_time, &warning);
286
288
  if (ret_val || warning)
287
 
    make_truncated_value_warning(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
288
 
                                 str, length, DRIZZLE_TIMESTAMP_TIME, NULL);
 
289
    make_truncated_value_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
 
290
                                 str, length, MYSQL_TIMESTAMP_TIME, NullS);
289
291
  return ret_val;
290
292
}
291
293
 
294
296
  Convert a system time structure to TIME
295
297
*/
296
298
 
297
 
void localtime_to_TIME(DRIZZLE_TIME *to, struct tm *from)
 
299
void localtime_to_TIME(MYSQL_TIME *to, struct tm *from)
298
300
{
299
301
  to->neg=0;
300
302
  to->second_part=0;
306
308
  to->second=   (int) from->tm_sec;
307
309
}
308
310
 
309
 
void calc_time_from_sec(DRIZZLE_TIME *to, long seconds, long microseconds)
 
311
void calc_time_from_sec(MYSQL_TIME *to, long seconds, long microseconds)
310
312
{
311
313
  long t_seconds;
312
314
  // to->neg is not cleared, it may already be set to a useful value
313
 
  to->time_type= DRIZZLE_TIMESTAMP_TIME;
 
315
  to->time_type= MYSQL_TIMESTAMP_TIME;
314
316
  to->year= 0;
315
317
  to->month= 0;
316
318
  to->day= 0;
348
350
    1   error
349
351
*/
350
352
 
351
 
bool parse_date_time_format(enum enum_drizzle_timestamp_type format_type, 
352
 
                            const char *format, uint32_t format_length,
 
353
bool parse_date_time_format(timestamp_type format_type, 
 
354
                            const char *format, uint format_length,
353
355
                            DATE_TIME_FORMAT *date_time_format)
354
356
{
355
 
  uint32_t offset= 0, separators= 0;
 
357
  uint offset= 0, separators= 0;
356
358
  const char *ptr= format, *format_str;
357
359
  const char *end= ptr+format_length;
358
 
  unsigned char *dt_pos= date_time_format->positions;
 
360
  uchar *dt_pos= date_time_format->positions;
359
361
  /* need_p is set if we are using AM/PM format */
360
362
  bool need_p= 0, allow_separator= 0;
361
 
  uint32_t part_map= 0, separator_map= 0;
 
363
  ulong part_map= 0, separator_map= 0;
362
364
  const char *parts[16];
363
365
 
364
366
  date_time_format->time_separator= 0;
375
377
  {
376
378
    if (*ptr == '%' && ptr+1 != end)
377
379
    {
378
 
      uint32_t position;
 
380
      uint position;
379
381
      switch (*++ptr) {
380
382
      case 'y':                                 // Year
381
383
      case 'Y':
428
430
      */
429
431
      if (part_map && position <= 2 && !(part_map & (1 | 2 | 4)))
430
432
        offset=5;
431
 
      part_map|= UINT32_C(1) << position;
 
433
      part_map|= (ulong) 1 << position;
432
434
      dt_pos[position]= offset++;
433
435
      allow_separator= 1;
434
436
    }
443
445
      allow_separator= 0;                       // Don't allow two separators
444
446
      separators++;
445
447
      /* Store in separator_map which parts are punct characters */
446
 
      if (my_ispunct(&my_charset_utf8_general_ci, *ptr))
 
448
      if (my_ispunct(&my_charset_latin1, *ptr))
447
449
        separator_map|= (ulong) 1 << (offset-1);
448
 
      else if (!my_isspace(&my_charset_utf8_general_ci, *ptr))
 
450
      else if (!my_isspace(&my_charset_latin1, *ptr))
449
451
        return 1;
450
452
    }
451
453
  }
466
468
    The last test is to ensure that %p is used if and only if
467
469
    it's needed.
468
470
  */
469
 
  if ((format_type == DRIZZLE_TIMESTAMP_DATETIME &&
470
 
       !test_all_bits(part_map, (uint32_t) (1 | 2 | 4 | 8 | 16 | 32))) ||
471
 
      (format_type == DRIZZLE_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
472
 
      (format_type == DRIZZLE_TIMESTAMP_TIME &&
473
 
       !test_all_bits(part_map, (uint32_t) (8 | 16 | 32))) ||
 
471
  if ((format_type == MYSQL_TIMESTAMP_DATETIME &&
 
472
       !test_all_bits(part_map, (1 | 2 | 4 | 8 | 16 | 32))) ||
 
473
      (format_type == MYSQL_TIMESTAMP_DATE && part_map != (1 | 2 | 4)) ||
 
474
      (format_type == MYSQL_TIMESTAMP_TIME &&
 
475
       !test_all_bits(part_map, 8 | 16 | 32)) ||
474
476
      !allow_separator ||                       // %option should be last
475
477
      (need_p && dt_pos[6] +1 != dt_pos[7]) ||
476
478
      (need_p ^ (dt_pos[7] != 255)))
479
481
  if (dt_pos[6] != 255)                         // If fractional seconds
480
482
  {
481
483
    /* remove fractional seconds from later tests */
482
 
    uint32_t pos= dt_pos[6] -1;
 
484
    uint pos= dt_pos[6] -1;
483
485
    /* Remove separator before %f from sep map */
484
486
    separator_map= ((separator_map & ((ulong) (1 << pos)-1)) |
485
487
                    ((separator_map & ~((ulong) (1 << pos)-1)) >> 1));
512
514
 
513
515
  format_str= 0;
514
516
  switch (format_type) {
515
 
  case DRIZZLE_TIMESTAMP_DATE:
 
517
  case MYSQL_TIMESTAMP_DATE:
516
518
    format_str= known_date_time_formats[INTERNAL_FORMAT].date_format;
517
519
    /* fall through */
518
 
  case DRIZZLE_TIMESTAMP_TIME:
 
520
  case MYSQL_TIMESTAMP_TIME:
519
521
    if (!format_str)
520
522
      format_str=known_date_time_formats[INTERNAL_FORMAT].time_format;
521
523
 
525
527
    */
526
528
    if (format_length == 6 && !need_p &&
527
529
        !my_strnncoll(&my_charset_bin,
528
 
                      (const unsigned char *) format, 6, 
529
 
                      (const unsigned char *) format_str, 6))
 
530
                      (const uchar *) format, 6, 
 
531
                      (const uchar *) format_str, 6))
530
532
      return 0;
531
533
    if (separator_map == (1 | 2))
532
534
    {
533
 
      if (format_type == DRIZZLE_TIMESTAMP_TIME)
 
535
      if (format_type == MYSQL_TIMESTAMP_TIME)
534
536
      {
535
537
        if (*(format+2) != *(format+5))
536
538
          break;                                // Error
540
542
      return 0;
541
543
    }
542
544
    break;
543
 
  case DRIZZLE_TIMESTAMP_DATETIME:
 
545
  case MYSQL_TIMESTAMP_DATETIME:
544
546
    /*
545
547
      If there is no separators, allow the internal format as we can read
546
548
      this.  If separators are used, they must be between each part.
548
550
    */
549
551
    if ((format_length == 12 && !need_p &&
550
552
         !my_strnncoll(&my_charset_bin, 
551
 
                       (const unsigned char *) format, 12,
552
 
                       (const unsigned char*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
 
553
                       (const uchar *) format, 12,
 
554
                       (const uchar*) known_date_time_formats[INTERNAL_FORMAT].datetime_format,
553
555
                       12)) ||
554
556
        (separators == 5 && separator_map == (1 | 2 | 8 | 16)))
555
557
      return 0;
556
558
    break;
557
559
  default:
558
 
    assert(1);
 
560
    DBUG_ASSERT(1);
559
561
    break;
560
562
  }
561
563
  return 1;                                     // Error
572
574
    format_length       Length of string
573
575
 
574
576
  NOTES
575
 
    The returned object should be freed with free()
 
577
    The returned object should be freed with my_free()
576
578
 
577
579
  RETURN
578
580
    NULL ponter:        Error
580
582
*/
581
583
 
582
584
DATE_TIME_FORMAT
583
 
*date_time_format_make(enum enum_drizzle_timestamp_type format_type,
584
 
                       const char *format_str, uint32_t format_length)
 
585
*date_time_format_make(timestamp_type format_type,
 
586
                       const char *format_str, uint format_length)
585
587
{
586
588
  DATE_TIME_FORMAT tmp;
587
589
 
606
608
    format              format to copy
607
609
 
608
610
  NOTES
609
 
    The returned object should be freed with free()
 
611
    The returned object should be freed with my_free()
610
612
 
611
613
  RETURN
612
614
    NULL ponter:        Error
626
628
  {
627
629
    /* Put format string after current pos */
628
630
    new_format->format.str= (char*) (new_format+1);
629
 
    memcpy(new_format->positions, format->positions,
 
631
    memcpy((char*) new_format->positions, (char*) format->positions,
630
632
           sizeof(format->positions));
631
633
    new_format->time_separator= format->time_separator;
632
634
    /* We make the string null terminated for easy printf in SHOW VARIABLES */
633
 
    memcpy(new_format->format.str, format->format.str,
 
635
    memcpy((char*) new_format->format.str, format->format.str,
634
636
           format->format.length);
635
637
    new_format->format.str[format->format.length]= 0;
636
638
    new_format->format.length= format->format.length;
656
658
*/
657
659
 
658
660
const char *get_date_time_format_str(KNOWN_DATE_TIME_FORMAT *format,
659
 
                                     enum enum_drizzle_timestamp_type type)
 
661
                                     timestamp_type type)
660
662
{
661
663
  switch (type) {
662
 
  case DRIZZLE_TIMESTAMP_DATE:
 
664
  case MYSQL_TIMESTAMP_DATE:
663
665
    return format->date_format;
664
 
  case DRIZZLE_TIMESTAMP_DATETIME:
 
666
  case MYSQL_TIMESTAMP_DATETIME:
665
667
    return format->datetime_format;
666
 
  case DRIZZLE_TIMESTAMP_TIME:
 
668
  case MYSQL_TIMESTAMP_TIME:
667
669
    return format->time_format;
668
670
  default:
669
 
    assert(0);                          // Impossible
 
671
    DBUG_ASSERT(0);                             // Impossible
670
672
    return 0;
671
673
  }
672
674
}
679
681
    MySQL doesn't support comparing of date/time/datetime strings that
680
682
    are not in arbutary order as dates are compared as strings in some
681
683
    context)
682
 
    This functions don't check that given DRIZZLE_TIME structure members are
 
684
    This functions don't check that given MYSQL_TIME structure members are
683
685
    in valid range. If they are not, return value won't reflect any 
684
686
    valid date either. Additionally, make_time doesn't take into
685
687
    account time->day member: it's assumed that days have been converted
687
689
****************************************************************************/
688
690
 
689
691
void make_time(const DATE_TIME_FORMAT *format __attribute__((unused)),
690
 
               const DRIZZLE_TIME *l_time, String *str)
 
692
               const MYSQL_TIME *l_time, String *str)
691
693
{
692
 
  uint32_t length= (uint) my_time_to_str(l_time, (char*) str->ptr());
 
694
  uint length= (uint) my_time_to_str(l_time, (char*) str->ptr());
693
695
  str->length(length);
694
696
  str->set_charset(&my_charset_bin);
695
697
}
696
698
 
697
699
 
698
700
void make_date(const DATE_TIME_FORMAT *format __attribute__((unused)),
699
 
               const DRIZZLE_TIME *l_time, String *str)
 
701
               const MYSQL_TIME *l_time, String *str)
700
702
{
701
 
  uint32_t length= (uint) my_date_to_str(l_time, (char*) str->ptr());
 
703
  uint length= (uint) my_date_to_str(l_time, (char*) str->ptr());
702
704
  str->length(length);
703
705
  str->set_charset(&my_charset_bin);
704
706
}
705
707
 
706
708
 
707
709
void make_datetime(const DATE_TIME_FORMAT *format __attribute__((unused)),
708
 
                   const DRIZZLE_TIME *l_time, String *str)
 
710
                   const MYSQL_TIME *l_time, String *str)
709
711
{
710
 
  uint32_t length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
 
712
  uint length= (uint) my_datetime_to_str(l_time, (char*) str->ptr());
711
713
  str->length(length);
712
714
  str->set_charset(&my_charset_bin);
713
715
}
714
716
 
715
717
 
716
 
void make_truncated_value_warning(THD *thd, DRIZZLE_ERROR::enum_warning_level level,
 
718
void make_truncated_value_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
717
719
                                  const char *str_val,
718
 
                                  uint32_t str_length,
719
 
                                  enum enum_drizzle_timestamp_type time_type,
 
720
                                  uint str_length, timestamp_type time_type,
720
721
                                  const char *field_name)
721
722
{
722
 
  char warn_buff[DRIZZLE_ERRMSG_SIZE];
 
723
  char warn_buff[MYSQL_ERRMSG_SIZE];
723
724
  const char *type_str;
724
 
  CHARSET_INFO *cs= &my_charset_utf8_general_ci;
 
725
  CHARSET_INFO *cs= &my_charset_latin1;
725
726
  char buff[128];
726
 
  String str(buff,(uint32_t) sizeof(buff), system_charset_info);
 
727
  String str(buff,(uint32) sizeof(buff), system_charset_info);
727
728
  str.copy(str_val, str_length, system_charset_info);
728
729
  str[str_length]= 0;               // Ensure we have end 0 for snprintf
729
730
 
730
731
  switch (time_type) {
731
 
    case DRIZZLE_TIMESTAMP_DATE: 
 
732
    case MYSQL_TIMESTAMP_DATE: 
732
733
      type_str= "date";
733
734
      break;
734
 
    case DRIZZLE_TIMESTAMP_TIME:
 
735
    case MYSQL_TIMESTAMP_TIME:
735
736
      type_str= "time";
736
737
      break;
737
 
    case DRIZZLE_TIMESTAMP_DATETIME:  // FALLTHROUGH
 
738
    case MYSQL_TIMESTAMP_DATETIME:  // FALLTHROUGH
738
739
    default:
739
740
      type_str= "datetime";
740
741
      break;
746
747
                       (ulong) thd->row_count);
747
748
  else
748
749
  {
749
 
    if (time_type > DRIZZLE_TIMESTAMP_ERROR)
 
750
    if (time_type > MYSQL_TIMESTAMP_ERROR)
750
751
      cs->cset->snprintf(cs, warn_buff, sizeof(warn_buff),
751
752
                         ER(ER_TRUNCATED_WRONG_VALUE),
752
753
                         type_str, str.c_ptr());
761
762
/* Daynumber from year 0 to 9999-12-31 */
762
763
#define MAX_DAY_NUMBER 3652424L
763
764
 
764
 
bool date_add_interval(DRIZZLE_TIME *ltime, interval_type int_type, INTERVAL interval)
 
765
bool date_add_interval(MYSQL_TIME *ltime, interval_type int_type, INTERVAL interval)
765
766
{
766
767
  long period, sign;
767
768
 
785
786
  case INTERVAL_DAY_MINUTE:
786
787
  case INTERVAL_DAY_HOUR:
787
788
  {
788
 
    int64_t sec, days, daynr, microseconds, extra_sec;
789
 
    ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME; // Return full date
 
789
    longlong sec, days, daynr, microseconds, extra_sec;
 
790
    ltime->time_type= MYSQL_TIMESTAMP_DATETIME; // Return full date
790
791
    microseconds= ltime->second_part + sign*interval.second_part;
791
792
    extra_sec= microseconds/1000000L;
792
793
    microseconds= microseconds%1000000L;
793
794
 
794
795
    sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
795
796
         ltime->second +
796
 
         sign* (int64_t) (interval.day*3600*24L +
797
 
                           interval.hour*3600L+interval.minute*60L+
 
797
         sign* (longlong) (interval.day*3600*24L +
 
798
                           interval.hour*LL(3600)+interval.minute*LL(60)+
798
799
                           interval.second))+ extra_sec;
799
800
    if (microseconds < 0)
800
801
    {
801
 
      microseconds+= 1000000L;
 
802
      microseconds+= LL(1000000);
802
803
      sec--;
803
804
    }
804
 
    days= sec/(3600*24L);
805
 
    sec-= days*3600*24L;
 
805
    days= sec/(3600*LL(24));
 
806
    sec-= days*3600*LL(24);
806
807
    if (sec < 0)
807
808
    {
808
809
      days--;
809
 
      sec+= 3600*24L;
 
810
      sec+= 3600*LL(24);
810
811
    }
811
812
    ltime->second_part= (uint) microseconds;
812
813
    ltime->second= (uint) (sec % 60);
814
815
    ltime->hour=   (uint) (sec/3600);
815
816
    daynr= calc_daynr(ltime->year,ltime->month,1) + days;
816
817
    /* Day number from year 0 to 9999-12-31 */
817
 
    if ((uint64_t) daynr > MAX_DAY_NUMBER)
 
818
    if ((ulonglong) daynr > MAX_DAY_NUMBER)
818
819
      goto invalid_date;
819
820
    get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
820
821
                        &ltime->day);
861
862
  return 0;                                     // Ok
862
863
 
863
864
invalid_date:
864
 
  push_warning_printf(current_thd, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
865
  push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
865
866
                      ER_DATETIME_FUNCTION_OVERFLOW,
866
867
                      ER(ER_DATETIME_FUNCTION_OVERFLOW),
867
868
                      "datetime");
887
888
  NOTE
888
889
    This function calculates difference between l_time1 and l_time2 absolute
889
890
    values. So one should set l_sign and correct result if he want to take
890
 
    signs into account (i.e. for DRIZZLE_TIME values).
 
891
    signs into account (i.e. for MYSQL_TIME values).
891
892
 
892
893
  RETURN VALUES
893
894
    Returns sign of difference.
897
898
*/
898
899
 
899
900
bool
900
 
calc_time_diff(DRIZZLE_TIME *l_time1, DRIZZLE_TIME *l_time2, int l_sign, int64_t *seconds_out,
 
901
calc_time_diff(MYSQL_TIME *l_time1, MYSQL_TIME *l_time2, int l_sign, longlong *seconds_out,
901
902
               long *microseconds_out)
902
903
{
903
904
  long days;
904
905
  bool neg;
905
 
  int64_t microseconds;
 
906
  longlong microseconds;
906
907
 
907
908
  /*
908
 
    We suppose that if first argument is DRIZZLE_TIMESTAMP_TIME
 
909
    We suppose that if first argument is MYSQL_TIMESTAMP_TIME
909
910
    the second argument should be TIMESTAMP_TIME also.
910
911
    We should check it before calc_time_diff call.
911
912
  */
912
 
  if (l_time1->time_type == DRIZZLE_TIMESTAMP_TIME)  // Time value
 
913
  if (l_time1->time_type == MYSQL_TIMESTAMP_TIME)  // Time value
913
914
    days= (long)l_time1->day - l_sign * (long)l_time2->day;
914
915
  else
915
916
  {
916
917
    days= calc_daynr((uint) l_time1->year,
917
918
                     (uint) l_time1->month,
918
919
                     (uint) l_time1->day);
919
 
    if (l_time2->time_type == DRIZZLE_TIMESTAMP_TIME)
 
920
    if (l_time2->time_type == MYSQL_TIMESTAMP_TIME)
920
921
      days-= l_sign * (long)l_time2->day;
921
922
    else
922
923
      days-= l_sign*calc_daynr((uint) l_time2->year,
924
925
                               (uint) l_time2->day);
925
926
  }
926
927
 
927
 
  microseconds= ((int64_t)days*86400L +
928
 
                 (int64_t)(l_time1->hour*3600L +
 
928
  microseconds= ((longlong)days*LL(86400) +
 
929
                 (longlong)(l_time1->hour*3600L +
929
930
                            l_time1->minute*60L +
930
931
                            l_time1->second) -
931
 
                 l_sign*(int64_t)(l_time2->hour*3600L +
 
932
                 l_sign*(longlong)(l_time2->hour*3600L +
932
933
                                   l_time2->minute*60L +
933
 
                                   l_time2->second)) * 1000000L +
934
 
                (int64_t)l_time1->second_part -
935
 
                l_sign*(int64_t)l_time2->second_part;
 
934
                                   l_time2->second)) * LL(1000000) +
 
935
                (longlong)l_time1->second_part -
 
936
                l_sign*(longlong)l_time2->second_part;
936
937
 
937
938
  neg= 0;
938
939
  if (microseconds < 0)
947
948
 
948
949
 
949
950
/*
950
 
  Compares 2 DRIZZLE_TIME structures
 
951
  Compares 2 MYSQL_TIME structures
951
952
 
952
953
  SYNOPSIS
953
954
    my_time_compare()
965
966
*/
966
967
 
967
968
int
968
 
my_time_compare(DRIZZLE_TIME *a, DRIZZLE_TIME *b)
 
969
my_time_compare(MYSQL_TIME *a, MYSQL_TIME *b)
969
970
{
970
 
  uint64_t a_t= TIME_to_uint64_t_datetime(a);
971
 
  uint64_t b_t= TIME_to_uint64_t_datetime(b);
 
971
  my_ulonglong a_t= TIME_to_ulonglong_datetime(a);
 
972
  my_ulonglong b_t= TIME_to_ulonglong_datetime(b);
972
973
 
973
974
  if (a_t > b_t)
974
975
    return 1;