~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/date.cc

  • Committer: Brian Aker
  • Date: 2009-05-21 19:15:01 UTC
  • mfrom: (991.1.12 for-brian)
  • Revision ID: brian@gaz-20090521191501-u5qe56byfubioj1r
Merge Stewart

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
21
 
#include "config.h"
22
 
#include <boost/lexical_cast.hpp>
23
 
 
 
21
#include "drizzled/server_includes.h"
24
22
#include "drizzled/field/date.h"
25
23
#include "drizzled/error.h"
26
24
#include "drizzled/table.h"
27
25
#include "drizzled/temporal.h"
28
26
#include "drizzled/session.h"
29
 
#include "drizzled/time_functions.h"
30
 
 
31
 
#include <math.h>
32
27
 
33
28
#include <sstream>
34
29
#include <string>
35
30
 
36
 
namespace drizzled
37
 
{
38
 
 
39
31
 
40
32
/****************************************************************************
41
33
** Drizzle date type stored in 3 bytes
64
56
                         uint32_t len,
65
57
                         const CHARSET_INFO * const )
66
58
{
 
59
#ifdef NOTDEFINED
 
60
  long tmp;
 
61
  DRIZZLE_TIME l_time;
 
62
  int error;
 
63
  Session *session= table ? table->in_use : current_session;
 
64
  enum enum_drizzle_timestamp_type ret;
 
65
  if ((ret= str_to_datetime(from, len, &l_time,
 
66
                            (TIME_FUZZY_DATE |
 
67
                             (session->variables.sql_mode &
 
68
                              (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
 
69
                            &error)) <= DRIZZLE_TIMESTAMP_ERROR)
 
70
  {
 
71
    tmp= 0;
 
72
    error= 2;
 
73
  }
 
74
  else
 
75
  {
 
76
    tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
 
77
    if (!error && (ret != DRIZZLE_TIMESTAMP_DATE) &&
 
78
        (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
 
79
      error= 3;                                 // Datetime was cut (note)
 
80
  }
 
81
 
 
82
  if (error)
 
83
    set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
 
84
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
85
                         ER_WARN_DATA_TRUNCATED,
 
86
                         from, len, DRIZZLE_TIMESTAMP_DATE, 1);
 
87
 
 
88
  int3store(ptr, tmp);
 
89
#endif /* NOTDEFINED */
67
90
  /* 
68
91
   * Try to create a DateTime from the supplied string.  Throw an error
69
92
   * if unable to create a valid DateTime.  A DateTime is used so that
70
93
   * automatic conversion from the higher-storage DateTime can be used
71
94
   * and matches on datetime format strings can occur.
72
95
   */
73
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
74
 
  DateTime temporal;
 
96
  drizzled::DateTime temporal;
75
97
  if (! temporal.from_string(from, (size_t) len))
76
98
  {
77
99
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
78
100
    return 2;
79
101
  }
80
102
  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
81
 
  uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
82
 
  int4store(ptr, int_value);
 
103
  uint32_t int_value= (temporal.years() * 16 * 32) + (temporal.months() * 32) + temporal.days();
 
104
  int3store(ptr, int_value);
83
105
  return 0;
84
106
}
85
107
 
