summaryrefslogtreecommitdiff
path: root/sql/opt_range.h
diff options
context:
space:
mode:
authordlenev@mockturtle.local <>2006-09-21 13:39:29 +0400
committerdlenev@mockturtle.local <>2006-09-21 13:39:29 +0400
commit5f149dde099e1496ce4385b2bb80574ca448ea84 (patch)
tree46d94da2ee46e9db021755af73dc09ad937f73c4 /sql/opt_range.h
parent5d8598a405ab3af2df90f02514b778966ad66e7b (diff)
downloadmariadb-git-5f149dde099e1496ce4385b2bb80574ca448ea84.tar.gz
Fix for bug#20670 "UPDATE using key and invoking trigger that modifies
this key does not stop" (5.1 version). UPDATE statement which WHERE clause used key and which invoked trigger that modified field in this key worked indefinetely. This problem occured because in cases when UPDATE statement was executed in update-on-the-fly mode (in which row is updated right during evaluation of select for WHERE clause) the new version of the row became visible to select representing WHERE clause and was updated again and again. We already solve this problem for UPDATE statements which does not invoke triggers by detecting the fact that we are going to update field in key used for scanning and performing update in two steps, during the first step we gather information about the rows to be updated and then doing actual updates. We also do this for MULTI-UPDATE and in its case we even detect situation when such fields are updated in triggers (actually we simply assume that we always update fields used in key if we have before update trigger). The fix simply extends this check which is done with help of check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() routine/method in such way that it also detects cases when field used in key is updated in trigger. We do this by changing check_if_key_used() to take field bitmap instead field list as argument and passing TABLE::write_set to it (we also have to add info about fields used in triggers to this bitmap a bit earlier). As nice side-effect we have more precise and thus more optimal perfomance-wise check for the MULTI-UPDATE. Also check_if_key_used() routine and similar method were renamed to is_key_used()/is_keys_used() in order to better reflect that it is simple boolean predicate. Finally, partition_key_modified() routine now also takes field bitmap instead of field list as argument.
Diffstat (limited to 'sql/opt_range.h')
-rw-r--r--sql/opt_range.h11
1 files changed, 5 insertions, 6 deletions
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 6f26f9f782c..6099608f7cd 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -224,10 +224,9 @@ public:
virtual void add_info_string(String *str) {};
/*
Return 1 if any index used by this quick select
- a) uses field that is listed in passed field list or
- b) is automatically updated (like a timestamp)
+ uses field which is marked in passed bitmap.
*/
- virtual bool check_if_keys_used(List<Item> *fields);
+ virtual bool is_keys_used(const MY_BITMAP *fields);
/*
rowid of last row retrieved by this quick select. This is used only when
@@ -425,7 +424,7 @@ public:
int get_type() { return QS_TYPE_INDEX_MERGE; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
void add_info_string(String *str);
- bool check_if_keys_used(List<Item> *fields);
+ bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
@@ -484,7 +483,7 @@ public:
int get_type() { return QS_TYPE_ROR_INTERSECT; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
void add_info_string(String *str);
- bool check_if_keys_used(List<Item> *fields);
+ bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif
@@ -538,7 +537,7 @@ public:
int get_type() { return QS_TYPE_ROR_UNION; }
void add_keys_and_lengths(String *key_names, String *used_lengths);
void add_info_string(String *str);
- bool check_if_keys_used(List<Item> *fields);
+ bool is_keys_used(const MY_BITMAP *fields);
#ifndef DBUG_OFF
void dbug_dump(int indent, bool verbose);
#endif