1 #ifndef SQL_TRIGGER_INCLUDED
2 #define SQL_TRIGGER_INCLUDED
3 
4 /*
5    Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License, version 2.0,
9    as published by the Free Software Foundation.
10 
11    This program is also distributed with certain software (including
12    but not limited to OpenSSL) that is licensed under separate terms,
13    as designated in a particular file or component or in included license
14    documentation.  The authors of MySQL hereby grant you an additional
15    permission to link the program and your derivative works with the
16    separately licensed software that they have included with MySQL.
17 
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License, version 2.0, for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
26 
27 ///////////////////////////////////////////////////////////////////////////
28 
29 /**
30   @file
31 
32   @brief
33   This file contains declarations of global public functions which are used
34   directly from parser/executioner to perform basic operations on triggers
35   (CREATE TRIGGER, DROP TRIGGER, ALTER TABLE, DROP TABLE, ...)
36 */
37 
38 ///////////////////////////////////////////////////////////////////////////
39 
40 #include "lex_string.h"
41 #include "my_psi_config.h"
42 #include "my_sqlcommand.h"  // SQLCOM_CREATE_TRIGGER, SQLCOM_DROP_TRIGGER
43 #include "sql/mdl.h"        // enum_mdl_type
44 #include "sql/sql_cmd.h"    // Sql_cmd
45 
46 class THD;
47 struct TABLE;
48 struct TABLE_LIST;
49 
50 namespace dd {
51 class Table;
52 }
53 ///////////////////////////////////////////////////////////////////////////
54 
55 /**
56   Find trigger's table from trigger identifier.
57 
58   @param[in] thd                    Thread context.
59   @param[in] db_name                Schema name.
60   @param[in] trigger_name           Trigger name.
61   @param[in] continue_if_not_exist  true if SQL statement contains
62                                     "IF EXISTS" clause. That means a warning
63                                     instead of error should be thrown if trigger
64                                     with given name does not exist.
65   @param[out] table                 Pointer to TABLE_LIST object for the
66                                     table trigger.
67 
68   @return Operation status
69     @retval false On success.
70     @retval true  Otherwise.
71 */
72 
73 bool get_table_for_trigger(THD *thd, const LEX_CSTRING &db_name,
74                            const LEX_STRING &trigger_name,
75                            bool continue_if_not_exist, TABLE_LIST **table);
76 
77 /**
78   Check for table with triggers that old database name and new database name
79   are the same. This functions is called while handling the statement
80   RENAME TABLE to ensure that table moved within the same database.
81 
82   @param[in] db_name     Schema name.
83   @param[in] table       Table.
84   @param[in] new_db_name New schema name
85 
86   @note
87     Set error ER_TRG_IN_WRONG_SCHEMA in Diagnostics_area in case
88     function returns true.
89 
90   @return Operation status
91     @retval false Either there is no triggers assigned to a table or
92                   old and new schema name are the same.
93     @retval true  Old and new schema name aren't the same.
94 */
95 
96 bool check_table_triggers_are_not_in_the_same_schema(const char *db_name,
97                                                      const dd::Table &table,
98                                                      const char *new_db_name);
99 
100 /**
101   Acquire either exclusive or shared MDL lock for a trigger
102   in specified schema.
103 
104   @param[in] thd                     Current thread context
105   @param[in] db                      Schema name
106   @param[in] trg_name                Trigger name
107   @param[in] trigger_name_mdl_type   Type of MDL to acquire for trigger name
108 
109   @return Operation status.
110     @retval false Success
111     @retval true  Failure
112 */
113 
114 bool acquire_mdl_for_trigger(THD *thd, const char *db, const char *trg_name,
115                              enum_mdl_type trigger_name_mdl_type);
116 
117 /**
118   Acquire exclusive MDL lock for a trigger in specified schema.
119 
120   @param[in] thd         Current thread context
121   @param[in] db          Schema name
122   @param[in] trg_name    Trigger name
123 
124   @return Operation status.
125     @retval false Success
126     @retval true  Failure
127 */
128 
129 bool acquire_exclusive_mdl_for_trigger(THD *thd, const char *db,
130                                        const char *trg_name);
131 /**
132   Acquire shared MDL lock for a trigger in specified schema.
133 
134   @param[in] thd         Current thread context
135   @param[in] db          Schema name
136   @param[in] trg_name    Trigger name
137 
138   @return Operation status.
139     @retval false Success
140     @retval true  Failure
141 */
142 
acquire_shared_mdl_for_trigger(THD * thd,const char * db,const char * trg_name)143 inline bool acquire_shared_mdl_for_trigger(THD *thd, const char *db,
144                                            const char *trg_name) {
145   return acquire_mdl_for_trigger(thd, db, trg_name, MDL_SHARED_HIGH_PRIO);
146 }
147 
148 /**
149   Drop statistics from performance schema for every trigger
150   associated with a table.
151 
152   @param schema_name Name of schema containing the table.
153   @param table       Table reference, for that associated
154                      triggers statistics has to be deleted.
155 */
156 
157 #ifdef HAVE_PSI_SP_INTERFACE
158 void remove_all_triggers_from_perfschema(const char *schema_name,
159                                          const dd::Table &table);
160 #endif
161 ///////////////////////////////////////////////////////////////////////////
162 
163 /**
164   This class has common code for CREATE/DROP TRIGGER statements.
165 */
166 
167 class Sql_cmd_ddl_trigger_common : public Sql_cmd {
168  public:
169   /**
170     Set a table associated with a trigger.
171 
172     @param trigger_table  a table associated with a trigger.
173   */
174 
set_table(TABLE_LIST * trigger_table)175   void set_table(TABLE_LIST *trigger_table) { m_trigger_table = trigger_table; }
176 
177  protected:
Sql_cmd_ddl_trigger_common()178   Sql_cmd_ddl_trigger_common() : m_trigger_table(nullptr) {}
179 
180   bool check_trg_priv_on_subj_table(THD *thd, TABLE_LIST *table) const;
181   TABLE *open_and_lock_subj_table(THD *thd, TABLE_LIST *tables,
182                                   MDL_ticket **mdl_ticket) const;
183 
184   /**
185     Restore original state of meta-data locks.
186 
187     @param thd         current thread context
188     @param mdl_ticket  granted metadata lock
189   */
190 
191   void restore_original_mdl_state(THD *thd, MDL_ticket *mdl_ticket) const;
192 
193   TABLE_LIST *m_trigger_table{nullptr};
194 };
195 
196 /**
197   This class implements the CREATE TRIGGER statement.
198 */
199 
200 class Sql_cmd_create_trigger : public Sql_cmd_ddl_trigger_common {
201  public:
202   /**
203     Return the command code for CREATE TRIGGER
204   */
205 
sql_command_code()206   enum_sql_command sql_command_code() const override final {
207     return SQLCOM_CREATE_TRIGGER;
208   }
209 
210   bool execute(THD *thd) override final;
211 };
212 
213 /**
214   This class implements the DROP TRIGGER statement.
215 */
216 
217 class Sql_cmd_drop_trigger : public Sql_cmd_ddl_trigger_common {
218  public:
219   /**
220     Return the command code for DROP TRIGGER
221   */
222 
sql_command_code()223   enum_sql_command sql_command_code() const override final {
224     return SQLCOM_DROP_TRIGGER;
225   }
226 
227   bool execute(THD *thd) override final;
228 };
229 
230 #endif /* SQL_TRIGGER_INCLUDED */
231