~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/datetime.cc

  • Committer: Mats Kindahl
  • Date: 2008-08-26 07:32:59 UTC
  • mto: (489.1.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: mats@mysql.com-20080826073259-9k4evtajgldgolli
Replaced use of thd_proc_info() macro with calls to
set_proc_info() and get_proc_info() internally.  Introduced
functions set_thd_proc_info() and get_thd_proc_info() for
external users, i.e., plug-ins.

The set_thd_proc_info() accepted callers info that can be used to
print debug output, but the information was not used. The return
value was changed to void and the old value is not fetched any
more. To be able to get the value of proc_info for external
users, the function get_thd_proc_info() was introduced.

The thd_proc_info() macro called set_thd_proc_info() but almost
never used the return value of set_thd_proc_info() so the macro
was replaced with a call of THD::set_proc_info().

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
4
 *  Copyright (C) 2008 MySQL
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
 
#include "drizzled/field/datetime.h"
24
 
#include "drizzled/error.h"
25
 
#include "drizzled/table.h"
26
 
#include "drizzled/temporal.h"
27
 
#include "drizzled/session.h"
28
 
 
29
 
#include <math.h>
30
 
 
31
 
#include <sstream>
32
 
#include <string>
33
 
 
34
 
 
35
 
namespace drizzled
36
 
{
 
21
#ifdef USE_PRAGMA_IMPLEMENTATION
 
22
#pragma implementation                          // gcc: Class implementation
 
23
#endif
 
24
 
 
25
#include <drizzled/server_includes.h>
 
26
#include <drizzled/field/datetime.h>
37
27
 
38
28
/****************************************************************************
39
29
** datetime type
40
30
** In string context: YYYY-MM-DD HH:MM:DD
41
31
** In number context: YYYYMMDDHHMMDD
 
32
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
42
33
****************************************************************************/
43
34
 
44
35
int Field_datetime::store(const char *from,
45
 
                          uint32_t len,
46
 
                          const CHARSET_INFO * const )
47
 
{
48
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
49
 
  /* 
50
 
   * Try to create a DateTime from the supplied string.  Throw an error
51
 
   * if unable to create a valid DateTime.  
52
 
   */
53
 
  DateTime temporal;
54
 
  if (! temporal.from_string(from, (size_t) len))
55
 
  {
56
 
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
57
 
    return 2;
58
 
  }
59
 
  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
60
 
  int64_t int_value;
61
 
  temporal.to_int64_t(&int_value);
62
 
 
63
 
#ifdef WORDS_BIGENDIAN
64
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
65
 
  {
66
 
    int8store(ptr, int_value);
67
 
  }
68
 
  else
69
 
#endif
70
 
    int64_tstore(ptr, int_value);
71
 
  return 0;
72
 
}
73
 
 
74
 
int Field_datetime::store(double from)
75
 
{
76
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
77
 
  if (from < 0.0 || from > 99991231235959.0)
78
 
  {
79
 
    /* Convert the double to a string using boost::lexical_cast */
80
 
    std::string tmp(boost::lexical_cast<std::string>(from));
81
 
 
82
 
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
83
 
    return 2;
84
 
  }
85
 
  return Field_datetime::store((int64_t) rint(from), false);
86
 
}
87
 
 
88
 
int Field_datetime::store(int64_t from, bool)
89
 
{
90
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
91
 
  /* 
92
 
   * Try to create a DateTime from the supplied integer.  Throw an error
93
 
   * if unable to create a valid DateTime.  
94
 
   */
95
 
  DateTime temporal;
96
 
  if (! temporal.from_int64_t(from))
97
 
  {
98
 
    /* Convert the integer to a string using boost::lexical_cast */
99
 
    std::string tmp(boost::lexical_cast<std::string>(from));
100
 
 
101
 
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
102
 
    return 2;
103
 
  }
104
 
 
105
 
  /* 
106
 
   * Because "from" may be a silly MySQL-like "datetime number" (like, oh, 101)
107
 
   * we must here get the value of the DateTime as its *real* int64_t, after
108
 
   * the conversion above has been done...yuck. God, save us.
109
 
   */
110
 
  int64_t int_value;
111
 
  temporal.to_int64_t(&int_value);
112
 
 
113
 
#ifdef WORDS_BIGENDIAN
114
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
115
 
  {
116
 
    int8store(ptr, int_value);
117
 
  }
118
 
  else
119
 
#endif
120
 
    int64_tstore(ptr, int_value);
121
 
  return 0;
122
 
}
123
 
 
124
 
int Field_datetime::store_time(DRIZZLE_TIME *ltime, enum enum_drizzle_timestamp_type)
125
 
{
126
 
  DateTime temporal;
127
 
 
128
 
  temporal.set_years(ltime->year);
129
 
  temporal.set_months(ltime->month);
130
 
  temporal.set_days(ltime->day);
131
 
  temporal.set_hours(ltime->hour);
132
 
  temporal.set_minutes(ltime->minute);
133
 
  temporal.set_seconds(ltime->second);
134
 
 
135
 
  if (! temporal.is_valid())
136
 
  {
137
 
    char tmp_string[MAX_DATE_STRING_REP_LENGTH];
138
 
    size_t tmp_string_len;
139
 
 
140
 
    tmp_string_len= temporal.to_string(tmp_string, MAX_DATE_STRING_REP_LENGTH);
141
 
    assert(tmp_string_len < MAX_DATE_STRING_REP_LENGTH);
142
 
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp_string);
143
 
    return 1;
144
 
  }
145
 
 
146
 
  int64_t int_value;
147
 
  temporal.to_int64_t(&int_value);
148
 
 
149
 
#ifdef WORDS_BIGENDIAN
150
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
151
 
  {
152
 
    int8store(ptr, int_value);
153
 
  }
154
 
  else
155
 
#endif
156
 
    int64_tstore(ptr, int_value);
157
 
  return 0;
158
 
}
 
36
                          uint len,
 
37
                          const CHARSET_INFO * const cs __attribute__((unused)))
 
