~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/timestamp.cc

code clean move Item_func_num1 and Item_func_connection_id to functions directory

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