18
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/date.h>
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"
28
35
/****************************************************************************
30
** This is identical to the old date type, but stored on 3 bytes instead of 4
36
** Drizzle date type stored in 3 bytes
31
37
** In number context: YYYYMMDD
32
38
****************************************************************************/
49
55
nearly-identical class Field_date doesn't ever return 3 from its
53
int Field_newdate::store(const char *from,
55
const CHARSET_INFO * const cs __attribute__((unused)))
58
int Field_date::store(const char *from,
60
const CHARSET_INFO * const )
58
64
DRIZZLE_TIME l_time;
60
THD *thd= table ? table->in_use : current_thd;
66
Session *session= table ? table->in_use : current_session;
61
67
enum enum_drizzle_timestamp_type ret;
62
68
if ((ret= str_to_datetime(from, len, &l_time,
64
(thd->variables.sql_mode &
65
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
66
MODE_INVALID_DATES))),
70
(session->variables.sql_mode &
71
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
67
72
&error)) <= DRIZZLE_TIMESTAMP_ERROR)
84
89
from, len, DRIZZLE_TIMESTAMP_DATE, 1);
86
91
int3store(ptr, tmp);
91
int Field_newdate::store(double nr)
93
if (nr < 0.0 || nr > 99991231235959.0)
95
int3store(ptr,(int32_t) 0);
96
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
97
ER_WARN_DATA_TRUNCATED, nr, DRIZZLE_TIMESTAMP_DATE);
100
return Field_newdate::store((int64_t) rint(nr), false);
104
int Field_newdate::store(int64_t nr,
105
bool unsigned_val __attribute__((unused)))
110
THD *thd= table ? table->in_use : current_thd;
111
if (number_to_datetime(nr, &l_time,
113
(thd->variables.sql_mode &
114
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
115
MODE_INVALID_DATES))),
122
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
124
if (!error && l_time.time_type != DRIZZLE_TIMESTAMP_DATE &&
125
(l_time.hour || l_time.minute || l_time.second || l_time.second_part))
129
set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
130
DRIZZLE_ERROR::WARN_LEVEL_WARN,
132
ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED,
133
nr,DRIZZLE_TIMESTAMP_DATE, 1);
140
int Field_newdate::store_time(DRIZZLE_TIME *ltime,timestamp_type time_type)
92
#endif /* NOTDEFINED */
94
* Try to create a DateTime from the supplied string. Throw an error
95
* if unable to create a valid DateTime. A DateTime is used so that
96
* automatic conversion from the higher-storage DateTime can be used
97
* and matches on datetime format strings can occur.
99
ASSERT_COLUMN_MARKED_FOR_WRITE;
100
drizzled::DateTime temporal;
101
if (! temporal.from_string(from, (size_t) len))
103
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
106
/* Create the stored integer format. @TODO This should go away. Should be up to engine... */
107
uint32_t int_value= (temporal.years() * 16 * 32) + (temporal.months() * 32) + temporal.days();
108
int3store(ptr, int_value);
112
int Field_date::store(double from)
114
ASSERT_COLUMN_MARKED_FOR_WRITE;
115
if (from < 0.0 || from > 99991231235959.0)
117
/* Convert the double to a string using stringstream */
118
std::stringstream ss;
120
ss.precision(18); /* 18 places should be fine for error display of double input. */
121
ss << from; ss >> tmp;
123
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
126
return Field_date::store((int64_t) rint(from), false);
129
int Field_date::store(int64_t from, bool)
132
* Try to create a DateTime from the supplied integer. Throw an error
133
* if unable to create a valid DateTime.
135
ASSERT_COLUMN_MARKED_FOR_WRITE;
136
drizzled::DateTime temporal;
137
if (! temporal.from_int64_t(from))
139
/* Convert the integer to a string using stringstream */
140
std::stringstream ss;
142
ss << from; ss >> tmp;
144
my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
148
/* Create the stored integer format. @TODO This should go away. Should be up to engine... */
149
uint32_t int_value= (temporal.years() * 16 * 32) + (temporal.months() * 32) + temporal.days();
150
int3store(ptr, int_value);
154
int Field_date::store_time(DRIZZLE_TIME *ltime,
155
enum enum_drizzle_timestamp_type time_type)
147
162
tmp=ltime->year*16*32+ltime->month*32+ltime->day;
148
163
if (check_date(ltime, tmp != 0,
149
164
(TIME_FUZZY_DATE |
150
(current_thd->variables.sql_mode &
151
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
152
MODE_INVALID_DATES))), &error))
165
(current_session->variables.sql_mode &
166
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
154
168
char buff[MAX_DATE_STRING_REP_LENGTH];
155
String str(buff, sizeof(buff), &my_charset_latin1);
156
make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
169
String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
170
make_date(ltime, &str);
157
171
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
158
172
str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
161
175
(ltime->hour || ltime->minute || ltime->second || ltime->second_part))
163
177
char buff[MAX_DATE_STRING_REP_LENGTH];
164
String str(buff, sizeof(buff), &my_charset_latin1);
165
make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
178
String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
179
make_datetime(ltime, &str);
166
180
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
167
181
ER_WARN_DATA_TRUNCATED,
168
182
str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
183
bool Field_newdate::send_binary(Protocol *protocol)
186
Field_newdate::get_date(&tm,0);
187
return protocol->store_date(&tm);
191
double Field_newdate::val_real(void)
193
return (double) Field_newdate::val_int();
197
int64_t Field_newdate::val_int(void)
199
uint32_t j= uint3korr(ptr);
196
double Field_date::val_real(void)
198
return (double) Field_date::val_int();
201
int64_t Field_date::val_int(void)
205
ASSERT_COLUMN_MARKED_FOR_READ;
200
208
j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
201
210
return (int64_t) j;
205
String *Field_newdate::val_str(String *val_buffer,
206
String *val_ptr __attribute__((unused)))
213
String *Field_date::val_str(String *val_buffer,
208
216
val_buffer->alloc(field_length);
209
217
val_buffer->length(field_length);