38
{
 
39
  DRIZZLE_TIME time_tmp;
 
40
  int error;
 
41
  uint64_t tmp= 0;
 
42
  enum enum_drizzle_timestamp_type func_res;
 
43
  THD *thd= table ? table->in_use : current_thd;
 
44
 
 
45
  func_res= str_to_datetime(from, len, &time_tmp,
 
46
                            (TIME_FUZZY_DATE |
 
47
                             (thd->variables.sql_mode &
 
48
                              (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
 
49
                            &error);
 
50
  if ((int) func_res > (int) DRIZZLE_TIMESTAMP_ERROR)
 
51
    tmp= TIME_to_uint64_t_datetime(&time_tmp);
 
52
  else
 
53
    error= 1;                                 // Fix if invalid zero date
 
54
 
 
55
  if (error)
 
56
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
57
                         ER_WARN_DATA_OUT_OF_RANGE,
 
58
                         from, len, DRIZZLE_TIMESTAMP_DATETIME, 1);
 
59
 
 
60
#ifdef WORDS_BIGENDIAN
 
61
  if (table && table->s->db_low_byte_first)
 
62
  {
 
63
    int8store(ptr,tmp);
 
64
  }
 
65
  else
 
66
#endif
 
67
    int64_tstore(ptr,tmp);
 
68
  return error;
 
69
}
 
70
 
 
71
 
 
72
int Field_datetime::store(double nr)
 
73
{
 
74
  int error= 0;
 
75
  if (nr < 0.0 || nr > 99991231235959.0)
 
76
  {
 
77
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, 
 
78
                         ER_WARN_DATA_OUT_OF_RANGE,
 
79
                         nr, DRIZZLE_TIMESTAMP_DATETIME);
 
80
    nr= 0.0;
 
81
    error= 1;
 
82
  }
 
83
  error|= Field_datetime::store((int64_t) rint(nr), false);
 
84
  return error;
 
85
}
 
86
 
 
87
 
 
88
int Field_datetime::store(int64_t nr,
 
89
                          bool unsigned_val __attribute__((unused)))
 
90
{
 
91
  DRIZZLE_TIME not_used;
 
92
  int error;
 
93
  int64_t initial_nr= nr;
 
94
  THD *thd= table ? table->in_use : current_thd;
 
95
 
 
96
  nr= number_to_datetime(nr, &not_used, (TIME_FUZZY_DATE |
 
97
                                         (thd->variables.sql_mode &
 
98
                                          (MODE_NO_ZERO_DATE |
 
99
                                           MODE_INVALID_DATES))), &error);
 
100
 
 
101
  if (nr == -1LL)
 
102
  {
 
103
    nr= 0;
 
104
    error= 2;
 
105
  }
 
106
 
 
107
  if (error)
 
108
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
109
                         error == 2 ? ER_WARN_DATA_OUT_OF_RANGE :
 
110
                         ER_WARN_DATA_TRUNCATED, initial_nr,
 
111
                         DRIZZLE_TIMESTAMP_DATETIME, 1);
 
112
 
 
113
#ifdef WORDS_BIGENDIAN
 
114
  if (table && table->s->db_low_byte_first)
 
115
  {
 
116
    int8store(ptr,nr);
 
117
  }
 
118
  else
 
119
#endif
 
120
    int64_tstore(ptr,nr);
 
121
  return error;
 
122
}
 
