From 8f5b6ec237fdd152f651a3c5537763d2d0f8ef32 Mon Sep 17 00:00:00 2001 From: "svoj@mysql.com/april.(none)" <> Date: Fri, 15 Jun 2007 03:22:40 +0500 Subject: [PATCH] BUG#28971 - ALTER TABLE followed by UPDATE for a CSV table make server crash UPDATE against CSV table may cause server crash or update a table with wrong values. CSV can write only a whole row at once. That means it must read all columns, that it is not going to update, and write them along with updated columns. But only limited set of columns was read, those that were needed for the UPDATE query. With this fix all columns are read in case we're performing an UPDATE. --- mysql-test/r/csv.result | 8 ++++++++ mysql-test/t/csv.test | 11 +++++++++++ storage/csv/ha_tina.cc | 5 ++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index ede5d9a32fd..1196a264fd3 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -5240,3 +5240,11 @@ CREATE TABLE `bug21328` ( insert into bug21328 values (1,NULL,NULL); alter table bug21328 engine=myisam; drop table bug21328; +create table t1(a blob, b int) engine=csv; +insert into t1 values('a', 1); +flush tables; +update t1 set b=2; +select * from t1; +a b +a 2 +drop table t1; diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 62482d576b2..922fbb0d3f1 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1653,3 +1653,14 @@ CREATE TABLE `bug21328` ( insert into bug21328 values (1,NULL,NULL); alter table bug21328 engine=myisam; drop table bug21328; + +# +# BUG#28971 - ALTER TABLE followed by UPDATE for a CSV table make server +# crash +# +create table t1(a blob, b int) engine=csv; +insert into t1 values('a', 1); +flush tables; +update t1 set b=2; +select * from t1; +drop table t1; diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index 9eead7a059c..c0790d69888 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -590,6 +590,7 @@ int ha_tina::find_current_row(uchar *buf) int eoln_len; my_bitmap_map *org_bitmap; int error; + bool read_all; DBUG_ENTER("ha_tina::find_current_row"); /* @@ -601,6 +602,8 @@ int ha_tina::find_current_row(uchar *buf) local_saved_data_file_length, &eoln_len)) == 0) DBUG_RETURN(HA_ERR_END_OF_FILE); + /* We must read all columns in case a table is opened for update */ + read_all= !bitmap_is_clear_all(table->write_set); /* Avoid asserts in ::store() for columns that are not going to be updated */ org_bitmap= dbug_tmp_use_all_columns(table, table->write_set); error= HA_ERR_CRASHED_ON_USAGE; @@ -678,7 +681,7 @@ int ha_tina::find_current_row(uchar *buf) goto err; } - if (bitmap_is_set(table->read_set, (*field)->field_index)) + if (read_all || bitmap_is_set(table->read_set, (*field)->field_index)) (*field)->store(buffer.ptr(), buffer.length(), system_charset_info); } next_position= end_offset + eoln_len;