1#ifndef SQL_TRIGGER_INCLUDED
2#define SQL_TRIGGER_INCLUDED
3
4/*
5 Copyright (c) 2004, 2011, Oracle and/or its affiliates.
6 Copyright (c) 2017, MariaDB Corporation.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; version 2 of the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
20
21#include <mysqld_error.h>
22
23/* Forward declarations */
24
25class Item_trigger_field;
26class sp_head;
27class sp_name;
28class Query_tables_list;
29struct TABLE_LIST;
30class Query_tables_list;
31
32/** Event on which trigger is invoked. */
33enum trg_event_type
34{
35 TRG_EVENT_INSERT= 0,
36 TRG_EVENT_UPDATE= 1,
37 TRG_EVENT_DELETE= 2,
38 TRG_EVENT_MAX
39};
40
41#include "table.h" /* GRANT_INFO */
42
43/*
44 We need this two enums here instead of sql_lex.h because
45 at least one of them is used by Item_trigger_field interface.
46
47 Time when trigger is invoked (i.e. before or after row actually
48 inserted/updated/deleted).
49*/
50enum trg_action_time_type
51{
52 TRG_ACTION_BEFORE= 0, TRG_ACTION_AFTER= 1, TRG_ACTION_MAX
53};
54
55enum trigger_order_type
56{
57 TRG_ORDER_NONE= 0,
58 TRG_ORDER_FOLLOWS= 1,
59 TRG_ORDER_PRECEDES= 2
60};
61
62
63struct st_trg_execution_order
64{
65 /**
66 FOLLOWS or PRECEDES as specified in the CREATE TRIGGER statement.
67 */
68 enum trigger_order_type ordering_clause;
69
70 /**
71 Trigger name referenced in the FOLLOWS/PRECEDES clause of the
72 CREATE TRIGGER statement.
73 */
74 LEX_CSTRING anchor_trigger_name;
75};
76
77
78class Table_triggers_list;
79
80/**
81 The trigger object
82*/
83
84class Trigger :public Sql_alloc
85{
86public:
87 Trigger(Table_triggers_list *base_arg, sp_head *code):
88 base(base_arg), body(code), next(0), trigger_fields(0), action_order(0)
89 {
90 bzero((char *)&subject_table_grants, sizeof(subject_table_grants));
91 }
92 ~Trigger();
93 Table_triggers_list *base;
94 sp_head *body;
95 Trigger *next; /* Next trigger of same type */
96
97 /**
98 Heads of the lists linking items for all fields used in triggers
99 grouped by event and action_time.
100 */
101 Item_trigger_field *trigger_fields;
102 LEX_CSTRING name;
103 LEX_CSTRING on_table_name; /* Raw table name */
104 LEX_CSTRING definition;
105 LEX_CSTRING definer;
106
107 /* Character sets used */
108 LEX_CSTRING client_cs_name;
109 LEX_CSTRING connection_cl_name;
110 LEX_CSTRING db_cl_name;
111
112 GRANT_INFO subject_table_grants;
113 sql_mode_t sql_mode;
114 /* Store create time. Can't be mysql_time_t as this holds also sub seconds */
115 ulonglong create_time;
116 trg_event_type event;
117 trg_action_time_type action_time;
118 uint action_order;
119
120 bool is_fields_updated_in_trigger(MY_BITMAP *used_fields);
121 void get_trigger_info(LEX_CSTRING *stmt, LEX_CSTRING *body,
122 LEX_STRING *definer);
123 /* Functions executed over each active trigger */
124 bool change_on_table_name(void* param_arg);
125 bool change_table_name(void* param_arg);
126 bool add_to_file_list(void* param_arg);
127};
128
129typedef bool (Trigger::*Triggers_processor)(void *arg);
130
131/**
132 This class holds all information about triggers of table.
133*/
134
135class Table_triggers_list: public Sql_alloc
136{
137 friend class Trigger;
138
139 /* Points to first trigger for a certain type */
140 Trigger *triggers[TRG_EVENT_MAX][TRG_ACTION_MAX];
141 /**
142 Copy of TABLE::Field array which all fields made nullable
143 (using extra_null_bitmap, if needed). Used for NEW values in
144 BEFORE INSERT/UPDATE triggers.
145 */
146 Field **record0_field;
147 uchar *extra_null_bitmap;
148 /**
149 Copy of TABLE::Field array with field pointers set to TABLE::record[1]
150 buffer instead of TABLE::record[0] (used for OLD values in on UPDATE
151 trigger and DELETE trigger when it is called for REPLACE).
152 */
153 Field **record1_field;
154 /**
155 During execution of trigger new_field and old_field should point to the
156 array of fields representing new or old version of row correspondingly
157 (so it can point to TABLE::field or to Tale_triggers_list::record1_field)
158 */
159 Field **new_field;
160 Field **old_field;
161
162 /* TABLE instance for which this triggers list object was created */
163 TABLE *trigger_table;
164
165 /**
166 This flag indicates that one of the triggers was not parsed successfully,
167 and as a precaution the object has entered a state where all trigger
168 access results in errors until all such triggers are dropped. It is not
169 safe to add triggers since we don't know if the broken trigger has the
170 same name or event type. Nor is it safe to invoke any trigger for the
171 aforementioned reasons. The only safe operations are drop_trigger and
172 drop_all_triggers.
173
174 @see Table_triggers_list::set_parse_error
175 */
176 bool m_has_unparseable_trigger;
177
178 /**
179 This error will be displayed when the user tries to manipulate or invoke
180 triggers on a table that has broken triggers. It will get set only once
181 per statement and thus will contain the first parse error encountered in
182 the trigger file.
183 */
184 char m_parse_error_message[MYSQL_ERRMSG_SIZE];
185 uint count; /* Number of triggers */
186
187public:
188 /**
189 Field responsible for storing triggers definitions in file.
190 It have to be public because we are using it directly from parser.
191 */
192 List<LEX_CSTRING> definitions_list;
193 /**
194 List of sql modes for triggers
195 */
196 List<ulonglong> definition_modes_list;
197 /** Create times for triggers */
198 List<ulonglong> create_times;
199
200 List<LEX_CSTRING> definers_list;
201
202 /* Character set context, used for parsing and executing triggers. */
203
204 List<LEX_CSTRING> client_cs_names;
205 List<LEX_CSTRING> connection_cl_names;
206 List<LEX_CSTRING> db_cl_names;
207
208 /* End of character ser context. */
209
210 Table_triggers_list(TABLE *table_arg)
211 :record0_field(0), extra_null_bitmap(0), record1_field(0),
212 trigger_table(table_arg),
213 m_has_unparseable_trigger(false), count(0)
214 {
215 bzero((char *) triggers, sizeof(triggers));
216 }
217 ~Table_triggers_list();
218
219 bool create_trigger(THD *thd, TABLE_LIST *table, String *stmt_query);
220 bool drop_trigger(THD *thd, TABLE_LIST *table, String *stmt_query);
221 bool process_triggers(THD *thd, trg_event_type event,
222 trg_action_time_type time_type,
223 bool old_row_is_record1);
224 void empty_lists();
225 bool create_lists_needed_for_files(MEM_ROOT *root);
226 bool save_trigger_file(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name);
227
228 static bool check_n_load(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name,
229 TABLE *table, bool names_only);
230 static bool drop_all_triggers(THD *thd, const LEX_CSTRING *db,
231 const LEX_CSTRING *table_name);
232 static bool change_table_name(THD *thd, const LEX_CSTRING *db,
233 const LEX_CSTRING *old_alias,
234 const LEX_CSTRING *old_table,
235 const LEX_CSTRING *new_db,
236 const LEX_CSTRING *new_table);
237 void add_trigger(trg_event_type event_type,
238 trg_action_time_type action_time,
239 trigger_order_type ordering_clause,
240 LEX_CSTRING *anchor_trigger_name,
241 Trigger *trigger);
242 Trigger *get_trigger(trg_event_type event_type,
243 trg_action_time_type action_time)
244 {
245 return triggers[event_type][action_time];
246 }
247 /* Simpler version of the above, to avoid casts in the code */
248 Trigger *get_trigger(uint event_type, uint action_time)
249 {
250 return get_trigger((trg_event_type) event_type,
251 (trg_action_time_type) action_time);
252 }
253
254 bool has_triggers(trg_event_type event_type,
255 trg_action_time_type action_time)
256 {
257 return get_trigger(event_type,action_time) != 0;
258 }
259 bool has_delete_triggers()
260 {
261 return (has_triggers(TRG_EVENT_DELETE,TRG_ACTION_BEFORE) ||
262 has_triggers(TRG_EVENT_DELETE,TRG_ACTION_AFTER));
263 }
264
265 void mark_fields_used(trg_event_type event);
266
267 void set_parse_error_message(char *error_message);
268
269 friend class Item_trigger_field;
270
271 bool add_tables_and_routines_for_triggers(THD *thd,
272 Query_tables_list *prelocking_ctx,
273 TABLE_LIST *table_list);
274
275 Field **nullable_fields() { return record0_field; }
276 void reset_extra_null_bitmap()
277 {
278 size_t null_bytes= (trigger_table->s->stored_fields -
279 trigger_table->s->null_fields + 7)/8;
280 bzero(extra_null_bitmap, null_bytes);
281 }
282
283 Trigger *find_trigger(const LEX_CSTRING *name, bool remove_from_list);
284
285 Trigger* for_all_triggers(Triggers_processor func, void *arg);
286
287private:
288 bool prepare_record_accessors(TABLE *table);
289 Trigger *change_table_name_in_trignames(const LEX_CSTRING *old_db_name,
290 const LEX_CSTRING *new_db_name,
291 const LEX_CSTRING *new_table_name,
292 Trigger *trigger);
293 bool change_table_name_in_triggers(THD *thd,
294 const LEX_CSTRING *old_db_name,
295 const LEX_CSTRING *new_db_name,
296 const LEX_CSTRING *old_table_name,
297 const LEX_CSTRING *new_table_name);
298
299 bool check_for_broken_triggers()
300 {
301 if (m_has_unparseable_trigger)
302 {
303 my_message(ER_PARSE_ERROR, m_parse_error_message, MYF(0));
304 return true;
305 }
306 return false;
307 }
308};
309
310bool add_table_for_trigger(THD *thd,
311 const sp_name *trg_name,
312 bool continue_if_not_exist,
313 TABLE_LIST **table);
314
315void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path);
316
317bool check_trn_exists(const LEX_CSTRING *trn_path);
318
319bool load_table_name_for_trigger(THD *thd,
320 const sp_name *trg_name,
321 const LEX_CSTRING *trn_path,
322 LEX_CSTRING *tbl_name);
323bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create);
324
325extern const char * const TRG_EXT;
326extern const char * const TRN_EXT;
327
328#endif /* SQL_TRIGGER_INCLUDED */
329