Commit 50003a95 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-17274 Split Field_temporal_with_date::store*() for Field_date_common and Field_datetime

parent 81ba90b5
......@@ -5536,38 +5536,24 @@ 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(const Datetime *dt,
const ErrConv *str,
int was_cut)
int Field_datetime::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;
timestamp_type ts_type= type_handler()->mysql_timestamp_type();
ASSERT_COLUMN_MARKED_FOR_WRITE;
// Handle totally bad values
if (!dt->is_valid_datetime())
{
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;
}
return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATETIME);
// Store the value
DBUG_ASSERT(!dt->fraction_remainder(decimals()));
if (ts_type == MYSQL_TIMESTAMP_DATE && !dt->hhmmssff_is_zero())
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
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);
return store_TIME_return_code_with_warnings(was_cut, str,
MYSQL_TIMESTAMP_DATETIME);
}
int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO *cs)
int Field_datetime::store(const char *from, size_t len, CHARSET_INFO *cs)
{
MYSQL_TIME_STATUS st;
ErrConvString str(from, len, cs);
......@@ -5575,7 +5561,7 @@ int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO *
return store_TIME_with_warning(&dt, &str, st.warnings);
}
int Field_temporal_with_date::store(double nr)
int Field_datetime::store(double nr)
{
int error;
ErrConvDouble str(nr);
......@@ -5584,7 +5570,7 @@ int Field_temporal_with_date::store(double nr)
}
int Field_temporal_with_date::store(longlong nr, bool unsigned_val)
int Field_datetime::store(longlong nr, bool unsigned_val)
{
int error;
ErrConvInteger str(nr, unsigned_val);
......@@ -5592,7 +5578,7 @@ int Field_temporal_with_date::store(longlong nr, bool unsigned_val)
return store_TIME_with_warning(&dt, &str, error);
}
int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec)
int Field_datetime::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
int error;
ErrConvTime str(ltime);
......@@ -5602,6 +5588,14 @@ int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec)
}
int Field_datetime::store_decimal(const my_decimal *d)
{
int error;
ErrConvDecimal str(d);
Datetime tm(&error, d, sql_mode_for_dates(get_thd()), decimals());
return store_TIME_with_warning(&tm, &str, error);
}
bool
Field_temporal_with_date::validate_value_in_record(THD *thd,
const uchar *record) const
......@@ -5690,12 +5684,7 @@ int Field_time::store_TIME_with_warning(const Time *t,
ASSERT_COLUMN_MARKED_FOR_WRITE;
// Handle totally bad values
if (!t->is_valid_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;
}
return store_invalid_with_warning(str, warn, MYSQL_TIMESTAMP_TIME);
// Store the value
DBUG_ASSERT(!t->fraction_remainder(decimals()));
store_TIME(t->get_mysql_time());
......@@ -6236,6 +6225,67 @@ void Field_year::sql_type(String &res) const
}
/*****************************************************************************/
int Field_date_common::store_TIME_with_warning(const Datetime *dt,
const ErrConv *str,
int was_cut)
{
ASSERT_COLUMN_MARKED_FOR_WRITE;
// Handle totally bad values
if (!dt->is_valid_datetime())
return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATE);
// Store the value
if (!dt->hhmmssff_is_zero())
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
store_TIME(dt->get_mysql_time());
// Caclulate return value and send warnings if needed
return store_TIME_return_code_with_warnings(was_cut, str,
MYSQL_TIMESTAMP_DATE);
}
int Field_date_common::store(const char *from, size_t len, CHARSET_INFO *cs)
{
MYSQL_TIME_STATUS st;
ErrConvString str(from, len, cs);
Datetime dt(&st, from, len, cs, sql_mode_for_dates(get_thd()));
return store_TIME_with_warning(&dt, &str, st.warnings);
}
int Field_date_common::store(double nr)
{
int error;
ErrConvDouble str(nr);
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()));
return store_TIME_with_warning(&dt, &str, error);
}
int Field_date_common::store(longlong nr, bool unsigned_val)
{
int error;
ErrConvInteger str(nr, unsigned_val);
Datetime dt(&error, nr, unsigned_val, sql_mode_for_dates(get_thd()));
return store_TIME_with_warning(&dt, &str, error);
}
int Field_date_common::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));
return store_TIME_with_warning(&dt, &str, error);
}
int Field_date_common::store_decimal(const my_decimal *d)
{
int error;
ErrConvDecimal str(d);
Datetime tm(&error, d, sql_mode_for_dates(get_thd()));
return store_TIME_with_warning(&tm, &str, error);
}
/****************************************************************************
** date type
** In string context: YYYY-MM-DD
......@@ -6638,14 +6688,6 @@ void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime)
store_bigendian(packed, ptr, Field_datetime_hires::pack_length());
}
int Field_temporal_with_date::store_decimal(const my_decimal *d)
{
int error;
ErrConvDecimal str(d);
Datetime tm(&error, d, sql_mode_for_dates(get_thd()), decimals());
return store_TIME_with_warning(&tm, &str, error);
}
bool Field_datetime_with_dec::send_binary(Protocol *protocol)
{
MYSQL_TIME ltime;
......
......@@ -2594,6 +2594,8 @@ class Field_temporal: public Field {
protected:
Item *get_equal_const_item_datetime(THD *thd, const Context &ctx,
Item *const_item);
void set_warnings(Sql_condition::enum_warning_level trunc_level,
const ErrConv *str, int was_cut, timestamp_type ts_type);
int store_TIME_return_code_with_warnings(int warn, const ErrConv *str,
timestamp_type ts_type)
{
......@@ -2607,7 +2609,20 @@ class Field_temporal: public Field {
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, warn, ts_type);
return warn ? 2 : 0;
}
int store_invalid_with_warning(const ErrConv *str, int was_cut,
timestamp_type ts_type)
{
reset();
Sql_condition::enum_warning_level level= Sql_condition::WARN_LEVEL_WARN;
if (was_cut == 0) // special case: zero date
{
DBUG_ASSERT(ts_type != MYSQL_TIMESTAMP_TIME);
set_warnings(level, str, MYSQL_TIME_WARN_OUT_OF_RANGE, ts_type);
return 2;
}
set_warnings(level, str, MYSQL_TIME_WARN_TRUNCATED, ts_type);
return 1;
}
public:
Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
......@@ -2642,8 +2657,6 @@ class Field_temporal: public Field {
return (Field::eq_def(field) && decimals() == field->decimals());
}
my_decimal *val_decimal(my_decimal*);
void set_warnings(Sql_condition::enum_warning_level trunc_level,
const ErrConv *str, int was_cut, timestamp_type ts_type);
double pos_in_interval(Field *min, Field *max)
{
return pos_in_interval_val_real(min, max);
......@@ -2673,9 +2686,6 @@ class Field_temporal: public Field {
*/
class Field_temporal_with_date: public Field_temporal {
protected:
int store_TIME_with_warning(const Datetime *ltime, const ErrConv *str,
int was_cut);
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;
......@@ -2696,11 +2706,6 @@ class Field_temporal_with_date: public Field_temporal {
:Field_temporal(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg)
{}
int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
bool validate_value_in_record(THD *thd, const uchar *record) const;
};
......@@ -2951,6 +2956,9 @@ class Field_year :public Field_tiny {
class Field_date_common: public Field_temporal_with_date
{
protected:
int store_TIME_with_warning(const Datetime *ltime, const ErrConv *str,
int was_cut);
public:
Field_date_common(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg,
......@@ -2962,6 +2970,11 @@ class Field_date_common: public Field_temporal_with_date
SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, KEY_PART *key_part,
const Item_bool_func *cond,
scalar_comparison_op op, Item *value);
int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
};
......@@ -3039,11 +3052,6 @@ class Field_time :public Field_temporal {
protected:
virtual void store_TIME(const MYSQL_TIME *ltime);
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)
{
Field_temporal::set_warnings(level, str, was_cut, MYSQL_TIMESTAMP_TIME);
}
bool check_zero_in_date_with_warn(ulonglong fuzzydate);
static void do_field_time(Copy_field *copy);
public:
......@@ -3198,6 +3206,9 @@ class Field_timef :public Field_time_with_dec {
class Field_datetime :public Field_temporal_with_date {
void store_TIME(const MYSQL_TIME *ltime);
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
protected:
int store_TIME_with_warning(const Datetime *ltime, const ErrConv *str,
int was_cut);
public:
Field_datetime(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg,
......@@ -3211,6 +3222,11 @@ class Field_datetime :public Field_temporal_with_date {
}
const Type_handler *type_handler() const { return &type_handler_datetime; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
int store(const char *to, size_t length, CHARSET_INFO *charset);
int store(double nr);
int store(longlong nr, bool unsigned_val);
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
int store_decimal(const my_decimal *);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment