1
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 MySQL
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.
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.
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
21
#ifdef USE_PRAGMA_IMPLEMENTATION
22
#pragma implementation // gcc: Class implementation
25
#include <drizzled/server_includes.h>
26
#include <drizzled/field/datetime.h>
28
/****************************************************************************
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
****************************************************************************/
35
int Field_datetime::store(const char *from,
37
const CHARSET_INFO * const cs __attribute__((unused)))
39
DRIZZLE_TIME time_tmp;
42
enum enum_drizzle_timestamp_type func_res;
43
THD *thd= table ? table->in_use : current_thd;
45
func_res= str_to_datetime(from, len, &time_tmp,
47
(thd->variables.sql_mode &
48
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
50
if ((int) func_res > (int) DRIZZLE_TIMESTAMP_ERROR)
51
tmp= TIME_to_uint64_t_datetime(&time_tmp);
53
error= 1; // Fix if invalid zero date
56
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
57
ER_WARN_DATA_OUT_OF_RANGE,
58
from, len, DRIZZLE_TIMESTAMP_DATETIME, 1);
60
#ifdef WORDS_BIGENDIAN
61
if (table && table->s->db_low_byte_first)
67
int64_tstore(ptr,tmp);
72
int Field_datetime::store(double nr)
75
if (nr < 0.0 || nr > 99991231235959.0)
77
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
78
ER_WARN_DATA_OUT_OF_RANGE,
79
nr, DRIZZLE_TIMESTAMP_DATETIME);
83
error|= Field_datetime::store((int64_t) rint(nr), false);
88
int Field_datetime::store(int64_t nr,
89
bool unsigned_val __attribute__((unused)))
91
DRIZZLE_TIME not_used;
93
int64_t initial_nr= nr;
94
THD *thd= table ? table->in_use : current_thd;
96
nr= number_to_datetime(nr, ¬_used, (TIME_FUZZY_DATE |
97
(thd->variables.sql_mode &
99
MODE_INVALID_DATES))), &error);
101
if (nr == INT64_C(-1))
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);
113
#ifdef WORDS_BIGENDIAN
114
if (table && table->s->db_low_byte_first)
120
int64_tstore(ptr,nr);
125
int Field_datetime::store_time(DRIZZLE_TIME *ltime,
126
enum enum_drizzle_timestamp_type time_type)
131
We don't perform range checking here since values stored in TIME
132
structure always fit into DATETIME range.
134
if (time_type == DRIZZLE_TIMESTAMP_DATE ||
135
time_type == DRIZZLE_TIMESTAMP_DATETIME)
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,
141
(current_thd->variables.sql_mode &
142
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
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);
155
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
157
#ifdef WORDS_BIGENDIAN
158
if (table && table->s->db_low_byte_first)
164
int64_tstore(ptr,tmp);
168
bool Field_datetime::send_binary(Protocol *protocol)
171
Field_datetime::get_date(&tm, TIME_FUZZY_DATE);
172
return protocol->store(&tm);
176
double Field_datetime::val_real(void)
178
return (double) Field_datetime::val_int();
181
int64_t Field_datetime::val_int(void)
184
#ifdef WORDS_BIGENDIAN
185
if (table && table->s->db_low_byte_first)
194
String *Field_datetime::val_str(String *val_buffer,
195
String *val_ptr __attribute__((unused)))
197
val_buffer->alloc(field_length);
198
val_buffer->length(field_length);
204
#ifdef WORDS_BIGENDIAN
205
if (table && table->s->db_low_byte_first)
212
Avoid problem with slow int64_t arithmetic and sprintf
215
part1=(long) (tmp/INT64_C(1000000));
216
part2=(long) (tmp - (uint64_t) part1*INT64_C(1000000));
218
pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
220
*pos--= (char) ('0'+(char) (part2%10)); part2/=10;
221
*pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
223
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
224
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
226
*pos--= (char) ('0'+(char) (part3%10)); part3/=10;
227
*pos--= (char) ('0'+(char) part3);
229
*pos--= (char) ('0'+(char) (part1%10)); part1/=10;
230
*pos--= (char) ('0'+(char) (part1%10)); part1/=10;
232
*pos--= (char) ('0'+(char) (part1%10)); part1/=10;
233
*pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
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);
242
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
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));
249
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
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;
261
bool Field_datetime::get_time(DRIZZLE_TIME *ltime)
263
return Field_datetime::get_date(ltime,0);
266
int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
269
#ifdef WORDS_BIGENDIAN
270
if (table && table->s->db_low_byte_first)
281
return ((uint64_t) a < (uint64_t) b) ? -1 :
282
((uint64_t) a > (uint64_t) b) ? 1 : 0;
285
void Field_datetime::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
287
#ifdef WORDS_BIGENDIAN
288
if (!table || !table->s->db_low_byte_first)
314
void Field_datetime::sql_type(String &res) const
316
res.set_ascii(STRING_WITH_LEN("datetime"));