~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/epoch.cc

  • Committer: Monty Taylor
  • Date: 2010-12-24 02:13:05 UTC
  • mto: This revision was merged to the branch mainline in revision 2038.
  • Revision ID: mordred@inaugust.com-20101224021305-e3slv1cyjczqorij
Changed the bzrignore file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
 
4
 *  Copyright (C) 2008 Sun Microsystems, Inc.
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
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/timestamp.h>
 
21
#include "config.h"
 
22
#include <boost/lexical_cast.hpp>
 
23
#include <drizzled/field/epoch.h>
24
24
#include <drizzled/error.h>
25
25
#include <drizzled/tztime.h>
26
26
#include <drizzled/table.h>
27
27
#include <drizzled/session.h>
28
 
#include CMATH_H
29
 
 
30
 
#if defined(CMATH_NAMESPACE)
31
 
using namespace CMATH_NAMESPACE;
32
 
#endif
 
28
 
 
29
#include <math.h>
 
30
 
 
31
#include <sstream>
 
32
 
 
33
#include "drizzled/temporal.h"
 
34
 
 
35
namespace drizzled
 
36
{
 
37
 
 
38
namespace field
 
39
{
33
40
 
34
41
/**
35
 
  TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to 
36
 
  2038-01-01 00:00:00 UTC stored as number of seconds since Unix 
 
42
  TIMESTAMP type holds datetime values in range from 1970-01-01 00:00:01 UTC to
 
43
  2038-01-01 00:00:00 UTC stored as number of seconds since Unix
37
44
  Epoch in UTC.
38
 
  
39
 
  Up to one of timestamps columns in the table can be automatically 
 
45
 
 
46
  Up to one of timestamps columns in the table can be automatically
40
47
  set on row update and/or have NOW() as default value.
41
 
  TABLE::timestamp_field points to Field object for such timestamp with 
 
48
  TABLE::timestamp_field points to Field object for such timestamp with
42
49
  auto-set-on-update. TABLE::time_stamp holds offset in record + 1 for this
43
50
  field, and is used by handler code which performs updates required.
44
 
  
 
51
 
45
52
  Actually SQL-99 says that we should allow niladic functions (like NOW())
46
 
  as defaults for any field. Current limitations (only NOW() and only 
47
 
  for one TIMESTAMP field) are because of restricted binary .frm format 
 
53
  as defaults for any field. Current limitations (only NOW() and only
 
54
  for one TIMESTAMP field) are because of restricted binary .frm format
48
55
  and should go away in the future.
49
 
  
 
56
 
50
57
  Also because of this limitation of binary .frm format we use 5 different
51
58
  unireg_check values with TIMESTAMP field to distinguish various cases of
52
59
  DEFAULT or ON UPDATE values. These values are:
53
 
  
 
60
 
54
61
  TIMESTAMP_OLD_FIELD - old timestamp, if there was not any fields with
55
 
    auto-set-on-update (or now() as default) in this table before, then this 
56
 
    field has NOW() as default and is updated when row changes, else it is 
 
62
    auto-set-on-update (or now() as default) in this table before, then this
 
63
    field has NOW() as default and is updated when row changes, else it is
57
64
    field which has 0 as default value and is not automatically updated.
58
65
  TIMESTAMP_DN_FIELD - field with NOW() as default but not set on update
59
66
    automatically (TIMESTAMP DEFAULT NOW())
60
 
  TIMESTAMP_UN_FIELD - field which is set on update automatically but has not 
61
 
    NOW() as default (but it may has 0 or some other const timestamp as 
 
67
  TIMESTAMP_UN_FIELD - field which is set on update automatically but has not
 
68
    NOW() as default (but it may has 0 or some other const timestamp as
62
69
    default) (TIMESTAMP ON UPDATE NOW()).
63
 
  TIMESTAMP_DNUN_FIELD - field which has now() as default and is auto-set on 
 
70
  TIMESTAMP_DNUN_FIELD - field which has now() as default and is auto-set on
64
71
    update. (TIMESTAMP DEFAULT NOW() ON UPDATE NOW())
65
 
  NONE - field which is not auto-set on update with some other than NOW() 
 
72
  NONE - field which is not auto-set on update with some other than NOW()
66
73
    default value (TIMESTAMP DEFAULT 0).
67
74
 
68
 
  Note that TIMESTAMP_OLD_FIELDs are never created explicitly now, they are 
69
 
  left only for preserving ability to read old tables. Such fields replaced 
70
 
  with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is 
71
 
  because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for 
72
 
  "TIMESTAMP DEFAULT 'Const'" field. (Old timestamps allowed such 
73
 
  specification too but ignored default value for first timestamp, which of 
 
75
  Note that TIMESTAMP_OLD_FIELDs are never created explicitly now, they are
 
76
  left only for preserving ability to read old tables. Such fields replaced
 
77
  with their newer analogs in CREATE TABLE and in SHOW CREATE TABLE. This is
 
78
  because we want to prefer NONE unireg_check before TIMESTAMP_OLD_FIELD for
 
79
  "TIMESTAMP DEFAULT 'Const'" field. (Old timestamps allowed such
 
80
  specification too but ignored default value for first timestamp, which of
74
81
  course is non-standard.) In most cases user won't notice any change, only
75
82
  exception is different behavior of old/new timestamps during ALTER TABLE.
76
83
 */
77
 
 
78
 
Field_timestamp::Field_timestamp(unsigned char *ptr_arg,
79
 
                                 uint32_t len_arg __attribute__((unused)),
80
 
                                 unsigned char *null_ptr_arg, unsigned char null_bit_arg,
81
 
                                 enum utype unireg_check_arg,
82
 
                                 const char *field_name_arg,
83
 
                                 TABLE_SHARE *share,
84
 
                                 const CHARSET_INFO * const cs)
85
 
  :Field_str(ptr_arg, MAX_DATETIME_WIDTH, null_ptr_arg, null_bit_arg,
86
 
             unireg_check_arg, field_name_arg, cs)
 
84
  Epoch::Epoch(unsigned char *ptr_arg,
 
85
               uint32_t,
 
86
               unsigned char *null_ptr_arg,
 
87
               unsigned char null_bit_arg,
 
88
               enum utype unireg_check_arg,
 
89
               const char *field_name_arg,
 
90
               drizzled::TableShare *share,
 
91
               const drizzled::CHARSET_INFO * const cs) :
 
92
  Field_str(ptr_arg,
 
93
            DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
 
94
            null_ptr_arg,
 
95
            null_bit_arg,
 
96
            field_name_arg,
 
97
            cs)
87
98
{
88
 
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
89
 
  flags|= UNSIGNED_FLAG;
90
 
  if (!share->timestamp_field && unireg_check != NONE)
 
99
  unireg_check= unireg_check_arg;
 
100
  if (! share->getTimestampField() && unireg_check != NONE)
91
101
  {
92
102
    /* This timestamp has auto-update */
93
 
    share->timestamp_field= this;
94
 
    flags|= TIMESTAMP_FLAG;
 
103
    share->setTimestampField(this);
 
104
    flags|= FUNCTION_DEFAULT_FLAG;
95
105
    if (unireg_check != TIMESTAMP_DN_FIELD)
96
106
      flags|= ON_UPDATE_NOW_FLAG;
97
107
  }
98
108
}
99
109
 
100
 
 
101
 
Field_timestamp::Field_timestamp(bool maybe_null_arg,
102
 
                                 const char *field_name_arg,
103
 
                                 const CHARSET_INFO * const cs)
104
 
  :Field_str((unsigned char*) 0, MAX_DATETIME_WIDTH,
105
 
             maybe_null_arg ? (unsigned char*) "": 0, 0,
106
 
             NONE, field_name_arg, cs)
 
110
Epoch::Epoch(bool maybe_null_arg,
 
111
             const char *field_name_arg,
 
112
             const CHARSET_INFO * const cs) :
 
113
  Field_str((unsigned char*) NULL,
 
114
            DateTime::MAX_STRING_LENGTH - 1 /* no \0 */,
 
115
            maybe_null_arg ? (unsigned char*) "": 0,
 
116
            0,
 
117
            field_name_arg,
 
118
            cs)
107
119
{
108
 
  /* For 4.0 MYD and 4.0 InnoDB compatibility */
109
 
  flags|= UNSIGNED_FLAG;
110
 
    if (unireg_check != TIMESTAMP_DN_FIELD)
111
 
      flags|= ON_UPDATE_NOW_FLAG;
 
120
  if (unireg_check != TIMESTAMP_DN_FIELD)
 
121
    flags|= ON_UPDATE_NOW_FLAG;
112
122
}
113
123
 
114
 
 
115
124
/**
116
125
  Get auto-set type for TIMESTAMP field.
117
126
 
118
127
  Returns value indicating during which operations this TIMESTAMP field
119
128
  should be auto-set to current timestamp.
120
129
*/
121
 
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
 
130
timestamp_auto_set_type Epoch::get_auto_set_type() const
122
131
{
123
132
  switch (unireg_check)
124
133
  {
132
141
      function should be called only for first of them (i.e. the one
133
142
      having auto-set property).
134
143
    */
135
 
    assert(table->timestamp_field == this);
 
144
    assert(getTable()->timestamp_field == this);
136
145
    /* Fall-through */
137
146
  case TIMESTAMP_DNUN_FIELD:
138
147
    return TIMESTAMP_AUTO_SET_ON_BOTH;
146
155
  }
147
156
}
148
157
 
149
 
 
150
 
int Field_timestamp::store(const char *from,
151
 
                           uint32_t len,
152
 
                           const CHARSET_INFO * const cs __attribute__((unused)))
153
 
{
154
 
  DRIZZLE_TIME l_time;
155
 
  my_time_t tmp= 0;
156
 
  int error;
157
 
  bool have_smth_to_conv;
158
 
  bool in_dst_time_gap;
159
 
  Session *session= table ? table->in_use : current_session;
160
 
 
161
 
  /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
162
 
  have_smth_to_conv= (str_to_datetime(from, len, &l_time, 1, &error) >
163
 
                      DRIZZLE_TIMESTAMP_ERROR);
164
 
 
165
 
  if (error || !have_smth_to_conv)
166
 
  {
167
 
    error= 1;
168
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
169
 
                         from, len, DRIZZLE_TIMESTAMP_DATETIME, 1);
170
 
  }
171
 
 
172
 
  /* Only convert a correct date (not a zero date) */
173
 
  if (have_smth_to_conv && l_time.month)
174
 
  {
175
 
    if (!(tmp= TIME_to_timestamp(session, &l_time, &in_dst_time_gap)))
176
 
    {
177
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
178
 
                           ER_WARN_DATA_OUT_OF_RANGE,
179
 
                           from, len, DRIZZLE_TIMESTAMP_DATETIME, !error);
180
 
      error= 1;
181
 
    }
182
 
    else if (in_dst_time_gap)
183
 
    {
184
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
185
 
                           ER_WARN_INVALID_TIMESTAMP,
186
 
                           from, len, DRIZZLE_TIMESTAMP_DATETIME, !error);
187
 
      error= 1;
188
 
    }
189
 
  }
