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, ...@@ -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) 3 Datetime value that was cut (warning level NOTE)
This is used by opt_range.cc:get_mm_leaf(). This is used by opt_range.cc:get_mm_leaf().
*/ */
int Field_temporal_with_date::store_TIME_with_warning(const Datetime *dt, int Field_datetime::store_TIME_with_warning(const Datetime *dt,
const ErrConv *str, const ErrConv *str,
int was_cut) 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; ASSERT_COLUMN_MARKED_FOR_WRITE;
// Handle totally bad values // Handle totally bad values
if (!dt->is_valid_datetime()) if (!dt->is_valid_datetime())
{ return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_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;
}
// Store the value // Store the value
DBUG_ASSERT(!dt->fraction_remainder(decimals())); 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()); store_TIME(dt->get_mysql_time());
// Caclulate return value and send warnings if needed // 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; MYSQL_TIME_STATUS st;
ErrConvString str(from, len, cs); ErrConvString str(from, len, cs);
...@@ -5575,7 +5561,7 @@ int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO * ...@@ -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); 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; int error;
ErrConvDouble str(nr); ErrConvDouble str(nr);
...@@ -5584,7 +5570,7 @@ int Field_temporal_with_date::store(double 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; int error;
ErrConvInteger str(nr, unsigned_val); ErrConvInteger str(nr, unsigned_val);
...@@ -5592,7 +5578,7 @@ int Field_temporal_with_date::store(longlong nr, bool 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); 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; int error;
ErrConvTime str(ltime); ErrConvTime str(ltime);
...@@ -5602,6 +5588,14 @@ int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec) ...@@ -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 bool
Field_temporal_with_date::validate_value_in_record(THD *thd, Field_temporal_with_date::validate_value_in_record(THD *thd,
const uchar *record) const const uchar *record) const
...@@ -5690,12 +5684,7 @@ int Field_time::store_TIME_with_warning(const Time *t, ...@@ -5690,12 +5684,7 @@ int Field_time::store_TIME_with_warning(const Time *t,
ASSERT_COLUMN_MARKED_FOR_WRITE; ASSERT_COLUMN_MARKED_FOR_WRITE;
// Handle totally bad values // Handle totally bad values
if (!t->is_valid_time()) if (!t->is_valid_time())
{ return store_invalid_with_warning(str, warn, MYSQL_TIMESTAMP_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;
}
// Store the value // Store the value
DBUG_ASSERT(!t->fraction_remainder(decimals())); DBUG_ASSERT(!t->fraction_remainder(decimals()));
store_TIME(t->get_mysql_time()); store_TIME(t->get_mysql_time());
...@@ -6236,6 +6225,67 @@ void Field_year::sql_type(String &res) const ...@@ -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 ** date type
** In string context: YYYY-MM-DD ** In string context: YYYY-MM-DD
...@@ -6638,14 +6688,6 @@ void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime) ...@@ -6638,14 +6688,6 @@ void Field_datetime_hires::store_TIME(const MYSQL_TIME *ltime)
store_bigendian(packed, ptr, Field_datetime_hires::pack_length()); 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) bool Field_datetime_with_dec::send_binary(Protocol *protocol)
{ {
MYSQL_TIME ltime; MYSQL_TIME ltime;
......
...@@ -2594,6 +2594,8 @@ class Field_temporal: public Field { ...@@ -2594,6 +2594,8 @@ class Field_temporal: public Field {
protected: protected:
Item *get_equal_const_item_datetime(THD *thd, const Context &ctx, Item *get_equal_const_item_datetime(THD *thd, const Context &ctx,
Item *const_item); 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, int store_TIME_return_code_with_warnings(int warn, const ErrConv *str,
timestamp_type ts_type) timestamp_type ts_type)
{ {
...@@ -2607,7 +2609,20 @@ class Field_temporal: public Field { ...@@ -2607,7 +2609,20 @@ class Field_temporal: public Field {
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, warn, ts_type); set_warnings(Sql_condition::WARN_LEVEL_WARN, str, warn, ts_type);
return warn ? 2 : 0; 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: public:
Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg, uchar null_bit_arg, utype unireg_check_arg,
...@@ -2642,8 +2657,6 @@ class Field_temporal: public Field { ...@@ -2642,8 +2657,6 @@ class Field_temporal: public Field {
return (Field::eq_def(field) && decimals() == field->decimals()); return (Field::eq_def(field) && decimals() == field->decimals());
} }
my_decimal *val_decimal(my_decimal*); 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) double pos_in_interval(Field *min, Field *max)
{ {
return pos_in_interval_val_real(min, max); return pos_in_interval_val_real(min, max);
...@@ -2673,9 +2686,6 @@ class Field_temporal: public Field { ...@@ -2673,9 +2686,6 @@ class Field_temporal: public Field {
*/ */
class Field_temporal_with_date: public Field_temporal { class Field_temporal_with_date: public Field_temporal {
protected: 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 void store_TIME(const MYSQL_TIME *ltime) = 0;
virtual bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, virtual bool get_TIME(MYSQL_TIME *ltime, const uchar *pos,
ulonglong fuzzydate) const = 0; ulonglong fuzzydate) const = 0;
...@@ -2696,11 +2706,6 @@ class Field_temporal_with_date: public Field_temporal { ...@@ -2696,11 +2706,6 @@ class Field_temporal_with_date: public Field_temporal {
:Field_temporal(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, :Field_temporal(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_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; bool validate_value_in_record(THD *thd, const uchar *record) const;
}; };
...@@ -2951,6 +2956,9 @@ class Field_year :public Field_tiny { ...@@ -2951,6 +2956,9 @@ class Field_year :public Field_tiny {
class Field_date_common: public Field_temporal_with_date 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: public:
Field_date_common(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, Field_date_common(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg, enum utype unireg_check_arg,
...@@ -2962,6 +2970,11 @@ class Field_date_common: public Field_temporal_with_date ...@@ -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, SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, KEY_PART *key_part,
const Item_bool_func *cond, const Item_bool_func *cond,
scalar_comparison_op op, Item *value); 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 { ...@@ -3039,11 +3052,6 @@ class Field_time :public Field_temporal {
protected: protected:
virtual void store_TIME(const MYSQL_TIME *ltime); virtual void store_TIME(const MYSQL_TIME *ltime);
int store_TIME_with_warning(const 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)
{
Field_temporal::set_warnings(level, str, was_cut, MYSQL_TIMESTAMP_TIME);
}
bool check_zero_in_date_with_warn(ulonglong fuzzydate); bool check_zero_in_date_with_warn(ulonglong fuzzydate);
static void do_field_time(Copy_field *copy); static void do_field_time(Copy_field *copy);
public: public:
...@@ -3198,6 +3206,9 @@ class Field_timef :public Field_time_with_dec { ...@@ -3198,6 +3206,9 @@ class Field_timef :public Field_time_with_dec {
class Field_datetime :public Field_temporal_with_date { class Field_datetime :public Field_temporal_with_date {
void store_TIME(const MYSQL_TIME *ltime); void store_TIME(const MYSQL_TIME *ltime);
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const; 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: public:
Field_datetime(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg, Field_datetime(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg, uchar null_bit_arg, enum utype unireg_check_arg,
...@@ -3211,6 +3222,11 @@ class Field_datetime :public Field_temporal_with_date { ...@@ -3211,6 +3222,11 @@ class Field_datetime :public Field_temporal_with_date {
} }
const Type_handler *type_handler() const { return &type_handler_datetime; } const Type_handler *type_handler() const { return &type_handler_datetime; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } 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); double val_real(void);
longlong val_int(void); longlong val_int(void);
String *val_str(String*,String *); 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