~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/date.cc

  • Committer: Stewart Smith
  • Author(s): Marko Mäkelä
  • Date: 2010-12-20 03:21:44 UTC
  • mto: (2021.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2022.
  • Revision ID: stewart@flamingspork.com-20101220032144-7aqh2z403u7d7bdp
Merge Revision revid:marko.makela@oracle.com-20101104131215-pfxnpidlrzd4krg0 from MySQL InnoDB

Original revid:marko.makela@oracle.com-20101104131215-pfxnpidlrzd4krg0

Original Authors: Marko Mäkelä <marko.makela@oracle.com>
Original commit message:
row_ins_index_entry(): Note that only CREATE INDEX sets foreign=FALSE.

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
 
#include <drizzled/server_includes.h>
23
 
#include <drizzled/field/date.h>
24
 
#include <drizzled/error.h>
25
 
#include <drizzled/table.h>
26
 
#include <drizzled/session.h>
27
 
 
28
 
#include CMATH_H
29
 
 
30
 
#if defined(CMATH_NAMESPACE)
31
 
using namespace CMATH_NAMESPACE;
32
 
#endif
 
21
#include "config.h"
 
22
#include <boost/lexical_cast.hpp>
 
23
 
 
24
#include "drizzled/field/date.h"
 
25
#include "drizzled/error.h"
 
26
#include "drizzled/table.h"
 
27
#include "drizzled/temporal.h"
 
28
#include "drizzled/session.h"
 
29
#include "drizzled/time_functions.h"
 
30
 
 
31
#include <math.h>
 
32
 
 
33
#include <sstream>
 
34
#include <string>
 
35
 
 
36
namespace drizzled
 
37
{
 
38
 
33
39
 
34
40
/****************************************************************************
35
41
** Drizzle date type stored in 3 bytes
54
60
       nearly-identical class Field_date doesn't ever return 3 from its
55
61
       store function.
56
62
*/
57
 
 
58
63
int Field_date::store(const char *from,
59
64
                         uint32_t len,
60
 
                         const CHARSET_INFO * const cs __attribute__((unused)))
61
 
{
62
 
  long tmp;
63
 
  DRIZZLE_TIME l_time;
64
 
  int error;
65
 
  Session *session= table ? table->in_use : current_session;
66
 
  enum enum_drizzle_timestamp_type ret;
67
 
  if ((ret= str_to_datetime(from, len, &l_time,
68
 
                            (TIME_FUZZY_DATE |
69
 
                             (session->variables.sql_mode &
70
 
                              (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
71
 
                            &error)) <= DRIZZLE_TIMESTAMP_ERROR)
72
 
  {
73
 
    tmp= 0;
74
 
    error= 2;
75
 
  }
76
 
  else
77
 
  {
78
 
    tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
79
 
    if (!error && (ret != DRIZZLE_TIMESTAMP_DATE) &&
80
 
        (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
81
 
      error= 3;                                 // Datetime was cut (note)
82
 
  }
83
 
 
84
 
  if (error)
85
 
    set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
86
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
87
 
                         ER_WARN_DATA_TRUNCATED,
88
 
                         from, len, DRIZZLE_TIMESTAMP_DATE, 1);
89
 
 
90
 
  int3store(ptr, tmp);
91
 
  return error;
92
 
}
93
 
 
94
 
 
95
 
int Field_date::store(double nr)
96
 
{
97
 
  if (nr < 0.0 || nr > 99991231235959.0)
98
 
  {
99
 
    int3store(ptr,(int32_t) 0);
100
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
101
 
                         ER_WARN_DATA_TRUNCATED, nr, DRIZZLE_TIMESTAMP_DATE);
102
 
    return 1;
103
 
  }
104
 
  return Field_date::store((int64_t) rint(nr), false);
105
 
}
106
 
 
107
 
 
108
 
int Field_date::store(int64_t nr,
109
 
                         bool unsigned_val __attribute__((unused)))
110
 
{
111
 
  DRIZZLE_TIME l_time;
112
 
  int64_t tmp;
113
 
  int error;
114
 
  Session *session= table ? table->in_use : current_session;
115
 
  if (number_to_datetime(nr, &l_time,
116
 
                         (TIME_FUZZY_DATE |
117
 
                          (session->variables.sql_mode &
118
 
                           (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))),
119
 
                         &error) == INT64_C(-1))
120
 
  {
121
 
    tmp= 0L;
122
 
    error= 2;
123
 
  }
124
 
  else
125
 
    tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
126
 
 
127
 
  if (!error && l_time.time_type != DRIZZLE_TIMESTAMP_DATE &&
128
 
      (l_time.hour || l_time.minute || l_time.second || l_time.second_part))
129
 
    error= 3;
130
 
 
131
 
  if (error)
132
 
    set_datetime_warning(error == 3 ? DRIZZLE_ERROR::WARN_LEVEL_NOTE :
133
 
                         DRIZZLE_ERROR::WARN_LEVEL_WARN,
134
 
                         error == 2 ? 
135
 
                         ER_WARN_DATA_OUT_OF_RANGE : ER_WARN_DATA_TRUNCATED,
136
 
                         nr,DRIZZLE_TIMESTAMP_DATE, 1);
137
 
 
138
 
  int3store(ptr,tmp);
139
 
  return error;
140
 
}
141
 
 
 
65
                         const CHARSET_INFO * const )
 
66
{
 
67
  /* 
 
68
   * Try to create a DateTime from the supplied string.  Throw an error
 
69
   * if unable to create a valid DateTime.  A DateTime is used so that
 
70
   * automatic conversion from the higher-storage DateTime can be used
 
71
   * and matches on datetime format strings can occur.
 
72
   */
 
73
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
74
  DateTime temporal;
 
75
  if (! temporal.from_string(from, (size_t) len))
 
76
  {
 
77
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
 
78
    return 2;
 
79
  }
 
80
  /* 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);
 
83
  return 0;
 
84
}
 
85
 
 
86
int Field_date::store(double from)
 
87
{
 
88
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
89
  if (from < 0.0 || from > 99991231235959.0)
 
90
  {
 
91
    /* Convert the double to a string using stringstream */
 
92
    std::stringstream ss;
 
93
    std::string tmp;
 
94
    ss.precision(18); /* 18 places should be fine for error display of double input. */
 
95
    ss << from; ss >> tmp;
 
96
 
 
97
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
98
    return 2;
 
99
  }
 
100
  return Field_date::store((int64_t) rint(from), false);
 
101
}
 
102
 
 
103
int Field_date::store(int64_t from, bool)
 
104
{
 
105
  /* 
 
106
   * Try to create a DateTime from the supplied integer.  Throw an error
 
107
   * if unable to create a valid DateTime.  
 
108
   */
 
109
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
110
  DateTime temporal;
 
111
  if (! temporal.from_int64_t(from))
 
112
  {
 
113
    /* Convert the integer to a string using boost::lexical_cast */
 
114
    std::string tmp(boost::lexical_cast<std::string>(from)); 
 
115
 
 
116
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
117
    return 2;
 
118
  }
 
119
 
 
120
  /* 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);
 
123
  return 0;
 
124
}
142
125
 
143
126
int Field_date::store_time(DRIZZLE_TIME *ltime,
144
127
                              enum enum_drizzle_timestamp_type time_type)
148
131
  if (time_type == DRIZZLE_TIMESTAMP_DATE ||
149
132
      time_type == DRIZZLE_TIMESTAMP_DATETIME)
150
133
  {
151
 
    tmp=ltime->year*16*32+ltime->month*32+ltime->day;
 
134
    tmp= ltime->year*10000 + ltime->month*100 + ltime->day;
152
135
    if (check_date(ltime, tmp != 0,
153
136
                   (TIME_FUZZY_DATE |
154
137
                    (current_session->variables.sql_mode &
156
139
    {
157
140
      char buff[MAX_DATE_STRING_REP_LENGTH];
158
141
      String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
159
 
      make_date((DATE_TIME_FORMAT *) 0, ltime, &str);
 
142
      make_date(ltime, &str);
160
143
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
161
144
                           str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
162
145
    }
165
148
    {
166
149
      char buff[MAX_DATE_STRING_REP_LENGTH];
167
150
      String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
168
 
      make_datetime((DATE_TIME_FORMAT *) 0, ltime, &str);
 
151
      make_datetime(ltime, &str);
169
152
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
170
153
                           ER_WARN_DATA_TRUNCATED,
171
154
                           str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
178
161
    error= 1;
179
162
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
180
163
  }
181
 
  int3store(ptr,tmp);
 
164
  int4store(ptr,tmp);
182
165
  return error;
183
166
}
184
167
 
185
 
 
186
 
bool Field_date::send_binary(Protocol *protocol)
187
 
{
188
 
  DRIZZLE_TIME tm;
189
 
  Field_date::get_date(&tm,0);
190
 
  return protocol->store_date(&tm);
191
 
}
192
 
 
193
 
 
194
168
double Field_date::val_real(void)
195
169
{
196
170
  return (double) Field_date::val_int();
197
171
}
198
172
 
199
 
 
200
173
int64_t Field_date::val_int(void)
201
174
{
202
 
  uint32_t j= uint3korr(ptr);
203
 
  j= (j % 32L)+(j / 32L % 16L)*100L + (j/(16L*32L))*10000L;
 
175
  uint32_t j;
 
176
 
 
177
  ASSERT_COLUMN_MARKED_FOR_READ;
 
178
 
 
179
  j= uint4korr(ptr);
 
180
 
204
181
  return (int64_t) j;
205
182
}
206
183
 
207
 
 
208
 
String *Field_date::val_str(String *val_buffer,
209
 
                               String *val_ptr __attribute__((unused)))
 
184
String *Field_date::val_str(String *val_buffer, String *)
210
185
{
211
186
  val_buffer->alloc(field_length);
212
187
  val_buffer->length(field_length);
213
 
  uint32_t tmp=(uint32_t) uint3korr(ptr);
214
 
  int part;
 
188
  uint32_t tmp=(uint32_t) uint4korr(ptr);
 
189
  int32_t part;
215
190
  char *pos=(char*) val_buffer->ptr()+10;
216
191
 
 
192
  ASSERT_COLUMN_MARKED_FOR_READ;
 
193
 
217
194
  /* Open coded to get more speed */
218
195
  *pos--=0;                                     // End NULL
219
 
  part=(int) (tmp & 31);
220
 
  *pos--= (char) ('0'+part%10);
221
 
  *pos--= (char) ('0'+part/10);
222
 
  *pos--= '-';
223
 
  part=(int) (tmp >> 5 & 15);
224
 
  *pos--= (char) ('0'+part%10);
225
 
  *pos--= (char) ('0'+part/10);
226
 
  *pos--= '-';
227
 
  part=(int) (tmp >> 9);
 
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);
228
205
  *pos--= (char) ('0'+part%10); part/=10;
229
206
  *pos--= (char) ('0'+part%10); part/=10;
230
207
  *pos--= (char) ('0'+part%10); part/=10;
232
209
  return val_buffer;
233
210
}
234
211
 
235
 
 
236
212
bool Field_date::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
237
213
{
238
 
  uint32_t tmp=(uint32_t) uint3korr(ptr);
239
 
  ltime->day=   tmp & 31;
240
 
  ltime->month= (tmp >> 5) & 15;
241
 
  ltime->year=  (tmp >> 9);
 
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);
242
218
  ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
243
219
  ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
244
220
  return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
245
221
          1 : 0);
246
222
}
247
223
 