190
 
  store_timestamp(tmp);
191
 
  return error;
192
 
}
193
 
 
194
 
 
195
 
int Field_timestamp::store(double nr)
196
 
{
197
 
  int error= 0;
198
 
  if (nr < 0 || nr > 99991231235959.0)
199
 
  {
200
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
201
 
                         ER_WARN_DATA_OUT_OF_RANGE,
202
 
                         nr, DRIZZLE_TIMESTAMP_DATETIME);
203
 
    nr= 0;                                      // Avoid overflow on buff
204
 
    error= 1;
205
 
  }
206
 
  error|= Field_timestamp::store((int64_t) rint(nr), false);
207
 
  return error;
208
 
}
209
 
 
210
 
 
211
 
int Field_timestamp::store(int64_t nr,
212
 
                           bool unsigned_val __attribute__((unused)))
213
 
{
214
 
  DRIZZLE_TIME l_time;
215
 
  my_time_t timestamp= 0;
216
 
  int error;
217
 
  bool in_dst_time_gap;
218
 
  Session *session= table ? table->in_use : current_session;
219
 
 
220
 
  /* We don't want to store invalid or fuzzy datetime values in TIMESTAMP */
221
 
  int64_t tmp= number_to_datetime(nr, &l_time, (session->variables.sql_mode &
222
 
                                                 MODE_NO_ZERO_DATE), &error);
223
 
  if (tmp == INT64_C(-1))
224
 
  {
225
 
    error= 2;
226
 
  }
227
 
 
228
 
  if (!error && tmp)
229
 
  {
230
 
    if (!(timestamp= TIME_to_timestamp(session, &l_time, &in_dst_time_gap)))
231
 
    {
232
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
233
 
                           ER_WARN_DATA_OUT_OF_RANGE,
234
 
                           nr, DRIZZLE_TIMESTAMP_DATETIME, 1);
235
 
      error= 1;
236
 
    }
237
 
    if (in_dst_time_gap)
238
 
    {
239
 
      set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
240
 
                           ER_WARN_INVALID_TIMESTAMP,
241
 
                           nr, DRIZZLE_TIMESTAMP_DATETIME, 1);
242
 
      error= 1;
243
 
    }
