Browse Source

MDEV-14111 Inplace update assert after instant adding column

row_upd_changes_field_size_or_external(): Always return TRUE
if an instantly added column is being updated such that the
column value is absent from the record.

Also, avoid some unnecessary computations.
pull/492/head
Marko Mäkelä 8 years ago
parent
commit
770c5c1c9e
  1. BIN
      mysql-test/suite/innodb/r/instant_alter.result
  2. 10
      mysql-test/suite/innodb/t/instant_alter.test
  3. 17
      storage/innobase/row/row0upd.cc

BIN
mysql-test/suite/innodb/r/instant_alter.result

10
mysql-test/suite/innodb/t/instant_alter.test

@ -58,8 +58,12 @@ SELECT * FROM t1;
ALTER TABLE t1 ADD COLUMN (
d1 INT, d2 INT UNSIGNED DEFAULT 10, d3 VARCHAR(20) NOT NULL DEFAULT 'abcde',
d4 TIMESTAMP NOT NULL DEFAULT current_timestamp());
ALTER TABLE t1 ADD INDEX(d3);
--disable_info
BEGIN;
UPDATE t1 SET d3='';
ROLLBACK;
SELECT * FROM t1;
INSERT INTO t1 (id) VALUES(2),(3),(4),(5),(6);
@ -69,8 +73,11 @@ CHANGE d3 d3 VARCHAR(20) NOT NULL DEFAULT 'fghij',
CHANGE d4 dfour TIMESTAMP NOT NULL DEFAULT now();
--disable_info
UPDATE t1 SET d3='foo' WHERE id = 2;
UPDATE t1 SET d3=DEFAULT WHERE id = 4;
INSERT INTO t1 SET id = 7;
SELECT * FROM t1;
CHECK TABLE t1;
# add virtual columns
--enable_info
@ -80,7 +87,8 @@ ALTER TABLE t1 ADD COLUMN e3 INT AS (id * 2);
# instant alter
ALTER TABLE t1 CHANGE d3 d3 VARCHAR(20) NOT NULL DEFAULT 'foobar',
ADD COLUMN (d5 CHAR(20) DEFAULT 'hijkl', d6 INT DEFAULT -12345, d7 INT);
ADD COLUMN (d5 CHAR(20) DEFAULT 'hijkl', d6 INT DEFAULT -12345, d7 INT),
DROP INDEX d3;
--disable_info
INSERT INTO t1 SET id = 8;

17
storage/innobase/row/row0upd.cc

@ -594,6 +594,9 @@ row_upd_changes_field_size_or_external(
}
new_val = &(upd_field->new_val);
if (dfield_is_ext(new_val)) {
return(TRUE);
}
new_len = dfield_get_len(new_val);
ut_ad(new_len != UNIV_SQL_DEFAULT);
@ -609,11 +612,14 @@ row_upd_changes_field_size_or_external(
0);
}
old_len = rec_offs_nth_size(offsets, upd_field->field_no);
if (rec_offs_nth_default(offsets, upd_field->field_no)) {
/* This is an instantly added column that is
at the initial default value. */
return(TRUE);
}
if (rec_offs_comp(offsets)
&& rec_offs_nth_sql_null(offsets,
upd_field->field_no)) {
&& rec_offs_nth_sql_null(offsets, upd_field->field_no)) {
/* Note that in the compact table format, for a
variable length field, an SQL NULL will use zero
bytes in the offset array at the start of the physical
@ -622,9 +628,12 @@ row_upd_changes_field_size_or_external(
if we update an SQL NULL varchar to an empty string! */
old_len = UNIV_SQL_NULL;
} else {
old_len = rec_offs_nth_size(offsets,
upd_field->field_no);
}
if (dfield_is_ext(new_val) || old_len != new_len
if (old_len != new_len
|| rec_offs_nth_extern(offsets, upd_field->field_no)) {
return(TRUE);

Loading…
Cancel
Save