~drizzle-trunk/drizzle/development

466 by Monty Taylor
Fixed modelines... these files are c++.
1
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
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
873.1.2 by Jay Pipes
Fixed Field_datetime to never accept any bad datetimes as a string. This broke
21
#include "drizzled/server_includes.h"
22
#include "drizzled/field/datetime.h"
23
#include "drizzled/error.h"
24
#include "drizzled/table.h"
25
#include "drizzled/temporal.h"
26
#include "drizzled/session.h"
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
27
1241.9.1 by Monty Taylor
Removed global.h. Fixed all the headers.
28
#include <math.h>
29
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
30
#include <sstream>
31
#include <string>
32
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
33
34
/****************************************************************************
35
** datetime type
36
** In string context: YYYY-MM-DD HH:MM:DD
37
** In number context: YYYYMMDDHHMMDD
38
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
39
****************************************************************************/
40
41
int Field_datetime::store(const char *from,
482 by Brian Aker
Remove uint.
42
                          uint32_t len,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
43
                          const CHARSET_INFO * const )
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
44
{
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
45
  ASSERT_COLUMN_MARKED_FOR_WRITE;
873.1.2 by Jay Pipes
Fixed Field_datetime to never accept any bad datetimes as a string. This broke
46
  /* 
47
   * Try to create a DateTime from the supplied string.  Throw an error
48
   * if unable to create a valid DateTime.  
49
   */
50
  drizzled::DateTime temporal;
51
  if (! temporal.from_string(from, (size_t) len))
52
  {
53
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
54
    return 2;
55
  }
56
  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
57
  int64_t int_value;
58
  temporal.to_int64_t(&int_value);
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
59
60
#ifdef WORDS_BIGENDIAN
61
  if (table && table->s->db_low_byte_first)
62
  {
63
    int8store(ptr, int_value);
64
  }
65
  else
66
#endif
67
    int64_tstore(ptr, int_value);
68
  return 0;
69
}
70
71
int Field_datetime::store(double from)
72
{
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
73
  ASSERT_COLUMN_MARKED_FOR_WRITE;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
74
  if (from < 0.0 || from > 99991231235959.0)
75
  {
76
    /* Convert the double to a string using stringstream */
77
    std::stringstream ss;
78
    std::string tmp;
79
    ss.precision(18); /* 18 places should be fine for error display of double input. */
80
    ss << from; ss >> tmp;
81
82
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
83
    return 2;
84
  }
85
  return Field_datetime::store((int64_t) rint(from), false);
86
}
87
88
int Field_datetime::store(int64_t from, bool)
89
{
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
90
  ASSERT_COLUMN_MARKED_FOR_WRITE;
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
91
  /* 
873.1.8 by Jay Pipes
Fixes Arg_comparator::can_compare_as_dates to never, ever allow bad
92
   * Try to create a DateTime from the supplied integer.  Throw an error
873.1.7 by Jay Pipes
Fixes Field_datetime::store(NUMBER) to throw an error when invalid
93
   * if unable to create a valid DateTime.  
94
   */
95
  drizzled::DateTime temporal;
96
  if (! temporal.from_int64_t(from))
97
  {
98
    /* Convert the integer to a string using stringstream */
99
    std::stringstream ss;
100
    std::string tmp;
101
    ss << from; ss >> tmp;
102
103
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
104
    return 2;
105
  }
106
107
  /* 
108
   * Because "from" may be a silly MySQL-like "datetime number" (like, oh, 101)
109
   * we must here get the value of the DateTime as its *real* int64_t, after
110
   * the conversion above has been done...yuck. God, save us.
111
   */
112
  int64_t int_value;
113
  temporal.to_int64_t(&int_value);
114
115
#ifdef WORDS_BIGENDIAN
116
  if (table && table->s->db_low_byte_first)
117
  {
118
    int8store(ptr, int_value);
119
  }
120
  else
121
#endif
122
    int64_tstore(ptr, int_value);
123
  return 0;
124
}
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
125
907.1.7 by Jay Pipes
Merged in remove-timezone work
126
int Field_datetime::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
127
{
907.1.7 by Jay Pipes
Merged in remove-timezone work
128
  drizzled::DateTime temporal;
129
130
  temporal.set_years(ltime->year);
131
  temporal.set_months(ltime->month);
132
  temporal.set_days(ltime->day);
133
  temporal.set_hours(ltime->hour);
134
  temporal.set_minutes(ltime->minute);
135
  temporal.set_seconds(ltime->second);
136
137
  if (! temporal.is_valid())
138
  {
139
    char tmp_string[MAX_DATE_STRING_REP_LENGTH];
140
    size_t tmp_string_len;
141
1079.3.1 by Stewart Smith
Change temporal to_string routines to use snprintf instead of sprintf.
142
    tmp_string_len= temporal.to_string(tmp_string, MAX_DATE_STRING_REP_LENGTH);
143
    assert(tmp_string_len < MAX_DATE_STRING_REP_LENGTH);
907.1.7 by Jay Pipes
Merged in remove-timezone work
144
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp_string);
145
    return 1;
146
  }
147
148
  int64_t int_value;
149
  temporal.to_int64_t(&int_value);
150
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
151
#ifdef WORDS_BIGENDIAN
152
  if (table && table->s->db_low_byte_first)
153
  {
907.1.7 by Jay Pipes
Merged in remove-timezone work
154
    int8store(ptr, int_value);
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
155
  }
156
  else
