~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/date.cc

  • Committer: Brian Aker
  • Date: 2008-06-28 01:01:34 UTC
  • Revision ID: brian@tangent.org-20080628010134-n44ixrdgb6yexhkb
Remove my_pthread_getspecific_ptr()

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
 
#include "config.h"
22
 
#include "drizzled/field/date.h"
23
 
#include "drizzled/error.h"
24
 
#include "drizzled/table.h"
25
 
#include "drizzled/temporal.h"
26
 
#include "drizzled/session.h"
27
 
#include "drizzled/time_functions.h"
28
 
 
29
 
#include <math.h>
30
 
 
31
 
#include <sstream>
32
 
#include <string>
33
 
 
34
 
namespace drizzled
35
 
{
36
 
 
37
 
 
38
 
/****************************************************************************
39
 
** Drizzle date type stored in 3 bytes
40
 
** In number context: YYYYMMDD
41
 
****************************************************************************/
42
 
 
43
 
/*
44
 
  Store string into a date field
45
 
 
46
 
  SYNOPSIS
47
 
    Field_date::store()
48
 
    from                Date string
49
 
    len                 Length of date field
50
 
    cs                  Character set (not used)
51
 
 
52
 
  RETURN
53
 
    0  ok
54
 
    1  Value was cut during conversion
55
 
    2  Wrong date string
56
 
    3  Datetime value that was cut (warning level NOTE)
57
 
       This is used by opt_range.cc:get_mm_leaf(). Note that there is a
58
 
       nearly-identical class Field_date doesn't ever return 3 from its
59
 
       store function.
60
 
*/
61
 
int Field_date::store(const char *from,
62
 
                         uint32_t len,
63
 
                         const CHARSET_INFO * const )
64
 
{
65
 
  /* 
66
 
   * Try to create a DateTime from the supplied string.  Throw an error
67
 
   * if unable to create a valid DateTime.  A DateTime is used so that
68
 
   * automatic conversion from the higher-storage DateTime can be used
69
 
   * and matches on datetime format strings can occur.
70
 
   */
71
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
72
 
  DateTime temporal;
73
 
  if (! temporal.from_string(from, (size_t) len))
74
 
  {
75
 
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), from);
76
 
    return 2;
77
 
  }
78
 
  /* Create the stored integer format. @TODO This should go away. Should be up to engine... */
79
 
  uint32_t int_value= (temporal.years() * 10000) + (temporal.months() * 100) + temporal.days();
80
 
  int4store(ptr, int_value);
81
 
  return 0;
82
 
}
83
 
 
84
 
int Field_date::store(double from)
85
 
{
86
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
87
 
  if (from < 0.0 || from > 99991231235959.0)
88
 
  {
89
 
    /* Convert the double to a string using stringstream */
90
 
    std::stringstream ss;
91
 
    std::string tmp;
92
 
    ss.precision(18); /* 18 places should be fine for error display of double input. */
93
 
    ss << from; ss >> tmp;
94
 
 
95
 
    my_error(ER_INVALID_DATETIME_VALUE, MYF(ME_FATALERROR), tmp.c_str());
96
 
    return 2;
97
 
  }
98
 
  return Field_date::store((int64_t) rint(from), false);
99
 
}
100
 
 
101
 
int Field_date::store(int64_t from, bool)
102
 
