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; ...@@ -615,6 +615,11 @@ DROP TABLE t1;
CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT; CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST; ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1; 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 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1176,6 +1181,11 @@ DROP TABLE t1; ...@@ -1176,6 +1181,11 @@ DROP TABLE t1;
CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=COMPACT; CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=COMPACT;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST; ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1; 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 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1737,6 +1747,11 @@ DROP TABLE t1; ...@@ -1737,6 +1747,11 @@ DROP TABLE t1;
CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC; CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST; ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1; 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; disconnect analyze;
SELECT variable_value-@old_instant instants SELECT variable_value-@old_instant instants
FROM information_schema.global_status FROM information_schema.global_status
......
...@@ -490,6 +490,13 @@ eval CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) $engine; ...@@ -490,6 +490,13 @@ eval CREATE TABLE t1 (f1 VARCHAR(1), f2 VARCHAR(2)) $engine;
ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST; ALTER TABLE t1 MODIFY f2 VARCHAR (8) FIRST;
DROP TABLE t1; 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; dec $format;
} }
disconnect analyze; disconnect analyze;
......
...@@ -1372,13 +1372,15 @@ check_v_col_in_order( ...@@ -1372,13 +1372,15 @@ check_v_col_in_order(
/** Determine if an instant operation is possible for altering columns. /** Determine if an instant operation is possible for altering columns.
@param[in] ib_table InnoDB table definition @param[in] ib_table InnoDB table definition
@param[in] ha_alter_info the ALTER TABLE operation @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 static
bool bool
instant_alter_column_possible( instant_alter_column_possible(
const dict_table_t& ib_table, const dict_table_t& ib_table,
const Alter_inplace_info* ha_alter_info, const Alter_inplace_info* ha_alter_info,
const TABLE* table) const TABLE* table,
const TABLE* altered_table)
{ {
if (!ib_table.supports_instant()) { if (!ib_table.supports_instant()) {
return false; return false;
...@@ -1470,10 +1472,36 @@ instant_alter_column_possible( ...@@ -1470,10 +1472,36 @@ instant_alter_column_possible(
return false; return false;
} }
if ((ha_alter_info->handler_flags if (ha_alter_info->handler_flags & ALTER_COLUMN_NULLABLE) {
& ALTER_COLUMN_NULLABLE) if (ib_table.not_redundant()) {
&& ib_table.not_redundant()) { return false;
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; return true;
...@@ -1784,7 +1812,7 @@ ha_innobase::check_if_supported_inplace_alter( ...@@ -1784,7 +1812,7 @@ ha_innobase::check_if_supported_inplace_alter(
} }
const bool supports_instant = instant_alter_column_possible( 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; bool add_drop_v_cols = false;
/* If there is add or drop virtual columns, we will support operations /* If there is add or drop virtual columns, we will support operations
...@@ -6285,7 +6313,7 @@ prepare_inplace_alter_table_dict( ...@@ -6285,7 +6313,7 @@ prepare_inplace_alter_table_dict(
|| !ctx->new_table->persistent_autoinc); || !ctx->new_table->persistent_autoinc);
if (ctx->need_rebuild() && instant_alter_column_possible( 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 #if 1 // MDEV-17459: adjust fts_fetch_doc_from_rec() and friends; remove this
&& !innobase_fulltext_exist(altered_table) && !innobase_fulltext_exist(altered_table)
#endif #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