157
#endif
907.1.7 by Jay Pipes
Merged in remove-timezone work
158
    int64_tstore(ptr, int_value);
159
  return 0;
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
160
}
161
162
double Field_datetime::val_real(void)
163
{
164
  return (double) Field_datetime::val_int();
165
}
166
167
int64_t Field_datetime::val_int(void)
168
{
169
  int64_t j;
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
170
171
  ASSERT_COLUMN_MARKED_FOR_READ;
172
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
173
#ifdef WORDS_BIGENDIAN
174
  if (table && table->s->db_low_byte_first)
175
    j=sint8korr(ptr);
176
  else
177
#endif
178
    int64_tget(j,ptr);
179
  return j;
180
}
181
182
183
String *Field_datetime::val_str(String *val_buffer,
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
184
				String *)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
185
{
1079.3.2 by Stewart Smith
Replace MAX_(DATE|TIME).*_WIDTH defines in definitions.h with real (and correct) static const members to Temporal types.
186
  val_buffer->alloc(drizzled::DateTime::MAX_STRING_LENGTH);
187
  val_buffer->length(drizzled::DateTime::MAX_STRING_LENGTH);
188
  int64_t tmp;
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
189
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
190
  ASSERT_COLUMN_MARKED_FOR_READ;
191
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
192
#ifdef WORDS_BIGENDIAN
193
  if (table && table->s->db_low_byte_first)
194
    tmp=sint8korr(ptr);
195
  else
196
#endif
197
    int64_tget(tmp,ptr);
198
1079.3.2 by Stewart Smith
Replace MAX_(DATE|TIME).*_WIDTH defines in definitions.h with real (and correct) static const members to Temporal types.
199
  drizzled::DateTime dt;
200
201
  /* TODO: add an assert that this succeeds
202
   * currently fails due to bug in allowing
203
   * ALTER TABLE to add a datetime column that's
204
   * not null without a default value.
205
   */
206
  dt.from_int64_t(tmp, false); /* NOTE: this does *NOT* attempt convertion
207
				        from formats such as 20090101 as
208
					the stored value has already been
209
					converted.
210
			       */
211
212
  int rlen;
213
  rlen= dt.to_string((char*)val_buffer->ptr(), drizzled::DateTime::MAX_STRING_LENGTH);
214
  assert((rlen+1) <  drizzled::DateTime::MAX_STRING_LENGTH);
215
216
  val_buffer->length(rlen);
217
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
218
  return val_buffer;
219
}
220
482 by Brian Aker
Remove uint.
221
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
222
{
223
  int64_t tmp=Field_datetime::val_int();
205 by Brian Aker
uint32 -> uin32_t
224
  uint32_t part1,part2;
422 by Monty
Various int64 constant fixes.
225
  part1=(uint32_t) (tmp/INT64_C(1000000));
226
  part2=(uint32_t) (tmp - (uint64_t) part1*INT64_C(1000000));
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
227
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
228
  ltime->time_type=	DRIZZLE_TIMESTAMP_DATETIME;
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
229
  ltime->neg=		0;
230
  ltime->second_part=	0;
231
  ltime->second=	(int) (part2%100);
232
  ltime->minute=	(int) (part2/100%100);
233
  ltime->hour=		(int) (part2/10000);
234
  ltime->day=		(int) (part1%100);
235
  ltime->month= 	(int) (part1/100%100);
236
  ltime->year= 		(int) (part1/10000);
237
  return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
238
}
239
236.1.24 by Monty Taylor
Renamed MYSQL_TIME to DRIZZLE_TIME.
240
bool Field_datetime::get_time(DRIZZLE_TIME *ltime)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
241
{
242
  return Field_datetime::get_date(ltime,0);
243
}
244
481 by Brian Aker
Remove all of uchar.
245
int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
246
{
247
  int64_t a,b;
248
#ifdef WORDS_BIGENDIAN
249
  if (table && table->s->db_low_byte_first)
250
  {
251
    a=sint8korr(a_ptr);
252
    b=sint8korr(b_ptr);
253
  }
254
  else
255
#endif
256
  {
257
    int64_tget(a,a_ptr);
258
    int64_tget(b,b_ptr);
259
  }
260
  return ((uint64_t) a < (uint64_t) b) ? -1 :
261
    ((uint64_t) a > (uint64_t) b) ? 1 : 0;
262
}
263
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
264
void Field_datetime::sort_string(unsigned char *to,uint32_t )
173.1.3 by Toru Maesaka
ripped out datetime and moved to field/
265
{
266
#ifdef WORDS_BIGENDIAN
267
  if (!table || !table->s->db_low_byte_first)
268
  {
269
    to[0] = ptr[0];
270
    to[1] = ptr[1];
271
    to[2] = ptr[2];
272
    to[3] = ptr[3];
273
    to[4] = ptr[4];
274
    to[5] = ptr[5];
275
    to[6] = ptr[6];
276
    to[7] = ptr[7];
277
  }
278
  else
279
#endif
280
  {
281
    to[0] = ptr[7];
282
    to[1] = ptr[6];
283
    to[2] = ptr[5];
284
    to[3] = ptr[4];
285
    to[4] = ptr[3];
286
    to[5] = ptr[2];
287
    to[6] = ptr[1];
288
    to[7] = ptr[0];
289
  }
290
}
291
292
293
void Field_datetime::sql_type(String &res) const
294
{
295
  res.set_ascii(STRING_WITH_LEN("datetime"));
296
}
297