diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-06-10 15:38:14 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-06-10 15:38:46 +0530 |
commit | c5489d07655a968bcdfa29f064f2ed13f0abdf62 (patch) | |
tree | 7321270fc229fccc3aa7109f038bf9162fc3957d | |
parent | 396864c6b3d2cca9962f7eb58964f50ed6b612dc (diff) | |
download | mariadb-git-bb-10.2-MDEV-25872.tar.gz |
MDEV-25872 InnoDB: Assertion failure in row_merge_read_clustered_index upon ALTER on table with indexed virtual columnsbb-10.2-MDEV-25872
InnoDB fails to check DB_COMPUTE_VALUE_FAILED error in
row_merge_read_clustered_index() and wrongly asserts that
the buffer shouldn't be ran out of memory. Alter table
should give warning when the column value is being
truncated.
-rw-r--r-- | mysql-test/suite/gcol/r/gcol_keys_innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/gcol/r/innodb_virtual_index.result | 20 | ||||
-rw-r--r-- | mysql-test/suite/gcol/t/innodb_virtual_index.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/gcol/t/innodb_virtual_index.test | 21 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-alter.result | 8 | ||||
-rw-r--r-- | sql/sql_table.cc | 8 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 17 |
7 files changed, 67 insertions, 10 deletions
diff --git a/mysql-test/suite/gcol/r/gcol_keys_innodb.result b/mysql-test/suite/gcol/r/gcol_keys_innodb.result index 5a29c64bc20..37b350c0c32 100644 --- a/mysql-test/suite/gcol/r/gcol_keys_innodb.result +++ b/mysql-test/suite/gcol/r/gcol_keys_innodb.result @@ -691,6 +691,8 @@ a b c 1 127 0 SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR ALTER TABLE t ADD UNIQUE INDEX (c(1)); +Warnings: +Warning 1264 Out of range value for column 'b' at row 1 SELECT * FROM t WHERE c = '0'; a b c 1 127 0 diff --git a/mysql-test/suite/gcol/r/innodb_virtual_index.result b/mysql-test/suite/gcol/r/innodb_virtual_index.result index 20311a21136..ff339280e8a 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_index.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_index.result @@ -266,3 +266,23 @@ CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK DROP TABLE t1; +# +# MDEV-25872 InnoDB: Assertion failure in row_merge_read_clustered_index +# upon ALTER on table with indexed virtual columns +# +CREATE TABLE t1 ( +id BIGINT AUTO_INCREMENT PRIMARY KEY, +a INT, +va INT ZEROFILL AS (a) VIRTUAL, +b TIMESTAMP, +c CHAR(204), +vc CHAR(8), +KEY(vc,c(64),b,va) +) ENGINE=InnoDB CHARACTER SET utf32; +INSERT INTO t1 (id) SELECT NULL FROM seq_1_to_75; +INSERT IGNORE INTO t1 (id, a) VALUES (NULL, -1); +Warnings: +Warning 1264 Out of range value for column 'va' at row 1 +ALTER TABLE t1 FORCE; +ERROR 22003: Out of range value for column 'va' at row 1 +DROP TABLE t1; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.opt b/mysql-test/suite/gcol/t/innodb_virtual_index.opt new file mode 100644 index 00000000000..c3f4a891cca --- /dev/null +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.opt @@ -0,0 +1 @@ +--innodb_sort_buffer_size=64k diff --git a/mysql-test/suite/gcol/t/innodb_virtual_index.test b/mysql-test/suite/gcol/t/innodb_virtual_index.test index 353841840dc..9e765ca104c 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_index.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_index.test @@ -1,4 +1,5 @@ --source include/have_innodb.inc +--source include/have_sequence.inc # Ensure that the history list length will actually be decremented by purge. SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency; @@ -281,3 +282,23 @@ ROLLBACK; SELECT * FROM t1; CHECK TABLE t1; DROP TABLE t1; + +--echo # +--echo # MDEV-25872 InnoDB: Assertion failure in row_merge_read_clustered_index +--echo # upon ALTER on table with indexed virtual columns +--echo # + +CREATE TABLE t1 ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + a INT, + va INT ZEROFILL AS (a) VIRTUAL, + b TIMESTAMP, + c CHAR(204), + vc CHAR(8), + KEY(vc,c(64),b,va) +) ENGINE=InnoDB CHARACTER SET utf32; +INSERT INTO t1 (id) SELECT NULL FROM seq_1_to_75; +INSERT IGNORE INTO t1 (id, a) VALUES (NULL, -1); +--error ER_WARN_DATA_OUT_OF_RANGE +ALTER TABLE t1 FORCE; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result index 80cf14c1725..53e6c95af0f 100644 --- a/mysql-test/suite/innodb/r/innodb-alter.result +++ b/mysql-test/suite/innodb/r/innodb-alter.result @@ -1041,7 +1041,9 @@ CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB; iNSERT INTO t1 VALUES (10); ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0); affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Note 1265 Data truncated for column 'b' at row 1 SELECT * FROM t1; a b 10 2001-01-01 @@ -1050,7 +1052,9 @@ CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB; iNSERT INTO t1 VALUES (10); ALTER TABLE t1 ADD b TIME NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0); affected rows: 0 -info: Records: 0 Duplicates: 0 Warnings: 0 +info: Records: 0 Duplicates: 0 Warnings: 1 +Warnings: +Note 1265 Data truncated for column 'b' at row 1 SELECT * FROM t1; a b 10 10:20:30 diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 3a3a903bc35..9556cb9f136 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9680,9 +9680,17 @@ do_continue:; if (use_inplace) { table->s->frm_image= &frm; + enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; + /* + Set the truncated column values of thd as warning for alter table. + */ + thd->count_cuted_fields= CHECK_FIELD_WARN; int res= mysql_inplace_alter_table(thd, table_list, table, altered_table, &ha_alter_info, inplace_supported, &target_mdl_request, &alter_ctx); + + thd->count_cuted_fields= save_count_cuted_fields; + my_free(const_cast<uchar*>(frm.str)); if (res) diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index e3b3f2c2762..b2091c162a9 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -2561,21 +2561,22 @@ write_buffers: that the buffer has been written out and emptied. */ - if (UNIV_UNLIKELY - (!(rows_added = row_merge_buf_add( + rows_added = row_merge_buf_add( buf, fts_index, old_table, new_table, psort_info, row, ext, - &doc_id, conv_heap, - &err, &v_heap, eval_table, trx)))) { - /* An empty buffer should have enough - room for at least one record. */ - ut_error; - } + &doc_id, conv_heap, &err, &v_heap, + eval_table, trx); if (err != DB_SUCCESS) { break; } + if (rows_added == 0) { + /* An empty buffer should have enough + room for at least one record. */ + ut_error; + } + file->n_rec += rows_added; } } |