22 #include <drizzled/internal/m_string.h>
23 #include <drizzled/error.h>
24 #include <drizzled/session.h>
25 #include <drizzled/current_session.h>
26 #include <drizzled/function/time/date.h>
27 #include <drizzled/temporal_interval.h>
28 #include <drizzled/time_functions.h>
34 interval_type int_type,
39 const char *str= NULL;
45 if (static_cast<int>(int_type) <= INTERVAL_MICROSECOND)
60 if (!(res= args->
val_str(str_value)))
65 const char *end= str+res->length();
67 while (str != end && cs->isspace(*str))
69 if (str != end && *str ==
'-')
75 length=
static_cast<size_t>(end-str);
81 year=
static_cast<uint32_t
>(value);
83 case INTERVAL_QUARTER:
84 month=
static_cast<uint32_t
>(value*3);
87 month=
static_cast<uint32_t
>(value);
90 day=
static_cast<uint32_t
>(value*7);
93 day=
static_cast<uint32_t
>(value);
96 hour=
static_cast<uint32_t
>(value);
98 case INTERVAL_MICROSECOND:
101 case INTERVAL_MINUTE:
104 case INTERVAL_SECOND:
107 case INTERVAL_YEAR_MONTH:
110 year=
static_cast<uint32_t
>(array[0]);
111 month=
static_cast<uint32_t
>(array[1]);
113 case INTERVAL_DAY_HOUR:
116 day=
static_cast<uint32_t
>(array[0]);
117 hour=
static_cast<uint32_t
>(array[1]);
119 case INTERVAL_DAY_MICROSECOND:
122 day=
static_cast<uint32_t
>(array[0]);
123 hour=
static_cast<uint32_t
>(array[1]);
126 second_part= array[4];
128 case INTERVAL_DAY_MINUTE:
131 day=
static_cast<uint32_t
>(array[0]);
132 hour=
static_cast<uint32_t
>(array[1]);
135 case INTERVAL_DAY_SECOND:
138 day=
static_cast<uint32_t
>(array[0]);
139 hour=
static_cast<uint32_t
>(array[1]);
143 case INTERVAL_HOUR_MICROSECOND:
146 hour=
static_cast<uint32_t
>(array[0]);
149 second_part= array[3];
151 case INTERVAL_HOUR_MINUTE:
154 hour=
static_cast<uint32_t
>(array[0]);
157 case INTERVAL_HOUR_SECOND:
160 hour=
static_cast<uint32_t
>(array[0]);
164 case INTERVAL_MINUTE_MICROSECOND:
169 second_part= array[2];
171 case INTERVAL_MINUTE_SECOND:
177 case INTERVAL_SECOND_MICROSECOND:
181 second_part= array[1];
196 sign= (neg ? -1 : 1);
200 case INTERVAL_SECOND:
201 case INTERVAL_SECOND_MICROSECOND:
202 case INTERVAL_MICROSECOND:
203 case INTERVAL_MINUTE:
205 case INTERVAL_MINUTE_MICROSECOND:
206 case INTERVAL_MINUTE_SECOND:
207 case INTERVAL_HOUR_MICROSECOND:
208 case INTERVAL_HOUR_SECOND:
209 case INTERVAL_HOUR_MINUTE:
210 case INTERVAL_DAY_MICROSECOND:
211 case INTERVAL_DAY_SECOND:
212 case INTERVAL_DAY_MINUTE:
213 case INTERVAL_DAY_HOUR:
214 int64_t sec, days, daynr, microseconds, extra_sec;
215 ltime->time_type= type::DRIZZLE_TIMESTAMP_DATETIME;
216 microseconds= ltime->second_part + sign*second_part;
217 extra_sec= microseconds/1000000L;
218 microseconds= microseconds%1000000L;
220 sec= ((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
222 sign* (int64_t) (day*3600*24L +
223 hour*3600L+minute*60L+
225 if (microseconds < 0)
227 microseconds+= 1000000L;
230 days= sec/(3600*24L);
237 ltime->second_part= (uint32_t) microseconds;
238 ltime->second= (uint32_t) (sec % 60);
239 ltime->minute= (uint32_t) (sec/60 % 60);
240 ltime->hour= (uint32_t) (sec/3600);
241 daynr= calc_daynr(ltime->year,ltime->month,1) + days;
243 if ((uint64_t) daynr > MAX_DAY_NUMBER)
245 get_date_from_daynr((
long) daynr, <ime->year, <ime->month, <ime->day);
249 period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
252 if (period > MAX_DAY_NUMBER)
254 get_date_from_daynr((
long) period,<ime->year,<ime->month,<ime->day);
257 ltime->year+= sign * (long) year;
258 if (ltime->year >= 10000L)
260 if (ltime->month == 2 && ltime->day == 29 &&
261 calc_days_in_year(ltime->year) != 366)
264 case INTERVAL_YEAR_MONTH:
265 case INTERVAL_QUARTER:
267 period= (ltime->year*12 + sign * (
long) year*12 +
268 ltime->month-1 + sign * (long) month);
269 if (period >= 120000L)
271 ltime->year= (uint32_t) (period / 12);
272 ltime->month= (uint32_t) (period % 12L)+1;
274 if (ltime->day > days_in_month[ltime->month-1])
276 ltime->day= days_in_month[ltime->month-1];
277 if (ltime->month == 2 && calc_days_in_year(ltime->year) == 366)
288 push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
289 ER_DATETIME_FUNCTION_OVERFLOW,
290 ER(ER_DATETIME_FUNCTION_OVERFLOW),
299 uint32_t count, uint64_t *values,
302 const char *end= str+length;
305 while (str != end && !cs->isdigit(*str))
308 for (x= 0 ; x < count ; x++)
311 const char *start= str;
312 for (value= 0 ; str != end && cs->isdigit(*str) ; str++)
313 value= value * 10L + (int64_t) (*str -
'0');
314 if (transform_msec && (x == count - 1 || str == end))
316 long msec_length= 6 - (str - start);
318 value*= (long) log_10_int[msec_length];
321 while (str != end && !cs->isdigit(*str))
323 if (str == end && x != count-1)
327 internal::bmove_upp((
unsigned char*) (values+count),
328 (
unsigned char*) (values+x),
330 memset(values, 0,
sizeof(*values)*(count-x));
bool getIntervalFromString(const char *str, uint32_t length, const charset_info_st *const cs, uint32_t count, uint64_t *values, bool transform_msec)
bool initFromItem(Item *args, interval_type int_type, String *str_value)
virtual int64_t val_int()=0
TODO: Rename this file - func.h is stupid.
bool addDate(type::Time *ltime, interval_type int_type)
static const uint32_t NUM_YEAR_MONTH_STRING_ELEMENTS
static const uint32_t MAX_STRING_ELEMENTS
virtual String * val_str(String *str)=0