Commit f89a27b4 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-17319 Assertion `ts_type != MYSQL_TIMESTAMP_TIME' failed upon inserting into TIME field

parent 17e371ff
......@@ -294,17 +294,17 @@ SELECT TIMESTAMP'2001-00-00 00:00:00.9999999';
TIMESTAMP'2001-00-00 00:00:00.9999999'
2001-00-00 00:00:00.999999
Warnings:
Note 1292 Truncated incorrect datetime value: '2001-00-00 00:00:00.9999999'
Note 1292 Truncated incorrect DATETIME value: '2001-00-00 00:00:00.9999999'
SELECT TIMESTAMP'2001-00-01 00:00:00.9999999';
TIMESTAMP'2001-00-01 00:00:00.9999999'
2001-00-01 00:00:00.999999
Warnings:
Note 1292 Truncated incorrect datetime value: '2001-00-01 00:00:00.9999999'
Note 1292 Truncated incorrect DATETIME value: '2001-00-01 00:00:00.9999999'
SELECT TIMESTAMP'2001-01-00 00:00:00.9999999';
TIMESTAMP'2001-01-00 00:00:00.9999999'
2001-01-00 00:00:00.999999
Warnings:
Note 1292 Truncated incorrect datetime value: '2001-01-00 00:00:00.9999999'
Note 1292 Truncated incorrect DATETIME value: '2001-01-00 00:00:00.9999999'
#
# String literal with bad dates and nanoseconds to DATETIME(N)
#
......@@ -416,7 +416,7 @@ SELECT TIME'10:10:10.1234567';
TIME'10:10:10.1234567'
10:10:10.123456
Warnings:
Note 1292 Truncated incorrect time value: '10:10:10.1234567'
Note 1292 Truncated incorrect TIME value: '10:10:10.1234567'
SELECT TIME('10:10:10.1234567');
TIME('10:10:10.1234567')
10:10:10.123456
......@@ -440,7 +440,7 @@ SELECT TIMESTAMP'2001-01-01 10:10:10.1234567';
TIMESTAMP'2001-01-01 10:10:10.1234567'
2001-01-01 10:10:10.123456
Warnings:
Note 1292 Truncated incorrect datetime value: '2001-01-01 10:10:10.1234567'
Note 1292 Truncated incorrect DATETIME value: '2001-01-01 10:10:10.1234567'
SELECT TIMESTAMP('2001-01-01 10:10:10.1234567');
TIMESTAMP('2001-01-01 10:10:10.1234567')
2001-01-01 10:10:10.123456
......@@ -463,7 +463,7 @@ Warning 1292 Truncated incorrect datetime value: '2001-01-01 10:10:10.1234567xyz
CREATE TABLE t1 (a TIME(6));
INSERT INTO t1 VALUES (TIME'10:20:30.1234567');
Warnings:
Note 1292 Truncated incorrect time value: '10:20:30.1234567'
Note 1292 Truncated incorrect TIME value: '10:20:30.1234567'
INSERT INTO t1 VALUES (TIME('10:20:30.1234567'));
Warnings:
Note 1292 Truncated incorrect time value: '10:20:30.1234567'
......
......@@ -2168,5 +2168,14 @@ Warning 1292 Truncated incorrect datetime value: 'z'
Warning 1292 Truncated incorrect datetime value: 'z'
Warning 1292 Truncated incorrect time value: 'z'
#
# MDEV-17319 Assertion `ts_type != MYSQL_TIMESTAMP_TIME' failed upon inserting into TIME field
#
CREATE TABLE t1 (t TIME);
SET SESSION SQL_MODE='TRADITIONAL';
INSERT INTO t1 VALUES ('0000-00-00 00:00:00'),('0000-00-00 00:00:00');
ERROR 22007: Incorrect time value: '0000-00-00 00:00:00' for column 't' at row 1
SET sql_mode=DEFAULT;
DROP TABLE t1;
#
# End of 10.4 tests
#
......@@ -1409,6 +1409,18 @@ DROP TABLE IF EXISTS t1;
SELECT TIMESTAMP(0)='z', DATE(0)='z', TIME(0)='z';
--echo #
--echo # MDEV-17319 Assertion `ts_type != MYSQL_TIMESTAMP_TIME' failed upon inserting into TIME field
--echo #
CREATE TABLE t1 (t TIME);
SET SESSION SQL_MODE='TRADITIONAL';
--error ER_TRUNCATED_WRONG_VALUE
INSERT INTO t1 VALUES ('0000-00-00 00:00:00'),('0000-00-00 00:00:00');
SET sql_mode=DEFAULT;
DROP TABLE t1;
--echo #
--echo # End of 10.4 tests
--echo #
......@@ -53,7 +53,7 @@ Variable_name Value
system_versioning_asof 1900-01-01 00:00:00.000000
set global system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
Warnings:
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
Note 1292 Truncated incorrect DATETIME value: '1911-11-11 11:11:11.1111119'
show global variables like 'system_versioning_asof';
Variable_name Value
system_versioning_asof 1911-11-11 11:11:11.111111
......@@ -80,7 +80,7 @@ Variable_name Value
system_versioning_asof 1900-01-01 00:00:00.000000
set system_versioning_asof= timestamp'1911-11-11 11:11:11.1111119';
Warnings:
Note 1292 Truncated incorrect datetime value: '1911-11-11 11:11:11.1111119'
Note 1292 Truncated incorrect DATETIME value: '1911-11-11 11:11:11.1111119'
show variables like 'system_versioning_asof';
Variable_name Value
system_versioning_asof 1911-11-11 11:11:11.111111
......@@ -136,7 +136,7 @@ drop table t;
SET sql_mode=TIME_ROUND_FRACTIONAL;
SET @@global.system_versioning_asof= timestamp'2001-12-31 23:59:59.9999999';
Warnings:
Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999'
Note 1292 Truncated incorrect DATETIME value: '2001-12-31 23:59:59.9999999'
SELECT @@global.system_versioning_asof;
@@global.system_versioning_asof
2002-01-01 00:00:00.000000
......
......@@ -33,11 +33,6 @@
#include "rpl_rli.h" // Pull in Relay_log_info
#include "slave.h" // Pull in rpl_master_has_bug()
#include "strfunc.h" // find_type2, find_set
#include "sql_time.h" // str_to_datetime_with_warn,
// str_to_time_with_warn,
// TIME_to_timestamp,
// make_time, make_date,
// make_truncated_value_warning
#include "tztime.h" // struct Time_zone
#include "filesort.h" // change_double_for_sort
#include "log_event.h" // class Table_map_log_event
......@@ -5040,7 +5035,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
// Handle totally bad values
if (!dt->is_valid_datetime())
{
set_datetime_warning(WARN_DATA_TRUNCATED, str, MYSQL_TIMESTAMP_DATETIME, 1);
set_datetime_warning(WARN_DATA_TRUNCATED, str, "datetime", 1);
store_TIMESTAMP(zero);
return 1;
}
......@@ -5054,8 +5049,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
INSERT INTO t1 (ts) VALUES ('0000-00-00 00:00:00 some tail');
*/
store_TIMESTAMP(zero);
return store_TIME_return_code_with_warnings(was_cut, str,
MYSQL_TIMESTAMP_DATETIME);
return store_TIME_return_code_with_warnings(was_cut, str, "datetime");
}
// Convert DATETIME to TIMESTAMP
......@@ -5064,7 +5058,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
my_time_t timestamp= TIME_to_timestamp(thd, l_time, &conversion_error);
if (timestamp == 0 && l_time->second_part == 0)
{
set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, MYSQL_TIMESTAMP_DATETIME, 1);
set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, "datetime", 1);
store_TIMESTAMP(zero);
return 1; // date was fine but pointed to a DST gap
}
......@@ -5076,11 +5070,10 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
// Calculate return value and send warnings if needed
if (unlikely(conversion_error)) // e.g. DATETIME in the DST gap
{
set_datetime_warning(conversion_error, str, MYSQL_TIMESTAMP_DATETIME, 1);
set_datetime_warning(conversion_error, str, "datetime", 1);
return 1;
}
return store_TIME_return_code_with_warnings(was_cut, str,
MYSQL_TIMESTAMP_DATETIME);
return store_TIME_return_code_with_warnings(was_cut, str, "datetime");
}
......@@ -5157,7 +5150,7 @@ int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
ErrConvString s(
STRING_WITH_LEN("0000-00-00 00:00:00.000000") - (decimals() ? 6 - decimals() : 7),
system_charset_info);
set_datetime_warning(WARN_DATA_TRUNCATED, &s, MYSQL_TIMESTAMP_DATETIME, 1);
set_datetime_warning(WARN_DATA_TRUNCATED, &s, "datetime", 1);
return 1;
}
return 0;
......@@ -5536,7 +5529,7 @@ uint Field_temporal::is_equal(Create_field *new_field)
void Field_temporal::set_warnings(Sql_condition::enum_warning_level trunc_level,
const ErrConv *str, int was_cut,
timestamp_type ts_type)
const char *typestr)
{
/*
error code logic:
......@@ -5549,9 +5542,9 @@ void Field_temporal::set_warnings(Sql_condition::enum_warning_level trunc_level,
a DATE field and non-zero time part is thrown away.
*/
if (was_cut & MYSQL_TIME_WARN_TRUNCATED)
set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED, str, ts_type, 1);
set_datetime_warning(trunc_level, WARN_DATA_TRUNCATED, str, typestr, 1);
if (was_cut & MYSQL_TIME_WARN_OUT_OF_RANGE)
set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, ts_type, 1);
set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, typestr, 1);
}
......@@ -5572,13 +5565,12 @@ int Field_datetime::store_TIME_with_warning(const Datetime *dt,
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
// Handle totally bad values
if (!dt->is_valid_datetime())
return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATETIME);
return store_invalid_with_warning(str, was_cut, "datetime");
// Store the value
DBUG_ASSERT(!dt->fraction_remainder(decimals()));
store_datetime(*dt);
// Caclulate return value and send warnings if needed
return store_TIME_return_code_with_warnings(was_cut, str,
MYSQL_TIMESTAMP_DATETIME);
return store_TIME_return_code_with_warnings(was_cut, str, "datetime");
}
......@@ -5720,12 +5712,12 @@ int Field_time::store_TIME_with_warning(const Time *t,
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
// Handle totally bad values
if (!t->is_valid_time())
return store_invalid_with_warning(str, warn, MYSQL_TIMESTAMP_TIME);
return store_invalid_with_warning(str, warn, "time");
// Store the value
DBUG_ASSERT(!t->fraction_remainder(decimals()));
store_TIME(*t);
// Calculate return value and send warnings if needed
return store_TIME_return_code_with_warnings(warn, str, MYSQL_TIMESTAMP_TIME);
return store_TIME_return_code_with_warnings(warn, str, "time");
}
......@@ -6219,7 +6211,8 @@ int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg)
if (Field_year::store(ltime->year, 0))
return 1;
set_datetime_warning(WARN_DATA_TRUNCATED, &str, ltime->time_type, 1);
const char *typestr= Temporal::type_name_by_timestamp_type(ltime->time_type);
set_datetime_warning(WARN_DATA_TRUNCATED, &str, typestr, 1);
return 0;
}
......@@ -6291,14 +6284,13 @@ int Field_date_common::store_TIME_with_warning(const Datetime *dt,
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
// Handle totally bad values
if (!dt->is_valid_datetime())
return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATE);
return store_invalid_with_warning(str, was_cut, "date");
// Store the value
if (!dt->hhmmssff_is_zero())
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
store_datetime(*dt);
// Caclulate return value and send warnings if needed
return store_TIME_return_code_with_warnings(was_cut, str,
MYSQL_TIMESTAMP_DATE);
return store_TIME_return_code_with_warnings(was_cut, str, "date");
}
int Field_date_common::store(const char *from, size_t len, CHARSET_INFO *cs)
......@@ -10863,12 +10855,13 @@ Field::set_warning(Sql_condition::enum_warning_level level, uint code,
void Field::set_datetime_warning(Sql_condition::enum_warning_level level,
uint code, const ErrConv *str,
timestamp_type ts_type, int cuted_increment)
const char *typestr, int cuted_increment)
const
{
THD *thd= get_thd();
if (thd->really_abort_on_warning() && level >= Sql_condition::WARN_LEVEL_WARN)
make_truncated_value_warning(thd, level, str, ts_type, field_name.str);
thd->push_warning_truncated_value_for_field(level, typestr,
str->ptr(), field_name.str);
else
set_warning(level, code, cuted_increment);
}
......
......@@ -1368,13 +1368,13 @@ class Field: public Value_source
return set_warning(Sql_condition::WARN_LEVEL_NOTE, code, cuted_increment);
}
void set_datetime_warning(Sql_condition::enum_warning_level, uint code,
const ErrConv *str, timestamp_type ts_type,
const ErrConv *str, const char *typestr,
int cuted_increment) const;
void set_datetime_warning(uint code,
const ErrConv *str, timestamp_type ts_type,
const ErrConv *str, const char *typestr,
int cuted_increment) const
{
set_datetime_warning(Sql_condition::WARN_LEVEL_WARN, code, str, ts_type,
set_datetime_warning(Sql_condition::WARN_LEVEL_WARN, code, str, typestr,
cuted_increment);
}
void set_warning_truncated_wrong_value(const char *type, const char *value);
......@@ -2598,33 +2598,32 @@ class Field_temporal: public Field {
Item *get_equal_const_item_datetime(THD *thd, const Context &ctx,
Item *const_item);
void set_warnings(Sql_condition::enum_warning_level trunc_level,
const ErrConv *str, int was_cut, timestamp_type ts_type);
const ErrConv *str, int was_cut, const char *typestr);
int store_TIME_return_code_with_warnings(int warn, const ErrConv *str,
timestamp_type ts_type)
const char *typestr)
{
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);
warn | MYSQL_TIME_WARN_TRUNCATED, typestr);
return 3;
}
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, warn, ts_type);
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, warn, typestr);
return warn ? 2 : 0;
}
int store_invalid_with_warning(const ErrConv *str, int was_cut,
timestamp_type ts_type)
const char *typestr)
{
DBUG_ASSERT(was_cut);
reset();
Sql_condition::enum_warning_level level= Sql_condition::WARN_LEVEL_WARN;
if (was_cut & MYSQL_TIME_WARN_ZERO_DATE)
{
DBUG_ASSERT(ts_type != MYSQL_TIMESTAMP_TIME);
set_warnings(level, str, MYSQL_TIME_WARN_OUT_OF_RANGE, ts_type);
set_warnings(level, str, MYSQL_TIME_WARN_OUT_OF_RANGE, typestr);
return 2;
}
set_warnings(level, str, MYSQL_TIME_WARN_TRUNCATED, ts_type);
set_warnings(level, str, MYSQL_TIME_WARN_TRUNCATED, typestr);
return 1;
}
public:
......
......@@ -31,7 +31,6 @@
#include <m_ctype.h>
#include "sql_select.h"
#include "sql_parse.h" // check_stack_overrun
#include "sql_time.h" // make_truncated_value_warning
#include "sql_base.h" // dynamic_column_error_message
......
......@@ -33,7 +33,6 @@
// partition_info
// NOT_A_PARTITION_ID
#include "sql_db.h" // load_db_opt_by_name
#include "sql_time.h" // make_truncated_value_warning
#include "records.h" // init_read_record, end_read_record
#include "filesort.h" // filesort_free_buffers
#include "sql_select.h" // setup_order
......
......@@ -7767,7 +7767,6 @@ static bool have_important_literal_warnings(const MYSQL_TIME_STATUS *status)
static void literal_warn(THD *thd, const Item *item,
const char *str, size_t length, CHARSET_INFO *cs,
timestamp_type time_type,
const MYSQL_TIME_STATUS *st,
const char *typestr, bool send_error)
{
......@@ -7776,9 +7775,9 @@ static void literal_warn(THD *thd, const Item *item,
if (st->warnings) // e.g. a note on nanosecond truncation
{
ErrConvString err(str, length, cs);
make_truncated_value_warning(thd,
thd->push_warning_wrong_or_truncated_value(
Sql_condition::time_warn_level(st->warnings),
&err, time_type, 0);
false, typestr, err.ptr(), NullS);
}
}
else if (send_error)
......@@ -7803,8 +7802,7 @@ Type_handler_date_common::create_literal_item(THD *thd,
tmp.get_mysql_time()->time_type == MYSQL_TIMESTAMP_DATE &&
!have_important_literal_warnings(&st))
item= new (thd->mem_root) Item_date_literal(thd, tmp.get_mysql_time());
literal_warn(thd, item, str, length, cs, MYSQL_TIMESTAMP_DATE,
&st, "DATE", send_error);
literal_warn(thd, item, str, length, cs, &st, "DATE", send_error);
return item;
}
......@@ -7824,8 +7822,7 @@ Type_handler_temporal_with_date::create_literal_item(THD *thd,
!have_important_literal_warnings(&st))
item= new (thd->mem_root) Item_datetime_literal(thd, tmp.get_mysql_time(),
st.precision);
literal_warn(thd, item, str, length, cs, MYSQL_TIMESTAMP_DATETIME,
&st, "DATETIME", send_error);
literal_warn(thd, item, str, length, cs, &st, "DATETIME", send_error);
return item;
}
......@@ -7845,7 +7842,6 @@ Type_handler_time_common::create_literal_item(THD *thd,
!have_important_literal_warnings(&st))
item= new (thd->mem_root) Item_time_literal(thd, tmp.get_mysql_time(),
st.precision);
literal_warn(thd, item, str, length, cs, MYSQL_TIMESTAMP_TIME,
&st, "TIME", send_error);
literal_warn(thd, item, str, length, cs, &st, "TIME", send_error);
return item;
}
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