summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2020-07-29 01:01:24 +1000
committerNikita Malyavin <nikitamalyavin@gmail.com>2020-07-31 17:38:41 +1000
commitfd0abc890f99e2b5ca1b8ae4cb0dc3968eef1208 (patch)
treee447f8d04288935cbaa44f70ac6fff2c465921db
parent91ebf1844f4fbc36edb66023332a045895d07cf5 (diff)
downloadmariadb-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.result17
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter.test22
-rw-r--r--sql/field.cc2
-rw-r--r--sql/item.cc2
-rw-r--r--sql/item_create.cc2
-rw-r--r--sql/item_timefunc.cc8
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/sql_time.cc21
-rw-r--r--sql/sql_time.h9
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,