~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/date.cc

  • Committer: Monty Taylor
  • Date: 2008-07-02 14:35:48 UTC
  • mto: This revision was merged to the branch mainline in revision 51.
  • Revision ID: monty@inaugust.com-20080702143548-onj30ry0sugr01uw
Removed all references to THREAD.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 MySQL
5
 
 *
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.
10
 
 *
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.
15
 
 *
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
19
 
 */
20
 
 
21
 
 
22
 
#include <drizzled/server_includes.h>
23
 
#include <drizzled/field/date.h>
24
 
 
25
 
/****************************************************************************
26
 
** The new date type
27
 
** This is identical to the old date type, but stored on 3 bytes instead of 4
28
 
** In number context: YYYYMMDD
29
 
****************************************************************************/
30
 
 
31
 
/*
32
 
  Store string into a date field
33
 
 
34
 
  SYNOPSIS
35
 
    Field_newdate::store()
36
 
    from                Date string
37
 
    len                 Length of date field
38
 
    cs                  Character set (not used)
39
 
 
40
 
  RETURN
41
 
    0  ok
42
 
    1  Value was cut during conversion
43
 
    2  Wrong date string
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
47
 
       store function.
48
 
*/
49
 
 
50
 
int Field_newdate::store(const char *from,
51
 
                         uint32_t len,
52
 
                         const CHARSET_INFO * const cs __attribute__((unused)))
53
 
{
54
 
  long tmp;
55
 
  DRIZZLE_TIME l_time;
56
 
  int error;
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,
60
 
                            (TIME_FUZZY_DATE |
61
 
                             (thd->variables.sql_mode &
62
 
                              (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
63
 
                            &error)) <= DRIZZLE_TIMESTAMP_ERROR)
64
 
  {
65
 
    tmp= 0;
66
 
    error= 2;
67
 
  }
68
 
  else
69
 
  {
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)
74
 
  }
75
 
 
76
 
  if (error)
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);
81
 
 
82
 
  int3store(ptr, tmp);
83
 
  return error;
84
 
}
85
 
 
86
 
 
87
 
int Field_newdate::store(double nr)
88
 
{
89
 
  if (nr < 0.0 || nr > 99991231235959.0)
90
 
  {
91
 
    int3store(ptr,(int32_t) 0);
92
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
93
 
                         ER_WARN_DATA_TRUNCATED, nr, DRIZZLE_TIMESTAMP_DATE);
94
 
    return 1;
95
 
  }
96
 
  return Field_newdate::store((int64_t) rint(nr), false);
97
 
}
98
 
 
99
 
 
100
 
int Field_newdate::store(int64_t nr,
101
 
                         bool unsigned_val __attribute__((unused)))
102
 
{
103
 
  DRIZZLE_TIME l_time;
104
 
  int64_t tmp;
105
 
  int error;
106
 
  THD *thd= table ? table->in_use : current_thd;
107
 
  if (number_to_datetime(nr, &l_time,
108
 
                         (TIME_FUZZY_DATE |
109
 
                          (thd->variables.sql_mode &
110
 
                           (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
111
 
                         &error) == INT64_C(-1))
112
 
  {
113
 
    tmp= 0L;
114
 
    error= 2;
115
 
  }
116
 
  else
117
 
    tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
118
 
 
119
 
  if (!error && l_time.time_type != DRIZZLE_TIMESTAMP_DATE &&
120
 
      (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
121
 
    error= 3;
122
 
 
123
 
  if (error)
124
 
    set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
125
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
126
 
                         error == 2 ? 
127
 
                         ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED,
128
 
                         nr,DRIZZLE_TIMESTAMP_DATE, 1);
129
 
 
130
 
  int3store(ptr,tmp);
131
 
  return error;
132
 
}
133
 
 
134
 
 
135
 
int Field_newdate::store_time(DRIZZLE_TIME *ltime,
136
 
                              enum enum_drizzle_timestamp_type time_type)
137
 
{
138
 
  long tmp;
139
 
  int error= 0;
140
 
  if (time_type == DRIZZLE_TIMESTAMP_DATE ||
141
 
      time_type == DRIZZLE_TIMESTAMP_DATETIME)
142
 
  {
143
 
    tmp=ltime->year*16*32+ltime->month*32+ltime->day;
144
 
    if (check_date(ltime, tmp != 0,
145
 
                   (TIME_FUZZY_DATE |
146
 
                    (current_thd->variables.sql_mode &
147
 
                     (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
148
 
    {
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);
154
 
    }
155
 
    if (!error && ltime->time_type != DRIZZLE_TIMESTAMP_DATE &&
156
 
        (ltime->hour || ltime->minute || ltime->second || ltime->second_part))
157
 
    {
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);
164
 
      error= 3;
165
 
    }
166
 
  }
167
 
  else
168
 
  {
169
 
    tmp=0;
170
 
    error= 1;
171
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
172
 
  }
173
 
  int3store(ptr,tmp);
174
 
  return error;
175
 
}
176
 
 
177
 
 
178
 
bool Field_newdate::send_binary(Protocol *protocol)
179
 
{
180
 
  DRIZZLE_TIME tm;
181
 
  Field_newdate::get_date(&tm,0);
182
 
  return protocol->store_date(&tm);
183
 
}
184
 
 
185
 
 
186
 
double Field_newdate::val_real(void)
187
 
{
188
 
  return (double) Field_newdate::val_int();
189
 
}
190
 
 
191
 
 
192
 
int64_t Field_newdate::val_int(void)
193
 
{
194
 
  uint32_t j= uint3korr(ptr);
195
 
  j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
196
 
  return (int64_t) j;
197
 
}
198
 
 
199
 
 
200
 
String *Field_newdate::val_str(String *val_buffer,
201
 
                               String *val_ptr __attribute__((unused)))
202
 
{
203
 
  val_buffer->alloc(field_length);
204
 
  val_buffer->length(field_length);
205
 
  uint32_t tmp=(uint32_t) uint3korr(ptr);
206
 
  int part;
207
 
  char *pos=(char*) val_buffer->ptr()+10;
208
 
 
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);
214
 
  *pos--= '-';
215
 
  part=(int) (tmp >> 5 & 15);
216
 
  *pos--= (char) ('0'+part%10);
217
 
  *pos--= (char) ('0'+part/10);
218
 
  *pos--= '-';
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);
224
 
  return val_buffer;
225
 
}
226
 
 
227
 
 
228
 
bool Field_newdate::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
229
 
{
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)) ?
237
 
          1 : 0);
238
 
}
239
 
 
240
 
 
241
 
bool Field_newdate::get_time(DRIZZLE_TIME *ltime)
242
 
{
243
 
  return Field_newdate::get_date(ltime,0);
244
 
}
245
 
 
246
 
 
247
 
int Field_newdate::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
248
 
{
249
 
  uint32_t a,b;
250
 
  a=(uint32_t) uint3korr(a_ptr);
251
 
  b=(uint32_t) uint3korr(b_ptr);
252
 
  return (a < b) ? -1 : (a > b) ? 1 : 0;
253
 
}
254
 
 
255
 
 
256
 
void Field_newdate::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
257
 
{
258
 
  to[0] = ptr[2];
259
 
  to[1] = ptr[1];
260
 
  to[2] = ptr[0];
261
 
}
262
 
 
263
 
 
264
 
void Field_newdate::sql_type(String &res) const
265
 
{
266
 
  res.set_ascii(STRING_WITH_LEN("date"));
267
 
}
268