~posulliv/drizzle/memcached_applier

« back to all changes in this revision

Viewing changes to drizzled/time.cc

  • Committer: Jay Pipes
  • Date: 2009-08-03 14:23:22 UTC
  • mfrom: (1039.2.68 staging)
  • mto: This revision was merged to the branch mainline in revision 1078.
  • Revision ID: jpipes@serialcoder-20090803142322-1g67h7su9mocg9ig
Merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
334
334
               ER_TRUNCATED_WRONG_VALUE, warn_buff);
335
335
}
336
336
 
337
 
bool date_add_interval(DRIZZLE_TIME *ltime, interval_type int_type, INTERVAL interval)
338
 
{
339
 
  long period, sign;
340
 
 
341
 
  ltime->neg= 0;
342
 
 
343
 
  sign= (interval.neg ? -1 : 1);
344
 
 
345
 
  switch (int_type) {
346
 
  case INTERVAL_SECOND:
347
 
  case INTERVAL_SECOND_MICROSECOND:
348
 
  case INTERVAL_MICROSECOND:
349
 
  case INTERVAL_MINUTE:
350
 
  case INTERVAL_HOUR:
351
 
  case INTERVAL_MINUTE_MICROSECOND:
352
 
  case INTERVAL_MINUTE_SECOND:
353
 
  case INTERVAL_HOUR_MICROSECOND:
354
 
  case INTERVAL_HOUR_SECOND:
355
 
  case INTERVAL_HOUR_MINUTE:
356
 
  case INTERVAL_DAY_MICROSECOND:
357
 
  case INTERVAL_DAY_SECOND:
358
 
  case INTERVAL_DAY_MINUTE:
359
 
  case INTERVAL_DAY_HOUR:
360
 
  {
361
 
    int64_t sec, days, daynr, microseconds, extra_sec;
362
 
    ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME; // Return full date
363
 
    microseconds= ltime->second_part + sign*interval.second_part;
364
 
    extra_sec= microseconds/1000000L;
365
 
    microseconds= microseconds%1000000L;
366
 
 
367
 
    sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
368
 
         ltime->second +
369
 
         sign* (int64_t) (interval.day*3600*24L +
370
 
                           interval.hour*3600L+interval.minute*60L+
371
 
                           interval.second))+ extra_sec;
372
 
    if (microseconds < 0)
373
 
    {
374
 
      microseconds+= 1000000L;
375
 
      sec--;
376
 
    }
377
 
    days= sec/(3600*24L);
378
 
    sec-= days*3600*24L;
379
 
    if (sec < 0)
380
 
    {
381
 
      days--;
382
 
      sec+= 3600*24L;
383
 
    }
384
 
    ltime->second_part= (uint32_t) microseconds;
385
 
    ltime->second= (uint32_t) (sec % 60);
386
 
    ltime->minute= (uint32_t) (sec/60 % 60);
387
 
    ltime->hour=   (uint32_t) (sec/3600);
388
 
    daynr= calc_daynr(ltime->year,ltime->month,1) + days;
389
 
    /* Day number from year 0 to 9999-12-31 */
390
 
    if ((uint64_t) daynr > MAX_DAY_NUMBER)
391
 
      goto invalid_date;
392
 
    get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
393
 
                        &ltime->day);
394
 
    break;
395
 
  }
396
 
  case INTERVAL_DAY:
397
 
  case INTERVAL_WEEK:
398
 
    period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
399
 
             sign * (long) interval.day);
400
 
    /* Daynumber from year 0 to 9999-12-31 */
401
 
    if (period > MAX_DAY_NUMBER)
402
 
      goto invalid_date;
403
 
    get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
404
 
    break;
405
 
  case INTERVAL_YEAR:
406
 
    ltime->year+= sign * (long) interval.year;
407
 
    if (ltime->year >= 10000L)
408
 
      goto invalid_date;
409
 
    if (ltime->month == 2 && ltime->day == 29 &&
410
 
        calc_days_in_year(ltime->year) != 366)
411
 
      ltime->day=28;                            // Was leap-year
412
 
    break;
413
 
  case INTERVAL_YEAR_MONTH:
414
 
  case INTERVAL_QUARTER:
415
 
  case INTERVAL_MONTH:
416
 
    period= (ltime->year*12 + sign * (long) interval.year*12 +
417
 
             ltime->month-1 + sign * (long) interval.month);
418
 
    if (period >= 120000L)
419
 
      goto invalid_date;
420
 
    ltime->year= (uint32_t) (period / 12);
421
 
    ltime->month= (uint32_t) (period % 12L)+1;
422
 
    /* Adjust day if the new month doesn't have enough days */
423
 
    if (ltime->day > days_in_month[ltime->month-1])
424
 
    {
425
 
      ltime->day = days_in_month[ltime->month-1];
426
 
      if (ltime->month == 2 && calc_days_in_year(ltime->year) == 366)
427
 
        ltime->day++;                           // Leap-year
428
 
    }
429
 
    break;
430
 
  default:
431
 
    goto null_date;
432
 
  }
433
 
 
434
 
  return 0;                                     // Ok
435
 
 
436
 
invalid_date:
437
 
  push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
438
 
                      ER_DATETIME_FUNCTION_OVERFLOW,
439
 
                      ER(ER_DATETIME_FUNCTION_OVERFLOW),
440
 
                      "datetime");
441
 
null_date:
442
 
  return 1;
443
 
}
444
 
 
445
 
 
446
337
/*
447
338
  Calculate difference between two datetime values as seconds + microseconds.
448
339