MDEV-17928 Conversion from TIMESTAMP to VARCHAR SP variables does not work well on fractional digits
This commit is contained in:
parent
fac997feef
commit
a25ce5ab4b
@ -8559,11 +8559,11 @@ RETURN a = timestamp'2038-01-19 03:14:07.999999'
|
|||||||
END
|
END
|
||||||
$$
|
$$
|
||||||
SELECT f1(e) FROM t1;
|
SELECT f1(e) FROM t1;
|
||||||
ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30'
|
ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30.000000'
|
||||||
SELECT f2(e) FROM t1;
|
SELECT f2(e) FROM t1;
|
||||||
ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30'
|
ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30.000000'
|
||||||
SELECT f3(e) FROM t1;
|
SELECT f3(e) FROM t1;
|
||||||
ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30'
|
ERROR 22007: Truncated incorrect DOUBLE value: '2001-01-01 10:20:30.000000'
|
||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP FUNCTION f2;
|
DROP FUNCTION f2;
|
||||||
DROP FUNCTION f3;
|
DROP FUNCTION f3;
|
||||||
|
@ -1033,5 +1033,40 @@ CREATE TABLE t1 (a TIMESTAMP);
|
|||||||
INSERT INTO t1 SELECT CAST(20010101 AS UNSIGNED);
|
INSERT INTO t1 SELECT CAST(20010101 AS UNSIGNED);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-17928 Conversion from TIMESTAMP to VARCHAR SP variables does not work well on fractional digits
|
||||||
|
#
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30.123456');
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE ts10 TIMESTAMP(1) DEFAULT NOW();
|
||||||
|
DECLARE ts16 TIMESTAMP(1) DEFAULT NOW(6);
|
||||||
|
DECLARE dt10 DATETIME(1) DEFAULT NOW();
|
||||||
|
DECLARE dt16 DATETIME(1) DEFAULT NOW(6);
|
||||||
|
DECLARE vts10 VARCHAR(32) DEFAULT ts10;
|
||||||
|
DECLARE vts16 VARCHAR(32) DEFAULT ts16;
|
||||||
|
DECLARE vdt10 VARCHAR(32) DEFAULT dt10;
|
||||||
|
DECLARE vdt16 VARCHAR(32) DEFAULT dt16;
|
||||||
|
DECLARE tts10 TEXT(32) DEFAULT ts10;
|
||||||
|
DECLARE tts16 TEXT(32) DEFAULT ts16;
|
||||||
|
DECLARE tdt10 TEXT(32) DEFAULT dt10;
|
||||||
|
DECLARE tdt16 TEXT(32) DEFAULT dt16;
|
||||||
|
SELECT vts10, vts16, vdt10, vdt16;
|
||||||
|
SELECT tts10, tts16, tdt10, tdt16;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
CALL p1;
|
||||||
|
vts10 2001-01-01 10:20:30.0
|
||||||
|
vts16 2001-01-01 10:20:30.1
|
||||||
|
vdt10 2001-01-01 10:20:30.0
|
||||||
|
vdt16 2001-01-01 10:20:30.1
|
||||||
|
tts10 2001-01-01 10:20:30.0
|
||||||
|
tts16 2001-01-01 10:20:30.1
|
||||||
|
tdt10 2001-01-01 10:20:30.0
|
||||||
|
tdt16 2001-01-01 10:20:30.1
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
#
|
||||||
# End of 10.4 tests
|
# End of 10.4 tests
|
||||||
#
|
#
|
||||||
|
@ -625,6 +625,41 @@ CREATE TABLE t1 (a TIMESTAMP);
|
|||||||
INSERT INTO t1 SELECT CAST(20010101 AS UNSIGNED);
|
INSERT INTO t1 SELECT CAST(20010101 AS UNSIGNED);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-17928 Conversion from TIMESTAMP to VARCHAR SP variables does not work well on fractional digits
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET time_zone='+00:00';
|
||||||
|
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30.123456');
|
||||||
|
DELIMITER $$;
|
||||||
|
CREATE PROCEDURE p1()
|
||||||
|
BEGIN
|
||||||
|
DECLARE ts10 TIMESTAMP(1) DEFAULT NOW();
|
||||||
|
DECLARE ts16 TIMESTAMP(1) DEFAULT NOW(6);
|
||||||
|
DECLARE dt10 DATETIME(1) DEFAULT NOW();
|
||||||
|
DECLARE dt16 DATETIME(1) DEFAULT NOW(6);
|
||||||
|
DECLARE vts10 VARCHAR(32) DEFAULT ts10;
|
||||||
|
DECLARE vts16 VARCHAR(32) DEFAULT ts16;
|
||||||
|
DECLARE vdt10 VARCHAR(32) DEFAULT dt10;
|
||||||
|
DECLARE vdt16 VARCHAR(32) DEFAULT dt16;
|
||||||
|
DECLARE tts10 TEXT(32) DEFAULT ts10;
|
||||||
|
DECLARE tts16 TEXT(32) DEFAULT ts16;
|
||||||
|
DECLARE tdt10 TEXT(32) DEFAULT dt10;
|
||||||
|
DECLARE tdt16 TEXT(32) DEFAULT dt16;
|
||||||
|
|
||||||
|
SELECT vts10, vts16, vdt10, vdt16;
|
||||||
|
SELECT tts10, tts16, tdt10, tdt16;
|
||||||
|
END;
|
||||||
|
$$
|
||||||
|
DELIMITER ;$$
|
||||||
|
--vertical_results
|
||||||
|
CALL p1;
|
||||||
|
--horizontal_results
|
||||||
|
DROP PROCEDURE p1;
|
||||||
|
SET timestamp=DEFAULT;
|
||||||
|
SET time_zone=DEFAULT;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.4 tests
|
--echo # End of 10.4 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
15
sql/field.cc
15
sql/field.cc
@ -1831,12 +1831,9 @@ int Field::store(const char *to, size_t length, CHARSET_INFO *cs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field::store_timestamp(my_time_t ts, ulong sec_part)
|
int Field::store_timestamp_dec(const timeval &ts, uint dec)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
return store_time_dec(Datetime(get_thd(), ts).get_mysql_time(), dec);
|
||||||
THD *thd= get_thd();
|
|
||||||
thd->timestamp_to_TIME(<ime, ts, sec_part, date_mode_t(0));
|
|
||||||
return store_time_dec(<ime, decimals());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -5014,7 +5011,7 @@ int Field_timestamp::save_in_field(Field *to)
|
|||||||
{
|
{
|
||||||
ulong sec_part;
|
ulong sec_part;
|
||||||
my_time_t ts= get_timestamp(&sec_part);
|
my_time_t ts= get_timestamp(&sec_part);
|
||||||
return to->store_timestamp(ts, sec_part);
|
return to->store_timestamp_dec(Timeval(ts, sec_part), decimals());
|
||||||
}
|
}
|
||||||
|
|
||||||
my_time_t Field_timestamp::get_timestamp(const uchar *pos,
|
my_time_t Field_timestamp::get_timestamp(const uchar *pos,
|
||||||
@ -5126,11 +5123,11 @@ int Field_timestamp::store(longlong nr, bool unsigned_val)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
|
int Field_timestamp::store_timestamp_dec(const timeval &ts, uint dec)
|
||||||
{
|
{
|
||||||
int warn= 0;
|
int warn= 0;
|
||||||
time_round_mode_t mode= Datetime::default_round_mode(get_thd());
|
time_round_mode_t mode= Datetime::default_round_mode(get_thd());
|
||||||
store_TIMESTAMP(Timestamp(ts, sec_part).round(decimals(), mode, &warn));
|
store_TIMESTAMP(Timestamp(ts).round(decimals(), mode, &warn));
|
||||||
if (warn)
|
if (warn)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -5144,7 +5141,7 @@ int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
|
|||||||
*/
|
*/
|
||||||
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
|
||||||
}
|
}
|
||||||
if (ts == 0 && sec_part == 0 &&
|
if (ts.tv_sec == 0 && ts.tv_usec == 0 &&
|
||||||
get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE)
|
get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE)
|
||||||
{
|
{
|
||||||
ErrConvString s(
|
ErrConvString s(
|
||||||
|
@ -784,7 +784,12 @@ public:
|
|||||||
virtual int store(longlong nr, bool unsigned_val)=0;
|
virtual int store(longlong nr, bool unsigned_val)=0;
|
||||||
virtual int store_decimal(const my_decimal *d)=0;
|
virtual int store_decimal(const my_decimal *d)=0;
|
||||||
virtual int store_time_dec(const MYSQL_TIME *ltime, uint dec);
|
virtual int store_time_dec(const MYSQL_TIME *ltime, uint dec);
|
||||||
virtual int store_timestamp(my_time_t timestamp, ulong sec_part);
|
virtual int store_timestamp_dec(const timeval &ts, uint dec);
|
||||||
|
int store_timestamp(my_time_t timestamp, ulong sec_part)
|
||||||
|
{
|
||||||
|
return store_timestamp_dec(Timeval(timestamp, sec_part),
|
||||||
|
TIME_SECOND_PART_DIGITS);
|
||||||
|
}
|
||||||
int store_time(const MYSQL_TIME *ltime)
|
int store_time(const MYSQL_TIME *ltime)
|
||||||
{ return store_time_dec(ltime, TIME_SECOND_PART_DIGITS); }
|
{ return store_time_dec(ltime, TIME_SECOND_PART_DIGITS); }
|
||||||
int store(const char *to, size_t length, CHARSET_INFO *cs,
|
int store(const char *to, size_t length, CHARSET_INFO *cs,
|
||||||
@ -2744,7 +2749,7 @@ public:
|
|||||||
int store(longlong nr, bool unsigned_val);
|
int store(longlong nr, bool unsigned_val);
|
||||||
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
|
int store_time_dec(const MYSQL_TIME *ltime, uint dec);
|
||||||
int store_decimal(const my_decimal *);
|
int store_decimal(const my_decimal *);
|
||||||
int store_timestamp(my_time_t timestamp, ulong sec_part);
|
int store_timestamp_dec(const timeval &ts, uint dec);
|
||||||
int save_in_field(Field *to);
|
int save_in_field(Field *to);
|
||||||
double val_real(void);
|
double val_real(void);
|
||||||
longlong val_int(void);
|
longlong val_int(void);
|
||||||
|
@ -7495,7 +7495,8 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
|
|||||||
}
|
}
|
||||||
else if (part_info->vers_info->interval.is_set())
|
else if (part_info->vers_info->interval.is_set())
|
||||||
{
|
{
|
||||||
table->field[11]->store_timestamp((my_time_t)part_elem->range_value, 0);
|
Timeval tv((my_time_t) part_elem->range_value, 0);
|
||||||
|
table->field[11]->store_timestamp_dec(tv, AUTO_SEC_PART_DIGITS);
|
||||||
table->field[11]->set_notnull();
|
table->field[11]->set_notnull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2234,6 +2234,9 @@ public:
|
|||||||
Timestamp(my_time_t timestamp, ulong sec_part)
|
Timestamp(my_time_t timestamp, ulong sec_part)
|
||||||
:Timeval(timestamp, sec_part)
|
:Timeval(timestamp, sec_part)
|
||||||
{ }
|
{ }
|
||||||
|
explicit Timestamp(const timeval &tv)
|
||||||
|
:Timeval(tv)
|
||||||
|
{ }
|
||||||
const struct timeval &tv() const { return *this; }
|
const struct timeval &tv() const { return *this; }
|
||||||
long fraction_remainder(uint dec) const
|
long fraction_remainder(uint dec) const
|
||||||
{
|
{
|
||||||
|
@ -853,6 +853,9 @@ public:
|
|||||||
tv_sec= sec;
|
tv_sec= sec;
|
||||||
tv_usec= usec;
|
tv_usec= usec;
|
||||||
}
|
}
|
||||||
|
explicit Timeval(const timeval &tv)
|
||||||
|
:timeval(tv)
|
||||||
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user