mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
MDEV-16935 Change the parameter of Field_xxx::store_TIME_with_dec() to const Datetime* and const Time*
This commit is contained in:
196
sql/field.cc
196
sql/field.cc
@ -5020,13 +5020,12 @@ my_time_t Field_timestamp::get_timestamp(const uchar *pos,
|
||||
}
|
||||
|
||||
|
||||
int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
|
||||
int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
|
||||
const ErrConv *str, int was_cut)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_WRITE;
|
||||
uint error = 0;
|
||||
|
||||
if (MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) || !l_time)
|
||||
if (MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) || !dt->is_valid_datetime())
|
||||
{
|
||||
error= 1;
|
||||
set_datetime_warning(WARN_DATA_TRUNCATED,
|
||||
@ -5038,10 +5037,12 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, MYSQL_TIME *l_time,
|
||||
set_datetime_warning(Sql_condition::WARN_LEVEL_NOTE, WARN_DATA_TRUNCATED,
|
||||
str, MYSQL_TIMESTAMP_DATETIME, 1);
|
||||
}
|
||||
|
||||
/* Only convert a correct date (not a zero date) */
|
||||
if (l_time && l_time->month)
|
||||
if (dt->is_valid_datetime() && dt->get_mysql_time()->month)
|
||||
{
|
||||
uint conversion_error;
|
||||
const MYSQL_TIME *l_time= dt->get_mysql_time();
|
||||
my_time_t timestamp= TIME_to_timestamp(thd, l_time, &conversion_error);
|
||||
if (timestamp == 0 && l_time->second_part == 0)
|
||||
conversion_error= ER_WARN_DATA_OUT_OF_RANGE;
|
||||
@ -5074,46 +5075,37 @@ int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
||||
ErrConvTime str(ltime);
|
||||
THD *thd= get_thd();
|
||||
Datetime dt(thd, &warn, ltime, sql_mode_for_timestamp(thd));
|
||||
ltime= dt.is_valid_datetime() ? dt.get_mysql_time() : NULL;
|
||||
return store_TIME_with_warning(thd, const_cast<MYSQL_TIME*>(ltime),
|
||||
&str, warn);
|
||||
return store_TIME_with_warning(thd, &dt, &str, warn);
|
||||
}
|
||||
|
||||
|
||||
int Field_timestamp::store(const char *from,size_t len,CHARSET_INFO *cs)
|
||||
{
|
||||
MYSQL_TIME l_time;
|
||||
MYSQL_TIME_STATUS status;
|
||||
ErrConvString str(from, len, cs);
|
||||
THD *thd= get_thd();
|
||||
bool rc= str_to_datetime(cs, from, len, &l_time,
|
||||
sql_mode_for_timestamp(thd), &status);
|
||||
return store_TIME_with_warning(thd, rc ? NULL : &l_time, &str,
|
||||
status.warnings);
|
||||
int error;
|
||||
Datetime dt(&error, from, len, cs, sql_mode_for_timestamp(thd));
|
||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
int Field_timestamp::store(double nr)
|
||||
{
|
||||
MYSQL_TIME l_time;
|
||||
int error;
|
||||
ErrConvDouble str(nr);
|
||||
THD *thd= get_thd();
|
||||
bool rc= Sec6(nr).to_datetime(&l_time, sql_mode_for_timestamp(thd), &error);
|
||||
return store_TIME_with_warning(thd, rc ? NULL : &l_time, &str, error);
|
||||
Datetime dt(&error, nr, sql_mode_for_timestamp(thd));
|
||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
int Field_timestamp::store(longlong nr, bool unsigned_val)
|
||||
{
|
||||
MYSQL_TIME l_time;
|
||||
int error;
|
||||
ErrConvInteger str(nr, unsigned_val);
|
||||
THD *thd= get_thd();
|
||||
bool rc= Sec6(nr, unsigned_val).to_datetime(&l_time,
|
||||
sql_mode_for_timestamp(thd),
|
||||
&error);
|
||||
return store_TIME_with_warning(thd, rc ? NULL : &l_time, &str, error);
|
||||
Datetime dt(&error, nr, sql_mode_for_timestamp(thd));
|
||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
@ -5410,11 +5402,10 @@ my_decimal *Field_timestamp_with_dec::val_decimal(my_decimal *d)
|
||||
int Field_timestamp::store_decimal(const my_decimal *d)
|
||||
{
|
||||
int error;
|
||||
MYSQL_TIME ltime;
|
||||
THD *thd= get_thd();
|
||||
ErrConvDecimal str(d);
|
||||
bool rc= Sec6(d).to_datetime(<ime, sql_mode_for_timestamp(thd), &error);
|
||||
return store_TIME_with_warning(thd, rc ? NULL : <ime, &str, error);
|
||||
Datetime dt(&error, d, sql_mode_for_timestamp(thd));
|
||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||
}
|
||||
|
||||
int Field_timestamp_with_dec::set_time()
|
||||
@ -5538,91 +5529,78 @@ void Field_temporal::set_warnings(Sql_condition::enum_warning_level trunc_level,
|
||||
3 Datetime value that was cut (warning level NOTE)
|
||||
This is used by opt_range.cc:get_mm_leaf().
|
||||
*/
|
||||
int Field_temporal_with_date::store_TIME_with_warning(MYSQL_TIME *ltime,
|
||||
int Field_temporal_with_date::store_TIME_with_warning(const Datetime *dt,
|
||||
const ErrConv *str,
|
||||
int was_cut)
|
||||
{
|
||||
Sql_condition::enum_warning_level trunc_level= Sql_condition::WARN_LEVEL_WARN;
|
||||
int ret;
|
||||
timestamp_type ts_type= type_handler()->mysql_timestamp_type();
|
||||
|
||||
ASSERT_COLUMN_MARKED_FOR_WRITE;
|
||||
|
||||
if (was_cut == 0 && !ltime) // special case: zero date
|
||||
// Handle totally bad values
|
||||
if (!dt->is_valid_datetime())
|
||||
{
|
||||
was_cut= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||
store_TIME(const_cast<MYSQL_TIME*>(Datetime().get_mysql_time()));
|
||||
ret= 2;
|
||||
static const Datetime zero;
|
||||
store_TIME(zero.get_mysql_time());
|
||||
if (was_cut == 0) // special case: zero date
|
||||
{
|
||||
set_warnings(trunc_level, str, MYSQL_TIME_WARN_OUT_OF_RANGE, ts_type);
|
||||
return 2;
|
||||
}
|
||||
set_warnings(trunc_level, str, MYSQL_TIME_WARN_TRUNCATED, ts_type);
|
||||
return 1;
|
||||
}
|
||||
else if (!ltime)
|
||||
// Adjust and store the value
|
||||
if (ts_type == MYSQL_TIMESTAMP_DATE)
|
||||
{
|
||||
was_cut= MYSQL_TIME_WARN_TRUNCATED;
|
||||
store_TIME(const_cast<MYSQL_TIME*>(Datetime().get_mysql_time()));
|
||||
ret= 1;
|
||||
if (!dt->hhmmssff_is_zero())
|
||||
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
|
||||
store_TIME(dt->get_mysql_time());
|
||||
}
|
||||
else if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) &&
|
||||
(MYSQL_TIME_WARN_HAVE_NOTES(was_cut) ||
|
||||
(type_handler()->mysql_timestamp_type() == MYSQL_TIMESTAMP_DATE &&
|
||||
(ltime->hour || ltime->minute || ltime->second || ltime->second_part))))
|
||||
else if (dt->fraction_remainder(decimals()))
|
||||
{
|
||||
trunc_level= Sql_condition::WARN_LEVEL_NOTE;
|
||||
was_cut|= MYSQL_TIME_WARN_TRUNCATED;
|
||||
store_TIME(ltime);
|
||||
ret= 3;
|
||||
Datetime truncated(dt->trunc(decimals()));
|
||||
store_TIME(truncated.get_mysql_time());
|
||||
}
|
||||
else
|
||||
{
|
||||
store_TIME(ltime);
|
||||
ret= was_cut ? 2 : 0;
|
||||
}
|
||||
set_warnings(trunc_level, str, was_cut,
|
||||
type_handler()->mysql_timestamp_type());
|
||||
return ret;
|
||||
store_TIME(dt->get_mysql_time());
|
||||
// Caclulate return value and send warnings if needed
|
||||
return store_TIME_return_code_with_warnings(was_cut, str, ts_type);
|
||||
}
|
||||
|
||||
|
||||
int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO *cs)
|
||||
{
|
||||
MYSQL_TIME ltime;
|
||||
MYSQL_TIME_STATUS status;
|
||||
THD *thd= get_thd();
|
||||
int error;
|
||||
ErrConvString str(from, len, cs);
|
||||
bool rc= str_to_datetime(cs, from, len, <ime, sql_mode_for_dates(thd),
|
||||
&status);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, status.warnings);
|
||||
Datetime dt(&error, from, len, cs, sql_mode_for_dates(get_thd()));
|
||||
return store_TIME_with_warning(&dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
int Field_temporal_with_date::store(double nr)
|
||||
{
|
||||
int error= 0;
|
||||
MYSQL_TIME ltime;
|
||||
THD *thd= get_thd();
|
||||
int error;
|
||||
ErrConvDouble str(nr);
|
||||
bool rc= Sec6(nr).to_datetime(<ime, sql_mode_for_dates(thd), &error);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, error);
|
||||
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()));
|
||||
return store_TIME_with_warning(&dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
int Field_temporal_with_date::store(longlong nr, bool unsigned_val)
|
||||
{
|
||||
int error;
|
||||
MYSQL_TIME ltime;
|
||||
THD *thd= get_thd();
|
||||
ErrConvInteger str(nr, unsigned_val);
|
||||
bool rc= Sec6(nr, unsigned_val).to_datetime(<ime, sql_mode_for_dates(thd),
|
||||
&error);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, error);
|
||||
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()));
|
||||
return store_TIME_with_warning(&dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
||||
{
|
||||
int error;
|
||||
ErrConvTime str(ltime);
|
||||
THD *thd= get_thd();
|
||||
Datetime dt(thd, &error, ltime, sql_mode_for_dates(thd));
|
||||
ltime= dt.is_valid_datetime() ? dt.get_mysql_time() : NULL;
|
||||
return store_TIME_with_warning(const_cast<MYSQL_TIME*>(ltime), &str, error);
|
||||
return store_TIME_with_warning(&dt, &str, error);
|
||||
}
|
||||
|
||||
|
||||
@ -5708,34 +5686,28 @@ Item *Field_temporal::get_equal_const_item_datetime(THD *thd,
|
||||
** In number context: HHMMSS
|
||||
** Stored as a 3 byte unsigned int
|
||||
****************************************************************************/
|
||||
int Field_time::store_TIME_with_warning(MYSQL_TIME *ltime,
|
||||
const ErrConv *str, int was_cut)
|
||||
int Field_time::store_TIME_with_warning(const Time *t,
|
||||
const ErrConv *str, int warn)
|
||||
{
|
||||
ASSERT_COLUMN_MARKED_FOR_WRITE;
|
||||
|
||||
if (!ltime)
|
||||
// Handle totally bad values
|
||||
if (!t->is_valid_time())
|
||||
{
|
||||
Datetime tmp;
|
||||
store_TIME(const_cast<MYSQL_TIME*>(tmp.get_mysql_time()));
|
||||
static const Datetime zero;
|
||||
store_TIME(zero.get_mysql_time());
|
||||
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, MYSQL_TIME_WARN_TRUNCATED);
|
||||
return 1;
|
||||
}
|
||||
if (ltime->year != 0 || ltime->month != 0)
|
||||
// Adjust and store the value
|
||||
if (t->fraction_remainder(decimals()))
|
||||
{
|
||||
ltime->year= ltime->month= ltime->day= 0;
|
||||
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
|
||||
Time truncated(t->trunc(decimals()));
|
||||
store_TIME(truncated.get_mysql_time());
|
||||
}
|
||||
my_time_trunc(ltime, decimals());
|
||||
store_TIME(ltime);
|
||||
if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) &&
|
||||
MYSQL_TIME_WARN_HAVE_NOTES(was_cut))
|
||||
{
|
||||
set_warnings(Sql_condition::WARN_LEVEL_NOTE, str,
|
||||
was_cut | MYSQL_TIME_WARN_TRUNCATED);
|
||||
return 3;
|
||||
}
|
||||
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, was_cut);
|
||||
return was_cut ? 2 : 0;
|
||||
else
|
||||
store_TIME(t->get_mysql_time());
|
||||
// Calculate return value and send warnings if needed
|
||||
return store_TIME_return_code_with_warnings(warn, str, MYSQL_TIMESTAMP_TIME);
|
||||
}
|
||||
|
||||
|
||||
@ -5752,12 +5724,10 @@ void Field_time::store_TIME(const MYSQL_TIME *ltime)
|
||||
|
||||
int Field_time::store(const char *from,size_t len,CHARSET_INFO *cs)
|
||||
{
|
||||
MYSQL_TIME ltime;
|
||||
MYSQL_TIME_STATUS status;
|
||||
ErrConvString str(from, len, cs);
|
||||
bool rc= str_to_time(cs, from, len, <ime, sql_mode_for_dates(get_thd()),
|
||||
&status);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, status.warnings);
|
||||
int error;
|
||||
Time tm(&error, from, len, cs, sql_mode_for_dates(get_thd()));
|
||||
return store_TIME_with_warning(&tm, &str, error);
|
||||
}
|
||||
|
||||
|
||||
@ -5766,28 +5736,25 @@ int Field_time::store_time_dec(const MYSQL_TIME *ltime, uint dec)
|
||||
ErrConvTime str(ltime);
|
||||
int warn;
|
||||
Time tm(&warn, ltime, curdays);
|
||||
ltime= tm.is_valid_time() ? tm.get_mysql_time() : NULL;
|
||||
return store_TIME_with_warning(const_cast<MYSQL_TIME *>(ltime), &str, warn);
|
||||
return store_TIME_with_warning(&tm, &str, warn);
|
||||
}
|
||||
|
||||
|
||||
int Field_time::store(double nr)
|
||||
{
|
||||
MYSQL_TIME ltime;
|
||||
ErrConvDouble str(nr);
|
||||
int was_cut;
|
||||
bool rc= Sec6(nr).to_time(<ime, &was_cut);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, was_cut);
|
||||
Time tm(&was_cut, nr);
|
||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||
}
|
||||
|
||||
|
||||
int Field_time::store(longlong nr, bool unsigned_val)
|
||||
{
|
||||
MYSQL_TIME ltime;
|
||||
ErrConvInteger str(nr, unsigned_val);
|
||||
int was_cut;
|
||||
bool rc= Sec6(nr, unsigned_val).to_time(<ime, &was_cut);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, was_cut);
|
||||
Time tm(&was_cut, nr, unsigned_val);
|
||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||
}
|
||||
|
||||
|
||||
@ -5943,10 +5910,9 @@ void Field_time_hires::store_TIME(const MYSQL_TIME *ltime)
|
||||
int Field_time::store_decimal(const my_decimal *d)
|
||||
{
|
||||
ErrConvDecimal str(d);
|
||||
MYSQL_TIME ltime;
|
||||
int was_cut;
|
||||
bool rc= Sec6(d).to_time(<ime, &was_cut);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, was_cut);
|
||||
Time tm(&was_cut, d);
|
||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||
}
|
||||
|
||||
|
||||
@ -6268,7 +6234,7 @@ void Field_year::sql_type(String &res) const
|
||||
** Stored as a 4 byte unsigned int
|
||||
****************************************************************************/
|
||||
|
||||
void Field_date::store_TIME(MYSQL_TIME *ltime)
|
||||
void Field_date::store_TIME(const MYSQL_TIME *ltime)
|
||||
{
|
||||
uint tmp= ltime->year*10000L + ltime->month*100+ltime->day;
|
||||
int4store(ptr,tmp);
|
||||
@ -6361,7 +6327,7 @@ void Field_date::sql_type(String &res) const
|
||||
** In number context: YYYYMMDD
|
||||
****************************************************************************/
|
||||
|
||||
void Field_newdate::store_TIME(MYSQL_TIME *ltime)
|
||||
void Field_newdate::store_TIME(const MYSQL_TIME *ltime)
|
||||
{
|
||||
uint tmp= ltime->year*16*32 + ltime->month*32+ltime->day;
|
||||
int3store(ptr,tmp);
|
||||
@ -6512,7 +6478,7 @@ Item *Field_newdate::get_equal_const_item(THD *thd, const Context &ctx,
|
||||
** Stored as a 8 byte unsigned int. Should sometimes be change to a 6 byte int.
|
||||
****************************************************************************/
|
||||
|
||||
void Field_datetime::store_TIME(MYSQL_TIME *ltime)
|
||||
void Field_datetime::store_TIME(const MYSQL_TIME *ltime)
|
||||
{
|
||||
ulonglong tmp= TIME_to_ulonglong_datetime(ltime);
|
||||
int8store(ptr,tmp);
|
||||
@ -6650,13 +6616,14 @@ int Field_datetime::set_time()
|
||||
thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->query_start());
|
||||
now_time.second_part= thd->query_start_sec_part();
|
||||
set_notnull();
|
||||
my_time_trunc(&now_time, decimals());
|
||||
store_TIME(&now_time);
|
||||
thd->time_zone_used= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime)
|
||||
void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime)
|
||||
{
|
||||
ulonglong packed= sec_part_shift(pack_time(ltime), dec);
|
||||
store_bigendian(packed, ptr, Field_datetime_hires::pack_length());
|
||||
@ -6665,11 +6632,9 @@ void Field_datetime_hires::store_TIME(MYSQL_TIME *ltime)
|
||||
int Field_temporal_with_date::store_decimal(const my_decimal *d)
|
||||
{
|
||||
int error;
|
||||
MYSQL_TIME ltime;
|
||||
THD *thd= get_thd();
|
||||
ErrConvDecimal str(d);
|
||||
bool rc= Sec6(d).to_datetime(<ime, sql_mode_for_dates(thd), &error);
|
||||
return store_TIME_with_warning(rc ? NULL : <ime, &str, error);
|
||||
Datetime tm(&error, d, sql_mode_for_dates(get_thd()));
|
||||
return store_TIME_with_warning(&tm, &str, error);
|
||||
}
|
||||
|
||||
bool Field_datetime_with_dec::send_binary(Protocol *protocol)
|
||||
@ -6742,9 +6707,8 @@ int Field_datetimef::reset()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Field_datetimef::store_TIME(MYSQL_TIME *ltime)
|
||||
void Field_datetimef::store_TIME(const MYSQL_TIME *ltime)
|
||||
{
|
||||
my_time_trunc(ltime, decimals());
|
||||
longlong tmp= TIME_to_longlong_datetime_packed(ltime);
|
||||
my_datetime_packed_to_binary(tmp, ptr, dec);
|
||||
}
|
||||
|
34
sql/field.h
34
sql/field.h
@ -2595,6 +2595,20 @@ class Field_temporal: public Field {
|
||||
protected:
|
||||
Item *get_equal_const_item_datetime(THD *thd, const Context &ctx,
|
||||
Item *const_item);
|
||||
int store_TIME_return_code_with_warnings(int warn, const ErrConv *str,
|
||||
timestamp_type ts_type)
|
||||
{
|
||||
if (!MYSQL_TIME_WARN_HAVE_WARNINGS(warn) &&
|
||||
MYSQL_TIME_WARN_HAVE_NOTES(warn))
|
||||
{
|
||||
set_warnings(Sql_condition::WARN_LEVEL_NOTE, str,
|
||||
warn | MYSQL_TIME_WARN_TRUNCATED, ts_type);
|
||||
return 3;
|
||||
}
|
||||
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, warn, ts_type);
|
||||
return warn ? 2 : 0;
|
||||
}
|
||||
|
||||
public:
|
||||
Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
|
||||
uchar null_bit_arg, utype unireg_check_arg,
|
||||
@ -2660,9 +2674,10 @@ public:
|
||||
*/
|
||||
class Field_temporal_with_date: public Field_temporal {
|
||||
protected:
|
||||
int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str,
|
||||
int store_TIME_with_warning(const Datetime *ltime, const ErrConv *str,
|
||||
int was_cut);
|
||||
virtual void store_TIME(MYSQL_TIME *ltime) = 0;
|
||||
void store_TIME_with_trunc(const Time *);
|
||||
virtual void store_TIME(const MYSQL_TIME *ltime) = 0;
|
||||
virtual bool get_TIME(MYSQL_TIME *ltime, const uchar *pos,
|
||||
ulonglong fuzzydate) const = 0;
|
||||
bool validate_MMDD(bool not_zero_date, uint month, uint day,
|
||||
@ -2694,7 +2709,8 @@ public:
|
||||
class Field_timestamp :public Field_temporal {
|
||||
protected:
|
||||
sql_mode_t sql_mode_for_timestamp(THD *thd) const;
|
||||
int store_TIME_with_warning(THD *, MYSQL_TIME *, const ErrConv *, int warn);
|
||||
int store_TIME_with_warning(THD *, const Datetime *,
|
||||
const ErrConv *, int warn);
|
||||
public:
|
||||
Field_timestamp(uchar *ptr_arg, uint32 len_arg,
|
||||
uchar *null_ptr_arg, uchar null_bit_arg,
|
||||
@ -2948,7 +2964,7 @@ public:
|
||||
|
||||
class Field_date :public Field_date_common
|
||||
{
|
||||
void store_TIME(MYSQL_TIME *ltime);
|
||||
void store_TIME(const MYSQL_TIME *ltime);
|
||||
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
|
||||
public:
|
||||
Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||
@ -2984,7 +3000,7 @@ public:
|
||||
|
||||
class Field_newdate :public Field_date_common
|
||||
{
|
||||
void store_TIME(MYSQL_TIME *ltime);
|
||||
void store_TIME(const MYSQL_TIME *ltime);
|
||||
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
|
||||
public:
|
||||
Field_newdate(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
|
||||
@ -3019,7 +3035,7 @@ class Field_time :public Field_temporal {
|
||||
long curdays;
|
||||
protected:
|
||||
virtual void store_TIME(const MYSQL_TIME *ltime);
|
||||
int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str, int warn);
|
||||
int store_TIME_with_warning(const Time *ltime, const ErrConv *str, int warn);
|
||||
void set_warnings(Sql_condition::enum_warning_level level,
|
||||
const ErrConv *str, int was_cut)
|
||||
{
|
||||
@ -3177,7 +3193,7 @@ public:
|
||||
|
||||
|
||||
class Field_datetime :public Field_temporal_with_date {
|
||||
void store_TIME(MYSQL_TIME *ltime);
|
||||
void store_TIME(const MYSQL_TIME *ltime);
|
||||
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
|
||||
public:
|
||||
Field_datetime(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
|
||||
@ -3270,7 +3286,7 @@ public:
|
||||
DATETIME(1..6)
|
||||
*/
|
||||
class Field_datetime_hires :public Field_datetime_with_dec {
|
||||
void store_TIME(MYSQL_TIME *ltime);
|
||||
void store_TIME(const MYSQL_TIME *ltime);
|
||||
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
|
||||
public:
|
||||
Field_datetime_hires(uchar *ptr_arg, uchar *null_ptr_arg,
|
||||
@ -3293,7 +3309,7 @@ public:
|
||||
DATETIME(0..6) - MySQL56 version
|
||||
*/
|
||||
class Field_datetimef :public Field_datetime_with_dec {
|
||||
void store_TIME(MYSQL_TIME *ltime);
|
||||
void store_TIME(const MYSQL_TIME *ltime);
|
||||
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
|
||||
int save_field_metadata(uchar *metadata_ptr)
|
||||
{
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "sql_time.h"
|
||||
#include "item.h"
|
||||
#include "log.h"
|
||||
#include "tztime.h"
|
||||
|
||||
Type_handler_row type_handler_row;
|
||||
|
||||
@ -359,12 +360,13 @@ VYear_op::VYear_op(Item_func_hybrid_field_type *item)
|
||||
{ }
|
||||
|
||||
|
||||
void Time::make_from_item(Item *item, const Options opt)
|
||||
void Time::make_from_item(int *warn, Item *item, const Options opt)
|
||||
{
|
||||
*warn= 0;
|
||||
if (item->get_date(this, opt.get_date_flags()))
|
||||
time_type= MYSQL_TIMESTAMP_NONE;
|
||||
else
|
||||
valid_MYSQL_TIME_to_valid_value(opt);
|
||||
valid_MYSQL_TIME_to_valid_value(warn, opt);
|
||||
}
|
||||
|
||||
|
||||
|
168
sql/sql_type.h
168
sql/sql_type.h
@ -466,6 +466,10 @@ protected:
|
||||
time_type= MYSQL_TIMESTAMP_NONE;
|
||||
}
|
||||
public:
|
||||
long fraction_remainder(uint dec) const
|
||||
{
|
||||
return my_time_fraction_remainder(second_part, dec);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -474,7 +478,7 @@ public:
|
||||
using Item's native timestamp type, without automatic timestamp
|
||||
type conversion.
|
||||
*/
|
||||
class Temporal_hybrid: private Temporal
|
||||
class Temporal_hybrid: public Temporal
|
||||
{
|
||||
public:
|
||||
Temporal_hybrid(THD *thd, Item *item);
|
||||
@ -524,7 +528,7 @@ public:
|
||||
Time derives from MYSQL_TIME privately to make sure it is accessed
|
||||
externally only in the valid state.
|
||||
*/
|
||||
class Time: private Temporal
|
||||
class Time: public Temporal
|
||||
{
|
||||
public:
|
||||
enum datetime_to_time_mode_t
|
||||
@ -599,30 +603,27 @@ private:
|
||||
/*
|
||||
Convert a valid DATE or DATETIME to TIME.
|
||||
Before this call, "this" must be a valid DATE or DATETIME value,
|
||||
e.g. returned from Item::get_date().
|
||||
e.g. returned from Item::get_date(), str_to_time(), number_to_time().
|
||||
After this call, "this" is a valid TIME value.
|
||||
*/
|
||||
void valid_datetime_to_valid_time(const Options opt)
|
||||
void valid_datetime_to_valid_time(int *warn, const Options opt)
|
||||
{
|
||||
DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATE ||
|
||||
time_type == MYSQL_TIMESTAMP_DATETIME);
|
||||
/*
|
||||
Make sure that day and hour are valid, so the result hour value
|
||||
We're dealing with a DATE or DATETIME returned from
|
||||
str_to_time(), number_to_time() or unpack_time().
|
||||
Do some asserts to make sure the result hour value
|
||||
after mixing days to hours does not go out of the valid TIME range.
|
||||
The maximum hour value after mixing days will be 31*24+23=767,
|
||||
which is within the supported TIME range.
|
||||
Thus no adjust_time_range_or_invalidate() is needed here.
|
||||
*/
|
||||
DBUG_ASSERT(day < 32);
|
||||
DBUG_ASSERT(hour < 24);
|
||||
if (year == 0 && month == 0 &&
|
||||
opt.datetime_to_time_mode() ==
|
||||
if (opt.datetime_to_time_mode() ==
|
||||
DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
|
||||
{
|
||||
/*
|
||||
The maximum hour value after mixing days will be 31*24+23=767,
|
||||
which is within the supported TIME range.
|
||||
Thus no adjust_time_range_or_invalidate() is needed here.
|
||||
*/
|
||||
hour+= day * 24;
|
||||
}
|
||||
datetime_to_time_YYYYMMDD_000000DD_mix_to_hours(warn, year, month, day);
|
||||
year= month= day= 0;
|
||||
time_type= MYSQL_TIMESTAMP_TIME;
|
||||
DBUG_ASSERT(is_valid_time_slow());
|
||||
@ -630,6 +631,7 @@ private:
|
||||
/**
|
||||
Convert valid DATE/DATETIME to valid TIME if needed.
|
||||
This method is called after Item::get_date(),
|
||||
str_to_time(), number_to_time().
|
||||
which can return only valid TIME/DATE/DATETIME values.
|
||||
Before this call, "this" is:
|
||||
- either a valid TIME/DATE/DATETIME value
|
||||
@ -639,12 +641,12 @@ private:
|
||||
- either a valid TIME (within the supported TIME range),
|
||||
- or MYSQL_TIMESTAMP_NONE
|
||||
*/
|
||||
void valid_MYSQL_TIME_to_valid_value(const Options opt)
|
||||
void valid_MYSQL_TIME_to_valid_value(int *warn, const Options opt)
|
||||
{
|
||||
switch (time_type) {
|
||||
case MYSQL_TIMESTAMP_DATE:
|
||||
case MYSQL_TIMESTAMP_DATETIME:
|
||||
valid_datetime_to_valid_time(opt);
|
||||
valid_datetime_to_valid_time(warn, opt);
|
||||
break;
|
||||
case MYSQL_TIMESTAMP_NONE:
|
||||
break;
|
||||
@ -656,6 +658,19 @@ private:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This method is called after number_to_time() and str_to_time(),
|
||||
which can return DATE or DATETIME values. Convert to TIME if needed.
|
||||
We trust that xxx_to_time() returns a valid TIME/DATE/DATETIME value,
|
||||
so here we need to do only simple validation.
|
||||
*/
|
||||
void xxx_to_time_result_to_valid_value(int *warn, const Options opt)
|
||||
{
|
||||
// str_to_time(), number_to_time() never return MYSQL_TIMESTAMP_ERROR
|
||||
DBUG_ASSERT(time_type != MYSQL_TIMESTAMP_ERROR);
|
||||
valid_MYSQL_TIME_to_valid_value(warn, opt);
|
||||
}
|
||||
void adjust_time_range_or_invalidate(int *warn)
|
||||
{
|
||||
if (check_time_range(this, TIME_SECOND_PART_DIGITS, warn))
|
||||
@ -667,12 +682,49 @@ private:
|
||||
long curdays);
|
||||
void make_from_time(int *warn, const MYSQL_TIME *from);
|
||||
void make_from_datetime(int *warn, const MYSQL_TIME *from, long curdays);
|
||||
void make_from_item(class Item *item, const Options opt);
|
||||
void make_from_item(int *warn, Item *item, const Options opt);
|
||||
public:
|
||||
/*
|
||||
All constructors that accept an "int *warn" parameter initialize *warn.
|
||||
The old value gets lost.
|
||||
*/
|
||||
Time() { time_type= MYSQL_TIMESTAMP_NONE; }
|
||||
Time(Item *item) { make_from_item(item, Options()); }
|
||||
Time(Item *item, const Options opt) { make_from_item(item, opt); }
|
||||
Time(Item *item)
|
||||
{
|
||||
int warn;
|
||||
make_from_item(&warn, item, Options());
|
||||
}
|
||||
Time(Item *item, const Options opt)
|
||||
{
|
||||
int warn;
|
||||
make_from_item(&warn, item, opt);
|
||||
}
|
||||
Time(int *warn, const MYSQL_TIME *from, long curdays);
|
||||
Time(int *warn, const char *str, uint len, CHARSET_INFO *cs,
|
||||
const Options opt)
|
||||
{
|
||||
MYSQL_TIME_STATUS status;
|
||||
if (str_to_time(cs, str, len, this, opt.get_date_flags(), &status))
|
||||
time_type= MYSQL_TIMESTAMP_NONE;
|
||||
// The below call will optionally add notes to already collected warnings:
|
||||
xxx_to_time_result_to_valid_value(&status.warnings, opt);
|
||||
*warn= status.warnings;
|
||||
}
|
||||
Time(int *warn, const Sec6 &nr, const Options opt)
|
||||
{
|
||||
if (nr.to_time(this, warn))
|
||||
time_type= MYSQL_TIMESTAMP_NONE;
|
||||
xxx_to_time_result_to_valid_value(warn, opt);
|
||||
}
|
||||
Time(int *warn, double nr)
|
||||
:Temporal(Time(warn, Sec6(nr), Options()))
|
||||
{ }
|
||||
Time(int *warn, longlong nr, bool unsigned_val)
|
||||
:Temporal(Time(warn, Sec6(nr, unsigned_val), Options()))
|
||||
{ }
|
||||
Time(int *warn, const my_decimal *d)
|
||||
:Temporal(Time(warn, Sec6(d), Options()))
|
||||
{ }
|
||||
static sql_mode_t flags_for_get_date()
|
||||
{ return TIME_TIME_ONLY | TIME_INVALID_DATES; }
|
||||
static sql_mode_t comparison_flags_for_get_date()
|
||||
@ -748,6 +800,12 @@ public:
|
||||
{
|
||||
return is_valid_time() ? Temporal::to_packed() : 0;
|
||||
}
|
||||
Time trunc(uint dec) const
|
||||
{
|
||||
Time tm(*this);
|
||||
my_time_trunc(&tm, dec);
|
||||
return tm;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -774,7 +832,7 @@ public:
|
||||
it is accessed externally only in the valid state.
|
||||
*/
|
||||
|
||||
class Temporal_with_date: protected Temporal
|
||||
class Temporal_with_date: public Temporal
|
||||
{
|
||||
protected:
|
||||
void check_date_or_invalidate(int *warn, sql_mode_t flags);
|
||||
@ -792,6 +850,21 @@ protected:
|
||||
{
|
||||
make_from_item(thd, item);
|
||||
}
|
||||
Temporal_with_date(int *warn, const Sec6 &nr, sql_mode_t flags)
|
||||
{
|
||||
DBUG_ASSERT((flags & TIME_TIME_ONLY) == 0);
|
||||
if (nr.to_datetime(this, flags, warn))
|
||||
time_type= MYSQL_TIMESTAMP_NONE;
|
||||
}
|
||||
Temporal_with_date(int *warn, const char *str, uint len, CHARSET_INFO *cs,
|
||||
sql_mode_t flags)
|
||||
{
|
||||
DBUG_ASSERT((flags & TIME_TIME_ONLY) == 0);
|
||||
MYSQL_TIME_STATUS status;
|
||||
if (str_to_datetime(cs, str, len, this, flags, &status))
|
||||
time_type= MYSQL_TIMESTAMP_NONE;
|
||||
*warn= status.warnings;
|
||||
}
|
||||
public:
|
||||
bool check_date_with_warn(ulonglong flags)
|
||||
{
|
||||
@ -916,6 +989,11 @@ class Datetime: public Temporal_with_date
|
||||
DBUG_ASSERT(time_type == MYSQL_TIMESTAMP_DATETIME);
|
||||
return !check_datetime_range(this);
|
||||
}
|
||||
void date_to_datetime_if_needed()
|
||||
{
|
||||
if (time_type == MYSQL_TIMESTAMP_DATE)
|
||||
date_to_datetime(this);
|
||||
}
|
||||
void make_from_time(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||
sql_mode_t flags);
|
||||
void make_from_datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||
@ -924,22 +1002,19 @@ public:
|
||||
Datetime(THD *thd, Item *item, sql_mode_t flags)
|
||||
:Temporal_with_date(thd, item, flags)
|
||||
{
|
||||
if (time_type == MYSQL_TIMESTAMP_DATE)
|
||||
date_to_datetime(this);
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
Datetime(THD *thd, Item *item)
|
||||
:Temporal_with_date(thd, item)
|
||||
{
|
||||
if (time_type == MYSQL_TIMESTAMP_DATE)
|
||||
date_to_datetime(this);
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
Datetime(Item *item)
|
||||
:Temporal_with_date(current_thd, item)
|
||||
{
|
||||
if (time_type == MYSQL_TIMESTAMP_DATE)
|
||||
date_to_datetime(this);
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
Datetime(THD *thd, int *warn, const MYSQL_TIME *from, sql_mode_t flags);
|
||||
@ -947,6 +1022,39 @@ public:
|
||||
{
|
||||
set_zero_time(this, MYSQL_TIMESTAMP_DATETIME);
|
||||
}
|
||||
Datetime(int *warn, const char *str, uint len, CHARSET_INFO *cs,
|
||||
sql_mode_t flags)
|
||||
:Temporal_with_date(warn, str, len, cs, flags)
|
||||
{
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
Datetime(int *warn, double nr, sql_mode_t flags)
|
||||
:Temporal_with_date(warn, Sec6(nr), flags)
|
||||
{
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
Datetime(int *warn, const my_decimal *d, sql_mode_t flags)
|
||||
:Temporal_with_date(warn, Sec6(d), flags)
|
||||
{
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
/*
|
||||
Create a Datime object from a longlong number.
|
||||
Note, unlike in Time(), we don't need an "unsigned_val" here,
|
||||
as it's not important if overflow happened because
|
||||
of a negative number, or because of a huge positive number.
|
||||
*/
|
||||
Datetime(int *warn, longlong sec, ulong usec, sql_mode_t flags)
|
||||
:Temporal_with_date(warn, Sec6(false, (ulonglong) sec, usec), flags)
|
||||
{
|
||||
Sec6 nr(false, (ulonglong) sec, usec);
|
||||
date_to_datetime_if_needed();
|
||||
DBUG_ASSERT(is_valid_value_slow());
|
||||
}
|
||||
|
||||
bool is_valid_datetime() const
|
||||
{
|
||||
/*
|
||||
@ -1019,6 +1127,12 @@ public:
|
||||
{
|
||||
return is_valid_datetime() ? Temporal::to_packed() : 0;
|
||||
}
|
||||
Datetime trunc(uint dec) const
|
||||
{
|
||||
Datetime tm(*this);
|
||||
my_time_trunc(&tm, dec);
|
||||
return tm;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user