Skip to content
Permalink
Browse files
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.
  • Loading branch information
dr-m committed Dec 21, 2018
1 parent 2fe40a7 commit ccb1acb
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 8 deletions.
@@ -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

0 comments on commit ccb1acb

Please sign in to comment.