86
108
int Field_date::store(double from)
87
109
{
88
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
89
110
  if (from < 0.0 || from > 99991231235959.0)
90
111
  {
91
112
    /* Convert the double to a string using stringstream */
106
127
   * Try to create a DateTime from the supplied integer.  Throw an error
107
128
   * if unable to create a valid DateTime.  
108
129
   */
109
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
110
 
  DateTime temporal;
 
130
  drizzled::DateTime temporal;
111
131
  if (! temporal.from_int64_t(from))
112
132
  {
113
 
    /* Convert the integer to a string using boost::lexical_cast */
114
 
    std::string tmp(boost::lexical_cast<std::string>(from)); 
 
133
    /* Convert the integer to a string using stringstream */
 
134
    std::stringstream ss;
 
135
    std::string tmp;
 
136
    ss << from; ss >> tmp;
115
137
 
116
138
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
117
139
    return 2;
118
140
  }
119
141
 
120
142
  /* 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);
 
143
  uint32_t int_value= (temporal.years() * 16 * 32) + (temporal.months() * 32) + temporal.days();
 
144
  int3store(ptr, int_value);
123
145
  return 0;
124
146
}
125
147
 
131
153
  if (time_type == DRIZZLE_TIMESTAMP_DATE ||
132
154
      time_type == DRIZZLE_TIMESTAMP_DATETIME)
133
155
  {
134
 
    tmp= ltime->year*10000 + ltime->month*100 + ltime->day;
 
156
    tmp=ltime->year*16*32+ltime->month*32+ltime->day;
135
157
    if (check_date(ltime, tmp != 0,
136
158
                   (TIME_FUZZY_DATE |
137
159
                    (current_session->variables.sql_mode &
161
183
    error= 1;
162
184
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
163
185
  }
164
 
  int4store(ptr,tmp);
 
186
  int3store(ptr,tmp);
165
187
  return error;
166
188
}
167
189
 
172
194
 
173
195
int64_t Field_date::val_int(void)
174
196
{
175
 
  uint32_t j;
176
 
 
177
 
  ASSERT_COLUMN_MARKED_FOR_READ;
178
 
 
179
 
  j= uint4korr(ptr);
180
 
 
 
197
  uint32_t j= uint3korr(ptr);
 
198
  j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
181
199
  return (int64_t) j;
182
200
}
183
201
 
184
 
String *Field_date::val_str(String *val_buffer, String *)
 
202
String *Field_date::val_str(String *val_buffer,
 
203
                               String *)
185
204
{
186
205
  val_buffer->alloc(field_length);
187
206
  val_buffer->length(field_length);
188
 
  uint32_t tmp=(uint32_t) uint4korr(ptr);
189
 
  int32_t part;
 
207
  uint32_t tmp=(uint32_t) uint3korr(ptr);
 
208
  int part;
190
209
  char *pos=(char*) val_buffer->ptr()+10;
191
210
 
192
 
  ASSERT_COLUMN_MARKED_FOR_READ;
193
 
 
194
211
  /* Open coded to get more speed */
195
212
  *pos--=0;                                     // End NULL
196
 
  part=(int32_t) (tmp % 100);
197
 
  *pos--= (char) ('0'+part%10);
198
 
  *pos--= (char) ('0'+part/10);
199
 
  *pos--= '-';
200
 
  part=(int32_t) (tmp/100%100);
201
 
  *pos--= (char) ('0'+part%10);
202
 
  *pos--= (char) ('0'+part/10);
203
 
  *pos--= '-';
204
 
  part=(int32_t) (tmp/10000);
 
213
  part=(int) (tmp & 31);
 
214
  *pos--= (char) ('0'+part%10);
 
215
  *pos--= (char) ('0'+part/10);
 
216
  *pos--= '-';
 
217
  part=(int) (tmp >> 5 & 15);
 
218
  *pos--= (char) ('0'+part%10);
 
219
  *pos--= (char) ('0'+part/10);
 
220
  *pos--= '-';
 
221
  part=(int) (tmp >> 9);
205
222
  *pos--= (char) ('0'+part%10); part/=10;
206
223
  *pos--= (char) ('0'+part%10); part/=10;
207
224
  *pos--= (char) ('0'+part%10); part/=10;
211
228
 
212
229
bool Field_date::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
213
230
{
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);
 
231
  uint32_t tmp=(uint32_t) uint3korr(ptr);
 
232
  ltime->day=   tmp & 31;
 
233
  ltime->month= (tmp >> 5) & 15;
 
234
  ltime->year=  (tmp >> 9);
218
235
  ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
219
236
  ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
220
237
  return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
229
246
int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
230
247
{
231
248
  uint32_t a,b;
232
 
  a=(uint32_t) uint4korr(a_ptr);
233
 
  b=(uint32_t) uint4korr(b_ptr);
 
249
  a=(uint32_t) uint3korr(a_ptr);
 
250
  b=(uint32_t) uint3korr(b_ptr);
234
251
  return (a < b) ? -1 : (a > b) ? 1 : 0;
235
252
}
236
253
 
237
254
void Field_date::sort_string(unsigned char *to,uint32_t )
238
255
{
239
 
  to[0] = ptr[3];
240
 
  to[1] = ptr[2];
241
 
  to[2] = ptr[1];
242
 
  to[3] = ptr[0];
 
256
  to[0] = ptr[2];
 
257
  to[1] = ptr[1];
 
258
  to[2] = ptr[0];
243
259
}
244
260
 
245
261
void Field_date::sql_type(String &res) const
246
262
{
247
263
  res.set_ascii(STRING_WITH_LEN("date"));
248
264
}
249
 
 
250
 
} /* namespace drizzled */