244
 
  } else if (error)
245
 
    set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
246
 
                         ER_WARN_DATA_TRUNCATED,
247
 
                         nr, DRIZZLE_TIMESTAMP_DATETIME, 1);
248
 
 
249
 
  store_timestamp(timestamp);
250
 
  return error;
251
 
}
252
 
 
253
 
double Field_timestamp::val_real(void)
254
 
{
255
 
  return (double) Field_timestamp::val_int();
256
 
}
257
 
 
258
 
int64_t Field_timestamp::val_int(void)
259
 
{
260
 
  uint32_t temp;
261
 
  DRIZZLE_TIME time_tmp;
262
 
  Session  *session= table ? table->in_use : current_session;
263
 
 
264
 
#ifdef WORDS_BIGENDIAN
265
 
  if (table && table->s->db_low_byte_first)
266
 
    temp=uint4korr(ptr);
267
 
  else
268
 
#endif
269
 
    longget(temp,ptr);
270
 
 
271
 
  if (temp == 0L)                               // No time
272
 
    return(0);                                  /* purecov: inspected */
273
 
  
274
 
  session->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (my_time_t)temp);
275
 
  
276
 
  return time_tmp.year * INT64_C(10000000000) +
277
 
         time_tmp.month * INT64_C(100000000) +
