83
74
course is non-standard.) In most cases user won't notice any change, only
84
75
exception is different behavior of old/new timestamps during ALTER TABLE.
86
Epoch::Epoch(unsigned char *ptr_arg,
87
unsigned char *null_ptr_arg,
88
unsigned char null_bit_arg,
89
enum utype unireg_check_arg,
90
const char *field_name_arg,
91
drizzled::TableShare *share) :
93
MicroTimestamp::MAX_STRING_LENGTH - 1, /* no \0 */
78
Field_timestamp::Field_timestamp(unsigned char *ptr_arg,
80
unsigned char *null_ptr_arg, unsigned char null_bit_arg,
81
enum utype unireg_check_arg,
82
const char *field_name_arg,
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)
99
unireg_check= unireg_check_arg;
100
if (! share->getTimestampField() && unireg_check != NONE)
88
/* For 4.0 MYD and 4.0 InnoDB compatibility */
89
flags|= UNSIGNED_FLAG;
90
if (!share->timestamp_field && unireg_check != NONE)
102
92
/* This timestamp has auto-update */
103
share->setTimestampField(this);
104
flags|= FUNCTION_DEFAULT_FLAG;
93
share->timestamp_field= this;
94
flags|= TIMESTAMP_FLAG;
105
95
if (unireg_check != TIMESTAMP_DN_FIELD)
106
96
flags|= ON_UPDATE_NOW_FLAG;
110
Epoch::Epoch(bool maybe_null_arg,
111
const char *field_name_arg) :
112
Field_str((unsigned char*) NULL,
113
MicroTimestamp::MAX_STRING_LENGTH - 1, /* no \0 */
114
maybe_null_arg ? (unsigned char*) "": 0,
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)
119
if (unireg_check != TIMESTAMP_DN_FIELD)
120
flags|= ON_UPDATE_NOW_FLAG;
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;
124
116
Get auto-set type for TIMESTAMP field.
126
118
Returns value indicating during which operations this TIMESTAMP field
127
119
should be auto-set to current timestamp.
129
timestamp_auto_set_type Epoch::get_auto_set_type() const
121
timestamp_auto_set_type Field_timestamp::get_auto_set_type() const
131
123
switch (unireg_check)
157
int Epoch::store(const char *from,
159
const CHARSET_INFO * const )
163
ASSERT_COLUMN_MARKED_FOR_WRITE;
165
if (not temporal.from_string(from, (size_t) len))
167
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), from);
172
temporal.to_time_t(tmp);
174
uint64_t time_tmp= tmp;
179
int Epoch::store(double from)
181
ASSERT_COLUMN_MARKED_FOR_WRITE;
183
uint64_t from_tmp= (uint64_t)from;
186
if (not temporal.from_int64_t(from_tmp))
188
/* Convert the integer to a string using boost::lexical_cast */
189
std::string tmp(boost::lexical_cast<std::string>(from));
191
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
196
temporal.to_time_t(tmp);
198
uint64_t tmp_micro= tmp;
204
int Epoch::store_decimal(const type::Decimal *value)
212
int Epoch::store(int64_t from, bool)
214
ASSERT_COLUMN_MARKED_FOR_WRITE;
217
* Try to create a DateTime from the supplied integer. Throw an error
218
* if unable to create a valid DateTime.
221
if (not temporal.from_int64_t(from))
223
/* Convert the integer to a string using boost::lexical_cast */
224
std::string tmp(boost::lexical_cast<std::string>(from));
226
my_error(ER_INVALID_TIMESTAMP_VALUE, MYF(ME_FATALERROR), tmp.c_str());
231
temporal.to_time_t(tmp);
239
double Epoch::val_real(void) const
241
return (double) Epoch::val_int();
244
int64_t Epoch::val_int(void) const
248
ASSERT_COLUMN_MARKED_FOR_READ;
253
(void) temporal.from_time_t((time_t) temp);
255
/* We must convert into a "timestamp-formatted integer" ... */
257
temporal.to_int64_t(&result);
261
String *Epoch::val_str(String *val_buffer, String *) const
150
int Field_timestamp::store(const char *from,
152
const CHARSET_INFO * const )
157
bool have_smth_to_conv;
158
bool in_dst_time_gap;
159
Session *session= table ? table->in_use : current_session;
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);
165
if (error || !have_smth_to_conv)
168
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
169
from, len, DRIZZLE_TIMESTAMP_DATETIME, 1);
172
/* Only convert a correct date (not a zero date) */
173
if (have_smth_to_conv && l_time.month)
175
if (!(tmp= TIME_to_timestamp(session, &l_time, &in_dst_time_gap)))
177
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
178
ER_WARN_DATA_OUT_OF_RANGE,
179
from, len, DRIZZLE_TIMESTAMP_DATETIME, !error);
182
else if (in_dst_time_gap)
184
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
185
ER_WARN_INVALID_TIMESTAMP,
186
from, len, DRIZZLE_TIMESTAMP_DATETIME, !error);
190
store_timestamp(tmp);
195
int Field_timestamp::store(double nr)
198
if (nr < 0 || nr > 99991231235959.0)
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
206
error|= Field_timestamp::store((int64_t) rint(nr), false);
211
int Field_timestamp::store(int64_t nr,
217
bool in_dst_time_gap;
218
Session *session= table ? table->in_use : current_session;
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))
230
if (!(timestamp= TIME_to_timestamp(session, &l_time, &in_dst_time_gap)))
232
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
233
ER_WARN_DATA_OUT_OF_RANGE,
234
nr, DRIZZLE_TIMESTAMP_DATETIME, 1);
239
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
240
ER_WARN_INVALID_TIMESTAMP,
241
nr, DRIZZLE_TIMESTAMP_DATETIME, 1);
245
set_datetime_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
246
ER_WARN_DATA_TRUNCATED,
247
nr, DRIZZLE_TIMESTAMP_DATETIME, 1);
249
store_timestamp(timestamp);
253
double Field_timestamp::val_real(void)
255
return (double) Field_timestamp::val_int();
258
int64_t Field_timestamp::val_int(void)
261
DRIZZLE_TIME time_tmp;
262
Session *session= table ? table->in_use : current_session;
264
#ifdef WORDS_BIGENDIAN
265
if (table && table->s->db_low_byte_first)
271
if (temp == 0L) // No time
272
return(0); /* purecov: inspected */
274
session->variables.time_zone->gmt_sec_to_TIME(&time_tmp, (time_t)temp);
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;
283
String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
285
uint32_t temp, temp2;
286
DRIZZLE_TIME time_tmp;
287
Session *session= table ? table->in_use : current_session;
265
int to_len= field_length + 1;
267
val_buffer->alloc(to_len);
268
to= (char *) val_buffer->ptr();
272
val_buffer->set_charset(&my_charset_bin); /* Safety */
275
(void) temporal.from_time_t((time_t) temp);
278
rlen= temporal.to_string(to, to_len);
279
assert(rlen < to_len);
281
val_buffer->length(rlen);
290
val_buffer->alloc(field_length+1);
291
to= (char*) val_buffer->ptr();
292
val_buffer->length(field_length);
294
#ifdef WORDS_BIGENDIAN
295
if (table && table->s->db_low_byte_first)
302
{ /* Zero time is "000000" */
303
val_ptr->set(STRING_WITH_LEN("0000-00-00 00:00:00"), &my_charset_bin);
306
val_buffer->set_charset(&my_charset_bin); // Safety
308
session->variables.time_zone->gmt_sec_to_TIME(&time_tmp,(time_t)temp);
310
temp= time_tmp.year % 100;
311
if (temp < YY_PART_YEAR - 1)
321
temp2=temp/10; temp=temp-temp2*10;
322
*to++= (char) ('0'+(char) (temp2));
323
*to++= (char) ('0'+(char) (temp));
326
temp2=temp/10; temp=temp-temp2*10;
327
*to++= (char) ('0'+(char) (temp2));
328
*to++= (char) ('0'+(char) (temp));
331
temp2=temp/10; temp=temp-temp2*10;
332
*to++= (char) ('0'+(char) (temp2));
333
*to++= (char) ('0'+(char) (temp));
336
temp2=temp/10; temp=temp-temp2*10;
337
*to++= (char) ('0'+(char) (temp2));
338
*to++= (char) ('0'+(char) (temp));
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));
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));
282
350
return val_buffer;
285
bool Epoch::get_date(type::Time <ime, uint32_t) const
354
bool Field_timestamp::get_date(DRIZZLE_TIME *ltime, uint32_t fuzzydate)
288
type::Time::epoch_t time_temp;
295
ltime.store(time_temp);
357
Session *session= table ? table->in_use : current_session;
358
#ifdef WORDS_BIGENDIAN
359
if (table && table->s->db_low_byte_first)
365
{ /* Zero time is "000000" */
366
if (fuzzydate & TIME_NO_ZERO_DATE)
368
memset(ltime, 0, sizeof(*ltime));
372
session->variables.time_zone->gmt_sec_to_TIME(ltime, (time_t)temp);
300
bool Epoch::get_time(type::Time <ime) const
302
return Epoch::get_date(ltime, 0);
305
int Epoch::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
309
unpack_num(a, a_ptr);
310
unpack_num(b, b_ptr);
312
return (a < b) ? -1 : (a > b) ? 1 : 0;
316
void Epoch::sort_string(unsigned char *to,uint32_t )
318
#ifdef WORDS_BIGENDIAN
319
if (!getTable() || !getTable()->getShare()->db_low_byte_first)
377
bool Field_timestamp::get_time(DRIZZLE_TIME *ltime)
379
return Field_timestamp::get_date(ltime,0);
383
bool Field_timestamp::send_binary(Protocol *protocol)
386
Field_timestamp::get_date(&tm, 0);
387
return protocol->store(&tm);
391
int Field_timestamp::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
394
#ifdef WORDS_BIGENDIAN
395
if (table && table->s->db_low_byte_first)
406
return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
410
void Field_timestamp::sort_string(unsigned char *to,uint32_t )
412
#ifdef WORDS_BIGENDIAN
413
if (!table || !table->s->db_low_byte_first)
344
void Epoch::sql_type(String &res) const
431
void Field_timestamp::sql_type(String &res) const
346
433
res.set_ascii(STRING_WITH_LEN("timestamp"));
349
void Epoch::set_time()
437
void Field_timestamp::set_time()
351
Session *session= getTable() ? getTable()->in_use : current_session;
352
time_t tmp= session->getCurrentTimestampEpoch();
439
Session *session= table ? table->in_use : current_session;
440
long tmp= (long) session->query_start();
355
pack_num(static_cast<uint32_t>(tmp));
442
store_timestamp(tmp);
358
void Epoch::set_default()
446
void Field_timestamp::set_default()
360
if (getTable()->timestamp_field == this &&
448
if (table->timestamp_field == this &&
361
449
unireg_check != TIMESTAMP_UN_FIELD)
367
452
Field::set_default();
371
long Epoch::get_timestamp(bool *null_value) const
455
long Field_timestamp::get_timestamp(bool *null_value)
373
457
if ((*null_value= is_null()))
377
return unpack_num(tmp);
459
#ifdef WORDS_BIGENDIAN
460
if (table && table->s->db_low_byte_first)
461
return sint4korr(ptr);
380
size_t Epoch::max_string_length()
469
void Field_timestamp::store_timestamp(time_t timestamp)
382
return sizeof(uint64_t);
471
#ifdef WORDS_BIGENDIAN
472
if (table && table->s->db_low_byte_first)
474
int4store(ptr,timestamp);
478
longstore(ptr,(uint32_t) timestamp);
385
} /* namespace field */
386
} /* namespace drizzled */