248
 
 
249
224
bool Field_date::get_time(DRIZZLE_TIME *ltime)
250
225
{
251
226
  return Field_date::get_date(ltime,0);
252
227
}
253
228
 
254
 
 
255
229
int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
256
230
{
257
231
  uint32_t a,b;
258
 
  a=(uint32_t) uint3korr(a_ptr);
259
 
  b=(uint32_t) uint3korr(b_ptr);
 
232
  a=(uint32_t) uint4korr(a_ptr);
 
233
  b=(uint32_t) uint4korr(b_ptr);
260
234
  return (a < b) ? -1 : (a > b) ? 1 : 0;
261
235
}
262
236
 
263
 
 
264
 
void Field_date::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
 
237
void Field_date::sort_string(unsigned char *to,uint32_t )
265
238
{
266
 
  to[0] = ptr[2];
267
 
  to[1] = ptr[1];
268
 
  to[2] = ptr[0];
 
239
  to[0] = ptr[3];
 
240
  to[1] = ptr[2];
 
241
  to[2] = ptr[1];
 
242
  to[3] = ptr[0];
269
243
}
270
244
 
271
 
 
272
245
void Field_date::sql_type(String &res) const
273
246
{
274
247
  res.set_ascii(STRING_WITH_LEN("date"));
275
248
}
276
249
 
 
250
} /* namespace drizzled */