278
 
         time_tmp.day * 1000000 + time_tmp.hour * 10000 +
279
 
         time_tmp.minute * 100 + time_tmp.second;
280
 
}
281
 
 
282
 
 
283
 
String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
284
 
{
285
 
  uint32_t temp, temp2;
286
 
  DRIZZLE_TIME time_tmp;
287
 
  Session *session= table ? table->in_use : current_session;
 
158
int Epoch::store(const char *from,
 
159
                 uint32_t len,
 
160
                 const CHARSET_INFO * const )
 
161
{
 
162
  Timestamp temporal;
 
163
 
 
164
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
165
 
 
166
  if (not temporal.from_string(from, (size_t) len))
 
167
  {
 
168
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
 
169
    return 1;
 
170
  }
 
171
 
 
172
  time_t tmp;
 
173
  temporal.to_time_t(tmp);
 
174
 
 
175
  pack_num(tmp);
 
176
  return 0;
 
177
}
 
178
 
 
179
int Epoch::store(double from)
 
180
{
 
181
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
182
 
 
183
  if (from < 0 || from > 99991231235959.0)
 
184
  {
 
185
    /* Convert the double to a string using stringstream */
 
186
    std::stringstream ss;
 
187
    std::string tmp;
 
188
    ss.precision(18); /* 18 places should be fine for error display of double input. */
 
189
    ss << from; 
 
190
    ss >> tmp;
 
191
 
 
192
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
193
    return 2;
 
194
  }
 
195
  return Epoch::store((int64_t) rint(from), false);
 
196
}
 
197
 
 
198
int Epoch::store(int64_t from, bool)
 
199
{
 
200
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
201
 
 
202
  /* 
 
203
   * Try to create a DateTime from the supplied integer.  Throw an error
 
204
   * if unable to create a valid DateTime.  
 
205
   */
 
206
  Timestamp temporal;
 
207
  if (! temporal.from_int64_t(from))
 
208
  {
 
209
    /* Convert the integer to a string using boost::lexical_cast */
 
210
    std::string tmp(boost::lexical_cast<std::string>(from));
 
211
 
 
212
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
 
213
    return 2;
 
214
  }
 
215
 
 
216
  time_t tmp;
 
217
  temporal.to_time_t(tmp);
 
218
 
 
219
  pack_num(tmp);
 
220
 
 
221
  return 0;
 
222
}
 
223
 
 
224
double Epoch::val_real(void)
 
225
{
 
226
  return (double) Epoch::val_int();
 
227
}
 
228
 
 
229
int64_t Epoch::val_int(void)
 
230
{
 
231
  uint64_t temp;
 
232
 
 
233
  ASSERT_COLUMN_MARKED_FOR_READ;
 
234
 
 
235
  unpack_num(temp);
 
236
 
 
237
  Timestamp temporal;
 
238
  (void) temporal.from_time_t((time_t) temp);
 
239
 
 
240
  /* We must convert into a "timestamp-formatted integer" ... */
 
241
  int64_t result;
 
242
  temporal.to_int64_t(&result);
 
243
  return result;
 
244
}
 
245
 
 
246
String *Epoch::val_str(String *val_buffer, String *)
 
247
{
 
248
  uint64_t temp= 0;
288
249
  char *to;
289
 
 
290
 
  val_buffer->alloc(field_length+1);
291
 
  to= (char*) val_buffer->ptr();
292
 
  val_buffer->length(field_length);
293
 
 
294
 
#ifdef WORDS_BIGENDIAN
295
 
  if (table && table->s->db_low_byte_first)
296
 
    temp=uint4korr(ptr);
297
 
  else
298
 
#endif
299
 
    longget(temp,ptr);
300
 
 
301
 
  if (temp == 0L)
302
 
  {                                   /* Zero time is "000000" */
303
 
    val_ptr->set(STRING_WITH_LEN("0000-00-00 00:00:00"), &my_charset_bin);
304
 
    return val_ptr;
305
 
  }
306
 
  val_buffer->set_charset(&my_charset_bin);     // Safety
307
 
  
308
 
  session->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(my_time_t)temp);
309
 
 
310
 
  temp= time_tmp.year % 100;
311
 
  if (temp < YY_PART_YEAR - 1)
312
 
  {
313
 
    *to++= '2';
314
 
    *to++= '0';
315
 
  }
316
 
  else
317
 
  {
318
 
    *to++= '1';
319
 
    *to++= '9';
320
 
  }
321
 
  temp2=temp/10; temp=temp-temp2*10;
322
 
  *to++= (char) ('0'+(char) (temp2));
323
 
  *to++= (char) ('0'+(char) (temp));
324
 
  *to++= '-';
325
 
  temp=time_tmp.month;
326
 
  temp2=temp/10; temp=temp-temp2*10;
327
 
  *to++= (char) ('0'+(char) (temp2));
328
 
  *to++= (char) ('0'+(char) (temp));
329
 
  *to++= '-';
330
 
  temp=time_tmp.day;
331
 
  temp2=temp/10; temp=temp-temp2*10;
332
 
  *to++= (char) ('0'+(char) (temp2));
333
 
  *to++= (char) ('0'+(char) (temp));
334
 
  *to++= ' ';
335
 
  temp=time_tmp.hour;
336
 
  temp2=temp/10; temp=temp-temp2*10;
337
 
  *to++= (char) ('0'+(char) (temp2));
338
 
  *to++= (char) ('0'+(char) (temp));
339
 
  *to++= ':';
340
 
  temp=time_tmp.minute;
341
 
  temp2=temp/10; temp=temp-temp2*10;
342
 
  *to++= (char) ('0'+(char) (temp2));
343
 
  *to++= (char) ('0'+(char) (temp));
344
 
  *to++= ':';
345
 
  temp=time_tmp.second;
346
 
  temp2=temp/10; temp=temp-temp2*10;
347
 
  *to++= (char) ('0'+(char) (temp2));
348
 
  *to++= (char) ('0'+(char) (temp));
349
 
  *to= 0;
 
250
  int to_len= field_length + 1;
 
251
 
 
252
  val_buffer->alloc(to_len);
 
253
  to= (char *) val_buffer->ptr();
 
254
 
 
255
  unpack_num(temp);
 
256
 
 
257
  val_buffer->set_charset(&my_charset_bin);     /* Safety */
 
258
 
 
259
  Timestamp temporal;
 
260
  (void) temporal.from_time_t((time_t) temp);
 
261
 
 
262
  int rlen;
 
263
  rlen= temporal.to_string(to, to_len);
 
264
  assert(rlen < to_len);
 
265
 
 
266
  val_buffer->length(rlen);
350
267
  return val_buffer;
351
268
}
352
269
 
