summaryrefslogtreecommitdiff
path: root/sql/item_timefunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_timefunc.cc')
-rw-r--r--sql/item_timefunc.cc137
1 files changed, 72 insertions, 65 deletions
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index a578abc345a..f22c14c925f 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -634,8 +634,8 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
For example, '1.1' -> '1.100000'
*/
-bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
- uint count, long *values, bool transform_msec)
+static bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
+ uint count, long *values, bool transform_msec)
{
const char *end=str+length;
uint i;
@@ -644,10 +644,10 @@ bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
for (i=0 ; i < count ; i++)
{
- long value;
+ longlong value;
const char *start= str;
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
- value=value*10L + (long) (*str - '0');
+ value= value*LL(10) + (longlong) (*str - '0');
if (transform_msec && i == count - 1) // microseconds always last
{
long msec_length= 6 - (str - start);
@@ -662,14 +662,15 @@ bool get_interval_info(const char *str,uint length,CHARSET_INFO *cs,
i++;
/* Change values[0...i-1] -> values[0...count-1] */
bmove_upp((char*) (values+count), (char*) (values+i),
- sizeof(long)*i);
- bzero((char*) values, sizeof(long)*(count-i));
+ sizeof(*values)*i);
+ bzero((char*) values, sizeof(*values)*(count-i));
break;
}
}
return (str != end);
}
+
longlong Item_func_period_add::val_int()
{
DBUG_ASSERT(fixed == 1);
@@ -929,7 +930,8 @@ longlong Item_func_time_to_sec::val_int()
static bool get_interval_value(Item *args,interval_type int_type,
String *str_value, INTERVAL *interval)
{
- long array[5],value;
+ ulonglong array[5];
+ longlong value;
const char *str;
uint32 length;
CHARSET_INFO *cs=str_value->charset();
@@ -941,7 +943,7 @@ static bool get_interval_value(Item *args,interval_type int_type,
bzero((char*) interval,sizeof(*interval));
if ((int) int_type <= INTERVAL_MICROSECOND)
{
- value=(long) args->val_int();
+ value= args->val_int();
if (args->null_value)
return 1;
if (value < 0)
@@ -971,16 +973,16 @@ static bool get_interval_value(Item *args,interval_type int_type,
switch (int_type) {
case INTERVAL_YEAR:
- interval->year=value;
+ interval->year= (ulong) value;
break;
case INTERVAL_MONTH:
- interval->month=value;
+ interval->month= (ulong) value;
break;
case INTERVAL_DAY:
- interval->day=value;
+ interval->day= (ulong) value;
break;
case INTERVAL_HOUR:
- interval->hour=value;
+ interval->hour= (ulong) value;
break;
case INTERVAL_MICROSECOND:
interval->second_part=value;
@@ -994,78 +996,78 @@ static bool get_interval_value(Item *args,interval_type int_type,
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
if (get_interval_info(str,length,cs,2,array,0))
return (1);
- interval->year=array[0];
- interval->month=array[1];
+ interval->year= (ulong) array[0];
+ interval->month= (ulong) array[1];
break;
case INTERVAL_DAY_HOUR:
if (get_interval_info(str,length,cs,2,array,0))
return (1);
- interval->day=array[0];
- interval->hour=array[1];
+ interval->day= (ulong) array[0];
+ interval->hour= (ulong) array[1];
break;
case INTERVAL_DAY_MICROSECOND:
if (get_interval_info(str,length,cs,5,array,1))
return (1);
- interval->day=array[0];
- interval->hour=array[1];
- interval->minute=array[2];
- interval->second=array[3];
- interval->second_part=array[4];
+ interval->day= (ulong) array[0];
+ interval->hour= (ulong) array[1];
+ interval->minute= array[2];
+ interval->second= array[3];
+ interval->second_part= array[4];
break;
case INTERVAL_DAY_MINUTE:
if (get_interval_info(str,length,cs,3,array,0))
return (1);
- interval->day=array[0];
- interval->hour=array[1];
- interval->minute=array[2];
+ interval->day= (ulong) array[0];
+ interval->hour= (ulong) array[1];
+ interval->minute= array[2];
break;
case INTERVAL_DAY_SECOND:
if (get_interval_info(str,length,cs,4,array,0))
return (1);
- interval->day=array[0];
- interval->hour=array[1];
- interval->minute=array[2];
- interval->second=array[3];
+ interval->day= (ulong) array[0];
+ interval->hour= (ulong) array[1];
+ interval->minute= array[2];
+ interval->second= array[3];
break;
case INTERVAL_HOUR_MICROSECOND:
if (get_interval_info(str,length,cs,4,array,1))
return (1);
- interval->hour=array[0];
- interval->minute=array[1];
- interval->second=array[2];
- interval->second_part=array[3];
+ interval->hour= (ulong) array[0];
+ interval->minute= array[1];
+ interval->second= array[2];
+ interval->second_part= array[3];
break;
case INTERVAL_HOUR_MINUTE:
if (get_interval_info(str,length,cs,2,array,0))
return (1);
- interval->hour=array[0];
- interval->minute=array[1];
+ interval->hour= (ulong) array[0];
+ interval->minute= array[1];
break;
case INTERVAL_HOUR_SECOND:
if (get_interval_info(str,length,cs,3,array,0))
return (1);
- interval->hour=array[0];
- interval->minute=array[1];
- interval->second=array[2];
+ interval->hour= (ulong) array[0];
+ interval->minute= array[1];
+ interval->second= array[2];
break;
case INTERVAL_MINUTE_MICROSECOND:
if (get_interval_info(str,length,cs,3,array,1))
return (1);
- interval->minute=array[0];
- interval->second=array[1];
- interval->second_part=array[2];
+ interval->minute= array[0];
+ interval->second= array[1];
+ interval->second_part= array[2];
break;
case INTERVAL_MINUTE_SECOND:
if (get_interval_info(str,length,cs,2,array,0))
return (1);
- interval->minute=array[0];
- interval->second=array[1];
+ interval->minute= array[0];
+ interval->second= array[1];
break;
case INTERVAL_SECOND_MICROSECOND:
if (get_interval_info(str,length,cs,2,array,1))
return (1);
- interval->second=array[0];
- interval->second_part=array[1];
+ interval->second= array[0];
+ interval->second_part= array[1];
break;
}
return 0;
@@ -1639,7 +1641,8 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
case INTERVAL_DAY_SECOND:
case INTERVAL_DAY_MINUTE:
case INTERVAL_DAY_HOUR:
- long sec,days,daynr,microseconds,extra_sec;
+ {
+ longlong sec, days, daynr, microseconds, extra_sec;
ltime->time_type=TIMESTAMP_DATETIME; // Return full date
microseconds= ltime->second_part + sign*interval.second_part;
extra_sec= microseconds/1000000L;
@@ -1647,40 +1650,44 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
sec=((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
ltime->second +
- sign*(interval.day*3600*24L +
- interval.hour*3600+interval.minute*60+interval.second))+
- extra_sec;
-
+ sign* (longlong) (interval.day*3600*24L +
+ interval.hour*3600+interval.minute*60+
+ interval.second))+ extra_sec;
if (microseconds < 0)
{
- microseconds+= 1000000L;
+ microseconds+= LL(1000000);
sec--;
}
- days=sec/(3600*24L); sec=sec-days*3600*24L;
+ days= sec/(3600*LL(24));
+ sec-= days*3600*LL(24);
if (sec < 0)
{
days--;
- sec+=3600*24L;
+ sec+= 3600*LL(24);
}
ltime->second_part= microseconds;
- ltime->second=sec % 60;
- ltime->minute=sec/60 % 60;
- ltime->hour=sec/3600;
+ ltime->second= (uint) (sec % 60);
+ ltime->minute= (uint) (sec/60 % 60);
+ ltime->hour= (uint) (sec/3600);
daynr= calc_daynr(ltime->year,ltime->month,1) + days;
- get_date_from_daynr(daynr,&ltime->year,&ltime->month,&ltime->day);
- if (daynr < 0 || daynr >= MAX_DAY_NUMBER) // Day number from year 0 to 9999-12-31
+ /* Day number from year 0 to 9999-12-31 */
+ if ((ulonglong) daynr >= MAX_DAY_NUMBER)
goto null_date;
+ get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
+ &ltime->day);
break;
+ }
case INTERVAL_DAY:
- period= calc_daynr(ltime->year,ltime->month,ltime->day) +
- sign*interval.day;
- if (period < 0 || period >= MAX_DAY_NUMBER) // Daynumber from year 0 to 9999-12-31
+ period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
+ sign * (long) interval.day);
+ /* Daynumber from year 0 to 9999-12-31 */
+ if ((ulong) period >= MAX_DAY_NUMBER)
goto null_date;
get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
break;
case INTERVAL_YEAR:
- ltime->year += sign*interval.year;
- if ((int) ltime->year < 0 || ltime->year >= 10000L)
+ ltime->year+= sign * (long) interval.year;
+ if ((ulong) ltime->year >= 10000L)
goto null_date;
if (ltime->month == 2 && ltime->day == 29 &&
calc_days_in_year(ltime->year) != 366)
@@ -1688,9 +1695,9 @@ bool Item_date_add_interval::get_date(TIME *ltime, uint fuzzy_date)
break;
case INTERVAL_YEAR_MONTH:
case INTERVAL_MONTH:
- period= (ltime->year*12 + sign*interval.year*12 +
- ltime->month-1 + sign*interval.month);
- if (period < 0 || period >= 120000L)
+ period= (ltime->year*12 + sign * (long) interval.year*12 +
+ ltime->month-1 + sign * (long) interval.month);
+ if ((ulong) period >= 120000L)
goto null_date;
ltime->year= (uint) (period / 12);
ltime->month= (uint) (period % 12L)+1;