diff options
author | Sergei Golubchik <serg@mariadb.org> | 2016-11-21 16:16:52 +0100 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-12-12 20:27:32 +0100 |
commit | 8b6c0542db908bba548bdb217d78bae25d4522ca (patch) | |
tree | 04929cda5034711c67cd3194d3b368c0e4197820 | |
parent | 10089493bdc3f7b782d01fa8d2f3221449965458 (diff) | |
download | mariadb-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.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/vcol/t/update.test | 12 | ||||
-rw-r--r-- | sql/table.cc | 33 |
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; + } } } } |