~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/datetime.cc

  • Committer: Brian Aker
  • Date: 2008-07-14 22:40:46 UTC
  • Revision ID: brian@tangent.org-20080714224046-x183907w9wp1txwv
Removed sql_manager. Ever heard of just setting up the OS to sync when you
want it to?

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 MySQL
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; either version 2 of the License, or
9
 
 *  (at your option) any later version.
10
 
 *
11
 
 *  This program is distributed in the hope that it will be useful,
12
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 
 *  GNU General Public License for more details.
15
 
 *
16
 
 *  You should have received a copy of the GNU General Public License
17
 
 *  along with this program; if not, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 */
20
 
 
21
 
#ifdef USE_PRAGMA_IMPLEMENTATION
22
 
#pragma implementation                          // gcc: Class implementation
23
 
#endif
24
 
 
25
 
#include <drizzled/server_includes.h>
26
 
#include <drizzled/field/datetime.h>
27
 
 
28
 
/****************************************************************************
29
 
** datetime type
30
 
** In string context: YYYY-MM-DD HH:MM:DD
31
 
** In number context: YYYYMMDDHHMMDD
32
 
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
33
 
****************************************************************************/
34
 
 
35
 
int Field_datetime::store(const char *from,
36
 
                          uint32_t len,
37
 
                          const CHARSET_INFO * const cs __attribute__((unused)))
38
 
{
39
 
  DRIZZLE_TIME time_tmp;
40
 
  int error;
41
 
  uint64_t tmp= 0;
42
 
  enum enum_drizzle_timestamp_type func_res;
43
 
  THD *thd= table ? table->in_use : current_thd;
44
 
 
45
 
  func_res= str_to_datetime(from, len, &time_tmp,
46
 
                            (TIME_FUZZY_DATE |
47
 
                             (thd->variables.sql_mode &
48
 
                              (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
49
 
                            &error);
50
 
  if ((int) func_res > (int) DRIZZLE_TIMESTAMP_ERROR)
51
 
    tmp= TIME_to_uint64_t_datetime(&time_tmp);
52
 
  else
53
 
    error= 1;                                 // Fix if invalid zero date
54
 
 
55
 
  if (error)
56
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
57
 
                         ER_WARN_DATA_OUT_OF_RANGE,
58
 
                         from, len, DRIZZLE_TIMESTAMP_DATETIME, 1);
59
 
 
60
 
#ifdef WORDS_BIGENDIAN
61
 
  if (table && table->s->db_low_byte_first)
62
 
  {
63
 
    int8store(ptr,tmp);
64
 
  }
65
 
  else
66
 
#endif
67
 
    int64_tstore(ptr,tmp);
68
 
  return error;
69
 
}
70
 
 
71
 
 
72
 
int Field_datetime::store(double nr)
73
 
{
74
 
  int error= 0;
75
 
  if (nr < 0.0 || nr > 99991231235959.0)
76
 
  {
77
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, 
78
 
                         ER_WARN_DATA_OUT_OF_RANGE,
79
 
                         nr, DRIZZLE_TIMESTAMP_DATETIME);
80
 
    nr= 0.0;
81
 
    error= 1;
82
 
  }
83
 
  error|= Field_datetime::store((int64_t) rint(nr), false);
84
 
  return error;
85
 
}
86
 
 
87
 
 
88
 
int Field_datetime::store(int64_t nr,
89
 
                          bool unsigned_val __attribute__((unused)))
90
 
{
91
 
  DRIZZLE_TIME not_used;
92
 
  int error;
93
 
  int64_t initial_nr= nr;
94
 
  THD *thd= table ? table->in_use : current_thd;
95
 
 
96
 
  nr= number_to_datetime(nr, &not_used, (TIME_FUZZY_DATE |
97
 
                                         (thd->variables.sql_mode &
98
 
                                          (MODE_NO_ZERO_DATE |
99
 
                                           MODE_INVALID_DATES))), &error);
100
 
 
101
 
  if (nr == INT64_C(-1))
102
 
  {
103
 
    nr= 0;
104
 
    error= 2;
105
 
  }
106
 
 
107
 
  if (error)
108
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
109
 
                         error == 2 ? ER_WARN_DATA_OUT_OF_RANGE :
110
 
                         ER_WARN_DATA_TRUNCATED, initial_nr,
111
 
                         DRIZZLE_TIMESTAMP_DATETIME, 1);
112
 
 
113
 
#ifdef WORDS_BIGENDIAN
114
 
  if (table && table->s->db_low_byte_first)
115
 
  {
116
 
    int8store(ptr,nr);
117
 
  }
118
 
  else
119
 
#endif
120
 
    int64_tstore(ptr,nr);
121
 
  return error;
122
 
}
123
 
 
124
 
 
125
 
