summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-11-21 16:16:52 +0100
committerSergei Golubchik <serg@mariadb.org>2016-12-12 20:27:32 +0100
commit8b6c0542db908bba548bdb217d78bae25d4522ca (patch)
tree04929cda5034711c67cd3194d3b368c0e4197820
parent10089493bdc3f7b782d01fa8d2f3221449965458 (diff)
downloadmariadb-git-8b6c0542db908bba548bdb217d78bae25d4522ca.tar.gz
bugfix: stored column depends on virtual depends on updated
TABLE::mark_virtual_col() was polluting table->vcol_set and that confused the following mark_virtual_col()
-rw-r--r--mysql-test/suite/vcol/r/update.result10
-rw-r--r--mysql-test/suite/vcol/t/update.test12
-rw-r--r--sql/table.cc33
3 files changed, 41 insertions, 14 deletions
diff --git a/mysql-test/suite/vcol/r/update.result b/mysql-test/suite/vcol/r/update.result
new file mode 100644
index 00000000000..d56f85c1f1c
--- /dev/null
+++ b/mysql-test/suite/vcol/r/update.result
@@ -0,0 +1,10 @@
+create table t1 (a int, b int as (a+1), c int as (b+1) stored);
+insert t1 set a=1;
+select * from t1;
+a b c
+1 2 3
+update t1 set a=2;
+select * from t1;
+a b c
+2 3 4
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/update.test b/mysql-test/suite/vcol/t/update.test
new file mode 100644
index 00000000000..35dbab83bfc
--- /dev/null
+++ b/mysql-test/suite/vcol/t/update.test
@@ -0,0 +1,12 @@
+#
+# Test how UPDATE detects what columns need to be read (or generated) in a row
+#
+# stored column depends on virtual column depends on updated column.
+# this tests TABLE::mark_virtual_columns_for_write()
+#
+create table t1 (a int, b int as (a+1), c int as (b+1) stored);
+insert t1 set a=1;
+select * from t1;
+update t1 set a=2;
+select * from t1;
+drop table t1;
diff --git a/sql/table.cc b/sql/table.cc
index ad7e3e17cad..8bc2ef35bcf 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -6537,7 +6537,7 @@ bool TABLE::mark_virtual_col(Field *field)
bool TABLE::mark_virtual_columns_for_write(bool insert_fl)
{
Field **vfield_ptr, *tmp_vfield;
- bool bitmap_updated= FALSE;
+ bool bitmap_updated= false;
for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++)
{
@@ -6546,25 +6546,30 @@ bool TABLE::mark_virtual_columns_for_write(bool insert_fl)
bitmap_updated= mark_virtual_col(tmp_vfield);
else if (tmp_vfield->vcol_info->stored_in_db)
{
- bool mark_fl= insert_fl;
- if (!mark_fl)
+ if (insert_fl)
{
- MY_BITMAP *save_read_set;
+ bitmap_set_bit(write_set, tmp_vfield->field_index);
+ mark_virtual_col(tmp_vfield);
+ bitmap_updated= true;
+ }
+ else
+ {
+ MY_BITMAP *save_read_set= read_set, *save_vcol_set= vcol_set;
Item *vcol_item= tmp_vfield->vcol_info->expr_item;
DBUG_ASSERT(vcol_item);
bitmap_clear_all(&tmp_set);
- save_read_set= read_set;
- read_set= &tmp_set;
+ read_set= vcol_set= &tmp_set;
vcol_item->walk(&Item::register_field_in_read_map, 1, 0);
read_set= save_read_set;
- bitmap_intersect(&tmp_set, write_set);
- mark_fl= !bitmap_is_clear_all(&tmp_set);
- }
- if (mark_fl)
- {
- bitmap_set_bit(write_set, tmp_vfield->field_index);
- mark_virtual_col(tmp_vfield);
- bitmap_updated= TRUE;
+ vcol_set= save_vcol_set;
+ if (bitmap_is_overlapping(&tmp_set, write_set))
+ {
+ bitmap_set_bit(write_set, tmp_vfield->field_index);
+ bitmap_set_bit(vcol_set, tmp_vfield->field_index);
+ bitmap_union(read_set, &tmp_set);
+ bitmap_union(vcol_set, &tmp_set);
+ bitmap_updated= true;
+ }
}
}
}