summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2019-12-02 11:48:37 +0300
committerAleksey Midenkov <midenok@gmail.com>2019-12-02 11:48:37 +0300
commit97aa07abf544870faa0956784f33f158b092b2e5 (patch)
treeefcffbe5a3a123d2701522838de8180108a15092
parent498a96a4789e58549ce87b5843e804e055ab327f (diff)
downloadmariadb-git-97aa07abf544870faa0956784f33f158b092b2e5.tar.gz
MDEV-21147 Assertion `marked_for_read()' upon UPDATE on versioned table via view
"write set" for replication finally got its correct place (mark_columns_per_binlog_row_image()). When done generally in mark_columns_needed_for_update() it affects optimization algorithm. used_key_is_modified, query_plan.using_io_buffer are wrongly set and that leads to wrong prepare_for_keyread() which limits read_set.
-rw-r--r--mysql-test/suite/versioning/r/update.result12
-rw-r--r--mysql-test/suite/versioning/t/update.test16
-rw-r--r--sql/table.cc16
3 files changed, 38 insertions, 6 deletions
diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result
index 08b105e952b..64aa7c7068c 100644
--- a/mysql-test/suite/versioning/r/update.result
+++ b/mysql-test/suite/versioning/r/update.result
@@ -285,3 +285,15 @@ with system versioning;
insert into t1 (a) values ('foo');
update t1 set a = 'bar';
drop table t1;
+#
+# MDEV-21147 Assertion `marked_for_read()' upon UPDATE on versioned table via view
+#
+create or replace table t1 (
+pk int, a char(8), b char(8),
+primary key (pk)
+) with system versioning;
+create or replace view v1 as select * from t1;
+insert into t1 values (1, null, 'd') , (2, null, 'i') ;
+update v1 set a= null where b = '';
+drop view v1;
+drop table t1;
diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test
index 148cbbdc707..baf3c1ec876 100644
--- a/mysql-test/suite/versioning/t/update.test
+++ b/mysql-test/suite/versioning/t/update.test
@@ -202,4 +202,20 @@ insert into t1 (a) values ('foo');
update t1 set a = 'bar';
drop table t1;
+--echo #
+--echo # MDEV-21147 Assertion `marked_for_read()' upon UPDATE on versioned table via view
+--echo #
+create or replace table t1 (
+ pk int, a char(8), b char(8),
+ primary key (pk)
+) with system versioning;
+
+create or replace view v1 as select * from t1;
+insert into t1 values (1, null, 'd') , (2, null, 'i') ;
+update v1 set a= null where b = '';
+
+# cleanup
+drop view v1;
+drop table t1;
+
source suite/versioning/common_finish.inc;
diff --git a/sql/table.cc b/sql/table.cc
index 291418f55fe..cbf26031658 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6613,12 +6613,8 @@ void TABLE::mark_columns_needed_for_update()
/*
For System Versioning we have to read all columns since we store
a copy of previous row with modified row_end back to a table.
-
- Without write_set versioning.rpl,row is unstable until MDEV-16370 is
- applied.
*/
bitmap_union(read_set, &s->all_set);
- bitmap_union(write_set, &s->all_set);
need_signal= true;
}
if (check_constraints)
@@ -6781,8 +6777,16 @@ void TABLE::mark_columns_per_binlog_row_image()
binary log will include all columns read anyway.
*/
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
- /* Only write columns that have changed */
- rpl_write_set= write_set;
+ if (versioned())
+ {
+ // TODO: After MDEV-18432 we don't pass history rows, so remove this:
+ rpl_write_set= &s->all_set;
+ }
+ else
+ {
+ /* Only write columns that have changed */
+ rpl_write_set= write_set;
+ }
break;
default: