Commit ccb1acbd authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18035 Failing assertion on DELETE

instant_alter_column_possible(): Do not allow instant removal of NOT NULL
attribute from a column that belongs to the key of the clustered index.
parent 2fe40a7a
......@@ -615,6 +615,11 @@ DROP TABLE t1;
CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1;
CREATE TABLE t1 (a INT UNIQUE, b INT UNIQUE, PRIMARY KEY(a,b)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
ALTER TABLE t1 DROP PRIMARY KEY;
ALTER TABLE t1 CHANGE COLUMN a a INT;
DELETE FROM t1 WHERE a = NULL OR a IS NULL;
DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1176,6 +1181,11 @@ DROP TABLE t1;
CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=COMPACT;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1;
CREATE TABLE t1 (a INT UNIQUE, b INT UNIQUE, PRIMARY KEY(a,b)) ENGINE=InnoDB ROW_FORMAT=COMPACT;
ALTER TABLE t1 DROP PRIMARY KEY;
ALTER TABLE t1 CHANGE COLUMN a a INT;
DELETE FROM t1 WHERE a = NULL OR a IS NULL;
DROP TABLE t1;
CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1737,6 +1747,11 @@ DROP TABLE t1;
CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1;
CREATE TABLE t1 (a INT UNIQUE, b INT UNIQUE, PRIMARY KEY(a,b)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 DROP PRIMARY KEY;
ALTER TABLE t1 CHANGE COLUMN a a INT;
DELETE FROM t1 WHERE a = NULL OR a IS NULL;
DROP TABLE t1;
disconnect analyze;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
......
......@@ -490,6 +490,13 @@ eval CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) $engine;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1;
# MDEV-18035 Failing assertion on DELETE
eval CREATE TABLE t1 (a INT UNIQUE, b INT UNIQUE, PRIMARY KEY(a,b)) $engine;
ALTER TABLE t1 DROP PRIMARY KEY;
ALTER TABLE t1 CHANGE COLUMN a a INT;
DELETE FROM t1 WHERE a = NULL OR a IS NULL;
DROP TABLE t1;
dec $format;
}
disconnect analyze;
......
......@@ -1372,13 +1372,15 @@ check_v_col_in_order(
/** Determine if an instant operation is possible for altering columns.
@param[in] ib_table InnoDB table definition
@param[in] ha_alter_info the ALTER TABLE operation
@param[in] table table definition before ALTER TABLE */
@param[in] table table definition before ALTER TABLE
@param[in] table table definition after ALTER TABLE */
static
bool
instant_alter_column_possible(
const dict_table_t& ib_table,
const Alter_inplace_info* ha_alter_info,
const TABLE* table)
const TABLE* table,
const TABLE* altered_table)
{
if (!ib_table.supports_instant()) {
return false;
......@@ -1470,10 +1472,36 @@ instant_alter_column_possible(
return false;
}
if ((ha_alter_info->handler_flags
& ALTER_COLUMN_NULLABLE)
&& ib_table.not_redundant()) {
return false;
if (ha_alter_info->handler_flags & ALTER_COLUMN_NULLABLE) {
if (ib_table.not_redundant()) {
return false;
}
const dict_index_t* pk = ib_table.indexes.start;
Field** af = altered_table->field;
Field** const end = altered_table->field
+ altered_table->s->fields;
for (unsigned c = 0; af < end; af++) {
if (!(*af)->stored_in_db()) {
continue;
}
const dict_col_t* col = dict_table_get_nth_col(
&ib_table, c++);
if (!col->ord_part || col->is_nullable()
|| !(*af)->real_maybe_null()) {
continue;
}
/* The column would be changed from NOT NULL.
Ensure that it is not a clustered index key. */
for (auto i = pk->n_uniq; i--; ) {
if (pk->fields[i].col == col) {
return false;
}
}
}
}
return true;
......@@ -1784,7 +1812,7 @@ ha_innobase::check_if_supported_inplace_alter(
}
const bool supports_instant = instant_alter_column_possible(
*m_prebuilt->table, ha_alter_info, table);
*m_prebuilt->table, ha_alter_info, table, altered_table);
bool add_drop_v_cols = false;
/* If there is add or drop virtual columns, we will support operations
......@@ -6285,7 +6313,7 @@ prepare_inplace_alter_table_dict(
|| !ctx->new_table->persistent_autoinc);
if (ctx->need_rebuild() && instant_alter_column_possible(
*user_table, ha_alter_info, old_table)
*user_table, ha_alter_info, old_table, altered_table)
#if 1 // MDEV-17459: adjust fts_fetch_doc_from_rec() and friends; remove this
&& !innobase_fulltext_exist(altered_table)
#endif
......
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