Loading mysql-test/r/trigger.result +12 −0 Original line number Diff line number Diff line Loading @@ -1173,4 +1173,16 @@ TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2; 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 mysql-test/t/trigger.test +19 −0 Original line number Diff line number Diff line Loading @@ -1421,4 +1421,23 @@ DROP TABLE t1; 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 sql/key.cc +21 −23 Original line number Diff line number Diff line Loading @@ -359,31 +359,29 @@ void key_unpack(String *to,TABLE *table,uint idx) /* Return 1 if any field in a list is part of key or the key uses a field that is automaticly updated (like a timestamp) */ Check if key uses field that is marked in passed field bitmap. bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields) { List_iterator_fast<Item> f(fields); KEY_PART_INFO *key_part,*key_part_end; for (key_part=table->key_info[idx].key_part,key_part_end=key_part+ table->key_info[idx].key_parts ; key_part < key_part_end; key_part++) { Item_field *field; if (key_part->field == table->timestamp_field) return 1; // Can't be used for update SYNOPSIS is_key_used() table TABLE object with which keys and fields are associated. idx Key to be checked. fields Bitmap of fields to be checked. NOTE This function uses TABLE::tmp_set bitmap so the caller should care about saving/restoring its state if it also uses this bitmap. RETURN VALUE TRUE Key uses field from bitmap FALSE Otherwise */ f.rewind(); while ((field=(Item_field*) f++)) bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields) { if (key_part->field->eq(field->field)) bitmap_clear_all(&table->tmp_set); table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set); if (bitmap_is_overlapping(&table->tmp_set, fields)) return 1; } } /* If table handler has primary key as part of the index, check that primary Loading @@ -391,7 +389,7 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields) */ if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY && (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX)) return check_if_key_used(table, table->s->primary_key, fields); return is_key_used(table, table->s->primary_key, fields); return 0; } Loading sql/mysql_priv.h +1 −1 Original line number Diff line number Diff line Loading @@ -1417,7 +1417,7 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info, 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); Loading sql/opt_range.cc +8 −8 Original line number Diff line number Diff line Loading @@ -7526,42 +7526,42 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) } 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; Loading Loading
mysql-test/r/trigger.result +12 −0 Original line number Diff line number Diff line Loading @@ -1173,4 +1173,16 @@ TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2; 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
mysql-test/t/trigger.test +19 −0 Original line number Diff line number Diff line Loading @@ -1421,4 +1421,23 @@ DROP TABLE t1; 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
sql/key.cc +21 −23 Original line number Diff line number Diff line Loading @@ -359,31 +359,29 @@ void key_unpack(String *to,TABLE *table,uint idx) /* Return 1 if any field in a list is part of key or the key uses a field that is automaticly updated (like a timestamp) */ Check if key uses field that is marked in passed field bitmap. bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields) { List_iterator_fast<Item> f(fields); KEY_PART_INFO *key_part,*key_part_end; for (key_part=table->key_info[idx].key_part,key_part_end=key_part+ table->key_info[idx].key_parts ; key_part < key_part_end; key_part++) { Item_field *field; if (key_part->field == table->timestamp_field) return 1; // Can't be used for update SYNOPSIS is_key_used() table TABLE object with which keys and fields are associated. idx Key to be checked. fields Bitmap of fields to be checked. NOTE This function uses TABLE::tmp_set bitmap so the caller should care about saving/restoring its state if it also uses this bitmap. RETURN VALUE TRUE Key uses field from bitmap FALSE Otherwise */ f.rewind(); while ((field=(Item_field*) f++)) bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields) { if (key_part->field->eq(field->field)) bitmap_clear_all(&table->tmp_set); table->mark_columns_used_by_index_no_reset(idx, &table->tmp_set); if (bitmap_is_overlapping(&table->tmp_set, fields)) return 1; } } /* If table handler has primary key as part of the index, check that primary Loading @@ -391,7 +389,7 @@ bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields) */ if (idx != table->s->primary_key && table->s->primary_key < MAX_KEY && (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX)) return check_if_key_used(table, table->s->primary_key, fields); return is_key_used(table, table->s->primary_key, fields); return 0; } Loading
sql/mysql_priv.h +1 −1 Original line number Diff line number Diff line Loading @@ -1417,7 +1417,7 @@ void key_restore(byte *to_record, byte *from_key, KEY *key_info, 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); Loading
sql/opt_range.cc +8 −8 Original line number Diff line number Diff line Loading @@ -7526,42 +7526,42 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) } 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; Loading