~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/temporal_interval.cc

  • Committer: Mats Kindahl
  • Date: 2008-08-26 07:32:59 UTC
  • mto: (489.1.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: mats@mysql.com-20080826073259-9k4evtajgldgolli
Replaced use of thd_proc_info() macro with calls to
set_proc_info() and get_proc_info() internally.  Introduced
functions set_thd_proc_info() and get_thd_proc_info() for
external users, i.e., plug-ins.

The set_thd_proc_info() accepted callers info that can be used to
print debug output, but the information was not used. The return
value was changed to void and the old value is not fetched any
more. To be able to get the value of proc_info for external
users, the function get_thd_proc_info() was introduced.

The thd_proc_info() macro called set_thd_proc_info() but almost
never used the return value of set_thd_proc_info() so the macro
was replaced with a call of THD::set_proc_info().

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
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
 
 
20
 
#include "config.h"
21
 
#include "drizzled/internal/m_string.h"
22
 
#include "drizzled/error.h"
23
 
#include "drizzled/session.h"
24
 
#include "config.h"
25
 
#include "drizzled/function/time/date.h"
26
 
#include "drizzled/temporal_interval.h"
27
 
#include "drizzled/time_functions.h"
28
 
 
29
 
namespace drizzled
30
 
{
31
 
 
32
 
bool TemporalInterval::initFromItem(Item *args,
33
 
                                    interval_type int_type,
34
 
                                    String *str_value)
35
 
{
36
 
  uint64_t array[MAX_STRING_ELEMENTS];
37
 
  int64_t value= 0;
38
 
  const char *str= NULL;
39
 
  size_t length= 0;
40
 
  const CHARSET_INFO * const cs= str_value->charset();
41
 
 
42
 
 
43
 
  // Types <= microsecond can be converted as an integer
44
 
  if (static_cast<int>(int_type) <= INTERVAL_MICROSECOND)
45
 
  {
46
 
    value= args->val_int();
47
 
    if (args->null_value)
48
 
      return true;
49
 
    if (value < 0)
50
 
    {
51
 
      neg= true;
52
 
      value= -value;
53
 
    }
54
 
  }
55
 
  else
56
 
  {
57
 
    // Otherwise we must convert to a string and extract the multiple parts
58
 
    String *res;
59
 
    if (!(res= args->val_str(str_value)))
60
 
      return true;
61
 
 
62
 
    // record negative intervalls in interval->neg 
63
 
    str= res->ptr();
64
 
    const char *end= str+res->length();
65
 
    // Skip the whitespace
66
 
    while (str != end && my_isspace(cs,*str))
67
 
      str++;
68
 
    if (str != end && *str == '-')
69
 
    {
70
 
      neg= true;
71
 
      // skip the -
72
 
      str++;
73
 
    }
74
 
    length= static_cast<size_t>(end-str);               // Set up pointers to new str
75
 
  }
76
 
 
77
 
  switch (int_type)
78
 
  {
79
 
  case INTERVAL_YEAR:
80
 
    year= static_cast<uint32_t>(value);
81
 
    break;
82
 
  case INTERVAL_QUARTER:
83
 
    month= static_cast<uint32_t>(value*3);
84
 
    break;
85
 
  case INTERVAL_MONTH:
86
 
    month= static_cast<uint32_t>(value);
87
 
    break;
88
 
  case INTERVAL_WEEK:
89
 
    day= static_cast<uint32_t>(value*7);
90
 
    break;
91
 
  case INTERVAL_DAY:
92
 
    day= static_cast<uint32_t>(value);
93
 
    break;
94
 
  case INTERVAL_HOUR:
95
 
    hour= static_cast<uint32_t>(value);
96
 
    break;
97
 
  case INTERVAL_MICROSECOND:
98
 
    second_part= value;
99
 
    break;
100
 
  case INTERVAL_MINUTE:
101
 
    minute= value;
102
 
    break;
103
 
  case INTERVAL_SECOND:
104
 
    second= value;
105
 
    break;
106
 
  case INTERVAL_YEAR_MONTH:                     // Allow YEAR-MONTH YYYYYMM
107
 
    if (getIntervalFromString(str,length,cs,NUM_YEAR_MONTH_STRING_ELEMENTS,array,false))
108
 
      return true;
109
 
    year=  static_cast<uint32_t>(array[0]);
110
 
    month= static_cast<uint32_t>(array[1]);
111
 
    break;
112
 
  case INTERVAL_DAY_HOUR:
113
 
    if (getIntervalFromString(str,length,cs,NUM_DAY_HOUR_STRING_ELEMENTS,array,false))
114
 
      return true;
115
 
    day=  static_cast<uint32_t>(array[0]);
116
 
    hour= static_cast<uint32_t>(array[1]);
117
 
    break;
118
 
  case INTERVAL_DAY_MICROSECOND:
119
 
    if (getIntervalFromString(str,length,cs,NUM_DAY_MICROSECOND_STRING_ELEMENTS,array,true))
120
 
      return true;
121
 
    day=    static_cast<uint32_t>(array[0]);
122
 
    hour=   static_cast<uint32_t>(array[1]);
123
 
    minute= array[2];
124
 
    second= array[3];
125
 
    second_part= array[4];
126
 
    break;
127
 
  case INTERVAL_DAY_MINUTE:
128
 
    if (getIntervalFromString(str,length,cs,NUM_DAY_MINUTE_STRING_ELEMENTS,array,false))
129
 
      return true;
130
 
    day=    static_cast<uint32_t>(array[0]);
131
 
    hour=   static_cast<uint32_t>(array[1]);
132
 
    minute= array[2];
133
 
    break;
134
 
  case INTERVAL_DAY_SECOND:
135
 
    if (getIntervalFromString(str,length,cs,NUM_DAY_SECOND_STRING_ELEMENTS,array,false))
136
 
      return true;
137
 
    day=    static_cast<uint32_t>(array[0]);
138
 
    hour=   static_cast<uint32_t>(array[1]);
139
 
    minute= array[2];
140
 
    second= array[3];
141
 
    break;
142
 
  case INTERVAL_HOUR_MICROSECOND:
143
 
    if (getIntervalFromString(str,length,cs,NUM_HOUR_MICROSECOND_STRING_ELEMENTS,array,true))
144
 
      return true;
145
 
    hour=   static_cast<uint32_t>(array[0]);
146
 
    minute= array[1];
147
 
    second= array[2];
148
 
    second_part= array[3];
149
 
    break;
150
 
  case INTERVAL_HOUR_MINUTE:
151
 
    if (getIntervalFromString(str,length,cs,NUM_HOUR_MINUTE_STRING_ELEMENTS,array,false))
152
 
      return true;
153
 
    hour=   static_cast<uint32_t>(array[0]);
154
 
    minute= array[1];
155
 
    break;
156
 
  case INTERVAL_HOUR_SECOND:
157
 
    if (getIntervalFromString(str,length,cs,NUM_HOUR_SECOND_STRING_ELEMENTS,array,false))
158
 
      return true;
159
 
    hour=   static_cast<uint32_t>(array[0]);
160
 
    minute= array[1];
161
 
    second= array[2];
162
 
    break;
163
 
  case INTERVAL_MINUTE_MICROSECOND:
164
 
    if (getIntervalFromString(str,length,cs,NUM_MINUTE_MICROSECOND_STRING_ELEMENTS,array,true))
165
 
      return true;
166
 
    minute= array[0];
167
 
    second= array[1];
168
 
    second_part= array[2];
169
 
    break;
170
 
  case INTERVAL_MINUTE_SECOND:
171
 
    if (getIntervalFromString(str,length,cs,NUM_MINUTE_SECOND_STRING_ELEMENTS,array,false))
172
 
      return true;
173
 
    minute= array[0];
174
 
    second= array[1];
175
 
    break;
176
 
  case INTERVAL_SECOND_MICROSECOND:
177
 
    if (getIntervalFromString(str,length,cs,NUM_SECOND_MICROSECOND_STRING_ELEMENTS,array,true))
178
 
      return true;
179
 
    second= array[0];
180
 
    second_part= array[1];
181
 
    break;
182
 
  case INTERVAL_LAST:
183
 
    assert(0);
184
 
    break;
185
 
  }
186
 
  return false;
187
 
}
188
 
 
189
 
bool TemporalInterval::addDate(DRIZZLE_TIME *ltime, interval_type int_type)
190
 
{
191
 
  long period, sign;
192
 
 
193
 
  ltime->neg= 0;
194
 
 
195
 
  sign= (neg ? -1 : 1);
196
 
 
197
 
  switch (int_type)
198
 
  {
199
 
  case INTERVAL_SECOND:
200
 
  case INTERVAL_SECOND_MICROSECOND:
201
 
  case INTERVAL_MICROSECOND:
202
 
  case INTERVAL_MINUTE:
203
 
  case INTERVAL_HOUR:
204
 
  case INTERVAL_MINUTE_MICROSECOND:
205
 
  case INTERVAL_MINUTE_SECOND:
206
 
  case INTERVAL_HOUR_MICROSECOND:
207
 
  case INTERVAL_HOUR_SECOND:
208
 
  case INTERVAL_HOUR_MINUTE:
209
 
  case INTERVAL_DAY_MICROSECOND:
210
 
  case INTERVAL_DAY_SECOND:
211
 
  case INTERVAL_DAY_MINUTE:
212
 
  case INTERVAL_DAY_HOUR:
213
 
    int64_t sec, days, daynr, microseconds, extra_sec;
214
 
    ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME; // Return full date
215
 
    microseconds= ltime->second_part + sign*second_part;
216
 
    extra_sec= microseconds/1000000L;
217
 
    microseconds= microseconds%1000000L;
218
 
 
219
 
    sec= ((ltime->day-1)*3600*24L+ltime->hour*3600+ltime->minute*60+
220
 
        ltime->second +
221
 
        sign* (int64_t) (day*3600*24L +
222
 
          hour*3600L+minute*60L+
223
 
          second))+ extra_sec;
224
 
    if (microseconds < 0)
225
 
    {
226
 
      microseconds+= 1000000L;
227
 
      sec--;
228
 
    }
229
 
    days= sec/(3600*24L);
230
 
    sec-= days*3600*24L;
231
 
    if (sec < 0)
232
 
    {
233
 
      days--;
234
 
      sec+= 3600*24L;
235
 
    }
236
 
    ltime->second_part= (uint32_t) microseconds;
237
 
    ltime->second= (uint32_t) (sec % 60);
238
 
    ltime->minute= (uint32_t) (sec/60 % 60);
239
 
    ltime->hour=   (uint32_t) (sec/3600);
240
 
    daynr= calc_daynr(ltime->year,ltime->month,1) + days;
241
 
    /* Day number from year 0 to 9999-12-31 */
242
 
    if ((uint64_t) daynr > MAX_DAY_NUMBER)
243
 
      goto invalid_date;
244
 
    get_date_from_daynr((long) daynr, &ltime->year, &ltime->month,
245
 
        &ltime->day);
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;
283
 
  }
284
 
 
285
 
  return 0;                                     // Ok
286
 
 
287
 
invalid_date:
288
 
  push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
289
 
      ER_DATETIME_FUNCTION_OVERFLOW,
290
 
      ER(ER_DATETIME_FUNCTION_OVERFLOW),
291
 
      "datetime");
292
 
null_date:
293
 
  return 1;
294
 
}
295
 
 
296
 
bool TemporalInterval::getIntervalFromString(const char *str,
297
 
                                             uint32_t length,
298
 
                                             const CHARSET_INFO * const cs,
299
 
                                             uint32_t count, uint64_t *values,
300
 
                                             bool transform_msec)
301
 
{
302
 
  const char *end= str+length;
303
 
  uint32_t x;
304
 
 
305
 
  while (str != end && !my_isdigit(cs,*str))
306
 
    str++;
307
 
 
308
 
  for (x= 0 ; x < count ; x++)
309
 
  {
310
 
    int64_t value;
311
 
    const char *start= str;
312
 
    for (value= 0 ; str != end && my_isdigit(cs,*str) ; str++)
313
 
      value= value * 10L + (int64_t) (*str - '0');
314
 
    if (transform_msec && (x == count - 1 || str == end)) // microseconds always last
315
 
    {
316
 
      long msec_length= 6 - (str - start);
317
 
      if (msec_length > 0)
318
 
        value*= (long) log_10_int[msec_length];
319
 
    }
320
 
    values[x]= value;
321
 
    while (str != end && !my_isdigit(cs,*str))
322
 
      str++;
323
 
    if (str == end && x != count-1)
324
 
    {
325
 
      x++;
326
 
      /* Change values[0...x-1] -> values[count-x...count-1] */
327
 
      internal::bmove_upp((unsigned char*) (values+count),
328
 
                          (unsigned char*) (values+x),
329
 
                          sizeof(*values)*x);
330
 
      memset(values, 0, sizeof(*values)*(count-x));
331
 
      break;
332
 
    }
333
 
  }
334
 
  return (str != end);
335
 
}
336
 
 
337
 
} /* namespace drizzled */