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
|
||||
$$
|
||||
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;
|
||||
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;
|
||||
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 f2;
|
||||
DROP FUNCTION f3;
|
||||
|
@ -1033,5 +1033,40 @@ CREATE TABLE t1 (a TIMESTAMP);
|
||||
INSERT INTO t1 SELECT CAST(20010101 AS UNSIGNED);
|
||||
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
|
||||
#
|
||||
|
@ -625,6 +625,41 @@ CREATE TABLE t1 (a TIMESTAMP);
|
||||
INSERT INTO t1 SELECT CAST(20010101 AS UNSIGNED);
|
||||
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 # End of 10.4 tests
|
||||
--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;
|
||||
THD *thd= get_thd();
|
||||
thd->timestamp_to_TIME(<ime, ts, sec_part, date_mode_t(0));
|
||||
return store_time_dec(<ime, decimals());
|
||||
return store_time_dec(Datetime(get_thd(), ts).get_mysql_time(), dec);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -5014,7 +5011,7 @@ int Field_timestamp::save_in_field(Field *to)
|
||||
{
|
||||
ulong 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,
|
||||
@ -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;
|
||||
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)
|
||||
{
|
||||
/*
|
||||
@ -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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
ErrConvString s(
|
||||
|
@ -784,7 +784,12 @@ public:
|
||||
virtual int store(longlong nr, bool unsigned_val)=0;
|
||||
virtual int store_decimal(const my_decimal *d)=0;
|
||||
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)
|
||||
{ return store_time_dec(ltime, TIME_SECOND_PART_DIGITS); }
|
||||
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_time_dec(const MYSQL_TIME *ltime, uint dec);
|
||||
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);
|
||||
double val_real(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())
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -2234,6 +2234,9 @@ public:
|
||||
Timestamp(my_time_t timestamp, ulong sec_part)
|
||||
:Timeval(timestamp, sec_part)
|
||||
{ }
|
||||
explicit Timestamp(const timeval &tv)
|
||||
:Timeval(tv)
|
||||
{ }
|
||||
const struct timeval &tv() const { return *this; }
|
||||
long fraction_remainder(uint dec) const
|
||||
{
|
||||
|
@ -853,6 +853,9 @@ public:
|
||||
tv_sec= sec;
|
||||
tv_usec= usec;
|
||||
}
|
||||
explicit Timeval(const timeval &tv)
|
||||
:timeval(tv)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user