summaryrefslogtreecommitdiff
path: root/sql/sql_lex.cc
diff options
context:
space:
mode:
authorkostja@bodhi.(none) <>2007-07-12 22:26:41 +0400
committerkostja@bodhi.(none) <>2007-07-12 22:26:41 +0400
commit5ab4b6f1ac489967ed1853e75ef86828bc2fbf9d (patch)
treed11bf2d3e42fc0c5131eb24ddd22755bafd5796f /sql/sql_lex.cc
parent392b283f3d85a20ff4d3b91d40c83f0295eda25d (diff)
downloadmariadb-git-5ab4b6f1ac489967ed1853e75ef86828bc2fbf9d.tar.gz
A fix and a test case for Bug#26141 mixing table types in trigger
causes full table lock on innodb table. Also fixes Bug#28502 Triggers that update another innodb table will block on X lock unnecessarily (duplciate). Code review fixes. Both bugs' synopses are misleading: InnoDB table is not X locked. The statements, however, cannot proceed concurrently, but this happens due to lock conflicts for tables used in triggers, not for the InnoDB table. If a user had an InnoDB table, and two triggers, AFTER UPDATE and AFTER INSERT, competing for different resources (e.g. two distinct MyISAM tables), then these two triggers would not be able to execute concurrently. Moreover, INSERTS/UPDATES of the InnoDB table would not be able to run concurrently. The problem had other side-effects (see respective bug reports). This behavior was a consequence of a shortcoming of the pre-locking algorithm, which would not distinguish between different DML operations (e.g. INSERT and DELETE) and pre-lock all the tables that are used by any trigger defined on the subject table. The idea of the fix is to extend the pre-locking algorithm to keep track, for each table, what DML operation it is used for and not load triggers that are known to never be fired.
Diffstat (limited to 'sql/sql_lex.cc')
-rw-r--r--sql/sql_lex.cc21
1 files changed, 21 insertions, 0 deletions
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index dbce1e38139..c37d77345b6 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2034,6 +2034,27 @@ void st_select_lex_unit::set_limit(SELECT_LEX *sl)
}
+/**
+ Update the parsed tree with information about triggers that
+ may be fired when executing this statement.
+*/
+
+void st_lex::set_trg_event_type_for_tables()
+{
+ /*
+ Do not iterate over sub-selects, only the tables in the outermost
+ SELECT_LEX can be modified, if any.
+ */
+ TABLE_LIST *tables= select_lex.get_table_list();
+
+ while (tables)
+ {
+ tables->set_trg_event_type(this);
+ tables= tables->next_local;
+ }
+}
+
+
/*
Unlink the first table from the global table list and the first table from
outer select (lex->select_lex) local list