summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
authorJorgen Loland <jorgen.loland@oracle.com>2011-06-16 08:24:00 +0200
committerJorgen Loland <jorgen.loland@oracle.com>2011-06-16 08:24:00 +0200
commitebe94178d1bb3fcab49791462634d9e79ea72f25 (patch)
tree32635dc09bff582bae4370798dbd6f8dc204dc61 /sql/sql_update.cc
parent0357d0dcedb76f64ea8bbbc81c1f90ec7d886e86 (diff)
downloadmariadb-git-ebe94178d1bb3fcab49791462634d9e79ea72f25.tar.gz
BUG#11882110: UPDATE REPORTS ER_KEY_NOT_FOUND IF TABLE IS
UPDATED TWICE For multi update it is not allowed to update a column of a table if that table is accessed through multiple aliases and either 1) the updated column is used as partitioning key 2) the updated column is part of the primary key and the primary key is clustered This check is done in unsafe_key_update(). The bug was that for case 2), it was checked whether updated_column_number == table_share->primary_key However, the primary_key variable is the index number of the primary key, not a column number. Prior to this bugfix, the first column was wrongly believed to be the primary key. The columns covered by an index is found in table->key_info[idx_number]->key_part. The bugfix is to check if any of the columns in the keyparts of the primary key are updated. The user-visible effect is that for storage engines with clustered primary key (e.g. InnoDB but not MyISAM) queries like "UPDATE t1 AS A JOIN t2 AS B SET A.primkey=..." will now error with "ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'." instead of "ERROR 1032 (HY000): Can't find record in 't1_tb'" even if primkey is not the first column in the table. This was the intended behavior of bugfix 11764529.
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc30
1 files changed, 20 insertions, 10 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 59356540201..90c4697d663 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1071,17 +1071,27 @@ bool unsafe_key_update(TABLE_LIST *leaves, table_map tables_for_update)
return true;
}
- if (primkey_clustered &&
- (bitmap_is_set(table1->write_set, table1->s->primary_key) ||
- bitmap_is_set(table2->write_set, table2->s->primary_key)))
+ if (primkey_clustered)
{
- // Clustered primary key is updated
- my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
- tl->belong_to_view ? tl->belong_to_view->alias
- : tl->alias,
- tl2->belong_to_view ? tl2->belong_to_view->alias
- : tl2->alias);
- return true;
+ // The primary key can cover multiple columns
+ KEY key_info= table1->key_info[table1->s->primary_key];
+ KEY_PART_INFO *key_part= key_info.key_part;
+ KEY_PART_INFO *key_part_end= key_part + key_info.key_parts;
+
+ for (;key_part != key_part_end; ++key_part)
+ {
+ if (bitmap_is_set(table1->write_set, key_part->fieldnr-1) ||
+ bitmap_is_set(table2->write_set, key_part->fieldnr-1))
+ {
+ // Clustered primary key is updated
+ my_error(ER_MULTI_UPDATE_KEY_CONFLICT, MYF(0),
+ tl->belong_to_view ? tl->belong_to_view->alias
+ : tl->alias,
+ tl2->belong_to_view ? tl2->belong_to_view->alias
+ : tl2->alias);
+ return true;
+ }
+ }
}
}
}