~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/timestamp.cc

  • Committer: Monty Taylor
  • Date: 2008-08-01 23:59:59 UTC
  • mto: (236.1.42 codestyle)
  • mto: This revision was merged to the branch mainline in revision 261.
  • Revision ID: monty@inaugust.com-20080801235959-n8ypy9r5aohown77
Gettext error compiles and passes test!

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