Commit a25ce5ab authored by Alexander Barkov's avatar Alexander Barkov

MDEV-17928 Conversion from TIMESTAMP to VARCHAR SP variables does not work...

MDEV-17928 Conversion from TIMESTAMP to VARCHAR SP variables does not work well on fractional digits
parent fac997fe
...@@ -8559,11 +8559,11 @@ RETURN a = timestamp'2038-01-19 03:14:07.999999' ...@@ -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); ...@@ -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); ...@@ -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 #
...@@ -1831,12 +1831,9 @@ int Field::store(const char *to, size_t length, CHARSET_INFO *cs, ...@@ -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(&ltime, ts, sec_part, date_mode_t(0));
return store_time_dec(&ltime, decimals());
} }
/** /**
...@@ -5014,7 +5011,7 @@ int Field_timestamp::save_in_field(Field *to) ...@@ -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) ...@@ -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) ...@@ -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 @@ class Field: public Value_source ...@@ -784,7 +784,12 @@ class Field: public Value_source
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 @@ class Field_timestamp :public Field_temporal { ...@@ -2744,7 +2749,7 @@ class Field_timestamp :public Field_temporal {
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, ...@@ -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 @@ class Timestamp: protected Timeval ...@@ -2234,6 +2234,9 @@ class Timestamp: protected Timeval
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 @@ class Timeval: public timeval ...@@ -853,6 +853,9 @@ class Timeval: public timeval
tv_sec= sec; tv_sec= sec;
tv_usec= usec; tv_usec= usec;
} }
explicit Timeval(const timeval &tv)
:timeval(tv)
{ }
}; };
......
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