1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#include <drizzled/server_includes.h>
22
#include <drizzled/function/time/get_interval_value.h>
27
Get a array of positive numbers from a string object.
28
Each number is separated by 1 non digit character
29
Return error if there is too many numbers.
30
If there is too few numbers, assume that the numbers are left out
31
from the high end. This allows one to give:
32
DAY_TO_SECOND as "D MM:HH:SS", "MM:HH:SS" "HH:SS" or as seconds.
34
@param length: length of str
35
@param cs: charset of str
36
@param values: array of results
37
@param count: count of elements in result array
38
@param transform_msec: if value is true we suppose
39
that the last part of string value is microseconds
40
and we should transform value to six digit value.
41
For example, '1.1' -> '1.100000'
44
static bool get_interval_info(const char *str,uint32_t length, const CHARSET_INFO * const cs,
45
uint32_t count, uint64_t *values,
48
const char *end=str+length;
50
while (str != end && !my_isdigit(cs,*str))
53
for (i=0 ; i < count ; i++)
56
const char *start= str;
57
for (value=0; str != end && my_isdigit(cs,*str) ; str++)
58
value= value * 10L + (int64_t) (*str - '0');
59
if (transform_msec && i == count - 1) // microseconds always last
61
long msec_length= 6 - (str - start);
63
value*= (long) log_10_int[msec_length];
66
while (str != end && !my_isdigit(cs,*str))
68
if (str == end && i != count-1)
71
/* Change values[0...i-1] -> values[0...count-1] */
72
bmove_upp((unsigned char*) (values+count), (unsigned char*) (values+i),
74
memset(values, 0, sizeof(*values)*(count-i));
83
Convert a string to a interval value.
85
To make code easy, allow interval objects without separators.
88
bool get_interval_value(Item *args,interval_type int_type,
89
String *str_value, INTERVAL *interval)
93
const char *str= NULL;
95
const CHARSET_INFO * const cs= str_value->charset();
97
memset(interval, 0, sizeof(*interval));
98
if ((int) int_type <= INTERVAL_MICROSECOND)
100
value= args->val_int();
101
if (args->null_value)
112
if (!(res=args->val_str(str_value)))
115
/* record negative intervalls in interval->neg */
117
const char *end=str+res->length();
118
while (str != end && my_isspace(cs,*str))
120
if (str != end && *str == '-')
125
length= (size_t) (end-str); // Set up pointers to new str
130
interval->year= (ulong) value;
132
case INTERVAL_QUARTER:
133
interval->month= (ulong)(value*3);
136
interval->month= (ulong) value;
139
interval->day= (ulong)(value*7);
142
interval->day= (ulong) value;
145
interval->hour= (ulong) value;
147
case INTERVAL_MICROSECOND:
148
interval->second_part=value;
150
case INTERVAL_MINUTE:
151
interval->minute=value;
153
case INTERVAL_SECOND:
154
interval->second=value;
156
case INTERVAL_YEAR_MONTH: // Allow YEAR-MONTH YYYYYMM
157
if (get_interval_info(str,length,cs,2,array,0))
159
interval->year= (ulong) array[0];
160
interval->month= (ulong) array[1];
162
case INTERVAL_DAY_HOUR:
163
if (get_interval_info(str,length,cs,2,array,0))
165
interval->day= (ulong) array[0];
166
interval->hour= (ulong) array[1];
168
case INTERVAL_DAY_MICROSECOND:
169
if (get_interval_info(str,length,cs,5,array,1))
171
interval->day= (ulong) array[0];
172
interval->hour= (ulong) array[1];
173
interval->minute= array[2];
174
interval->second= array[3];
175
interval->second_part= array[4];
177
case INTERVAL_DAY_MINUTE:
178
if (get_interval_info(str,length,cs,3,array,0))
180
interval->day= (ulong) array[0];
181
interval->hour= (ulong) array[1];
182
interval->minute= array[2];
184
case INTERVAL_DAY_SECOND:
185
if (get_interval_info(str,length,cs,4,array,0))
187
interval->day= (ulong) array[0];
188
interval->hour= (ulong) array[1];
189
interval->minute= array[2];
190
interval->second= array[3];
192
case INTERVAL_HOUR_MICROSECOND:
193
if (get_interval_info(str,length,cs,4,array,1))
195
interval->hour= (ulong) array[0];
196
interval->minute= array[1];
197
interval->second= array[2];
198
interval->second_part= array[3];
200
case INTERVAL_HOUR_MINUTE:
201
if (get_interval_info(str,length,cs,2,array,0))
203
interval->hour= (ulong) array[0];
204
interval->minute= array[1];
206
case INTERVAL_HOUR_SECOND:
207
if (get_interval_info(str,length,cs,3,array,0))
209
interval->hour= (ulong) array[0];
210
interval->minute= array[1];
211
interval->second= array[2];
213
case INTERVAL_MINUTE_MICROSECOND:
214
if (get_interval_info(str,length,cs,3,array,1))
216
interval->minute= array[0];
217
interval->second= array[1];
218
interval->second_part= array[2];
220
case INTERVAL_MINUTE_SECOND:
221
if (get_interval_info(str,length,cs,2,array,0))
223
interval->minute= array[0];
224
interval->second= array[1];
226
case INTERVAL_SECOND_MICROSECOND:
227
if (get_interval_info(str,length,cs,2,array,1))
229
interval->second= array[0];
230
interval->second_part= array[1];
232
case INTERVAL_LAST: /* purecov: begin deadcode */
234
break; /* purecov: end */