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