353
 
 
354
 
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
 
270
bool Epoch::get_date(DRIZZLE_TIME *ltime, uint32_t)
355
271
{
356
 
  long temp;
357
 
  Session *session= table ? table->in_use : current_session;
358
 
#ifdef WORDS_BIGENDIAN
359
 
  if (table && table->s->db_low_byte_first)
360
 
    temp=uint4korr(ptr);
361
 
  else
362
 
#endif
363
 
    longget(temp,ptr);
364
 
  if (temp == 0L)
365
 
  {                                   /* Zero time is "000000" */
366
 
    if (fuzzydate & TIME_NO_ZERO_DATE)
367
 
      return 1;
368
 
    memset(ltime, 0, sizeof(*ltime));
369
 
  }
370
 
  else
371
 
  {
372
 
    session->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)temp);
373
 
  }
 
272
  uint64_t temp;
 
273
 
 
274
  unpack_num(temp);
 
275
  
 
276
  memset(ltime, 0, sizeof(*ltime));
 
277
 
 
278
  Timestamp temporal;
 
279
  (void) temporal.from_time_t((time_t) temp);
 
280
 
 
281
  /* @TODO Goodbye the below code when DRIZZLE_TIME is finally gone.. */
 
282
 
 
283
  ltime->time_type= DRIZZLE_TIMESTAMP_DATETIME;
 