{
103
 
  /* 
104
 
   * Try to create a DateTime from the supplied integer.  Throw an error
105
 
   * if unable to create a valid DateTime.  
106
 
   */
107
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
108
 
  DateTime temporal;
109
 
  if (! temporal.from_int64_t(from))
110
 
  {
111
 
    /* Convert the integer to a string using stringstream */
112
 
    std::stringstream ss;
113
 
    std::string tmp;
114
 
    ss << from; ss >> tmp;
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
 
}
125
 
 
126
 
int Field_date::store_time(DRIZZLE_TIME *ltime,
127
 
                              enum enum_drizzle_timestamp_type time_type)
128
 
{
129
 
  long tmp;
130
 
  int error= 0;
131
 
  if (time_type == DRIZZLE_TIMESTAMP_DATE ||
132
 
      time_type == DRIZZLE_TIMESTAMP_DATETIME)
133
 
  {
134
 
    tmp= ltime->year*10000 + ltime->month*100 + ltime->day;
135
 
    if (check_date(ltime, tmp != 0,
136
 
                   (TIME_FUZZY_DATE |
137
 
                    (current_session->variables.sql_mode &
138
 
                     (MODE_NO_ZERO_DATE | MODE_INVALID_DATES))), &error))
139
 
    {
140
 
      char buff[MAX_DATE_STRING_REP_LENGTH];
141
 
      String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
142
 
      make_date(ltime, &str);
143
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
144
 
                           str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
145
 
    }
146
 
    if (!error && ltime->time_type != DRIZZLE_TIMESTAMP_DATE &&
147
 
        (ltime->hour || ltime->minute || ltime->second || ltime->second_part))
148
 
    {
149
 
      char buff[MAX_DATE_STRING_REP_LENGTH];
150
 
      String str(buff, sizeof(buff), &my_charset_utf8_general_ci);
151
 
      make_datetime(ltime, &str);
152
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_NOTE,
153
 
                           ER_WARN_DATA_TRUNCATED,
154
 
                           str.ptr(), str.length(), DRIZZLE_TIMESTAMP_DATE, 1);
155
 
      error= 3;
156
 
    }
157
 
  }
158
 
  else
159
 
  {
160
 
    tmp=0;
161
 
    error= 1;
162
 
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
163
 
  }
164
 
  int4store(ptr,tmp);
165
 
  return error;
166
 
}
167
 
 
168
 
double Field_date::val_real(void)
169
 
{
170
 
  return (double) Field_date::val_int();
171
 
}
172
 
 
173
 
int64_t Field_date::val_int(void)
174
 
{
175
 
  uint32_t j;
176
 
 
177
 
  ASSERT_COLUMN_MARKED_FOR_READ;
178
 
 
179
 
  j= uint4korr(ptr);
180
 
 
181
 
  return (int64_t) j;
182
 
}
183
 
 
184
 
String *Field_date::val_str(String *val_buffer, String *)
185
 
{
186
 
  val_buffer->alloc(field_length);
187
 
  val_buffer->length(field_length);
188
 
  uint32_t tmp=(uint32_t) uint4korr(ptr);
189
 
  int32_t part;
190
 
  char *pos=(char*) val_buffer->ptr()+10;
191
 
 
192
 
  ASSERT_COLUMN_MARKED_FOR_READ;
193
 
 
194
 
  /* Open coded to get more speed */
195
 
  *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);
205
 
  *pos--= (char) ('0'+part%10); part/=10;
206
 
  *pos--= (char) ('0'+part%10); part/=10;
207
 
  *pos--= (char) ('0'+part%10); part/=10;
208
 
  *pos=   (char) ('0'+part);
209
 
  return val_buffer;
210
 
}
211
 
 
212
 
bool Field_date::get_date(DRIZZLE_TIME *ltime,uint32_t fuzzydate)
213
 
{
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);
218
 
  ltime->time_type= DRIZZLE_TIMESTAMP_DATE;
219
 
  ltime->hour= ltime->minute= ltime->second= ltime->second_part= ltime->neg= 0;
220
 
  return ((!(fuzzydate & TIME_FUZZY_DATE) && (!ltime->month || !ltime->day)) ?
221
 
          1 : 0);
222
 
}
223
 
 
224
 
bool Field_date::get_time(DRIZZLE_TIME *ltime)
225
 
{
226
 
  return Field_date::get_date(ltime,0);
227
 
}
228
 
 
229
 
int Field_date::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
230
 
{
231
 
  uint32_t a,b;
232
 
  a=(uint32_t) uint4korr(a_ptr);
233
 
  b=(uint32_t) uint4korr(b_ptr);
234
 
  return (a < b) ? -1 : (a > b) ? 1 : 0;
235
 
}
236
 
 
237
 
void Field_date::sort_string(unsigned char *to,uint32_t )
238
 
{
239
 
  to[0] = ptr[3];
240
 
  to[1] = ptr[2];
241
 
  to[2] = ptr[1];
242
 
  to[3] = ptr[0];
243
 
}
244
 
 
245
 
void Field_date::sql_type(String &res) const
246
 
{
247
 
  res.set_ascii(STRING_WITH_LEN("date"));
248
 
}
249
 
 
250
 
} /* namespace drizzled */