~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/date.cc

  • Committer: Jay Pipes
  • Date: 2009-02-12 18:16:06 UTC
  • mto: This revision was merged to the branch mainline in revision 883.
  • Revision ID: jpipes@serialcoder-20090212181606-vi7rd85rufufqxvc
Fixes Arg_comparator::can_compare_as_dates to never, ever allow bad
input data in comparisons.  No more implicit conversions from bad
datetimes are allowed.  We throw an error on bad input always.

In addition, fixes the Field_date class's store() methods for integer
types and corrects test cases that were allowing bad input.

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
 
 
22
21
#include "drizzled/server_includes.h"
23
22
#include "drizzled/field/date.h"
24
23
#include "drizzled/error.h"
26
25
#include "drizzled/temporal.h"
27
26
#include "drizzled/session.h"
28
27
 
 
28
#include <sstream>
 
29
#include <string>
 
30
 
29
31
#include CMATH_H
30
32
 
31
33
#if defined(CMATH_NAMESPACE)
55
57
       nearly-identical class Field_date doesn't ever return 3 from its
56
58
       store function.
57
59
*/
58
 
 
59
60
int Field_date::store(const char *from,
60
61
                         uint32_t len,
61
62
                         const CHARSET_INFO * const )
109
110
  return 0;
110
111
}
111
112
 
112
 
int Field_date::store(double nr)
113
 
{
114
 
  if (nr < 0.0 || nr > 99991231235959.0)
115
 
  {
116
 
    int3store(ptr,(int32_t) 0);
117
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
118
 
                         ER_WARN_DATA_TRUNCATED, nr, DRIZZLE_TIMESTAMP_DATE);
119
 
    return 1;
120
 
  }
121
 
  return Field_date::store((int64_t) rint(nr), false);
122
 
}
123
 
 
124
 
 
125
 
int Field_date::store(int64_t nr,
126
 
                         bool )
127
 
{
128
 
  DRIZZLE_TIME l_time;
129
 
  int64_t tmp;
130
 
  int error;
131
 
  Session *session= table ? table->in_use : current_session;
132
 
  if (number_to_datetime(nr, &l_time,
133
 
                         (TIME_FUZZY_DATE |
134
 
                          (session->variables.sql_mode &
135
 
                           (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
136
 
                         &error) == INT64_C(-1))
137
 
  {
138
 
    tmp= 0L;
139
 
    error= 2;
140
 
  }
141
 
  else
142
 
    tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
143
 
 
144
 
  if (!error && l_time.time_type != DRIZZLE_TIMESTAMP_DATE &&
145
 
      (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
146
 
    error= 3;
147
 
 
148
 
  if (error)
149
 
    set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
150
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
151
 
                         error == 2 ?
152
 
                         ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED,
153
 
                         nr,DRIZZLE_TIMESTAMP_DATE, 1);
154
 
 
155
 
  int3store(ptr,tmp);
156
 
  return error;
157
 
}
158
 
 
 
113
int Field_date::store(double from)
 
114
{
 
115
  if (from < 0.0 || from > 99991231235959.0)
 
116
  {
 
117
    /* Convert the double to a string using stringstream */
 
118
    std::stringstream ss;
 
119
    std::string tmp;
 
120
    ss.precision(18); /* 18 places should be fine for error display of double input. */
 
121
    ss << from; ss >> tmp;
 
122
 
 
123
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
124
    return 2;
 
125
  }
 
126
  return Field_date::store((int64_t) rint(from), false);
 
127
}
 
128
 
 
129
int Field_date::store(int64_t from, bool)
 
130
{
 
131
  /* 
 
132
   * Try to create a DateTime from the supplied integer.  Throw an error
 
133
   * if unable to create a valid DateTime.  
 
134
   */
 
135
  drizzled::DateTime temporal;
 
136
  if (! temporal.from_int64_t(from))
 
137
  {
 
138
    /* Convert the integer to a string using stringstream */
 
139
    std::stringstream ss;
 
140
    std::string tmp;
 
141
    ss << from; ss >> tmp;
 
142
 
 
143
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
144
    return 2;
 
145
  }
 
146
 
 
147
  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
 
148
  uint32_t int_value= (temporal.years() * 16 * 32) + (temporal.months() * 32) + temporal.days();
 
149
  int3store(ptr, int_value);
 
150
  return 0;
 
151
}
159
152
 
160
153
int Field_date::store_time(DRIZZLE_TIME *ltime,
161
154
                              enum enum_drizzle_timestamp_type time_type)
199
192
  return error;
200
193
}
201
194
 
202
 
 
203
195
bool Field_date::send_binary(Protocol *protocol)
204
196
{
205
197
  DRIZZLE_TIME tm;
207
199
  return protocol->store_date(&tm);
208
200
}
209
201
 
210
 
 
211
202
double Field_date::val_real(void)
212
203
{
213
204
  return (double) Field_date::val_int();
214
205
}
215
206
 
216
 
 
217
207
int64_t Field_date::val_int(void)
218
208
{
219
209
  uint32_t j= uint3korr(ptr);
221
211
  return (int64_t) j;
222
212
}
223
213
 
224
 
 
225
214
String *Field_date::val_str(String *val_buffer,
226
215
                               String *)
227
216
{
249
238
  return val_buffer;
250
239
}
251
240
 
252
 
 
253
241
bool Field_date::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
254
242
{
255
243
  uint32_t tmp=(uint32_t) uint3korr(ptr);
262
250
          1 : 0);
263
251
}
264
252
 
265
 
 
266
253
bool Field_date::get_time(DRIZZLE_TIME *ltime)
267
254
{
268
255
  return Field_date::get_date(ltime,0);
269
256
}
270
257
 
271
 
 
272
258
int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
273
259
{
274
260
  uint32_t a,b;
277
263
  return (a < b) ? -1 : (a > b) ? 1 : 0;
278
264
}
279
265
 
280
 
 
281
266
void Field_date::sort_string(unsigned char *to,uint32_t )
282
267
{
283
268
  to[0] = ptr[2];
285
270
  to[2] = ptr[0];
286
271
}
287
272
 
288
 
 
289
273
void Field_date::sql_type(String &res) const
290
274
{
291
275
  res.set_ascii(STRING_WITH_LEN("date"));
292
276
}
293