diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2020-07-29 01:01:24 +1000 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2020-07-31 17:38:41 +1000 |
commit | fd0abc890f99e2b5ca1b8ae4cb0dc3968eef1208 (patch) | |
tree | e447f8d04288935cbaa44f70ac6fff2c465921db | |
parent | 91ebf1844f4fbc36edb66023332a045895d07cf5 (diff) | |
download | mariadb-git-fd0abc890f99e2b5ca1b8ae4cb0dc3968eef1208.tar.gz |
MDEV-18042 Server crashes upon adding a non-null date column under NO_ZERO_DATE with ALGORITHM=INPLACE
accept table_name and db_name instead of table_share in make_truncated_value_warning
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-alter.result | 17 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-alter.test | 22 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/item.cc | 2 | ||||
-rw-r--r-- | sql/item_create.cc | 2 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 | ||||
-rw-r--r-- | sql/sql_time.cc | 21 | ||||
-rw-r--r-- | sql/sql_time.h | 9 |
9 files changed, 64 insertions, 22 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index a5361f720ce..80cf14c1725 100644 --- a/mysql-test/suite/innodb/r/innodb-alter.result +++ b/mysql-test/suite/innodb/r/innodb-alter.result @@ -1055,3 +1055,20 @@ SELECT * FROM t1; a b 10 10:20:30 DROP TABLE t1; +# +# MDEV-18042 Server crashes in mysql_alter_table upon adding a non-null +# date column under NO_ZERO_DATE with ALGORITHM=INPLACE +# +SET @OLD_SQL_MODE= @@SQL_MODE; +SET @@SQL_MODE= 'NO_ZERO_DATE'; +CREATE OR REPLACE TABLE t1 (i INT) ENGINE=MyISAM; +ALTER TABLE t1 ADD COLUMN d DATE NOT NULL, ALGORITHM=INPLACE; +ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY +CREATE OR REPLACE TABLE t1 (i INT) ENGINE=InnoDB; +ALTER TABLE t1 ADD d DATETIME NOT NULL CHECK (f <= 0), ALGORITHM=COPY; +ERROR 42S22: Unknown column 'f' in 'CHECK' +CREATE OR REPLACE TABLE t1 (a int) ENGINE=InnoDB; +ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE; +# Cleanup +SET @@SQL_MODE= @OLD_SQL_MODE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test index 9bfc1262a1b..aae3f3960a2 100644 --- a/mysql-test/suite/innodb/t/innodb-alter.test +++ b/mysql-test/suite/innodb/t/innodb-alter.test @@ -646,6 +646,28 @@ ALTER TABLE t1 ADD b TIME NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001- SELECT * FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-18042 Server crashes in mysql_alter_table upon adding a non-null +--echo # date column under NO_ZERO_DATE with ALGORITHM=INPLACE +--echo # + +SET @OLD_SQL_MODE= @@SQL_MODE; +SET @@SQL_MODE= 'NO_ZERO_DATE'; +CREATE OR REPLACE TABLE t1 (i INT) ENGINE=MyISAM; +--error ER_ALTER_OPERATION_NOT_SUPPORTED +ALTER TABLE t1 ADD COLUMN d DATE NOT NULL, ALGORITHM=INPLACE; + +CREATE OR REPLACE TABLE t1 (i INT) ENGINE=InnoDB; +--error ER_BAD_FIELD_ERROR +ALTER TABLE t1 ADD d DATETIME NOT NULL CHECK (f <= 0), ALGORITHM=COPY; + +CREATE OR REPLACE TABLE t1 (a int) ENGINE=InnoDB; +ALTER TABLE t1 ADD COLUMN b DATETIME NOT NULL, LOCK=NONE; + +--echo # Cleanup +SET @@SQL_MODE= @OLD_SQL_MODE; +DROP TABLE t1; + # # End of 10.2 tests # diff --git a/sql/field.cc b/sql/field.cc index 65bd9d22857..9a1779dea5f 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -11059,7 +11059,7 @@ void Field::set_datetime_warning(Sql_condition::enum_warning_level level, 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, - table->s, field_name); + table->s->db.str, table->s->table_name.str, field_name); else set_warning(level, code, cuted_increment); } diff --git a/sql/item.cc b/sql/item.cc index 644bef7524a..2915b0cfb4d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3669,7 +3669,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, { ErrConvTime str(&value.time); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, time_type, 0, 0); + &str, time_type, NULL, NULL, NULL); set_zero_time(&value.time, time_type); } maybe_null= 0; diff --git a/sql/item_create.cc b/sql/item_create.cc index 4b7400eb0c0..1cf5a06a3a4 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -7338,7 +7338,7 @@ Item *create_temporal_literal(THD *thd, ErrConvString err(str, length, cs); make_truncated_value_warning(thd, Sql_condition::time_warn_level(status.warnings), - &err, ltime.time_type, 0, 0); + &err, ltime.time_type, NULL, NULL, NULL); } return item; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index b7455f36d1b..f2f3fdaafe3 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -430,7 +430,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, val_begin, length, - cached_timestamp_type, 0, NullS); + cached_timestamp_type, NULL, NULL, NULL); break; } } while (++val != val_end); @@ -1870,13 +1870,13 @@ overflow: { ErrConvInteger err2(sec, unsigned_flag); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &err2, MYSQL_TIMESTAMP_TIME, 0, NullS); + &err2, MYSQL_TIMESTAMP_TIME, NULL, NULL, NULL); } else { ErrConvString err2(err); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &err2, MYSQL_TIMESTAMP_TIME, 0, NullS); + &err2, MYSQL_TIMESTAMP_TIME, NULL, NULL, NULL); } return 0; } @@ -2894,7 +2894,7 @@ bool Item_func_maketime::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date) int len = (int)(ptr - buf) + sprintf(ptr, ":%02u:%02u", (uint)minute, (uint)second); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, buf, len, MYSQL_TIMESTAMP_TIME, - 0, NullS); + NULL, NULL, NULL); } return (null_value= 0); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b3a600eec36..57284272316 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9952,7 +9952,8 @@ err_new_table_cleanup: thd->abort_on_warning= true; make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, f_val, strlength(f_val), t_type, - new_table->s, + alter_ctx.new_db, + alter_ctx.new_name, alter_ctx.datetime_field->field_name); thd->abort_on_warning= save_abort_on_warning; } diff --git a/sql/sql_time.cc b/sql/sql_time.cc index a6fe937df4b..7f5919007e8 100644 --- a/sql/sql_time.cc +++ b/sql/sql_time.cc @@ -18,7 +18,6 @@ /* Functions to handle date and time */ #include <my_global.h> -#include "sql_priv.h" #include "sql_time.h" #include "tztime.h" // struct Time_zone #include "sql_class.h" // THD @@ -223,7 +222,7 @@ check_date_with_warn(const MYSQL_TIME *ltime, ulonglong fuzzy_date, { ErrConvTime str(ltime); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, ts_type, 0, 0); + &str, ts_type, NULL, NULL, NULL); return true; } return false; @@ -240,7 +239,7 @@ adjust_time_range_with_warn(MYSQL_TIME *ltime, uint dec) return true; if (warnings) make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_TIME, 0, NullS); + &str, MYSQL_TIMESTAMP_TIME, NULL, NULL, NULL); return false; } @@ -329,7 +328,8 @@ str_to_datetime_with_warn(CHARSET_INFO *cs, ret_val ? Sql_condition::WARN_LEVEL_WARN : Sql_condition::time_warn_level(status.warnings), str, length, flags & TIME_TIME_ONLY ? - MYSQL_TIMESTAMP_TIME : l_time->time_type, 0, NullS); + MYSQL_TIMESTAMP_TIME : l_time->time_type, + NULL, NULL, NULL); DBUG_EXECUTE_IF("str_to_datetime_warn", push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_YES, str);); @@ -387,7 +387,8 @@ static bool number_to_time_with_warn(bool neg, ulonglong nr, ulong sec_part, Sql_condition::WARN_LEVEL_WARN, str, res < 0 ? MYSQL_TIMESTAMP_ERROR : mysql_type_to_time_type(f_type), - s, field_name); + s ? s->db.str : NULL, + s ? s->table_name.str : NULL, field_name); } return res < 0; } @@ -859,7 +860,8 @@ void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const ErrConv *sval, timestamp_type time_type, - const TABLE_SHARE *s, const char *field_name) + const char *db_name, const char *table_name, + const char *field_name) { char warn_buff[MYSQL_ERRMSG_SIZE]; const char *type_str; @@ -879,9 +881,6 @@ void make_truncated_value_warning(THD *thd, } if (field_name) { - const char *db_name= s->db.str; - const char *table_name= s->table_name.str; - if (!db_name) db_name= ""; if (!table_name) @@ -1219,7 +1218,7 @@ make_date_with_warn(MYSQL_TIME *ltime, ulonglong fuzzy_date, /* e.g. negative time */ ErrConvTime str(ltime); make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, - &str, ts_type, 0, 0); + &str, ts_type, NULL, NULL, NULL); return true; } if ((ltime->time_type= ts_type) == MYSQL_TIMESTAMP_DATE) @@ -1383,7 +1382,7 @@ time_to_datetime_with_warn(THD *thd, { ErrConvTime str(from); make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN, - &str, MYSQL_TIMESTAMP_DATETIME, 0, 0); + &str, MYSQL_TIMESTAMP_DATETIME, NULL, NULL, NULL); return true; } return false; diff --git a/sql/sql_time.h b/sql/sql_time.h index 1dafb9b783b..ebfb86cde61 100644 --- a/sql/sql_time.h +++ b/sql/sql_time.h @@ -120,15 +120,18 @@ void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const ErrConv *str_val, timestamp_type time_type, - const TABLE_SHARE *s, const char *field_name); + const char *db_name, const char *table_name, + const char *field_name); static inline void make_truncated_value_warning(THD *thd, Sql_condition::enum_warning_level level, const char *str_val, uint str_length, timestamp_type time_type, - const TABLE_SHARE *s, const char *field_name) + const char *db_name, const char *table_name, + const char *field_name) { const ErrConvString str(str_val, str_length, &my_charset_bin); - make_truncated_value_warning(thd, level, &str, time_type, s, field_name); + make_truncated_value_warning(thd, level, &str, time_type, db_name, table_name, + field_name); } extern DATE_TIME_FORMAT *date_time_format_make(timestamp_type format_type, |