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/date.h"
23
#include "drizzled/error.h"
24
#include "drizzled/table.h"
25
#include "drizzled/temporal.h"
26
#include "drizzled/session.h"
27
#include "drizzled/time_functions.h"
38
/****************************************************************************
39
** Drizzle date type stored in 3 bytes
40
** In number context: YYYYMMDD
41
****************************************************************************/
44
Store string into a date field
49
len Length of date field
50
cs Character set (not used)
54
1 Value was cut during conversion
56
3 Datetime value that was cut (warning level NOTE)
57
This is used by opt_range.cc:get_mm_leaf(). Note that there is a
58
nearly-identical class Field_date doesn't ever return 3 from its
61
int Field_date::store(const char *from,
63
const CHARSET_INFO * const )
66
* Try to create a DateTime from the supplied string. Throw an error
67
* if unable to create a valid DateTime. A DateTime is used so that
68
* automatic conversion from the higher-storage DateTime can be used
69
* and matches on datetime format strings can occur.
71
ASSERT_COLUMN_MARKED_FOR_WRITE;
73
if (! temporal.from_string(from, (size_t) len))
75
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
78
/* Create the stored integer format. @TODO This should go away. Should be up to engine... */
79
uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
80
int4store(ptr, int_value);
84
int Field_date::store(double from)
86
ASSERT_COLUMN_MARKED_FOR_WRITE;
87
if (from < 0.0 || from > 99991231235959.0)
89
/* Convert the double to a string using stringstream */
92
ss.precision(18); /* 18 places should be fine for error display of double input. */
93
ss << from; ss >> tmp;
95
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
98
return Field_date::store((int64_t) rint(from), false);
101
int Field_date::store(int64_t from, bool)
104
* Try to create a DateTime from the supplied integer. Throw an error
105
* if unable to create a valid DateTime.
107
ASSERT_COLUMN_MARKED_FOR_WRITE;
109
if (! temporal.from_int64_t(from))
111
/* Convert the integer to a string using stringstream */
112
std::stringstream ss;
114
ss << from; ss >> tmp;
116
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
120
/* Create the stored integer format. @TODO This should go away. Should be up to engine... */
121
uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
122
int4store(ptr, int_value);
126
int Field_date::store_time(DRIZZLE_TIME *ltime,
127
enum enum_drizzle_timestamp_type time_type)
131
if (time_type == DRIZZLE_TIMESTAMP_DATE ||
132
time_type == DRIZZLE_TIMESTAMP_DATETIME)
134
tmp= ltime->year*10000 + ltime->month*100 + ltime->day;
135
if (check_date(ltime, tmp != 0,
137
(current_session->variables.sql_mode &
138
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
140
char buff[MAX_DATE_STRING_REP_LENGTH];
141
String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
142
make_date(ltime, &str);
143
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
144
str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
146
if (!error && ltime->time_type != DRIZZLE_TIMESTAMP_DATE &&
147
(ltime->hour || ltime->minute || ltime->second || ltime->second_part))
149
char buff[MAX_DATE_STRING_REP_LENGTH];
150
String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
151
make_datetime(ltime, &str);
152
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
153
ER_WARN_DATA_TRUNCATED,
154
str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
162
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
168
double Field_date::val_real(void)
170
return (double) Field_date::val_int();
173
int64_t Field_date::val_int(void)
177
ASSERT_COLUMN_MARKED_FOR_READ;
184
String *Field_date::val_str(String *val_buffer, String *)
186
val_buffer->alloc(field_length);
187
val_buffer->length(field_length);
188
uint32_t tmp=(uint32_t) uint4korr(ptr);
190
char *pos=(char*) val_buffer->ptr()+10;
192
ASSERT_COLUMN_MARKED_FOR_READ;
194
/* Open coded to get more speed */
195
*pos--=0; // End NULL
196
part=(int32_t) (tmp % 100);
197
*pos--= (char) ('0'+part%10);
198
*pos--= (char) ('0'+part/10);
200
part=(int32_t) (tmp/100%100);
201
*pos--= (char) ('0'+part%10);
202
*pos--= (char) ('0'+part/10);
204
part=(int32_t) (tmp/10000);
205
*pos--= (char) ('0'+part%10); part/=10;
206
*pos--= (char) ('0'+part%10); part/=10;
207
*pos--= (char) ('0'+part%10); part/=10;
208
*pos= (char) ('0'+part);
212
bool Field_date::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
214
uint32_t tmp=(uint32_t) uint4korr(ptr);
215
ltime->day= (int) (tmp%100);
216
ltime->month= (int) (tmp/100%100);
217
ltime->year= (int) (tmp/10000);
218
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
219
ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
220
return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
224
bool Field_date::get_time(DRIZZLE_TIME *ltime)
226
return Field_date::get_date(ltime,0);
229
int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
232
a=(uint32_t) uint4korr(a_ptr);
233
b=(uint32_t) uint4korr(b_ptr);
234
return (a < b) ? -1 : (a > b) ? 1 : 0;
237
void Field_date::sort_string(unsigned char *to,uint32_t )
245
void Field_date::sql_type(String &res) const
247
res.set_ascii(STRING_WITH_LEN("date"));
250
} /* namespace drizzled */