int Field_datetime::store_time(DRIZZLE_TIME *ltime,
126
 
                               enum enum_drizzle_timestamp_type time_type)
127
 
{
128
 
  int64_t tmp;
129
 
  int error= 0;
130
 
  /*
131
 
    We don't perform range checking here since values stored in TIME
132
 
    structure always fit into DATETIME range.
133
 
  */
134
 
  if (time_type == DRIZZLE_TIMESTAMP_DATE ||
135
 
      time_type == DRIZZLE_TIMESTAMP_DATETIME)
136
 
  {
137
 
    tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*INT64_C(1000000)+
138
 
         (ltime->hour*10000L+ltime->minute*100+ltime->second));
139
 
    if (check_date(ltime, tmp != 0,
140
 
                   (TIME_FUZZY_DATE |
141
 
                    (current_thd->variables.sql_mode &
142
 
                     (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
143
 
    {
144
 
      char buff[MAX_DATE_STRING_REP_LENGTH];
145
 
      String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
146
 
      make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
147
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
148
 
                           str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATETIME,1);
149
 
    }
150
 
  }
151
 
  else
152
 
  {
153
 
    tmp=0;
154
 
    error= 1;
155
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
156
 
  }
157
 
#ifdef WORDS_BIGENDIAN
158
 
  if (table && table->s->db_low_byte_first)
159
 
  {
160
 
    int8store(ptr,tmp);
161
 
  }
162
 
  else
163
 
#endif
164
 
    int64_tstore(ptr,tmp);
165
 
  return error;
166
 
}
167
 
 
168
 
bool Field_datetime::send_binary(Protocol *protocol)
169
 
{
170
 
  DRIZZLE_TIME tm;
171
 
  Field_datetime::get_date(&tm, TIME_FUZZY_DATE);
172
 
  return protocol->store(&tm);
173
 
}
174
 
 
175
 
 
176
 
double Field_datetime::val_real(void)
177
 
{
178
 
  return (double) Field_datetime::val_int();
179
 
}
180
 
 
181
 
int64_t Field_datetime::val_int(void)
182
 
{
183
 
  int64_t j;
184
 
#ifdef WORDS_BIGENDIAN
185
 
  if (table && table->s->db_low_byte_first)
186
 
    j=sint8korr(ptr);
187
 
  else
188
 
#endif
189
 
    int64_tget(j,ptr);
190
 
  return j;
191
 
}
192
 
 
193
 
 
194
 
String *Field_datetime::val_str(String *val_buffer,
195
 
                                String *val_ptr __attribute__((unused)))
196
 
{
197
 
  val_buffer->alloc(field_length);
198
 
  val_buffer->length(field_length);
199
 
  uint64_t tmp;
200
 
  long part1,part2;
201
 
  char *pos;
202
 
  int part3;
203
 
 
204
 
#ifdef WORDS_BIGENDIAN
205
 
  if (table && table->s->db_low_byte_first)
206
 
    tmp=sint8korr(ptr);
207
 
  else
208
 
#endif
209
 
    int64_tget(tmp,ptr);
210
 
 
211
 
  /*
212
 
    Avoid problem with slow int64_t arithmetic and sprintf
213
 
  */
214
 
 
215
 
  part1=(long) (tmp/INT64_C(1000000));
216
 
  part2=(long) (tmp - (uint64_t) part1*INT64_C(1000000));
217
 
 
218
 
  pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
219
 
  *pos--=0;
220
 
  *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
221
 
  *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
222
 
  *pos--= ':';
223
 
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
224
 
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
225
 
  *pos--= ':';
226
 
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
227
 
  *pos--= (char) ('0'+(char) part3);
228
 
  *pos--= ' ';
229
 
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
230
 
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
231
 
  *pos--= '-';
232
 
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
233
 
  *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
234
 
  *pos--= '-';
235
 
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
236
 
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
237
 
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
238
 
  *pos=(char) ('0'+(char) part3);
239
 
  return val_buffer;
240
 
}
241
 
 
242
 
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
243
 
{
244
 
  int64_t tmp=Field_datetime::val_int();
245
 
  uint32_t part1,part2;
246
 
  part1=(uint32_t) (tmp/INT64_C(1000000));
247
 
  part2=(uint32_t) (tmp - (uint64_t) part1*INT64_C(1000000));
248
 
 
249
 
  ltime->time_type=     DRIZZLE_TIMESTAMP_DATETIME;
250
 
  ltime->neg=           0;
251
 
  ltime->second_part=   0;
252
 
  ltime->second=        (int) (part2%100);
253
 
  ltime->minute=        (int) (part2/100%100);
254
 
  ltime->hour=          (int) (part2/10000);
255
 
  ltime->day=           (int) (part1%100);
256
 
  ltime->month=         (int) (part1/100%100);
257
 
  ltime->year=          (int) (part1/10000);
258
 
  return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
259
 
}
260
 
 
261
 
bool Field_datetime::get_time(DRIZZLE_TIME *ltime)
262
 
{
263
 
  return Field_datetime::get_date(ltime,0);
264
 
}
265
 
 
266
 
int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
267
 
{
268
 
  int64_t a,b;
269
 
#ifdef WORDS_BIGENDIAN
270
 
  if (table && table->s->db_low_byte_first)
271
 
  {
272
 
    a=sint8korr(a_ptr);
273
 
    b=sint8korr(b_ptr);
274
 
  }
275
 
  else
276
 
#endif
277
 
  {
278
 
    int64_tget(a,a_ptr);
279
 
    int64_tget(b,b_ptr);
280
 
  }
281
 
  return ((uint64_t) a < (uint64_t) b) ? -1 :
282
 
    ((uint64_t) a > (uint64_t) b) ? 1 : 0;
283
 
}
284
 
 
285
 
void Field_datetime::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
286
 
{
287
 
#ifdef WORDS_BIGENDIAN
288
 
  if (!table || !table->s->db_low_byte_first)
289
 
  {
290
 
    to[0] = ptr[0];
291
 
    to[1] = ptr[1];
292
 
    to[2] = ptr[2];
293
 
    to[3] = ptr[3];
294
 
    to[4] = ptr[4];
295
 
    to[5] = ptr[5];
296
 
    to[6] = ptr[6];
297
 
    to[7] = ptr[7];
298
 
  }
299
 
  else
300
 
#endif
301
 
  {
302
 
    to[0] = ptr[7];
303
 
    to[1] = ptr[6];
304
 
    to[2] = ptr[5];
305
 
    to[3] = ptr[4];
306
 
    to[4] = ptr[3];
307
 
    to[5] = ptr[2];
308
 
    to[6] = ptr[1];
309
 
    to[7] = ptr[0];
310
 
  }
311
 
}
312
 
 
313
 
 
314
 
void Field_datetime::sql_type(String &res) const
315
 
{
316
 
  res.set_ascii(STRING_WITH_LEN("datetime"));
317
 
}
318