mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
MDEV-25872 InnoDB: Assertion failure in row_merge_read_clustered_index upon ALTER on table with indexed virtual columns
- 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.
This commit is contained in:
@ -691,6 +691,8 @@ a b c
|
|||||||
1 127 0
|
1 127 0
|
||||||
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
SET STATEMENT sql_mode = 'NO_ENGINE_SUBSTITUTION' FOR
|
||||||
ALTER TABLE t ADD UNIQUE INDEX (c(1));
|
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';
|
SELECT * FROM t WHERE c = '0';
|
||||||
a b c
|
a b c
|
||||||
1 127 0
|
1 127 0
|
||||||
|
@ -266,3 +266,23 @@ CHECK TABLE t1;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.t1 check status OK
|
test.t1 check status OK
|
||||||
DROP TABLE t1;
|
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;
|
||||||
|
1
mysql-test/suite/gcol/t/innodb_virtual_index.opt
Normal file
1
mysql-test/suite/gcol/t/innodb_virtual_index.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--innodb_sort_buffer_size=64k
|
@ -1,4 +1,5 @@
|
|||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
|
--source include/have_sequence.inc
|
||||||
|
|
||||||
# Ensure that the history list length will actually be decremented by purge.
|
# Ensure that the history list length will actually be decremented by purge.
|
||||||
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
SET @saved_frequency = @@GLOBAL.innodb_purge_rseg_truncate_frequency;
|
||||||
@ -281,3 +282,23 @@ ROLLBACK;
|
|||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
CHECK TABLE t1;
|
CHECK TABLE t1;
|
||||||
DROP 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;
|
||||||
|
@ -1041,7 +1041,9 @@ CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
|||||||
iNSERT INTO t1 VALUES (10);
|
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);
|
ALTER TABLE t1 ADD b DATE NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||||
affected rows: 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;
|
SELECT * FROM t1;
|
||||||
a b
|
a b
|
||||||
10 2001-01-01
|
10 2001-01-01
|
||||||
@ -1050,7 +1052,9 @@ CREATE TABLE t1 (a INT NOT NULL DEFAULT 0) ENGINE=InnoDB;
|
|||||||
iNSERT INTO t1 VALUES (10);
|
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);
|
ALTER TABLE t1 ADD b TIME NOT NULL DEFAULT if(unix_timestamp()>1,TIMESTAMP'2001-01-01 10:20:30',0);
|
||||||
affected rows: 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;
|
SELECT * FROM t1;
|
||||||
a b
|
a b
|
||||||
10 10:20:30
|
10 10:20:30
|
||||||
|
@ -9680,9 +9680,17 @@ do_continue:;
|
|||||||
if (use_inplace)
|
if (use_inplace)
|
||||||
{
|
{
|
||||||
table->s->frm_image= &frm;
|
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,
|
int res= mysql_inplace_alter_table(thd, table_list, table, altered_table,
|
||||||
&ha_alter_info, inplace_supported,
|
&ha_alter_info, inplace_supported,
|
||||||
&target_mdl_request, &alter_ctx);
|
&target_mdl_request, &alter_ctx);
|
||||||
|
|
||||||
|
thd->count_cuted_fields= save_count_cuted_fields;
|
||||||
|
|
||||||
my_free(const_cast<uchar*>(frm.str));
|
my_free(const_cast<uchar*>(frm.str));
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
|
@ -524,7 +524,9 @@ row_merge_buf_add(
|
|||||||
DBUG_ENTER("row_merge_buf_add");
|
DBUG_ENTER("row_merge_buf_add");
|
||||||
|
|
||||||
if (buf->n_tuples >= buf->max_tuples) {
|
if (buf->n_tuples >= buf->max_tuples) {
|
||||||
DBUG_RETURN(0);
|
error:
|
||||||
|
n_row_added = 0;
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_EXECUTE_IF(
|
DBUG_EXECUTE_IF(
|
||||||
@ -845,11 +847,6 @@ end:
|
|||||||
if (vcol_storage.innobase_record)
|
if (vcol_storage.innobase_record)
|
||||||
innobase_free_row_for_vcol(&vcol_storage);
|
innobase_free_row_for_vcol(&vcol_storage);
|
||||||
DBUG_RETURN(n_row_added);
|
DBUG_RETURN(n_row_added);
|
||||||
|
|
||||||
error:
|
|
||||||
if (vcol_storage.innobase_record)
|
|
||||||
innobase_free_row_for_vcol(&vcol_storage);
|
|
||||||
DBUG_RETURN(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************//**
|
/*************************************************************//**
|
||||||
@ -2567,16 +2564,18 @@ write_buffers:
|
|||||||
new_table, psort_info, row, ext,
|
new_table, psort_info, row, ext,
|
||||||
&doc_id, conv_heap,
|
&doc_id, conv_heap,
|
||||||
&err, &v_heap, eval_table, trx)))) {
|
&err, &v_heap, eval_table, trx)))) {
|
||||||
/* An empty buffer should have enough
|
/* An empty buffer should have enough
|
||||||
room for at least one record. */
|
room for at least one record. */
|
||||||
ut_error;
|
ut_ad(err == DB_COMPUTE_VALUE_FAILED
|
||||||
|
|| err == DB_OUT_OF_MEMORY
|
||||||
|
|| err == DB_TOO_BIG_RECORD);
|
||||||
|
} else if (err == DB_SUCCESS) {
|
||||||
|
file->n_rec += rows_added;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
trx->error_key_num = i;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
file->n_rec += rows_added;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user