284
  ltime->year= temporal.years();
 
285
  ltime->month= temporal.months();
 
286
  ltime->day= temporal.days();
 
287
  ltime->hour= temporal.hours();
 
288
  ltime->minute= temporal.minutes();
 
289
  ltime->second= temporal.seconds();
 
290
 
374
291
  return 0;
375
292
}
376
293
 
377
 
bool Field_timestamp::get_time(DRIZZLE_TIME *ltime)
378
 
{
379
 
  return Field_timestamp::get_date(ltime,0);
380
 
}
381
 
 
382
 
 
383
 
bool Field_timestamp::send_binary(Protocol *protocol)
384
 
{
385
 
  DRIZZLE_TIME tm;
386
 
  Field_timestamp::get_date(&tm, 0);
387
 
  return protocol->store(&tm);
388
 
}
389
 
 
390
 
 
391
 
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
392
 
{
393
 
  int32_t a,b;
394
 
#ifdef WORDS_BIGENDIAN
395
 
  if (table && table->s->db_low_byte_first)
396
 
  {
397
 
    a=sint4korr(a_ptr);
398
 
    b=sint4korr(b_ptr);
399
 
  }
400
 
  else
401
 
#endif
402
 
  {
403
 
  longget(a,a_ptr);
404
 
  longget(b,b_ptr);
405
 
  }
406
 
  return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
407
 
}
408
 
 
409
 
 
410
 
void Field_timestamp::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
411
 