123
 
 
124
 
 
125
int Field_datetime::store_time(DRIZZLE_TIME *ltime,timestamp_type time_type)
 
126
{
 
127
  int64_t tmp;
 
128
  int error= 0;
 
129
  /*
 
130
    We don't perform range checking here since values stored in TIME
 
131
    structure always fit into DATETIME range.
 
132
  */
 
133
  if (time_type == DRIZZLE_TIMESTAMP_DATE ||
 
134
      time_type == DRIZZLE_TIMESTAMP_DATETIME)
 
135
  {
 
136
    tmp=((ltime->year*10000L+ltime->month*100+ltime->day)*1000000LL+
 
137
         (ltime->hour*10000L+ltime->minute*100+ltime->second));
 
138
    if (check_date(ltime, tmp != 0,
 
139
                   (TIME_FUZZY_DATE |
 
140
                    (current_thd->variables.sql_mode &
 
141
                     (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
 
142
    {
 
143
      char buff[MAX_DATE_STRING_REP_LENGTH];
 
144
      String str(buff, sizeof(buff), &my_charset_latin1);
 
145
      make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
 
146
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
 
147
                           str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATETIME,1);
 
148
    }
 
149
  }
 
150
  else
 
151
  {
 
152
    tmp=0;
 
153
    error= 1;
 
154
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
 
155
  }
 
156
#ifdef WORDS_BIGENDIAN
 
157
  if (table && table->s->db_low_byte_first)
 
158
  {
 
159
    int8store(ptr,tmp);
 
160
  }
 
161
  else
 
162
#endif
 
163
    int64_tstore(ptr,tmp);
 
164
  return error;
 
165
}
 
166
 
 
167
bool Field_datetime::send_binary(Protocol *protocol)
 
168
{
 
169
  DRIZZLE_TIME tm;
 
170
  Field_datetime::get_date(&tm, TIME_FUZZY_DATE);
 
171
  return protocol->store(&tm);
 
172
}
 
173
 
159
174
 
160
175
double Field_datetime::val_real(void)
161
176
{
165
180
int64_t Field_datetime::val_int(void)
166
181
{
167
182
  int64_t j;
168
 
 
169
 
  ASSERT_COLUMN_MARKED_FOR_READ;
170
 
 
171
183
#ifdef WORDS_BIGENDIAN
172
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
 
184
  if (table && table->s->db_low_byte_first)
173
185
    j=sint8korr(ptr);
174
186
  else
175
187
#endif
179
191
 
180
192
 
181
193
String *Field_datetime::val_str(String *val_buffer,
182
 
                                String *)
 
194
                                String *val_ptr __attribute__((unused)))
183
195
{
184
 
  val_buffer->alloc(DateTime::MAX_STRING_LENGTH);
185
 
  val_buffer->length(DateTime::MAX_STRING_LENGTH);
186
 
  int64_t tmp;
187
 
 
188
 
  ASSERT_COLUMN_MARKED_FOR_READ;
 
196
  val_buffer->alloc(field_length);
 
197
  val_buffer->length(field_length);
 
198
  uint64_t tmp;
 
199
  long part1,part2;
 
200
  char *pos;
 
201
  int part3;
189
202
 
190
203
#ifdef WORDS_BIGENDIAN
191
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
 
204
  if (table && table->s->db_low_byte_first)
192
205
    tmp=sint8korr(ptr);
193
206
  else
194
207
#endif
195
208
    int64_tget(tmp,ptr);
196
209
 
197
 
  DateTime dt;
198
 
 
199
 
  /* TODO: add an assert that this succeeds
200
 
   * currently fails due to bug in allowing
201
 
   * ALTER TABLE to add a datetime column that's
202
 
   * not null without a default value.
203
 
   */
204
 
  dt.from_int64_t(tmp, false); /* NOTE: this does *NOT* attempt convertion
205
 
                                 from formats such as 20090101 as
206
 
                                 the stored value has already been
207
 
                                 converted.
208
 
                               */
209
 
 
210
 
  int rlen;
211
 
  rlen= dt.to_string((char*)val_buffer->ptr(), DateTime::MAX_STRING_LENGTH);
212
 
  assert((rlen+1) <  DateTime::MAX_STRING_LENGTH);
213
 
 
214
 
  val_buffer->length(rlen);
215
 
 
 
210
  /*
 
211
    Avoid problem with slow int64_t arithmetic and sprintf
 
212
  */
 
213
 
 
214
  part1=(long) (tmp/1000000LL);
 
215
  part2=(long) (tmp - (uint64_t) part1*1000000LL);
 
216
 
 
217
  pos=(char*) val_buffer->ptr() + MAX_DATETIME_WIDTH;
 
218
  *pos--=0;
 
219
  *pos--= (char) ('0'+(char) (part2%10)); part2/=10;
 
220
  *pos--= (char) ('0'+(char) (part2%10)); part3= (int) (part2 / 10);
 
221
  *pos--= ':';
 
222
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
 
223
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
 
224
  *pos--= ':';
 
225
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
 
226
  *pos--= (char) ('0'+(char) part3);
 
227
  *pos--= ' ';
 
228
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
 
229
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
 
230
  *pos--= '-';
 
231
  *pos--= (char) ('0'+(char) (part1%10)); part1/=10;
 
232
  *pos--= (char) ('0'+(char) (part1%10)); part3= (int) (part1/10);
 
233
  *pos--= '-';
 
234
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
 
235
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
 
236
  *pos--= (char) ('0'+(char) (part3%10)); part3/=10;
 
237
  *pos=(char) ('0'+(char) part3);
216
238
  return val_buffer;
217
239
}
218
240
 
219
 
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
 
241
bool Field_datetime::get_date(DRIZZLE_TIME *ltime, uint fuzzydate)
220
242
{
221
243
  int64_t tmp=Field_datetime::val_int();
222
244
  uint32_t part1,part2;
223
 
  part1=(uint32_t) (tmp/INT64_C(1000000));
224
 
  part2=(uint32_t) (tmp - (uint64_t) part1*INT64_C(1000000));
 
245
  part1=(uint32_t) (tmp/1000000LL);
 
246
  part2=(uint32_t) (tmp - (uint64_t) part1*1000000LL);
225
247
 
226
248
  ltime->time_type=     DRIZZLE_TIMESTAMP_DATETIME;
227
249
  ltime->neg=           0;
240
262
  return Field_datetime::get_date(ltime,0);
241
263
}
242
264
 
243
 
int Field_datetime::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
 
265
int Field_datetime::cmp(const uchar *a_ptr, const uchar *b_ptr)
244
266
{
245
267
  int64_t a,b;
246
268
#ifdef WORDS_BIGENDIAN
247
 
  if (getTable() && getTable()->getShare()->db_low_byte_first)
 
269
  if (table && table->s->db_low_byte_first)
248
270
  {
249
271
    a=sint8korr(a_ptr);
250
272
    b=sint8korr(b_ptr);
259
281
    ((uint64_t) a > (uint64_t) b) ? 1 : 0;
260
282
}
261
283
 
262
 
void Field_datetime::sort_string(unsigned char *to,uint32_t )
 
284
void Field_datetime::sort_string(uchar *to,uint length __attribute__((unused)))
263
285
{
264
286
#ifdef WORDS_BIGENDIAN
265
 
  if (!getTable() || !getTable()->getShare()->db_low_byte_first)
 
287
  if (!table || !table->s->db_low_byte_first)
266
288
  {
267
289
    to[0] = ptr[0];
268
290
    to[1] = ptr[1];
293
315
  res.set_ascii(STRING_WITH_LEN("datetime"));
294
316
}
295
317
 
296
 
} /* namespace drizzled */