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/server_includes.h>
23
#include <drizzled/field/date.h>
25
/****************************************************************************
27
** This is identical to the old date type, but stored on 3 bytes instead of 4
28
** In number context: YYYYMMDD
29
****************************************************************************/
32
Store string into a date field
35
Field_newdate::store()
37
len Length of date field
38
cs Character set (not used)
42
1 Value was cut during conversion
44
3 Datetime value that was cut (warning level NOTE)
45
This is used by opt_range.cc:get_mm_leaf(). Note that there is a
46
nearly-identical class Field_date doesn't ever return 3 from its
50
int Field_newdate::store(const char *from,
52
const CHARSET_INFO * const cs __attribute__((unused)))
57
THD *thd= table ? table->in_use : current_thd;
58
enum enum_drizzle_timestamp_type ret;
59
if ((ret= str_to_datetime(from, len, &l_time,
61
(thd->variables.sql_mode &
62
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
63
&error)) <= DRIZZLE_TIMESTAMP_ERROR)
70
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
71
if (!error && (ret != DRIZZLE_TIMESTAMP_DATE) &&
72
(l_time.hour || l_time.minute || l_time.second || l_time.second_part))
73
error= 3; // Datetime was cut (note)
77
set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
78
DRIZZLE_ERROR::WARN_LEVEL_WARN,
79
ER_WARN_DATA_TRUNCATED,
80
from, len, DRIZZLE_TIMESTAMP_DATE, 1);
87
int Field_newdate::store(double nr)
89
if (nr < 0.0 || nr > 99991231235959.0)
91
int3store(ptr,(int32_t) 0);
92
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
93
ER_WARN_DATA_TRUNCATED, nr, DRIZZLE_TIMESTAMP_DATE);
96
return Field_newdate::store((int64_t) rint(nr), false);
100
int Field_newdate::store(int64_t nr,
101
bool unsigned_val __attribute__((unused)))
106
THD *thd= table ? table->in_use : current_thd;
107
if (number_to_datetime(nr, &l_time,
109
(thd->variables.sql_mode &
110
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
111
&error) == INT64_C(-1))
117
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
119
if (!error && l_time.time_type != DRIZZLE_TIMESTAMP_DATE &&
120
(l_time.hour || l_time.minute || l_time.second || l_time.second_part))
124
set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
125
DRIZZLE_ERROR::WARN_LEVEL_WARN,
127
ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED,
128
nr,DRIZZLE_TIMESTAMP_DATE, 1);
135
int Field_newdate::store_time(DRIZZLE_TIME *ltime,
136
enum enum_drizzle_timestamp_type time_type)
140
if (time_type == DRIZZLE_TIMESTAMP_DATE ||
141
time_type == DRIZZLE_TIMESTAMP_DATETIME)
143
tmp=ltime->year*16*32+ltime->month*32+ltime->day;
144
if (check_date(ltime, tmp != 0,
146
(current_thd->variables.sql_mode &
147
(MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
149
char buff[MAX_DATE_STRING_REP_LENGTH];
150
String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
151
make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
152
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
153
str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
155
if (!error && ltime->time_type != DRIZZLE_TIMESTAMP_DATE &&
156
(ltime->hour || ltime->minute || ltime->second || ltime->second_part))
158
char buff[MAX_DATE_STRING_REP_LENGTH];
159
String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
160
make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
161
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
162
ER_WARN_DATA_TRUNCATED,
163
str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
171
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
178
bool Field_newdate::send_binary(Protocol *protocol)
181
Field_newdate::get_date(&tm,0);
182
return protocol->store_date(&tm);
186
double Field_newdate::val_real(void)
188
return (double) Field_newdate::val_int();
192
int64_t Field_newdate::val_int(void)
194
uint32_t j= uint3korr(ptr);
195
j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
200
String *Field_newdate::val_str(String *val_buffer,
201
String *val_ptr __attribute__((unused)))
203
val_buffer->alloc(field_length);
204
val_buffer->length(field_length);
205
uint32_t tmp=(uint32_t) uint3korr(ptr);
207
char *pos=(char*) val_buffer->ptr()+10;
209
/* Open coded to get more speed */
210
*pos--=0; // End NULL
211
part=(int) (tmp & 31);
212
*pos--= (char) ('0'+part%10);
213
*pos--= (char) ('0'+part/10);
215
part=(int) (tmp >> 5 & 15);
216
*pos--= (char) ('0'+part%10);
217
*pos--= (char) ('0'+part/10);
219
part=(int) (tmp >> 9);
220
*pos--= (char) ('0'+part%10); part/=10;
221
*pos--= (char) ('0'+part%10); part/=10;
222
*pos--= (char) ('0'+part%10); part/=10;
223
*pos= (char) ('0'+part);
228
bool Field_newdate::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
230
uint32_t tmp=(uint32_t) uint3korr(ptr);
231
ltime->day= tmp & 31;
232
ltime->month= (tmp >> 5) & 15;
233
ltime->year= (tmp >> 9);
234
ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
235
ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
236
return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
241
bool Field_newdate::get_time(DRIZZLE_TIME *ltime)
243
return Field_newdate::get_date(ltime,0);
247
int Field_newdate::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
250
a=(uint32_t) uint3korr(a_ptr);
251
b=(uint32_t) uint3korr(b_ptr);
252
return (a < b) ? -1 : (a > b) ? 1 : 0;
256
void Field_newdate::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
264
void Field_newdate::sql_type(String &res) const
266
res.set_ascii(STRING_WITH_LEN("date"));