{
412
 
#ifdef WORDS_BIGENDIAN
413
 
  if (!table || !table->s->db_low_byte_first)
 
294
bool Epoch::get_time(DRIZZLE_TIME *ltime)
 
295
{
 
296
  return Epoch::get_date(ltime,0);
 
297
}
 
298
 
 
299
int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
 
300
{
 
301
  uint64_t a,b;
 
302
 
 
303
  unpack_num(a, a_ptr);
 
304
  unpack_num(b, b_ptr);
 
305
 
 
306
  return (a < b) ? -1 : (a > b) ? 1 : 0;
 
307
}
 
308
 
 
309
 
 
310
void Epoch::sort_string(unsigned char *to,uint32_t )
 
311
{
 
312
#ifdef WORDS_BIGENDIAN
 
313
  if (!getTable() || !getTable()->getShare()->db_low_byte_first)
414
314
  {
415
315
    to[0] = ptr[0];
416
316
    to[1] = ptr[1];
417
317
    to[2] = ptr[2];
418
318
    to[3] = ptr[3];
 
319
    to[4] = ptr[4];
 
320
    to[5] = ptr[5];
 
321
    to[6] = ptr[6];
 
322
    to[7] = ptr[7];
419
323
  }
420
324
  else
421
325
#endif
422
326
  {
423
 
    to[0] = ptr[3];
424
 
    to[1] = ptr[2];
425
 
    to[2] = ptr[1];
426
 
    to[3] = ptr[0];
 
327
    to[0] = ptr[7];
 
328
    to[1] = ptr[6];
 
329
    to[2] = ptr[5];
 
330
    to[3] = ptr[4];
 
331
    to[4] = ptr[3];
 
332
    to[5] = ptr[2];
 
333
    to[6] = ptr[1];
 
334
    to[7] = ptr[0];
427
335
  }
428
336
}
429
337
 
430
 
 
431
 
void Field_timestamp::sql_type(String &res) const
 
338
void Epoch::sql_type(String &res) const
432
339
{
433
340
  res.set_ascii(STRING_WITH_LEN("timestamp"));
434
341
}
435
342
 
436
 
 
437
 
void Field_timestamp::set_time()
 
343
void Epoch::set_time()
438
344
{
439
 
  Session *session= table ? table->in_use : current_session;
440
 
  long tmp= (long) session->query_start();
 
345
  Session *session= getTable() ? getTable()->in_use : current_session;
 
346
  time_t tmp= session->query_start();
441
347
  set_notnull();
442
 
  store_timestamp(tmp);
 
348
  pack_num(tmp);
443
349
}
444
350
 
445
 
 
446
 
void Field_timestamp::set_default()
 
351
void Epoch::set_default()
447
352
{
448
 
  if (table->timestamp_field == this &&
 
353
  if (getTable()->timestamp_field == this &&
449
354
      unireg_check != TIMESTAMP_UN_FIELD)
 
355
  {
450
356
    set_time();
 
357
  }
451
358
  else
 
359
  {
452
360
    Field::set_default();
 
361
  }
453
362
}
454
363
 
455
 
long Field_timestamp::get_timestamp(bool *null_value)
 
364
long Epoch::get_timestamp(bool *null_value)
456
365
{
457
366
  if ((*null_value= is_null()))
458
367
    return 0;
459
 
#ifdef WORDS_BIGENDIAN
460
 
  if (table && table->s->db_low_byte_first)
461
 
    return sint4korr(ptr);
462
 
#endif
463
 
  long tmp;
464
 
  longget(tmp,ptr);
465
 
  return tmp;
 
368
 
 
369
  uint64_t tmp;
 
370
  return unpack_num(tmp);
466
371
}
467
372
 
468
 
 
469
 
void Field_timestamp::store_timestamp(my_time_t timestamp)
 
373
size_t Epoch::max_string_length()
470
374
{
471
 
#ifdef WORDS_BIGENDIAN
472
 
  if (table && table->s->db_low_byte_first)
473
 
  {
474
 
    int4store(ptr,timestamp);
475
 
  }
476
 
  else
477
 
#endif
478
 
    longstore(ptr,(uint32_t) timestamp);
 
375
  return sizeof(uint64_t);
479
376
}
480
377
 
 
378
} /* namespace field */
 
379
} /* namespace drizzled */