~drizzle-trunk/drizzle/development

1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
1999.6.1 by kalebral at gmail
update Copyright strings to a more common format to help with creating the master debian copyright file
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
5
 *
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.
9
 *
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.
14
 *
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
18
 */
19
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
20
#include <config.h>
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
21
2173.2.1 by Monty Taylor
Fixes incorrect usage of include
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>
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
29
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
30
namespace drizzled
31
{
32
33
bool TemporalInterval::initFromItem(Item *args,
34
                                    interval_type int_type,
35
                                    String *str_value)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
36
{
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
37
  uint64_t array[MAX_STRING_ELEMENTS];
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
38
  int64_t value= 0;
39
  const char *str= NULL;
40
  size_t length= 0;
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
41
  const charset_info_st * const cs= str_value->charset();
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
42
43
44
  // Types <= microsecond can be converted as an integer
1097.2.5 by clint at fewbar
use C++ style cast for int_type
45
  if (static_cast<int>(int_type) <= INTERVAL_MICROSECOND)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
46
  {
47
    value= args->val_int();
48
    if (args->null_value)
49
      return true;
50
    if (value < 0)
51
    {
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
52
      neg= true;
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
53
      value= -value;
54
    }
55
  }
56
  else
57
  {
58
    // Otherwise we must convert to a string and extract the multiple parts
59
    String *res;
1097.2.4 by clint at fewbar
coding standards cleanup
60
    if (!(res= args->val_str(str_value)))
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
61
      return true;
62
63
    // record negative intervalls in interval->neg 
1097.2.4 by clint at fewbar
coding standards cleanup
64
    str= res->ptr();
65
    const char *end= str+res->length();
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
66
    // Skip the whitespace
2445.1.3 by Olaf van der Spek
Refactor
67
    while (str != end && cs->isspace(*str))
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
68
      str++;
69
    if (str != end && *str == '-')
70
    {
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
71
      neg= true;
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
72
      // skip the -
73
      str++;
74
    }
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
75
    length= static_cast<size_t>(end-str);		// Set up pointers to new str
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
76
  }
77
1097.2.4 by clint at fewbar
coding standards cleanup
78
  switch (int_type)
79
  {
80
  case INTERVAL_YEAR:
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
81
    year= static_cast<uint32_t>(value);
1097.2.4 by clint at fewbar
coding standards cleanup
82
    break;
83
  case INTERVAL_QUARTER:
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
84
    month= static_cast<uint32_t>(value*3);
1097.2.4 by clint at fewbar
coding standards cleanup
85
    break;
86
  case INTERVAL_MONTH:
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
87
    month= static_cast<uint32_t>(value);
1097.2.4 by clint at fewbar
coding standards cleanup
88
    break;
89
  case INTERVAL_WEEK:
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
90
    day= static_cast<uint32_t>(value*7);
1097.2.4 by clint at fewbar
coding standards cleanup
91
    break;
92
  case INTERVAL_DAY:
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
93
    day= static_cast<uint32_t>(value);
1097.2.4 by clint at fewbar
coding standards cleanup
94
    break;
95
  case INTERVAL_HOUR:
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
96
    hour= static_cast<uint32_t>(value);
1097.2.4 by clint at fewbar
coding standards cleanup
97
    break;
98
  case INTERVAL_MICROSECOND:
99
    second_part= value;
100
    break;
101
  case INTERVAL_MINUTE:
102
    minute= value;
103
    break;
104
  case INTERVAL_SECOND:
105
    second= value;
106
    break;
107
  case INTERVAL_YEAR_MONTH:			// Allow YEAR-MONTH YYYYYMM
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
108
    if (getIntervalFromString(str,length,cs,NUM_YEAR_MONTH_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
109
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
110
    year=  static_cast<uint32_t>(array[0]);
111
    month= static_cast<uint32_t>(array[1]);
1097.2.4 by clint at fewbar
coding standards cleanup
112
    break;
113
  case INTERVAL_DAY_HOUR:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
114
    if (getIntervalFromString(str,length,cs,NUM_DAY_HOUR_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
115
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
116
    day=  static_cast<uint32_t>(array[0]);
117
    hour= static_cast<uint32_t>(array[1]);
1097.2.4 by clint at fewbar
coding standards cleanup
118
    break;
119
  case INTERVAL_DAY_MICROSECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
120
    if (getIntervalFromString(str,length,cs,NUM_DAY_MICROSECOND_STRING_ELEMENTS,array,true))
1097.2.4 by clint at fewbar
coding standards cleanup
121
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
122
    day=    static_cast<uint32_t>(array[0]);
123
    hour=   static_cast<uint32_t>(array[1]);
1097.2.4 by clint at fewbar
coding standards cleanup
124
    minute= array[2];
125
    second= array[3];
126
    second_part= array[4];
127
    break;
128
  case INTERVAL_DAY_MINUTE:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
129
    if (getIntervalFromString(str,length,cs,NUM_DAY_MINUTE_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
130
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
131
    day=    static_cast<uint32_t>(array[0]);
132
    hour=   static_cast<uint32_t>(array[1]);
1097.2.4 by clint at fewbar
coding standards cleanup
133
    minute= array[2];
134
    break;
135
  case INTERVAL_DAY_SECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
136
    if (getIntervalFromString(str,length,cs,NUM_DAY_SECOND_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
137
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
138
    day=    static_cast<uint32_t>(array[0]);
139
    hour=   static_cast<uint32_t>(array[1]);
1097.2.4 by clint at fewbar
coding standards cleanup
140
    minute= array[2];
141
    second= array[3];
142
    break;
143
  case INTERVAL_HOUR_MICROSECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
144
    if (getIntervalFromString(str,length,cs,NUM_HOUR_MICROSECOND_STRING_ELEMENTS,array,true))
1097.2.4 by clint at fewbar
coding standards cleanup
145
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
146
    hour=   static_cast<uint32_t>(array[0]);
1097.2.4 by clint at fewbar
coding standards cleanup
147
    minute= array[1];
148
    second= array[2];
149
    second_part= array[3];
150
    break;
151
  case INTERVAL_HOUR_MINUTE:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
152
    if (getIntervalFromString(str,length,cs,NUM_HOUR_MINUTE_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
153
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
154
    hour=   static_cast<uint32_t>(array[0]);
1097.2.4 by clint at fewbar
coding standards cleanup
155
    minute= array[1];
156
    break;
157
  case INTERVAL_HOUR_SECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
158
    if (getIntervalFromString(str,length,cs,NUM_HOUR_SECOND_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
159
      return true;
1097.2.8 by clint at fewbar
using static_cast and uint32_t per coding standards
160
    hour=   static_cast<uint32_t>(array[0]);
1097.2.4 by clint at fewbar
coding standards cleanup
161
    minute= array[1];
162
    second= array[2];
163
    break;
164
  case INTERVAL_MINUTE_MICROSECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
165
    if (getIntervalFromString(str,length,cs,NUM_MINUTE_MICROSECOND_STRING_ELEMENTS,array,true))
1097.2.4 by clint at fewbar
coding standards cleanup
166
      return true;
167
    minute= array[0];
168
    second= array[1];
169
    second_part= array[2];
170
    break;
171
  case INTERVAL_MINUTE_SECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
172
    if (getIntervalFromString(str,length,cs,NUM_MINUTE_SECOND_STRING_ELEMENTS,array,false))
1097.2.4 by clint at fewbar
coding standards cleanup
173
      return true;
174
    minute= array[0];
175
    second= array[1];
176
    break;
177
  case INTERVAL_SECOND_MICROSECOND:
1097.2.7 by clint at fewbar
using constants for magic numbers and true/false instead of 1/0. renamed getIntervalInfo -> getIntervalFromString for clarity
178
    if (getIntervalFromString(str,length,cs,NUM_SECOND_MICROSECOND_STRING_ELEMENTS,array,true))
1097.2.4 by clint at fewbar
coding standards cleanup
179
      return true;
180
    second= array[0];
181
    second_part= array[1];
182
    break;
971.6.11 by Eric Day
Removed purecov messages.
183
  case INTERVAL_LAST:
1097.2.4 by clint at fewbar
coding standards cleanup
184
    assert(0);
971.6.11 by Eric Day
Removed purecov messages.
185
    break;
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
186
  }
187
  return false;
188
}
189
2030.1.5 by Brian Aker
Update for moving DRIZZLE_TIME to type::Time
190
bool TemporalInterval::addDate(type::Time *ltime, interval_type int_type)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
191
{
192
  long period, sign;
193
194
  ltime->neg= 0;
195
196
  sign= (neg ? -1 : 1);
197
1097.2.4 by clint at fewbar
coding standards cleanup
198
  switch (int_type)
199
  {
200
  case INTERVAL_SECOND:
201
  case INTERVAL_SECOND_MICROSECOND:
202
  case INTERVAL_MICROSECOND:
203
  case INTERVAL_MINUTE:
204
  case INTERVAL_HOUR:
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;
2088.8.9 by Brian Aker
Merge in namespace of enum.
215
    ltime->time_type= type::DRIZZLE_TIMESTAMP_DATETIME; // Return full date
1097.2.4 by clint at fewbar
coding standards cleanup
216
    microseconds= ltime->second_part + sign*second_part;
217
    extra_sec= microseconds/1000000L;
218
    microseconds= microseconds%1000000L;
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
219
1097.2.4 by clint at fewbar
coding standards cleanup
220
    sec= ((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
221
        ltime->second +
222
        sign* (int64_t) (day*3600*24L +
223
          hour*3600L+minute*60L+
224
          second))+ extra_sec;
225
    if (microseconds < 0)
226
    {
227
      microseconds+= 1000000L;
228
      sec--;
229
    }
230
    days= sec/(3600*24L);
231
    sec-= days*3600*24L;
232
    if (sec < 0)
233
    {
234
      days--;
235
      sec+= 3600*24L;
236
    }
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;
242
    /* Day number from year 0 to 9999-12-31 */
243
    if ((uint64_t) daynr > MAX_DAY_NUMBER)
244
      goto invalid_date;
2088.8.5 by Brian Aker
Remove duplicate code around store() for type::Time
245
    get_date_from_daynr((long) daynr, &ltime->year, &ltime->month, &ltime->day);
1097.2.4 by clint at fewbar
coding standards cleanup
246
    break;
247
  case INTERVAL_DAY:
248
  case INTERVAL_WEEK:
249
    period= (calc_daynr(ltime->year,ltime->month,ltime->day) +
250
        sign * (long) day);
251
    /* Daynumber from year 0 to 9999-12-31 */
252
    if (period > MAX_DAY_NUMBER)
253
      goto invalid_date;
254
    get_date_from_daynr((long) period,&ltime->year,&ltime->month,&ltime->day);
255
    break;
256
  case INTERVAL_YEAR:
257
    ltime->year+= sign * (long) year;
258
    if (ltime->year >= 10000L)
259
      goto invalid_date;
260
    if (ltime->month == 2 && ltime->day == 29 &&
261
        calc_days_in_year(ltime->year) != 366)
262
      ltime->day= 28;				// Was leap-year
263
    break;
264
  case INTERVAL_YEAR_MONTH:
265
  case INTERVAL_QUARTER:
266
  case INTERVAL_MONTH:
267
    period= (ltime->year*12 + sign * (long) year*12 +
268
        ltime->month-1 + sign * (long) month);
269
    if (period >= 120000L)
270
      goto invalid_date;
271
    ltime->year= (uint32_t) (period / 12);
272
    ltime->month= (uint32_t) (period % 12L)+1;
273
    /* Adjust day if the new month doesn't have enough days */
274
    if (ltime->day > days_in_month[ltime->month-1])
275
    {
276
      ltime->day= days_in_month[ltime->month-1];
277
      if (ltime->month == 2 && calc_days_in_year(ltime->year) == 366)
278
        ltime->day++;				// Leap-year
279
    }
280
    break;
281
  default:
282
    goto null_date;
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
283
  }
284
285
  return 0;					// Ok
286
287
invalid_date:
288
  push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
2154.2.24 by Brian Aker
Merge in all changes for current_session, etc.
289
                      ER_DATETIME_FUNCTION_OVERFLOW,
290
                      ER(ER_DATETIME_FUNCTION_OVERFLOW),
291
                      "datetime");
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
292
null_date:
293
  return 1;
294
}
295
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
296
bool TemporalInterval::getIntervalFromString(const char *str,
297
                                             uint32_t length,
2254 by Brian Aker
Shift CHARSET_INFO to charset_info_st
298
                                             const charset_info_st * const cs,
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
299
                                             uint32_t count, uint64_t *values,
300
                                             bool transform_msec)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
301
{
1097.2.4 by clint at fewbar
coding standards cleanup
302
  const char *end= str+length;
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
303
  uint32_t x;
304
2445.1.3 by Olaf van der Spek
Refactor
305
  while (str != end && !cs->isdigit(*str))
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
306
    str++;
307
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
308
  for (x= 0 ; x < count ; x++)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
309
  {
310
    int64_t value;
311
    const char *start= str;
2445.1.3 by Olaf van der Spek
Refactor
312
    for (value= 0 ; str != end && cs->isdigit(*str) ; str++)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
313
      value= value * 10L + (int64_t) (*str - '0');
1377.8.31 by Paweł Blokus
little fix in include.am
314
    if (transform_msec && (x == count - 1 || str == end)) // microseconds always last
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
315
    {
316
      long msec_length= 6 - (str - start);
317
      if (msec_length > 0)
318
        value*= (long) log_10_int[msec_length];
319
    }
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
320
    values[x]= value;
2445.1.3 by Olaf van der Spek
Refactor
321
    while (str != end && !cs->isdigit(*str))
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
322
      str++;
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
323
    if (str == end && x != count-1)
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
324
    {
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
325
      x++;
1377.8.29 by Paweł Blokus
tests for init/deinit_temporal_formats
326
      /* Change values[0...x-1] -> values[count-x...count-1] */
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
327
      internal::bmove_upp((unsigned char*) (values+count),
328
                          (unsigned char*) (values+x),
329
                          sizeof(*values)*x);
1097.2.2 by clint at fewbar
style/documentation cleanups and replacing copyright notices
330
      memset(values, 0, sizeof(*values)*(count-x));
1097.2.1 by clint at fewbar
refactoring INTERVAL into C++ class
331
      break;
332
    }
333
  }
334
  return (str != end);
335
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
336
337
} /* namespace drizzled */