Commit c02d6164 authored by Michael Widenius's avatar Michael Widenius

MDEV-19771 REPLACE on table with virtual_field can cause crash

Fixes also MDEV-17837

Problem was that we did not ignore warnings from virtual fields when
updated virtual fields for to-be-replaced row.
parent 21eed902
...@@ -423,5 +423,43 @@ ERROR HY000: Incorrect information in file: './test/t1.frm' ...@@ -423,5 +423,43 @@ ERROR HY000: Incorrect information in file: './test/t1.frm'
ALTER TABLE t1; ALTER TABLE t1;
ERROR HY000: Incorrect information in file: './test/t1.frm' ERROR HY000: Incorrect information in file: './test/t1.frm'
# #
# MDEV-19771 REPLACE on table with virtual_field can cause crash in set_ok_status()
create or replace table t1 (pk int primary key, col_bit bit(15) default null,
vcol_bit bit(10) GENERATED ALWAYS AS (`col_bit`) VIRTUAL);
replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
select pk, col_bit+0, vcol_bit+0 from t1;
pk col_bit+0 vcol_bit+0
99 1000 1000
replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
select pk, col_bit+0, vcol_bit+0 from t1;
pk col_bit+0 vcol_bit+0
99 10000 1023
REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
Warnings:
Warning 1264 Out of range value for column 'vcol_bit' at row 1
drop table t1;
#
# MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
#
SET @old_sql_mode=@@sql_mode;
SET sql_mode= STRICT_ALL_TABLES;
CREATE TABLE t1 (
pk INT,
i TINYINT,
vi TINYINT AS (i+1) PERSISTENT,
PRIMARY KEY(pk)
);
INSERT INTO t1 (pk,i) VALUES (1,1);
TRUNCATE TABLE t1;
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
REPLACE INTO t1 (pk,i) VALUES (1,2);
Warnings:
Warning 1264 Out of range value for column 'vi' at row 1
DROP TABLE t1;
SET @sql_mode=@old_sql_mode;
#
# End of 10.2 tests # End of 10.2 tests
# #
...@@ -215,12 +215,12 @@ drop table t1; ...@@ -215,12 +215,12 @@ drop table t1;
create table t1 (a int, b int); create table t1 (a int, b int);
insert into t1 values (3, 30), (4, 20), (1, 20); insert into t1 values (3, 30), (4, 20), (1, 20);
create table t2 (c int, d int, v int as (d+1), index idx(c)); create table t2 (c int, d int, v int as (d+1), index idx(c));
insert into t2(c,d) values insert into t2(c,d) values
(20, 100), (20, 300), (30, 100), (30, 200), (40, 500), (20, 100), (20, 300), (30, 100), (30, 200), (40, 500),
(70, 100), (40, 300), (60, 100), (40, 100), (70, 100); (70, 100), (40, 300), (60, 100), (40, 100), (70, 100);
insert into t2(c,d) values insert into t2(c,d) values
(120, 100), (150, 300), (130, 100), (130, 200), (140, 500), (120, 100), (150, 300), (130, 100), (130, 200), (140, 500),
(170, 100), (180, 300), (160, 100), (40, 100), (170, 100); (170, 100), (180, 300), (160, 100), (40, 100), (170, 100);
set join_cache_level=6; set join_cache_level=6;
explain explain
...@@ -391,6 +391,40 @@ SHOW CREATE TABLE t1; ...@@ -391,6 +391,40 @@ SHOW CREATE TABLE t1;
ALTER TABLE t1; ALTER TABLE t1;
--remove_file $MYSQLD_DATADIR/test/t1.frm --remove_file $MYSQLD_DATADIR/test/t1.frm
--echo #
--echo # MDEV-19771 REPLACE on table with virtual_field can cause crash in set_ok_status()
--echo
create or replace table t1 (pk int primary key, col_bit bit(15) default null,
vcol_bit bit(10) GENERATED ALWAYS AS (`col_bit`) VIRTUAL);
replace INTO `t1` (`pk`,col_bit) VALUES (99,1000);
select pk, col_bit+0, vcol_bit+0 from t1;
replace INTO `t1` (`pk`,col_bit) VALUES (99,10000);
select pk, col_bit+0, vcol_bit+0 from t1;
REPLACE LOW_PRIORITY INTO `t1` (`pk`) VALUES (99);
drop table t1;
--echo #
--echo # MDEV-17837 REPLACE on table with virtual_field can cause crash in set_ok_status()
--echo #
SET @old_sql_mode=@@sql_mode;
SET sql_mode= STRICT_ALL_TABLES;
CREATE TABLE t1 (
pk INT,
i TINYINT,
vi TINYINT AS (i+1) PERSISTENT,
PRIMARY KEY(pk)
);
INSERT INTO t1 (pk,i) VALUES (1,1);
TRUNCATE TABLE t1;
INSERT IGNORE INTO t1 (pk,i) VALUES (1,127);
REPLACE INTO t1 (pk,i) VALUES (1,2);
DROP TABLE t1;
SET @sql_mode=@old_sql_mode;
--echo # --echo #
--echo # End of 10.2 tests --echo # End of 10.2 tests
--echo # --echo #
...@@ -1747,12 +1747,15 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1747,12 +1747,15 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
} }
if (table->vfield) if (table->vfield)
{ {
my_bool abort_on_warning= thd->abort_on_warning;
/* /*
We have not yet called update_virtual_fields(VOL_UPDATE_FOR_READ) We have not yet called update_virtual_fields(VOL_UPDATE_FOR_READ)
in handler methods for the just read row in record[1]. in handler methods for the just read row in record[1].
*/ */
table->move_fields(table->field, table->record[1], table->record[0]); table->move_fields(table->field, table->record[1], table->record[0]);
thd->abort_on_warning= 0;
table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE); table->update_virtual_fields(table->file, VCOL_UPDATE_FOR_REPLACE);
thd->abort_on_warning= abort_on_warning;
table->move_fields(table->field, table->record[0], table->record[1]); table->move_fields(table->field, table->record[0], table->record[1]);
} }
if (info->handle_duplicates == DUP_UPDATE) if (info->handle_duplicates == DUP_UPDATE)
......
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