summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/trigger.result12
-rw-r--r--mysql-test/t/trigger.test19
-rw-r--r--sql/sql_trigger.cc32
-rw-r--r--sql/sql_trigger.h5
4 files changed, 63 insertions, 5 deletions
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 7fe3194304c..5f027195e2e 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -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
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index cd6de45a7ce..ccc17e55dc8 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -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
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index acb7d5b61df..5dd6173d5bb 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1583,6 +1583,38 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
/*
+ Check if field of subject table can be changed in before update trigger.
+
+ SYNOPSIS
+ is_updated_in_before_update_triggers()
+ field Field object for field to be checked
+
+ NOTE
+ Field passed to this function should be bound to the same
+ TABLE object as Table_triggers_list.
+
+ RETURN VALUE
+ TRUE Field is changed
+ FALSE Otherwise
+*/
+
+bool Table_triggers_list::is_updated_in_before_update_triggers(Field *fld)
+{
+ Item_trigger_field *trg_fld;
+ for (trg_fld= trigger_fields[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE];
+ trg_fld != 0;
+ trg_fld= trg_fld->next_trg_field)
+ {
+ if (trg_fld->get_settable_routine_parameter() &&
+ trg_fld->field_idx != (uint)-1 &&
+ table->field[trg_fld->field_idx]->eq(fld))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+/*
Trigger BUG#14090 compatibility hook
SYNOPSIS
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index b2464745f7c..09576f5e523 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -116,11 +116,6 @@ public:
bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]);
}
- bool has_before_update_triggers()
- {
- return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]);
- }
-
void set_table(TABLE *new_table);
void mark_fields_used(trg_event_type event);