Below is the list of changes that have just been committed into a local
5.1 repository of dlenev. When dlenev does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-09-30 00:31:33+04:00, dlenev@stripped +7 -0
Merge bk-internal.mysql.com:/home/bk/mysql-5.1-runtime
into mockturtle.local:/home/dlenev/src/mysql-5.1-bg20670
MERGE: 1.2255.60.8
mysql-test/r/trigger.result@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0
-0
Auto merged
MERGE: 1.46.1.1
mysql-test/t/trigger.test@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0 -0
Auto merged
MERGE: 1.50.1.1
sql/mysql_priv.h@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0 -0
Auto merged
MERGE: 1.432.1.2
sql/opt_range.cc@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0 -0
Auto merged
MERGE: 1.228.2.2
sql/opt_range.h@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0 -0
Auto merged
MERGE: 1.62.1.2
sql/sql_partition.cc@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0 -0
Auto merged
MERGE: 1.82.2.3
sql/sql_update.cc@stripped, 2006-09-30 00:31:29+04:00, dlenev@stripped +0 -0
Auto merged
MERGE: 1.204.1.2
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: dlenev
# Host: mockturtle.local
# Root: /home/dlenev/src/mysql-5.1-bg20670/RESYNC
--- 1.445/sql/mysql_priv.h 2006-09-30 00:31:40 +04:00
+++ 1.446/sql/mysql_priv.h 2006-09-30 00:31:40 +04:00
@@ -1417,7 +1417,7 @@
uint key_length);
bool key_cmp_if_same(TABLE *form,const byte *key,uint index,uint key_length);
void key_unpack(String *to,TABLE *form,uint index);
-bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields);
+bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields);
int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length);
int key_rec_cmp(void *key_info, byte *a, byte *b);
--- 1.235/sql/opt_range.cc 2006-09-30 00:31:40 +04:00
+++ 1.236/sql/opt_range.cc 2006-09-30 00:31:40 +04:00
@@ -7526,42 +7526,42 @@
}
-bool QUICK_SELECT_I::check_if_keys_used(List<Item> *fields)
+bool QUICK_SELECT_I::is_keys_used(const MY_BITMAP *fields)
{
- return check_if_key_used(head, index, *fields);
+ return is_key_used(head, index, fields);
}
-bool QUICK_INDEX_MERGE_SELECT::check_if_keys_used(List<Item> *fields)
+bool QUICK_INDEX_MERGE_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++))
{
- if (check_if_key_used(head, quick->index, *fields))
+ if (is_key_used(head, quick->index, fields))
return 1;
}
return 0;
}
-bool QUICK_ROR_INTERSECT_SELECT::check_if_keys_used(List<Item> *fields)
+bool QUICK_ROR_INTERSECT_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
while ((quick= it++))
{
- if (check_if_key_used(head, quick->index, *fields))
+ if (is_key_used(head, quick->index, fields))
return 1;
}
return 0;
}
-bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List<Item> *fields)
+bool QUICK_ROR_UNION_SELECT::is_keys_used(const MY_BITMAP *fields)
{
QUICK_SELECT_I *quick;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
while ((quick= it++))
{
- if (quick->check_if_keys_used(fields))
+ if (quick->is_keys_used(fields))
return 1;
}
return 0;
--- 1.64/sql/opt_range.h 2006-09-30 00:31:40 +04:00
+++ 1.65/sql/opt_range.h 2006-09-30 00:31:40 +04:00
@@ -224,10 +224,9 @@
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 @@
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 @@
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 @@
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
--- 1.206/sql/sql_update.cc 2006-09-30 00:31:40 +04:00
+++ 1.207/sql/sql_update.cc 2006-09-30 00:31:40 +04:00
@@ -25,7 +25,7 @@
#include "sp_head.h"
#include "sql_trigger.h"
-static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields);
+static bool safe_update_on_fly(JOIN_TAB *join_tab);
/* Return 0 if row hasn't changed */
@@ -271,13 +271,16 @@
}
}
init_ftfuncs(thd, select_lex, 1);
+
+ table->mark_columns_needed_for_update();
+
/* Check if we are modifying a key that we are used to search with */
if (select && select->quick)
{
used_index= select->quick->index;
used_key_is_modified= (!select->quick->unique_key_range() &&
- select->quick->check_if_keys_used(&fields));
+ select->quick->is_keys_used(table->write_set));
}
else
{
@@ -285,12 +288,13 @@
if (used_index == MAX_KEY) // no index for sort order
used_index= table->file->key_used_on_scan;
if (used_index != MAX_KEY)
- used_key_is_modified= check_if_key_used(table, used_index, fields);
+ used_key_is_modified= is_key_used(table, used_index, table->write_set);
}
+
#ifdef WITH_PARTITION_STORAGE_ENGINE
if (used_key_is_modified || order ||
- partition_key_modified(table, fields))
+ partition_key_modified(table, table->write_set))
#else
if (used_key_is_modified || order)
#endif
@@ -449,8 +453,6 @@
MODE_STRICT_ALL_TABLES)));
will_batch= !table->file->start_bulk_update();
- table->mark_columns_needed_for_update();
-
/*
We can use compare_record() to optimize away updates if
the table handler is returning all columns OR if
@@ -1217,7 +1219,7 @@
table->mark_columns_needed_for_update();
if (table == main_table) // First table in join
{
- if (safe_update_on_fly(join->join_tab, &temp_fields))
+ if (safe_update_on_fly(join->join_tab))
{
table_to_update= main_table; // Update table on the fly
continue;
@@ -1275,7 +1277,6 @@
SYNOPSIS
safe_update_on_fly
join_tab How table is used in join
- fields Fields that are updated
NOTES
We can update the first table in join on the fly if we know that
@@ -1288,9 +1289,8 @@
- We are doing a range scan and we don't update the scan key or
the primary key for a clustered table handler.
- When checking for above cases we also should take into account that
- BEFORE UPDATE trigger potentially may change value of any field in row
- being updated.
+ This function gets information about fields to be updated from
+ the TABLE::write_set bitmap.
WARNING
This code is a bit dependent of how make_join_readinfo() works.
@@ -1300,7 +1300,7 @@
1 Safe to update
*/
-static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
+static bool safe_update_on_fly(JOIN_TAB *join_tab)
{
TABLE *table= join_tab->table;
switch (join_tab->type) {
@@ -1310,21 +1310,15 @@
return TRUE; // At most one matching row
case JT_REF:
case JT_REF_OR_NULL:
- return !check_if_key_used(table, join_tab->ref.key, *fields) &&
- !(table->triggers &&
- table->triggers->has_before_update_triggers());
+ return !is_key_used(table, join_tab->ref.key, table->write_set);
case JT_ALL:
/* If range search on index */
if (join_tab->quick)
- return !join_tab->quick->check_if_keys_used(fields) &&
- !(table->triggers &&
- table->triggers->has_before_update_triggers());
+ return !join_tab->quick->is_keys_used(table->write_set);
/* If scanning in clustered key */
if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX)
&&
table->s->primary_key < MAX_KEY)
- return !check_if_key_used(table, table->s->primary_key, *fields) &&
- !(table->triggers &&
- table->triggers->has_before_update_triggers());
+ return !is_key_used(table, table->s->primary_key, table->write_set);
return TRUE;
default:
break; // Avoid compler warning
--- 1.48/mysql-test/r/trigger.result 2006-09-30 00:31:40 +04:00
+++ 1.49/mysql-test/r/trigger.result 2006-09-30 00:31:40 +04:00
@@ -1173,4 +1173,16 @@
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY'
is too long for host name (should be no longer than 60)
DROP TABLE t1;
DROP TABLE t2;
+drop table if exists t1;
+create table t1 (i int, j int key);
+insert into t1 values (1,1), (2,2), (3,3);
+create trigger t1_bu before update on t1 for each row
+set new.j = new.j + 10;
+update t1 set i= i+ 10 where j > 2;
+select * from t1;
+i j
+1 1
+2 2
+13 13
+drop table t1;
End of 5.0 tests
--- 1.52/mysql-test/t/trigger.test 2006-09-30 00:31:40 +04:00
+++ 1.53/mysql-test/t/trigger.test 2006-09-30 00:31:40 +04:00
@@ -1421,4 +1421,23 @@
DROP TABLE t2;
+#
+# Bug#20670 "UPDATE using key and invoking trigger that modifies
+# this key does not stop"
+#
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+create table t1 (i int, j int key);
+insert into t1 values (1,1), (2,2), (3,3);
+create trigger t1_bu before update on t1 for each row
+ set new.j = new.j + 10;
+# This should not work indefinitely and should cause
+# expected result
+update t1 set i= i+ 10 where j > 2;
+select * from t1;
+drop table t1;
+
+
--echo End of 5.0 tests
--- 1.89/sql/sql_partition.cc 2006-09-30 00:31:40 +04:00
+++ 1.90/sql/sql_partition.cc 2006-09-30 00:31:40 +04:00
@@ -2037,18 +2037,17 @@
SYNOPSIS
partition_key_modified
table TABLE object for which partition fields are set-up
- fields A list of the to be modifed
+ fields Bitmap representing fields to be modified
RETURN VALUES
TRUE Need special handling of UPDATE
FALSE Normal UPDATE handling is ok
*/
-bool partition_key_modified(TABLE *table, List<Item> &fields)
+bool partition_key_modified(TABLE *table, const MY_BITMAP *fields)
{
- List_iterator_fast<Item> f(fields);
+ Field **fld;
partition_info *part_info= table->part_info;
- Item_field *item_field;
DBUG_ENTER("partition_key_modified");
if (!part_info)
@@ -2056,9 +2055,8 @@
if (table->s->db_type->partition_flags &&
(table->s->db_type->partition_flags() & HA_CAN_UPDATE_PARTITION_KEY))
DBUG_RETURN(FALSE);
- f.rewind();
- while ((item_field=(Item_field*) f++))
- if (item_field->field->flags & FIELD_IN_PART_FUNC_FLAG)
+ for (fld= part_info->full_part_field_array; *fld; fld++)
+ if (bitmap_is_set(fields, (*fld)->field_index))
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
| Thread |
|---|
| • bk commit into 5.1 tree (dlenev:1.2334) | dlenev | 29 Sep |