summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-05-25 18:43:45 +0400
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-05-25 18:43:45 +0400
commit8fabbdd789826ef4b9a02ad1480619e8a4446911 (patch)
tree71545c602ecb882ad5319079c4454c93f5493769 /sql
parent6e34b8b0ce0bd52cdc36182baeb3f313012d694b (diff)
downloadmariadb-git-8fabbdd789826ef4b9a02ad1480619e8a4446911.tar.gz
Bug #53830: !table || (!table->read_set ||
bitmap_is_set(table->read_set, field_index)) UPDATE on an InnoDB table modifying the same index that is used to satisfy the WHERE condition could trigger a debug assertion under some circumstances. Since for engines with the HA_PRIMARY_KEY_IN_READ_INDEX flag set results of an index scan on a secondary index are appended by the primary key value, if a query involves only columns from the primary key and a secondary index, the latter is considered to be covering. That tricks mysql_update() to mark for reading only columns from the secondary index when it does an index scan to retrieve rows to update in case a part of that key is also being updated. However, there may be other columns in WHERE that are part of the primary key, but not the secondary one. What we actually want to do in this case is to add index columns to the existing WHERE columns bitmap rather than replace it.
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_update.cc2
-rw-r--r--sql/table.cc21
-rw-r--r--sql/table.h1
3 files changed, 23 insertions, 1 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 69f3a29e923..7df0898e841 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -397,7 +397,7 @@ int mysql_update(THD *thd,
matching rows before updating the table!
*/
if (used_index < MAX_KEY && old_covering_keys.is_set(used_index))
- table->mark_columns_used_by_index(used_index);
+ table->add_read_columns_used_by_index(used_index);
else
{
table->use_all_columns();
diff --git a/sql/table.cc b/sql/table.cc
index 8b97dd36170..0fef7fa639a 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -4378,6 +4378,27 @@ void st_table::mark_columns_used_by_index(uint index)
/*
+ Add fields used by a specified index to the table's read_set.
+
+ NOTE:
+ The original state can be restored with
+ restore_column_maps_after_mark_index().
+*/
+
+void st_table::add_read_columns_used_by_index(uint index)
+{
+ MY_BITMAP *bitmap= &tmp_set;
+ DBUG_ENTER("st_table::add_read_columns_used_by_index");
+
+ set_keyread(TRUE);
+ bitmap_copy(bitmap, read_set);
+ mark_columns_used_by_index_no_reset(index, bitmap);
+ column_bitmaps_set(bitmap, write_set);
+ DBUG_VOID_RETURN;
+}
+
+
+/*
Restore to use normal column maps after key read
NOTES
diff --git a/sql/table.h b/sql/table.h
index bddb0731625..4125c252427 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -865,6 +865,7 @@ struct st_table {
void prepare_for_position(void);
void mark_columns_used_by_index_no_reset(uint index, MY_BITMAP *map);
void mark_columns_used_by_index(uint index);
+ void add_read_columns_used_by_index(uint index);
void restore_column_maps_after_mark_index();
void mark_auto_increment_column(void);
void mark_columns_needed_for_update(void);