~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/timestamp.cc

  • Committer: Brian Aker
  • Date: 2010-02-10 18:04:24 UTC
  • mfrom: (1286.1.5 build)
  • Revision ID: brian@gaz-20100210180424-03ypoyifmlc2lgcp
Merge of Brian/Padraig

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