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
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"
37
/****************************************************************************
39
** In string context: YYYY-MM-DD HH:MM:DD
40
** In number context: YYYYMMDDHHMMDD
41
****************************************************************************/
43
int Field_datetime::store(const char *from,
45
const CHARSET_INFO * const )
47
ASSERT_COLUMN_MARKED_FOR_WRITE;
49
* Try to create a DateTime from the supplied string. Throw an error
50
* if unable to create a valid DateTime.
53
if (! temporal.from_string(from, (size_t) len))
55
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
58
/* Create the stored integer format. @TODO This should go away. Should be up to engine... */
60
temporal.to_int64_t(&int_value);
62
#ifdef WORDS_BIGENDIAN
63
if (getTable() && getTable()->s->db_low_byte_first)
65
int8store(ptr, int_value);
69
int64_tstore(ptr, int_value);
73
int Field_datetime::store(double from)
75
ASSERT_COLUMN_MARKED_FOR_WRITE;
76
if (from < 0.0 || from > 99991231235959.0)
78
/* Convert the double to a string using stringstream */
81
ss.precision(18); /* 18 places should be fine for error display of double input. */
82
ss << from; ss >> tmp;
84
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
87
return Field_datetime::store((int64_t) rint(from), false);
90
int Field_datetime::store(int64_t from, bool)
92
ASSERT_COLUMN_MARKED_FOR_WRITE;
94
* Try to create a DateTime from the supplied integer. Throw an error
95
* if unable to create a valid DateTime.
98
if (! temporal.from_int64_t(from))
100
/* Convert the integer to a string using stringstream */
101
std::stringstream ss;
103
ss << from; ss >> tmp;
105
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
110
* Because "from" may be a silly MySQL-like "datetime number" (like, oh, 101)
111
* we must here get the value of the DateTime as its *real* int64_t, after
112
* the conversion above has been done...yuck. God, save us.
115
temporal.to_int64_t(&int_value);
117
#ifdef WORDS_BIGENDIAN
118
if (getTable() && getTable()->s->db_low_byte_first)
120
int8store(ptr, int_value);
124
int64_tstore(ptr, int_value);
128
int Field_datetime::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
132
temporal.set_years(ltime->year);
133
temporal.set_months(ltime->month);
134
temporal.set_days(ltime->day);
135
temporal.set_hours(ltime->hour);
136
temporal.set_minutes(ltime->minute);
137
temporal.set_seconds(ltime->second);
139
if (! temporal.is_valid())
141
char tmp_string[MAX_DATE_STRING_REP_LENGTH];
142
size_t tmp_string_len;
144
tmp_string_len= temporal.to_string(tmp_string, MAX_DATE_STRING_REP_LENGTH);
145
assert(tmp_string_len < MAX_DATE_STRING_REP_LENGTH);
146
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp_string);
151
temporal.to_int64_t(&int_value);
153
#ifdef WORDS_BIGENDIAN
154
if (getTable() && getTable()->s->db_low_byte_first)
156
int8store(ptr, int_value);
160
int64_tstore(ptr, int_value);
164
double Field_datetime::val_real(void)
166
return (double) Field_datetime::val_int();
169
int64_t Field_datetime::val_int(void)
173
ASSERT_COLUMN_MARKED_FOR_READ;
175
#ifdef WORDS_BIGENDIAN
176
if (getTable() && getTable()->s->db_low_byte_first)
185
String *Field_datetime::val_str(String *val_buffer,
188
val_buffer->alloc(DateTime::MAX_STRING_LENGTH);
189
val_buffer->length(DateTime::MAX_STRING_LENGTH);
192
ASSERT_COLUMN_MARKED_FOR_READ;
194
#ifdef WORDS_BIGENDIAN
195
if (getTable() && getTable()->s->db_low_byte_first)
203
/* TODO: add an assert that this succeeds
204
* currently fails due to bug in allowing
205
* ALTER TABLE to add a datetime column that's
206
* not null without a default value.
208
dt.from_int64_t(tmp, false); /* NOTE: this does *NOT* attempt convertion
209
from formats such as 20090101 as
210
the stored value has already been
215
rlen= dt.to_string((char*)val_buffer->ptr(), DateTime::MAX_STRING_LENGTH);
216
assert((rlen+1) < DateTime::MAX_STRING_LENGTH);
218
val_buffer->length(rlen);
223
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
225
int64_t tmp=Field_datetime::val_int();
226
uint32_t part1,part2;
227
part1=(uint32_t) (tmp/INT64_C(1000000));
228
part2=(uint32_t) (tmp - (uint64_t) part1*INT64_C(1000000));
230
ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
232
ltime->second_part= 0;
233
ltime->second= (int) (part2%100);
234
ltime->minute= (int) (part2/100%100);
235
ltime->hour= (int) (part2/10000);
236
ltime->day= (int) (part1%100);
237
ltime->month= (int) (part1/100%100);
238
ltime->year= (int) (part1/10000);
239
return (!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ? 1 : 0;
242
bool Field_datetime::get_time(DRIZZLE_TIME *ltime)
244
return Field_datetime::get_date(ltime,0);
247
int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
250
#ifdef WORDS_BIGENDIAN
251
if (getTable() && getTable()->s->db_low_byte_first)
262
return ((uint64_t) a < (uint64_t) b) ? -1 :
263
((uint64_t) a > (uint64_t) b) ? 1 : 0;
266
void Field_datetime::sort_string(unsigned char *to,uint32_t )
268
#ifdef WORDS_BIGENDIAN
269
if (!getTable() || !getTable()->s->db_low_byte_first)
295
void Field_datetime::sql_type(String &res) const
297
res.set_ascii(STRING_WITH_LEN("datetime"));
300
} /* namespace drizzled */