Commit c45050d2 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-16935 Change the parameter of Field_xxx::store_TIME_with_dec() to const...

MDEV-16935 Change the parameter of Field_xxx::store_TIME_with_dec() to const Datetime* and const Time*
parent 522cd3c7
This diff is collapsed.
......@@ -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 @@ class Field_temporal: public Field {
*/
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 @@ class Field_temporal_with_date: public Field_temporal {
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 @@ class Field_date_common: public Field_temporal_with_date
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 @@ class Field_date :public Field_date_common
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 @@ class Field_timef :public Field_time_with_dec {
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 @@ class Field_datetime_with_dec :public Field_datetime {
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 @@ class Field_datetime_hires :public Field_datetime_with_dec {
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);
}
......
......@@ -466,6 +466,10 @@ class Temporal: protected MYSQL_TIME
time_type= MYSQL_TIMESTAMP_NONE;
}
public:
long fraction_remainder(uint dec) const
{
return my_time_fraction_remainder(second_part, dec);
}
};
......@@ -474,7 +478,7 @@ class Temporal: protected MYSQL_TIME
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 @@ class Temporal_hybrid: private Temporal
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 @@ class Time: private Temporal
/*
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.
*/
DBUG_ASSERT(day < 32);
DBUG_ASSERT(hour < 24);
if (year == 0 && month == 0 &&
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;
}
DBUG_ASSERT(day < 32);
DBUG_ASSERT(hour < 24);
if (opt.datetime_to_time_mode() ==
DATETIME_TO_TIME_YYYYMMDD_000000DD_MIX_TO_HOURS)
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 @@ class Time: private Temporal
/**
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 @@ class Time: private Temporal
- 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 @@ class Time: private Temporal
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 @@ class Time: private Temporal
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 @@ class Time: private Temporal
{
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 @@ class Time: private Temporal
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 @@ class Temporal_with_date: protected Temporal
{
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 @@ class Datetime: public Temporal_with_date
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 @@ class Datetime: public Temporal_with_date
{
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 @@ class Datetime: public Temporal_with_date
{
return is_valid_datetime() ? Temporal::to_packed() : 0;
}
Datetime trunc(uint dec) const
{
Datetime tm(*this);
my_time_trunc(&tm, dec);
return tm;
}
};
......
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