1/*
2 Copyright (c) 2004, 2012, Oracle and/or its affiliates.
3 Copyright (c) 2010, 2018, MariaDB
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17
18
19#define MYSQL_LEX 1
20#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */
21#include "sql_priv.h"
22#include "unireg.h"
23#include "sp_head.h"
24#include "sql_trigger.h"
25#include "sql_parse.h" // parse_sql
26#include "parse_file.h"
27#include "sp.h"
28#include "sql_base.h"
29#include "sql_show.h" // append_definer, append_identifier
30#include "sql_table.h" // build_table_filename,
31 // check_n_cut_mysql50_prefix
32#include "sql_db.h" // get_default_db_collation
33#include "sql_acl.h" // *_ACL
34#include "sql_handler.h" // mysql_ha_rm_tables
35#include "sp_cache.h" // sp_invalidate_cache
36#include <mysys_err.h>
37
38LEX_CSTRING *make_lex_string(LEX_CSTRING *lex_str,
39 const char* str, size_t length,
40 MEM_ROOT *mem_root)
41{
42 if (!(lex_str->str= strmake_root(mem_root, str, length)))
43 return 0;
44 lex_str->length= length;
45 return lex_str;
46}
47
48/*************************************************************************/
49
50/**
51 Trigger_creation_ctx -- creation context of triggers.
52*/
53
54class Trigger_creation_ctx : public Stored_program_creation_ctx,
55 public Sql_alloc
56{
57public:
58 static Trigger_creation_ctx *create(THD *thd,
59 const char *db_name,
60 const char *table_name,
61 const LEX_CSTRING *client_cs_name,
62 const LEX_CSTRING *connection_cl_name,
63 const LEX_CSTRING *db_cl_name);
64
65 Trigger_creation_ctx(CHARSET_INFO *client_cs,
66 CHARSET_INFO *connection_cl,
67 CHARSET_INFO *db_cl)
68 :Stored_program_creation_ctx(client_cs, connection_cl, db_cl)
69 { }
70
71 virtual Stored_program_creation_ctx *clone(MEM_ROOT *mem_root)
72 {
73 return new (mem_root) Trigger_creation_ctx(m_client_cs,
74 m_connection_cl,
75 m_db_cl);
76 }
77
78protected:
79 virtual Object_creation_ctx *create_backup_ctx(THD *thd) const
80 {
81 return new Trigger_creation_ctx(thd);
82 }
83
84 Trigger_creation_ctx(THD *thd)
85 :Stored_program_creation_ctx(thd)
86 { }
87};
88
89/**************************************************************************
90 Trigger_creation_ctx implementation.
91**************************************************************************/
92
93Trigger_creation_ctx *
94Trigger_creation_ctx::create(THD *thd,
95 const char *db_name,
96 const char *table_name,
97 const LEX_CSTRING *client_cs_name,
98 const LEX_CSTRING *connection_cl_name,
99 const LEX_CSTRING *db_cl_name)
100{
101 CHARSET_INFO *client_cs;
102 CHARSET_INFO *connection_cl;
103 CHARSET_INFO *db_cl;
104
105 bool invalid_creation_ctx= FALSE;
106
107 if (resolve_charset(client_cs_name->str,
108 thd->variables.character_set_client,
109 &client_cs))
110 {
111 sql_print_warning("Trigger for table '%s'.'%s': "
112 "invalid character_set_client value (%s).",
113 (const char *) db_name,
114 (const char *) table_name,
115 (const char *) client_cs_name->str);
116
117 invalid_creation_ctx= TRUE;
118 }
119
120 if (resolve_collation(connection_cl_name->str,
121 thd->variables.collation_connection,
122 &connection_cl))
123 {
124 sql_print_warning("Trigger for table '%s'.'%s': "
125 "invalid collation_connection value (%s).",
126 (const char *) db_name,
127 (const char *) table_name,
128 (const char *) connection_cl_name->str);
129
130 invalid_creation_ctx= TRUE;
131 }
132
133 if (resolve_collation(db_cl_name->str, NULL, &db_cl))
134 {
135 sql_print_warning("Trigger for table '%s'.'%s': "
136 "invalid database_collation value (%s).",
137 (const char *) db_name,
138 (const char *) table_name,
139 (const char *) db_cl_name->str);
140
141 invalid_creation_ctx= TRUE;
142 }
143
144 if (invalid_creation_ctx)
145 {
146 push_warning_printf(thd,
147 Sql_condition::WARN_LEVEL_WARN,
148 ER_TRG_INVALID_CREATION_CTX,
149 ER_THD(thd, ER_TRG_INVALID_CREATION_CTX),
150 (const char *) db_name,
151 (const char *) table_name);
152 }
153
154 /*
155 If we failed to resolve the database collation, load the default one
156 from the disk.
157 */
158
159 if (!db_cl)
160 db_cl= get_default_db_collation(thd, db_name);
161
162 return new Trigger_creation_ctx(client_cs, connection_cl, db_cl);
163}
164
165/*************************************************************************/
166
167static const LEX_CSTRING triggers_file_type=
168 { STRING_WITH_LEN("TRIGGERS") };
169
170const char * const TRG_EXT= ".TRG";
171
172/**
173 Table of .TRG file field descriptors.
174 We have here only one field now because in nearest future .TRG
175 files will be merged into .FRM files (so we don't need something
176 like md5 or created fields).
177*/
178static File_option triggers_file_parameters[]=
179{
180 {
181 { STRING_WITH_LEN("triggers") },
182 my_offsetof(class Table_triggers_list, definitions_list),
183 FILE_OPTIONS_STRLIST
184 },
185 {
186 { STRING_WITH_LEN("sql_modes") },
187 my_offsetof(class Table_triggers_list, definition_modes_list),
188 FILE_OPTIONS_ULLLIST
189 },
190 {
191 { STRING_WITH_LEN("definers") },
192 my_offsetof(class Table_triggers_list, definers_list),
193 FILE_OPTIONS_STRLIST
194 },
195 {
196 { STRING_WITH_LEN("client_cs_names") },
197 my_offsetof(class Table_triggers_list, client_cs_names),
198 FILE_OPTIONS_STRLIST
199 },
200 {
201 { STRING_WITH_LEN("connection_cl_names") },
202 my_offsetof(class Table_triggers_list, connection_cl_names),
203 FILE_OPTIONS_STRLIST
204 },
205 {
206 { STRING_WITH_LEN("db_cl_names") },
207 my_offsetof(class Table_triggers_list, db_cl_names),
208 FILE_OPTIONS_STRLIST
209 },
210 {
211 { STRING_WITH_LEN("created") },
212 my_offsetof(class Table_triggers_list, create_times),
213 FILE_OPTIONS_ULLLIST
214 },
215 { { 0, 0 }, 0, FILE_OPTIONS_STRING }
216};
217
218File_option sql_modes_parameters=
219{
220 { STRING_WITH_LEN("sql_modes") },
221 my_offsetof(class Table_triggers_list, definition_modes_list),
222 FILE_OPTIONS_ULLLIST
223};
224
225/**
226 This must be kept up to date whenever a new option is added to the list
227 above, as it specifies the number of required parameters of the trigger in
228 .trg file.
229 This defines the maximum number of parameters that is read. If there are
230 more paramaters in the file they are ignored. Less number of parameters
231 is regarded as ok.
232*/
233
234static const int TRG_NUM_REQUIRED_PARAMETERS= 7;
235
236/*
237 Structure representing contents of .TRN file which are used to support
238 database wide trigger namespace.
239*/
240
241struct st_trigname
242{
243 LEX_CSTRING trigger_table;
244};
245
246static const LEX_CSTRING trigname_file_type=
247 { STRING_WITH_LEN("TRIGGERNAME") };
248
249const char * const TRN_EXT= ".TRN";
250
251static File_option trigname_file_parameters[]=
252{
253 {
254 { STRING_WITH_LEN("trigger_table")},
255 offsetof(struct st_trigname, trigger_table),
256 FILE_OPTIONS_ESTRING
257 },
258 { { 0, 0 }, 0, FILE_OPTIONS_STRING }
259};
260
261
262class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook
263{
264private:
265 const char *path;
266public:
267 Handle_old_incorrect_sql_modes_hook(const char *file_path)
268 :path(file_path)
269 {};
270 virtual bool process_unknown_string(const char *&unknown_key, uchar* base,
271 MEM_ROOT *mem_root, const char *end);
272};
273
274
275class Handle_old_incorrect_trigger_table_hook: public Unknown_key_hook
276{
277public:
278 Handle_old_incorrect_trigger_table_hook(const char *file_path,
279 LEX_CSTRING *trigger_table_arg)
280 :path(file_path), trigger_table_value(trigger_table_arg)
281 {};
282 virtual bool process_unknown_string(const char *&unknown_key, uchar* base,
283 MEM_ROOT *mem_root, const char *end);
284private:
285 const char *path;
286 LEX_CSTRING *trigger_table_value;
287};
288
289
290/**
291 An error handler that catches all non-OOM errors which can occur during
292 parsing of trigger body. Such errors are ignored and corresponding error
293 message is used to construct a more verbose error message which contains
294 name of problematic trigger. This error message is later emitted when
295 one tries to perform DML or some of DDL on this table.
296 Also, if possible, grabs name of the trigger being parsed so it can be
297 used to correctly drop problematic trigger.
298*/
299class Deprecated_trigger_syntax_handler : public Internal_error_handler
300{
301private:
302
303 char m_message[MYSQL_ERRMSG_SIZE];
304 LEX_CSTRING *m_trigger_name;
305
306public:
307
308 Deprecated_trigger_syntax_handler() : m_trigger_name(NULL) {}
309
310 virtual bool handle_condition(THD *thd,
311 uint sql_errno,
312 const char* sqlstate,
313 Sql_condition::enum_warning_level *level,
314 const char* message,
315 Sql_condition ** cond_hdl)
316 {
317 if (sql_errno != EE_OUTOFMEMORY &&
318 sql_errno != ER_OUT_OF_RESOURCES)
319 {
320 if(thd->lex->spname)
321 m_trigger_name= &thd->lex->spname->m_name;
322 if (m_trigger_name)
323 my_snprintf(m_message, sizeof(m_message),
324 ER_THD(thd, ER_ERROR_IN_TRIGGER_BODY),
325 m_trigger_name->str, message);
326 else
327 my_snprintf(m_message, sizeof(m_message),
328 ER_THD(thd, ER_ERROR_IN_UNKNOWN_TRIGGER_BODY), message);
329 return true;
330 }
331 return false;
332 }
333
334 LEX_CSTRING *get_trigger_name() { return m_trigger_name; }
335 char *get_error_message() { return m_message; }
336};
337
338
339Trigger::~Trigger()
340{
341 delete body;
342}
343
344
345/**
346 Call a Table_triggers_list function for all triggers
347
348 @return 0 ok
349 @return # Something went wrong. Pointer to the trigger that mailfuncted
350 returned
351*/
352
353Trigger* Table_triggers_list::for_all_triggers(Triggers_processor func,
354 void *arg)
355{
356 for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++)
357 {
358 for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++)
359 {
360 for (Trigger *trigger= get_trigger(i,j) ;
361 trigger ;
362 trigger= trigger->next)
363 if ((trigger->*func)(arg))
364 return trigger;
365 }
366 }
367 return 0;
368}
369
370
371/**
372 Create or drop trigger for table.
373
374 @param thd current thread context (including trigger definition in LEX)
375 @param tables table list containing one table for which trigger is created.
376 @param create whenever we create (TRUE) or drop (FALSE) trigger
377
378 @note
379 This function is mainly responsible for opening and locking of table and
380 invalidation of all its instances in table cache after trigger creation.
381 Real work on trigger creation/dropping is done inside Table_triggers_list
382 methods.
383
384 @todo
385 TODO: We should check if user has TRIGGER privilege for table here.
386 Now we just require SUPER privilege for creating/dropping because
387 we don't have proper privilege checking for triggers in place yet.
388
389 @retval
390 FALSE Success
391 @retval
392 TRUE error
393*/
394
395bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
396{
397 /*
398 FIXME: The code below takes too many different paths depending on the
399 'create' flag, so that the justification for a single function
400 'mysql_create_or_drop_trigger', compared to two separate functions
401 'mysql_create_trigger' and 'mysql_drop_trigger' is not apparent.
402 This is a good candidate for a minor refactoring.
403 */
404 TABLE *table;
405 bool result= TRUE;
406 String stmt_query;
407 bool lock_upgrade_done= FALSE;
408 MDL_ticket *mdl_ticket= NULL;
409 Query_tables_list backup;
410 DBUG_ENTER("mysql_create_or_drop_trigger");
411
412 /* Charset of the buffer for statement must be system one. */
413 stmt_query.set_charset(system_charset_info);
414
415 /*
416 QQ: This function could be merged in mysql_alter_table() function
417 But do we want this ?
418 */
419
420 /*
421 Note that once we will have check for TRIGGER privilege in place we won't
422 need second part of condition below, since check_access() function also
423 checks that db is specified.
424 */
425 if (!thd->lex->spname->m_db.length || (create && !tables->db.length))
426 {
427 my_error(ER_NO_DB_ERROR, MYF(0));
428 DBUG_RETURN(TRUE);
429 }
430
431 /*
432 We don't allow creating triggers on tables in the 'mysql' schema
433 */
434 if (create && lex_string_eq(&tables->db, STRING_WITH_LEN("mysql")))
435 {
436 my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0));
437 DBUG_RETURN(TRUE);
438 }
439
440 /*
441 There is no DETERMINISTIC clause for triggers, so can't check it.
442 But a trigger can in theory be used to do nasty things (if it supported
443 DROP for example) so we do the check for privileges. For now there is
444 already a stronger test right above; but when this stronger test will
445 be removed, the test below will hold. Because triggers have the same
446 nature as functions regarding binlogging: their body is implicitly
447 binlogged, so they share the same danger, so trust_function_creators
448 applies to them too.
449 */
450 if (!trust_function_creators &&
451 (WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) &&
452 !(thd->security_ctx->master_access & SUPER_ACL))
453 {
454 my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0));
455 DBUG_RETURN(TRUE);
456 }
457 WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
458
459 if (!create)
460 {
461 bool if_exists= thd->lex->if_exists();
462
463 /*
464 Protect the query table list from the temporary and potentially
465 destructive changes necessary to open the trigger's table.
466 */
467 thd->lex->reset_n_backup_query_tables_list(&backup);
468 /*
469 Restore Query_tables_list::sql_command, which was
470 reset above, as the code that writes the query to the
471 binary log assumes that this value corresponds to the
472 statement that is being executed.
473 */
474 thd->lex->sql_command= backup.sql_command;
475
476 if (opt_readonly && !(thd->security_ctx->master_access & SUPER_ACL) &&
477 !thd->slave_thread)
478 {
479 my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
480 goto end;
481 }
482
483 if (add_table_for_trigger(thd, thd->lex->spname, if_exists, & tables))
484 goto end;
485
486 if (!tables)
487 {
488 DBUG_ASSERT(if_exists);
489 /*
490 Since the trigger does not exist, there is no associated table,
491 and therefore :
492 - no TRIGGER privileges to check,
493 - no trigger to drop,
494 - no table to lock/modify,
495 so the drop statement is successful.
496 */
497 result= FALSE;
498 /* Still, we need to log the query ... */
499 stmt_query.append(thd->query(), thd->query_length());
500 goto end;
501 }
502 }
503
504 /*
505 Check that the user has TRIGGER privilege on the subject table.
506 */
507 {
508 bool err_status;
509 TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
510 thd->lex->query_tables_own_last= 0;
511
512 err_status= check_table_access(thd, TRIGGER_ACL, tables, FALSE, 1, FALSE);
513
514 thd->lex->query_tables_own_last= save_query_tables_own_last;
515
516 if (err_status)
517 goto end;
518 }
519
520 /* We should have only one table in table list. */
521 DBUG_ASSERT(tables->next_global == 0);
522
523 /* We do not allow creation of triggers on temporary tables. */
524 if (create && thd->find_tmp_table_share(tables))
525 {
526 my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias.str);
527 goto end;
528 }
529
530 /* We also don't allow creation of triggers on views. */
531 tables->required_type= TABLE_TYPE_NORMAL;
532 /*
533 Also prevent DROP TRIGGER from opening temporary table which might
534 shadow the subject table on which trigger to be dropped is defined.
535 */
536 tables->open_type= OT_BASE_ONLY;
537
538 /* Keep consistent with respect to other DDL statements */
539 mysql_ha_rm_tables(thd, tables);
540
541 if (thd->locked_tables_mode)
542 {
543 /* Under LOCK TABLES we must only accept write locked tables. */
544 if (!(tables->table= find_table_for_mdl_upgrade(thd, tables->db.str,
545 tables->table_name.str,
546 FALSE)))
547 goto end;
548 }
549 else
550 {
551 tables->table= open_n_lock_single_table(thd, tables,
552 TL_READ_NO_INSERT, 0);
553 if (! tables->table)
554 goto end;
555 tables->table->use_all_columns();
556 }
557 table= tables->table;
558
559 /* Later on we will need it to downgrade the lock */
560 mdl_ticket= table->mdl_ticket;
561
562 if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
563 goto end;
564
565 lock_upgrade_done= TRUE;
566
567 if (!table->triggers)
568 {
569 if (!create)
570 {
571 my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
572 goto end;
573 }
574
575 if (!(table->triggers= new (&table->mem_root) Table_triggers_list(table)))
576 goto end;
577 }
578
579 result= (create ?
580 table->triggers->create_trigger(thd, tables, &stmt_query):
581 table->triggers->drop_trigger(thd, tables, &stmt_query));
582
583 if (result)
584 goto end;
585
586 close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL);
587 /*
588 Reopen the table if we were under LOCK TABLES.
589 Ignore the return value for now. It's better to
590 keep master/slave in consistent state.
591 */
592 if (thd->locked_tables_list.reopen_tables(thd, false))
593 thd->clear_error();
594
595 /*
596 Invalidate SP-cache. That's needed because triggers may change list of
597 pre-locking tables.
598 */
599 sp_cache_invalidate();
600
601end:
602 if (!result)
603 result= write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length());
604
605 /*
606 If we are under LOCK TABLES we should restore original state of
607 meta-data locks. Otherwise all locks will be released along
608 with the implicit commit.
609 */
610 if (thd->locked_tables_mode && tables && lock_upgrade_done)
611 mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
612
613 /* Restore the query table list. Used only for drop trigger. */
614 if (!create)
615 thd->lex->restore_backup_query_tables_list(&backup);
616
617 if (!result)
618 my_ok(thd);
619
620 DBUG_RETURN(result);
621#ifdef WITH_WSREP
622 error:
623 DBUG_RETURN(true);
624#endif /* WITH_WSREP */
625}
626
627/**
628 Build stmt_query to write it in the bin-log, the statement to write in
629 the trigger file and the trigger definer.
630
631 @param thd current thread context (including trigger definition in
632 LEX)
633 @param tables table list containing one open table for which the
634 trigger is created.
635 @param[out] stmt_query after successful return, this string contains
636 well-formed statement for creation this trigger.
637 @param[out] trigger_def query to be stored in trigger file. As stmt_query,
638 but without "OR REPLACE" and no FOLLOWS/PRECEDES.
639 @param[out] trg_definer The triggger definer.
640 @param[out] trg_definer_holder Used as a buffer for definer.
641
642 @note
643 - Assumes that trigger name is fully qualified.
644 - NULL-string means the following LEX_STRING instance:
645 { str = 0; length = 0 }.
646 - In other words, definer_user and definer_host should contain
647 simultaneously NULL-strings (non-SUID/old trigger) or valid strings
648 (SUID/new trigger).
649*/
650
651static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables,
652 String *stmt_query, String *trigger_def,
653 LEX_CSTRING *trg_definer,
654 char trg_definer_holder[])
655{
656 LEX_CSTRING stmt_definition;
657 LEX *lex= thd->lex;
658 size_t prefix_trimmed, suffix_trimmed;
659 size_t original_length;
660
661 /*
662 Create a query with the full trigger definition.
663 The original query is not appropriate, as it can miss the DEFINER=XXX part.
664 */
665 stmt_query->append(STRING_WITH_LEN("CREATE "));
666
667 trigger_def->copy(*stmt_query);
668
669 if (lex->create_info.or_replace())
670 stmt_query->append(STRING_WITH_LEN("OR REPLACE "));
671
672 if (lex->sphead->suid() != SP_IS_NOT_SUID)
673 {
674 /* SUID trigger */
675 lex->definer->set_lex_string(trg_definer, trg_definer_holder);
676 append_definer(thd, stmt_query, &lex->definer->user, &lex->definer->host);
677 append_definer(thd, trigger_def, &lex->definer->user, &lex->definer->host);
678 }
679 else
680 {
681 *trg_definer= empty_clex_str;
682 }
683
684
685 /* Create statement for binary logging */
686 stmt_definition.str= lex->stmt_definition_begin;
687 stmt_definition.length= (lex->stmt_definition_end -
688 lex->stmt_definition_begin);
689 original_length= stmt_definition.length;
690 trim_whitespace(thd->charset(), &stmt_definition, &prefix_trimmed);
691 suffix_trimmed= original_length - stmt_definition.length - prefix_trimmed;
692
693 stmt_query->append(stmt_definition.str, stmt_definition.length);
694
695 /* Create statement for storing trigger (without trigger order) */
696 if (lex->trg_chistics.ordering_clause == TRG_ORDER_NONE)
697 {
698 /*
699 Not that here stmt_definition doesn't end with a \0, which is
700 normally expected from a LEX_CSTRING
701 */
702 trigger_def->append(stmt_definition.str, stmt_definition.length);
703 }
704 else
705 {
706 /* Copy data before FOLLOWS/PRECEDES trigger_name */
707 trigger_def->append(stmt_definition.str,
708 (lex->trg_chistics.ordering_clause_begin -
709 lex->stmt_definition_begin) - prefix_trimmed);
710 /* Copy data after FOLLOWS/PRECEDES trigger_name */
711 trigger_def->append(stmt_definition.str +
712 (lex->trg_chistics.ordering_clause_end -
713 lex->stmt_definition_begin)
714 - prefix_trimmed,
715 (lex->stmt_definition_end -
716 lex->trg_chistics.ordering_clause_end) -
717 suffix_trimmed);
718 }
719}
720
721
722/**
723 Create trigger for table.
724
725 @param thd current thread context (including trigger definition in
726 LEX)
727 @param tables table list containing one open table for which the
728 trigger is created.
729 @param[out] stmt_query after successful return, this string contains
730 well-formed statement for creation this trigger.
731
732 @note
733 - Assumes that trigger name is fully qualified.
734 - NULL-string means the following LEX_STRING instance:
735 { str = 0; length = 0 }.
736 - In other words, definer_user and definer_host should contain
737 simultaneously NULL-strings (non-SUID/old trigger) or valid strings
738 (SUID/new trigger).
739
740 @retval
741 False success
742 @retval
743 True error
744*/
745
746bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
747 String *stmt_query)
748{
749 LEX *lex= thd->lex;
750 TABLE *table= tables->table;
751 char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN];
752 LEX_CSTRING file, trigname_file;
753 char trg_definer_holder[USER_HOST_BUFF_SIZE];
754 Item_trigger_field *trg_field;
755 struct st_trigname trigname;
756 String trigger_definition;
757 Trigger *trigger= 0;
758 bool trigger_dropped= 0;
759 DBUG_ENTER("create_trigger");
760
761 if (check_for_broken_triggers())
762 DBUG_RETURN(true);
763
764 /* Trigger must be in the same schema as target table. */
765 if (lex_string_cmp(table_alias_charset, &table->s->db, &lex->spname->m_db))
766 {
767 my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
768 DBUG_RETURN(true);
769 }
770
771 if (sp_process_definer(thd))
772 DBUG_RETURN(true);
773
774 /*
775 Let us check if all references to fields in old/new versions of row in
776 this trigger are ok.
777
778 NOTE: We do it here more from ease of use standpoint. We still have to
779 do some checks on each execution. E.g. we can catch privilege changes
780 only during execution. Also in near future, when we will allow access
781 to other tables from trigger we won't be able to catch changes in other
782 tables...
783
784 Since we don't plan to access to contents of the fields it does not
785 matter that we choose for both OLD and NEW values the same versions
786 of Field objects here.
787 */
788 old_field= new_field= table->field;
789
790 for (trg_field= lex->trg_table_fields.first;
791 trg_field; trg_field= trg_field->next_trg_field)
792 {
793 /*
794 NOTE: now we do not check privileges at CREATE TRIGGER time. This will
795 be changed in the future.
796 */
797 trg_field->setup_field(thd, table, NULL);
798
799 if (!trg_field->fixed &&
800 trg_field->fix_fields(thd, (Item **)0))
801 DBUG_RETURN(true);
802 }
803
804 /* Ensure anchor trigger exists */
805 if (lex->trg_chistics.ordering_clause != TRG_ORDER_NONE)
806 {
807 if (!(trigger= find_trigger(&lex->trg_chistics.anchor_trigger_name, 0)) ||
808 trigger->event != lex->trg_chistics.event ||
809 trigger->action_time != lex->trg_chistics.action_time)
810 {
811 my_error(ER_REFERENCED_TRG_DOES_NOT_EXIST, MYF(0),
812 lex->trg_chistics.anchor_trigger_name.str);
813 DBUG_RETURN(true);
814 }
815 }
816
817 /*
818 Here we are creating file with triggers and save all triggers in it.
819 sql_create_definition_file() files handles renaming and backup of older
820 versions
821 */
822 file.length= build_table_filename(file_buff, FN_REFLEN - 1,
823 tables->db.str, tables->table_name.str,
824 TRG_EXT, 0);
825 file.str= file_buff;
826 trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
827 tables->db.str,
828 lex->spname->m_name.str,
829 TRN_EXT, 0);
830 trigname_file.str= trigname_buff;
831
832 /* Use the filesystem to enforce trigger namespace constraints. */
833 if (!access(trigname_buff, F_OK))
834 {
835 if (lex->create_info.or_replace())
836 {
837 String drop_trg_query;
838 /*
839 The following can fail if the trigger is for another table or
840 there exists a .TRN file but there was no trigger for it in
841 the .TRG file
842 */
843 if (unlikely(drop_trigger(thd, tables, &drop_trg_query)))
844 DBUG_RETURN(true);
845 }
846 else if (lex->create_info.if_not_exists())
847 {
848 strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db.str, ".",
849 lex->spname->m_name.str, NullS);
850 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
851 ER_TRG_ALREADY_EXISTS,
852 ER_THD(thd, ER_TRG_ALREADY_EXISTS),
853 trigname_buff);
854 LEX_CSTRING trg_definer_tmp;
855 String trigger_def;
856
857 /*
858 Log query with IF NOT EXISTS to binary log. This is in line with
859 CREATE TABLE IF NOT EXISTS.
860 */
861 build_trig_stmt_query(thd, tables, stmt_query, &trigger_def,
862 &trg_definer_tmp, trg_definer_holder);
863 DBUG_RETURN(false);
864 }
865 else
866 {
867 strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db.str, ".",
868 lex->spname->m_name.str, NullS);
869 my_error(ER_TRG_ALREADY_EXISTS, MYF(0), trigname_buff);
870 DBUG_RETURN(true);
871 }
872 }
873
874 trigname.trigger_table= tables->table_name;
875
876 /*
877 We are not using lex->sphead here as an argument to Trigger() as we are
878 going to access lex->sphead later in build_trig_stmt_query()
879 */
880 if (!(trigger= new (&table->mem_root) Trigger(this, 0)))
881 goto err_without_cleanup;
882
883 /* Create trigger_name.TRN file to ensure trigger name is unique */
884 if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type,
885 (uchar*)&trigname, trigname_file_parameters))
886 goto err_without_cleanup;
887
888 /* Populate the trigger object */
889
890 trigger->sql_mode= thd->variables.sql_mode;
891 /* Time with 2 decimals, like in MySQL 5.7 */
892 trigger->create_time= ((ulonglong) thd->query_start())*100 + thd->query_start_sec_part()/10000;
893 build_trig_stmt_query(thd, tables, stmt_query, &trigger_definition,
894 &trigger->definer, trg_definer_holder);
895
896 trigger->definition.str= trigger_definition.c_ptr();
897 trigger->definition.length= trigger_definition.length();
898
899 /*
900 Fill character set information:
901 - client character set contains charset info only;
902 - connection collation contains pair {character set, collation};
903 - database collation contains pair {character set, collation};
904 */
905 lex_string_set(&trigger->client_cs_name, thd->charset()->csname);
906 lex_string_set(&trigger->connection_cl_name,
907 thd->variables.collation_connection->name);
908 lex_string_set(&trigger->db_cl_name,
909 get_default_db_collation(thd, tables->db.str)->name);
910
911 /* Add trigger in it's correct place */
912 add_trigger(lex->trg_chistics.event,
913 lex->trg_chistics.action_time,
914 lex->trg_chistics.ordering_clause,
915 &lex->trg_chistics.anchor_trigger_name,
916 trigger);
917
918 /* Create trigger definition file .TRG */
919 if (unlikely(create_lists_needed_for_files(thd->mem_root)))
920 goto err_with_cleanup;
921
922 if (!sql_create_definition_file(NULL, &file, &triggers_file_type,
923 (uchar*)this, triggers_file_parameters))
924 DBUG_RETURN(false);
925
926err_with_cleanup:
927 /* Delete .TRN file */
928 mysql_file_delete(key_file_trn, trigname_buff, MYF(MY_WME));
929
930err_without_cleanup:
931 delete trigger; // Safety, not critical
932
933 if (trigger_dropped)
934 {
935 String drop_trg_query;
936 drop_trg_query.append(STRING_WITH_LEN("DROP TRIGGER /* generated by failed CREATE TRIGGER */ "));
937 drop_trg_query.append(&lex->spname->m_name);
938 /*
939 We dropped an existing trigger and was not able to recreate it because
940 of an internal error. Ensure it's also dropped on the slave.
941 */
942 write_bin_log(thd, FALSE, drop_trg_query.ptr(), drop_trg_query.length());
943 }
944 DBUG_RETURN(true);
945}
946
947
948/**
949 Empty all list used to load and create .TRG file
950*/
951
952void Table_triggers_list::empty_lists()
953{
954 definitions_list.empty();
955 definition_modes_list.empty();
956 definers_list.empty();
957 client_cs_names.empty();
958 connection_cl_names.empty();
959 db_cl_names.empty();
960 create_times.empty();
961}
962
963
964/**
965 Create list of all trigger parameters for sql_create_definition_file()
966*/
967
968struct create_lists_param
969{
970 MEM_ROOT *root;
971};
972
973
974bool Table_triggers_list::create_lists_needed_for_files(MEM_ROOT *root)
975{
976 create_lists_param param;
977
978 empty_lists();
979 param.root= root;
980
981 return for_all_triggers(&Trigger::add_to_file_list, &param);
982}
983
984
985bool Trigger::add_to_file_list(void* param_arg)
986{
987 create_lists_param *param= (create_lists_param*) param_arg;
988 MEM_ROOT *mem_root= param->root;
989
990 if (base->definitions_list.push_back(&definition, mem_root) ||
991 base->definition_modes_list.push_back(&sql_mode, mem_root) ||
992 base->definers_list.push_back(&definer, mem_root) ||
993 base->client_cs_names.push_back(&client_cs_name, mem_root) ||
994 base->connection_cl_names.push_back(&connection_cl_name, mem_root) ||
995 base->db_cl_names.push_back(&db_cl_name, mem_root) ||
996 base->create_times.push_back(&create_time, mem_root))
997 return 1;
998 return 0;
999}
1000
1001
1002
1003/**
1004 Deletes the .TRG file for a table.
1005
1006 @param path char buffer of size FN_REFLEN to be used
1007 for constructing path to .TRG file.
1008 @param db table's database name
1009 @param table_name table's name
1010
1011 @retval
1012 False success
1013 @retval
1014 True error
1015*/
1016
1017static bool rm_trigger_file(char *path, const LEX_CSTRING *db,
1018 const LEX_CSTRING *table_name)
1019{
1020 build_table_filename(path, FN_REFLEN-1, db->str, table_name->str, TRG_EXT, 0);
1021 return mysql_file_delete(key_file_trg, path, MYF(MY_WME));
1022}
1023
1024
1025/**
1026 Deletes the .TRN file for a trigger.
1027
1028 @param path char buffer of size FN_REFLEN to be used
1029 for constructing path to .TRN file.
1030 @param db trigger's database name
1031 @param trigger_name trigger's name
1032
1033 @retval
1034 False success
1035 @retval
1036 True error
1037*/
1038
1039static bool rm_trigname_file(char *path, const LEX_CSTRING *db,
1040 const LEX_CSTRING *trigger_name)
1041{
1042 build_table_filename(path, FN_REFLEN - 1, db->str, trigger_name->str, TRN_EXT, 0);
1043 return mysql_file_delete(key_file_trn, path, MYF(MY_WME));
1044}
1045
1046
1047/**
1048 Helper function that saves .TRG file for Table_triggers_list object.
1049
1050 @param triggers Table_triggers_list object for which file should be saved
1051 @param db Name of database for subject table
1052 @param table_name Name of subject table
1053
1054 @retval
1055 FALSE Success
1056 @retval
1057 TRUE Error
1058*/
1059
1060bool Table_triggers_list::save_trigger_file(THD *thd, const LEX_CSTRING *db,
1061 const LEX_CSTRING *table_name)
1062{
1063 char file_buff[FN_REFLEN];
1064 LEX_CSTRING file;
1065
1066 if (create_lists_needed_for_files(thd->mem_root))
1067 return true;
1068
1069 file.length= build_table_filename(file_buff, FN_REFLEN - 1, db->str, table_name->str,
1070 TRG_EXT, 0);
1071 file.str= file_buff;
1072 return sql_create_definition_file(NULL, &file, &triggers_file_type,
1073 (uchar*) this, triggers_file_parameters);
1074}
1075
1076
1077/**
1078 Find a trigger with a given name
1079
1080 @param name Name of trigger
1081 @param remove_from_list If set, remove trigger if found
1082*/
1083
1084Trigger *Table_triggers_list::find_trigger(const LEX_CSTRING *name,
1085 bool remove_from_list)
1086{
1087 for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++)
1088 {
1089 for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++)
1090 {
1091 Trigger **parent, *trigger;
1092
1093 for (parent= &triggers[i][j];
1094 (trigger= *parent);
1095 parent= &trigger->next)
1096 {
1097 if (lex_string_cmp(table_alias_charset,
1098 &trigger->name, name) == 0)
1099 {
1100 if (remove_from_list)
1101 {
1102 *parent= trigger->next;
1103 count--;
1104 }
1105 return trigger;
1106 }
1107 }
1108 }
1109 }
1110 return 0;
1111}
1112
1113
1114/**
1115 Drop trigger for table.
1116
1117 @param thd current thread context
1118 (including trigger definition in LEX)
1119 @param tables table list containing one open table for which trigger
1120 is dropped.
1121 @param[out] stmt_query after successful return, this string contains
1122 well-formed statement for creation this trigger.
1123
1124 @todo
1125 Probably instead of removing .TRG file we should move
1126 to archive directory but this should be done as part of
1127 parse_file.cc functionality (because we will need it
1128 elsewhere).
1129
1130 @retval
1131 False success
1132 @retval
1133 True error
1134*/
1135
1136bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables,
1137 String *stmt_query)
1138{
1139 const LEX_CSTRING *sp_name= &thd->lex->spname->m_name; // alias
1140 char path[FN_REFLEN];
1141 Trigger *trigger;
1142
1143 stmt_query->set(thd->query(), thd->query_length(), stmt_query->charset());
1144
1145 /* Find and delete trigger from list */
1146 if (!(trigger= find_trigger(sp_name, true)))
1147 {
1148 my_message(ER_TRG_DOES_NOT_EXIST, ER_THD(thd, ER_TRG_DOES_NOT_EXIST),
1149 MYF(0));
1150 return 1;
1151 }
1152
1153 if (!count) // If no more triggers
1154 {
1155 /*
1156 TODO: Probably instead of removing .TRG file we should move
1157 to archive directory but this should be done as part of
1158 parse_file.cc functionality (because we will need it
1159 elsewhere).
1160 */
1161 if (rm_trigger_file(path, &tables->db, &tables->table_name))
1162 return 1;
1163 }
1164 else
1165 {
1166 if (save_trigger_file(thd, &tables->db, &tables->table_name))
1167 return 1;
1168 }
1169
1170 if (rm_trigname_file(path, &tables->db, sp_name))
1171 return 1;
1172
1173 delete trigger;
1174 return 0;
1175}
1176
1177
1178Table_triggers_list::~Table_triggers_list()
1179{
1180 DBUG_ENTER("Table_triggers_list::~Table_triggers_list");
1181
1182 for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++)
1183 {
1184 for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++)
1185 {
1186 Trigger *next, *trigger;
1187 for (trigger= get_trigger(i,j) ; trigger ; trigger= next)
1188 {
1189 next= trigger->next;
1190 delete trigger;
1191 }
1192 }
1193 }
1194 if (record1_field)
1195 for (Field **fld_ptr= record1_field; *fld_ptr; fld_ptr++)
1196 delete *fld_ptr;
1197
1198 DBUG_VOID_RETURN;
1199}
1200
1201
1202/**
1203 Prepare array of Field objects referencing to TABLE::record[1] instead
1204 of record[0] (they will represent OLD.* row values in ON UPDATE trigger
1205 and in ON DELETE trigger which will be called during REPLACE execution).
1206
1207 @param table pointer to TABLE object for which we are creating fields.
1208
1209 @retval
1210 False success
1211 @retval
1212 True error
1213*/
1214
1215bool Table_triggers_list::prepare_record_accessors(TABLE *table)
1216{
1217 Field **fld, **trg_fld;
1218
1219 if ((has_triggers(TRG_EVENT_INSERT,TRG_ACTION_BEFORE) ||
1220 has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE)) &&
1221 (table->s->stored_fields != table->s->null_fields))
1222
1223 {
1224 int null_bytes= (table->s->fields - table->s->null_fields + 7)/8;
1225 if (!(extra_null_bitmap= (uchar*)alloc_root(&table->mem_root, null_bytes)))
1226 return 1;
1227 if (!(record0_field= (Field **)alloc_root(&table->mem_root,
1228 (table->s->fields + 1) *
1229 sizeof(Field*))))
1230 return 1;
1231
1232 uchar *null_ptr= extra_null_bitmap;
1233 uchar null_bit= 1;
1234 for (fld= table->field, trg_fld= record0_field; *fld; fld++, trg_fld++)
1235 {
1236 if (!(*fld)->null_ptr && !(*fld)->vcol_info && !(*fld)->vers_sys_field())
1237 {
1238 Field *f;
1239 if (!(f= *trg_fld= (*fld)->make_new_field(&table->mem_root, table,
1240 table == (*fld)->table)))
1241 return 1;
1242
1243 f->flags= (*fld)->flags;
1244 f->invisible= (*fld)->invisible;
1245 f->null_ptr= null_ptr;
1246 f->null_bit= null_bit;
1247 if (null_bit == 128)
1248 null_ptr++, null_bit= 1;
1249 else
1250 null_bit*= 2;
1251 }
1252 else
1253 *trg_fld= *fld;
1254 }
1255 *trg_fld= 0;
1256 DBUG_ASSERT(null_ptr <= extra_null_bitmap + null_bytes);
1257 bzero(extra_null_bitmap, null_bytes);
1258 }
1259 else
1260 {
1261 record0_field= table->field;
1262 }
1263
1264 if (has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE) ||
1265 has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_AFTER) ||
1266 has_triggers(TRG_EVENT_DELETE,TRG_ACTION_BEFORE) ||
1267 has_triggers(TRG_EVENT_DELETE,TRG_ACTION_AFTER))
1268 {
1269 if (!(record1_field= (Field **)alloc_root(&table->mem_root,
1270 (table->s->fields + 1) *
1271 sizeof(Field*))))
1272 return 1;
1273
1274 for (fld= table->field, trg_fld= record1_field; *fld; fld++, trg_fld++)
1275 {
1276 if (!(*trg_fld= (*fld)->make_new_field(&table->mem_root, table,
1277 table == (*fld)->table)))
1278 return 1;
1279 (*trg_fld)->move_field_offset((my_ptrdiff_t)(table->record[1] -
1280 table->record[0]));
1281 }
1282 *trg_fld= 0;
1283 }
1284 return 0;
1285}
1286
1287
1288/**
1289 Check whenever .TRG file for table exist and load all triggers it contains.
1290
1291 @param thd current thread context
1292 @param db table's database name
1293 @param table_name table's name
1294 @param table pointer to table object
1295 @param names_only stop after loading trigger names
1296
1297 @todo
1298 A lot of things to do here e.g. how about other funcs and being
1299 more paranoical ?
1300
1301 @todo
1302 This could be avoided if there is no triggers for UPDATE and DELETE.
1303
1304 @retval
1305 False success
1306 @retval
1307 True error
1308*/
1309
1310bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db,
1311 const LEX_CSTRING *table_name, TABLE *table,
1312 bool names_only)
1313{
1314 char path_buff[FN_REFLEN];
1315 LEX_CSTRING path;
1316 File_parser *parser;
1317 LEX_CSTRING save_db;
1318 DBUG_ENTER("Table_triggers_list::check_n_load");
1319
1320 path.length= build_table_filename(path_buff, FN_REFLEN - 1,
1321 db->str, table_name->str, TRG_EXT, 0);
1322 path.str= path_buff;
1323
1324 // QQ: should we analyze errno somehow ?
1325 if (access(path_buff, F_OK))
1326 DBUG_RETURN(0);
1327
1328 /* File exists so we got to load triggers */
1329
1330 if ((parser= sql_parse_prepare(&path, &table->mem_root, 1)))
1331 {
1332 if (is_equal(&triggers_file_type, parser->type()))
1333 {
1334 Handle_old_incorrect_sql_modes_hook sql_modes_hook(path.str);
1335 LEX_CSTRING *trg_create_str;
1336 ulonglong *trg_sql_mode, *trg_create_time;
1337 Trigger *trigger;
1338 Table_triggers_list *trigger_list=
1339 new (&table->mem_root) Table_triggers_list(table);
1340 if (unlikely(!trigger_list))
1341 goto error;
1342
1343 if (parser->parse((uchar*)trigger_list, &table->mem_root,
1344 triggers_file_parameters,
1345 TRG_NUM_REQUIRED_PARAMETERS,
1346 &sql_modes_hook))
1347 goto error;
1348
1349 List_iterator_fast<LEX_CSTRING> it(trigger_list->definitions_list);
1350
1351 if (!trigger_list->definitions_list.is_empty() &&
1352 (trigger_list->client_cs_names.is_empty() ||
1353 trigger_list->connection_cl_names.is_empty() ||
1354 trigger_list->db_cl_names.is_empty()))
1355 {
1356 /* We will later use the current character sets */
1357 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1358 ER_TRG_NO_CREATION_CTX,
1359 ER_THD(thd, ER_TRG_NO_CREATION_CTX),
1360 db->str,
1361 table_name->str);
1362 }
1363
1364 table->triggers= trigger_list;
1365 status_var_increment(thd->status_var.feature_trigger);
1366
1367 List_iterator_fast<ulonglong> itm(trigger_list->definition_modes_list);
1368 List_iterator_fast<LEX_CSTRING> it_definer(trigger_list->definers_list);
1369 List_iterator_fast<LEX_CSTRING> it_client_cs_name(trigger_list->client_cs_names);
1370 List_iterator_fast<LEX_CSTRING> it_connection_cl_name(trigger_list->connection_cl_names);
1371 List_iterator_fast<LEX_CSTRING> it_db_cl_name(trigger_list->db_cl_names);
1372 List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times);
1373 LEX *old_lex= thd->lex;
1374 LEX lex;
1375 sp_rcontext *save_spcont= thd->spcont;
1376 sql_mode_t save_sql_mode= thd->variables.sql_mode;
1377
1378 thd->lex= &lex;
1379
1380 save_db= thd->db;
1381 thd->reset_db(db);
1382 while ((trg_create_str= it++))
1383 {
1384 sp_head *sp;
1385 sql_mode_t sql_mode;
1386 LEX_CSTRING *trg_definer;
1387 Trigger_creation_ctx *creation_ctx;
1388
1389 /*
1390 It is old file format then sql_mode may not be filled in.
1391 We use one mode (current) for all triggers, because we have not
1392 information about mode in old format.
1393 */
1394 sql_mode= ((trg_sql_mode= itm++) ? *trg_sql_mode :
1395 (ulonglong) global_system_variables.sql_mode);
1396
1397 trg_create_time= it_create_times++; // May be NULL if old file
1398 trg_definer= it_definer++; // May be NULL if old file
1399
1400 thd->variables.sql_mode= sql_mode;
1401
1402 Parser_state parser_state;
1403 if (parser_state.init(thd, (char*) trg_create_str->str,
1404 trg_create_str->length))
1405 goto err_with_lex_cleanup;
1406
1407 if (!trigger_list->client_cs_names.is_empty())
1408 creation_ctx= Trigger_creation_ctx::create(thd,
1409 db->str,
1410 table_name->str,
1411 it_client_cs_name++,
1412 it_connection_cl_name++,
1413 it_db_cl_name++);
1414 else
1415 {
1416 /* Old file with not stored character sets. Use current */
1417 creation_ctx= new
1418 Trigger_creation_ctx(thd->variables.character_set_client,
1419 thd->variables.collation_connection,
1420 thd->variables.collation_database);
1421 }
1422
1423 lex_start(thd);
1424 thd->spcont= NULL;
1425
1426 /* The following is for catching parse errors */
1427 lex.trg_chistics.event= TRG_EVENT_MAX;
1428 lex.trg_chistics.action_time= TRG_ACTION_MAX;
1429 Deprecated_trigger_syntax_handler error_handler;
1430 thd->push_internal_handler(&error_handler);
1431
1432 bool parse_error= parse_sql(thd, & parser_state, creation_ctx);
1433 thd->pop_internal_handler();
1434 DBUG_ASSERT(!parse_error || lex.sphead == 0);
1435
1436 /*
1437 Not strictly necessary to invoke this method here, since we know
1438 that we've parsed CREATE TRIGGER and not an
1439 UPDATE/DELETE/INSERT/REPLACE/LOAD/CREATE TABLE, but we try to
1440 maintain the invariant that this method is called for each
1441 distinct statement, in case its logic is extended with other
1442 types of analyses in future.
1443 */
1444 lex.set_trg_event_type_for_tables();
1445
1446 if (lex.sphead)
1447 lex.sphead->m_sql_mode= sql_mode;
1448
1449 if (unlikely(!(trigger= (new (&table->mem_root)
1450 Trigger(trigger_list, lex.sphead)))))
1451 goto err_with_lex_cleanup;
1452 lex.sphead= NULL; /* Prevent double cleanup. */
1453
1454 sp= trigger->body;
1455
1456 trigger->sql_mode= sql_mode;
1457 trigger->definition= *trg_create_str;
1458 trigger->create_time= trg_create_time ? *trg_create_time : 0;
1459 trigger->name= sp ? sp->m_name : empty_clex_str;
1460 trigger->on_table_name.str= (char*) lex.raw_trg_on_table_name_begin;
1461 trigger->on_table_name.length= (lex.raw_trg_on_table_name_end -
1462 lex.raw_trg_on_table_name_begin);
1463
1464 /* Copy pointers to character sets to make trigger easier to use */
1465 lex_string_set(&trigger->client_cs_name,
1466 creation_ctx->get_client_cs()->csname);
1467 lex_string_set(&trigger->connection_cl_name,
1468 creation_ctx->get_connection_cl()->name);
1469 lex_string_set(&trigger->db_cl_name,
1470 creation_ctx->get_db_cl()->name);
1471
1472 /* event can only be TRG_EVENT_MAX in case of fatal parse errors */
1473 if (lex.trg_chistics.event != TRG_EVENT_MAX)
1474 trigger_list->add_trigger(lex.trg_chistics.event,
1475 lex.trg_chistics.action_time,
1476 TRG_ORDER_NONE,
1477 &lex.trg_chistics.anchor_trigger_name,
1478 trigger);
1479
1480 if (unlikely(parse_error))
1481 {
1482 LEX_CSTRING *name;
1483
1484 /*
1485 In case of errors, disable all triggers for the table, but keep
1486 the wrong trigger around to allow the user to fix it
1487 */
1488 if (!trigger_list->m_has_unparseable_trigger)
1489 trigger_list->set_parse_error_message(error_handler.get_error_message());
1490 /* Currently sphead is always set to NULL in case of a parse error */
1491 DBUG_ASSERT(lex.sphead == 0);
1492 lex_end(&lex);
1493
1494 if (likely((name= error_handler.get_trigger_name())))
1495 {
1496 if (unlikely(!(make_lex_string(&trigger->name, name->str,
1497 name->length, &table->mem_root))))
1498 goto err_with_lex_cleanup;
1499 }
1500 trigger->definer= ((!trg_definer || !trg_definer->length) ?
1501 empty_clex_str : *trg_definer);
1502 continue;
1503 }
1504
1505 sp->m_sql_mode= sql_mode;
1506 sp->set_creation_ctx(creation_ctx);
1507
1508 if (!trg_definer || !trg_definer->length)
1509 {
1510 /*
1511 This trigger was created/imported from the previous version of
1512 MySQL, which does not support trigger_list definers. We should emit
1513 warning here.
1514 */
1515
1516 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1517 ER_TRG_NO_DEFINER,
1518 ER_THD(thd, ER_TRG_NO_DEFINER),
1519 db->str, sp->m_name.str);
1520
1521 /*
1522 Set definer to the '' to correct displaying in the information
1523 schema.
1524 */
1525
1526 sp->set_definer("", 0);
1527 trigger->definer= empty_clex_str;
1528
1529 /*
1530 trigger_list without definer information are executed under the
1531 authorization of the invoker.
1532 */
1533
1534 sp->set_suid(SP_IS_NOT_SUID);
1535 }
1536 else
1537 {
1538 sp->set_definer(trg_definer->str, trg_definer->length);
1539 trigger->definer= *trg_definer;
1540 }
1541
1542#ifndef DBUG_OFF
1543 /*
1544 Let us check that we correctly update trigger definitions when we
1545 rename tables with trigger_list.
1546
1547 In special cases like "RENAME TABLE `#mysql50#somename` TO `somename`"
1548 or "ALTER DATABASE `#mysql50#somename` UPGRADE DATA DIRECTORY NAME"
1549 we might be given table or database name with "#mysql50#" prefix (and
1550 trigger's definiton contains un-prefixed version of the same name).
1551 To remove this prefix we use check_n_cut_mysql50_prefix().
1552 */
1553
1554 char fname[SAFE_NAME_LEN + 1];
1555 DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db.str, db->str) ||
1556 (check_n_cut_mysql50_prefix(db->str, fname, sizeof(fname)) &&
1557 !my_strcasecmp(table_alias_charset, lex.query_tables->db.str, fname))));
1558 DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, table_name->str) ||
1559 (check_n_cut_mysql50_prefix(table_name->str, fname, sizeof(fname)) &&
1560 !my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, fname))));
1561#endif
1562 if (names_only)
1563 {
1564 lex_end(&lex);
1565 continue;
1566 }
1567
1568 /*
1569 Gather all Item_trigger_field objects representing access to fields
1570 in old/new versions of row in trigger into lists containing all such
1571 objects for the trigger_list with same action and timing.
1572 */
1573 trigger->trigger_fields= lex.trg_table_fields.first;
1574 /*
1575 Also let us bind these objects to Field objects in table being
1576 opened.
1577
1578 We ignore errors here, because if even something is wrong we still
1579 will be willing to open table to perform some operations (e.g.
1580 SELECT)...
1581 Anyway some things can be checked only during trigger execution.
1582 */
1583 for (Item_trigger_field *trg_field= lex.trg_table_fields.first;
1584 trg_field;
1585 trg_field= trg_field->next_trg_field)
1586 {
1587 trg_field->setup_field(thd, table,
1588 &trigger->subject_table_grants);
1589 }
1590
1591 lex_end(&lex);
1592 }
1593 thd->reset_db(&save_db);
1594 thd->lex= old_lex;
1595 thd->spcont= save_spcont;
1596 thd->variables.sql_mode= save_sql_mode;
1597
1598 if (!names_only && trigger_list->prepare_record_accessors(table))
1599 goto error;
1600
1601 /* Ensure no one is accidently using the temporary load lists */
1602 trigger_list->empty_lists();
1603 DBUG_RETURN(0);
1604
1605err_with_lex_cleanup:
1606 lex_end(&lex);
1607 thd->lex= old_lex;
1608 thd->spcont= save_spcont;
1609 thd->variables.sql_mode= save_sql_mode;
1610 thd->reset_db(&save_db);
1611 /* Fall trough to error */
1612 }
1613 }
1614
1615error:
1616 if (unlikely(!thd->is_error()))
1617 {
1618 /*
1619 We don't care about this error message much because .TRG files will
1620 be merged into .FRM anyway.
1621 */
1622 my_error(ER_WRONG_OBJECT, MYF(0),
1623 table_name->str, TRG_EXT + 1, "TRIGGER");
1624 }
1625 DBUG_RETURN(1);
1626}
1627
1628
1629/**
1630 Add trigger in the correct position according to ordering clause
1631 Also update action order
1632
1633 If anchor_trigger doesn't exist, add it last.
1634*/
1635
1636void Table_triggers_list::add_trigger(trg_event_type event,
1637 trg_action_time_type action_time,
1638 trigger_order_type ordering_clause,
1639 LEX_CSTRING *anchor_trigger_name,
1640 Trigger *trigger)
1641{
1642 Trigger **parent= &triggers[event][action_time];
1643 uint position= 0;
1644
1645 for ( ; *parent ; parent= &(*parent)->next, position++)
1646 {
1647 if (ordering_clause != TRG_ORDER_NONE &&
1648 !lex_string_cmp(table_alias_charset, anchor_trigger_name,
1649 &(*parent)->name))
1650 {
1651 if (ordering_clause == TRG_ORDER_FOLLOWS)
1652 {
1653 parent= &(*parent)->next; // Add after this one
1654 position++;
1655 }
1656 break;
1657 }
1658 }
1659
1660 /* Add trigger where parent points to */
1661 trigger->next= *parent;
1662 *parent= trigger;
1663
1664 /* Update action_orders and position */
1665 trigger->event= event;
1666 trigger->action_time= action_time;
1667 trigger->action_order= ++position;
1668 while ((trigger= trigger->next))
1669 trigger->action_order= ++position;
1670
1671 count++;
1672}
1673
1674
1675/**
1676 Obtains and returns trigger metadata.
1677
1678 @param trigger_stmt returns statement of trigger
1679 @param body returns body of trigger
1680 @param definer returns definer/creator of trigger. The caller is
1681 responsible to allocate enough space for storing
1682 definer information.
1683
1684 @retval
1685 False success
1686 @retval
1687 True error
1688*/
1689
1690void Trigger::get_trigger_info(LEX_CSTRING *trigger_stmt,
1691 LEX_CSTRING *trigger_body,
1692 LEX_STRING *definer)
1693{
1694 DBUG_ENTER("get_trigger_info");
1695
1696 *trigger_stmt= definition;
1697 if (!body)
1698 {
1699 /* Parse error */
1700 *trigger_body= definition;
1701 *definer= empty_lex_str;
1702 DBUG_VOID_RETURN;
1703 }
1704 *trigger_body= body->m_body_utf8;
1705
1706 if (body->suid() == SP_IS_NOT_SUID)
1707 {
1708 *definer= empty_lex_str;
1709 }
1710 else
1711 {
1712 definer->length= strxmov(definer->str, body->m_definer.user.str, "@",
1713 body->m_definer.host.str, NullS) - definer->str;
1714 }
1715 DBUG_VOID_RETURN;
1716}
1717
1718
1719/**
1720 Find trigger's table from trigger identifier and add it to
1721 the statement table list.
1722
1723 @param[in] thd Thread context.
1724 @param[in] trg_name Trigger name.
1725 @param[in] if_exists TRUE if SQL statement contains "IF EXISTS" clause.
1726 That means a warning instead of error should be
1727 thrown if trigger with given name does not exist.
1728 @param[out] table Pointer to TABLE_LIST object for the
1729 table trigger.
1730
1731 @return Operation status
1732 @retval FALSE On success.
1733 @retval TRUE Otherwise.
1734*/
1735
1736bool add_table_for_trigger(THD *thd,
1737 const sp_name *trg_name,
1738 bool if_exists,
1739 TABLE_LIST **table)
1740{
1741 LEX *lex= thd->lex;
1742 char trn_path_buff[FN_REFLEN];
1743 LEX_CSTRING trn_path= { trn_path_buff, 0 };
1744 LEX_CSTRING tbl_name= null_clex_str;
1745
1746 DBUG_ENTER("add_table_for_trigger");
1747
1748 build_trn_path(thd, trg_name, (LEX_STRING*) &trn_path);
1749
1750 if (check_trn_exists(&trn_path))
1751 {
1752 if (if_exists)
1753 {
1754 push_warning_printf(thd,
1755 Sql_condition::WARN_LEVEL_NOTE,
1756 ER_TRG_DOES_NOT_EXIST,
1757 ER_THD(thd, ER_TRG_DOES_NOT_EXIST));
1758
1759 *table= NULL;
1760
1761 DBUG_RETURN(FALSE);
1762 }
1763
1764 my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
1765 DBUG_RETURN(TRUE);
1766 }
1767
1768 if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
1769 DBUG_RETURN(TRUE);
1770
1771 *table= sp_add_to_query_tables(thd, lex, &trg_name->m_db,
1772 &tbl_name, TL_IGNORE,
1773 MDL_SHARED_NO_WRITE);
1774
1775 DBUG_RETURN(*table ? FALSE : TRUE);
1776}
1777
1778
1779/**
1780 Drop all triggers for table.
1781
1782 @param thd current thread context
1783 @param db schema for table
1784 @param name name for table
1785
1786 @retval
1787 False success
1788 @retval
1789 True error
1790*/
1791
1792bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db,
1793 const LEX_CSTRING *name)
1794{
1795 TABLE table;
1796 char path[FN_REFLEN];
1797 bool result= 0;
1798 DBUG_ENTER("Triggers::drop_all_triggers");
1799
1800 bzero(&table, sizeof(table));
1801 init_sql_alloc(&table.mem_root, "Triggers::drop_all_triggers", 8192, 0,
1802 MYF(0));
1803
1804 if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
1805 {
1806 result= 1;
1807 goto end;
1808 }
1809 if (table.triggers)
1810 {
1811 for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++)
1812 {
1813 for (uint j= 0; j < (uint)TRG_ACTION_MAX; j++)
1814 {
1815 Trigger *trigger;
1816 for (trigger= table.triggers->get_trigger(i,j) ;
1817 trigger ;
1818 trigger= trigger->next)
1819 {
1820 /*
1821 Trigger, which body we failed to parse during call
1822 Table_triggers_list::check_n_load(), might be missing name.
1823 Such triggers have zero-length name and are skipped here.
1824 */
1825 if (trigger->name.length &&
1826 rm_trigname_file(path, db, &trigger->name))
1827 {
1828 /*
1829 Instead of immediately bailing out with error if we were unable
1830 to remove .TRN file we will try to drop other files.
1831 */
1832 result= 1;
1833 }
1834 }
1835 }
1836 }
1837 if (rm_trigger_file(path, db, name))
1838 result= 1;
1839 delete table.triggers;
1840 }
1841end:
1842 free_root(&table.mem_root, MYF(0));
1843 DBUG_RETURN(result);
1844}
1845
1846
1847/**
1848 Update .TRG file after renaming triggers' subject table
1849 (change name of table in triggers' definitions).
1850
1851 @param thd Thread context
1852 @param old_db_name Old database of subject table
1853 @param new_db_name New database of subject table
1854 @param old_table_name Old subject table's name
1855 @param new_table_name New subject table's name
1856
1857 @retval
1858 FALSE Success
1859 @retval
1860 TRUE Failure
1861*/
1862
1863struct change_table_name_param
1864{
1865 THD *thd;
1866 LEX_CSTRING *old_db_name;
1867 LEX_CSTRING *new_db_name;
1868 LEX_CSTRING *new_table_name;
1869 Trigger *stopper;
1870};
1871
1872
1873bool
1874Table_triggers_list::
1875change_table_name_in_triggers(THD *thd,
1876 const LEX_CSTRING *old_db_name,
1877 const LEX_CSTRING *new_db_name,
1878 const LEX_CSTRING *old_table_name,
1879 const LEX_CSTRING *new_table_name)
1880{
1881 struct change_table_name_param param;
1882 sql_mode_t save_sql_mode= thd->variables.sql_mode;
1883 char path_buff[FN_REFLEN];
1884
1885 param.thd= thd;
1886 param.new_table_name= const_cast<LEX_CSTRING*>(new_table_name);
1887
1888 for_all_triggers(&Trigger::change_table_name, &param);
1889
1890 thd->variables.sql_mode= save_sql_mode;
1891
1892 if (unlikely(thd->is_fatal_error))
1893 return TRUE; /* OOM */
1894
1895 if (save_trigger_file(thd, new_db_name, new_table_name))
1896 return TRUE;
1897
1898 if (rm_trigger_file(path_buff, old_db_name, old_table_name))
1899 {
1900 (void) rm_trigger_file(path_buff, new_db_name, new_table_name);
1901 return TRUE;
1902 }
1903 return FALSE;
1904}
1905
1906
1907bool Trigger::change_table_name(void* param_arg)
1908{
1909 change_table_name_param *param= (change_table_name_param*) param_arg;
1910 THD *thd= param->thd;
1911 LEX_CSTRING *new_table_name= param->new_table_name;
1912 LEX_CSTRING *def= &definition, new_def;
1913 size_t on_q_table_name_len, before_on_len;
1914 String buff;
1915
1916 thd->variables.sql_mode= sql_mode;
1917
1918 /* Construct CREATE TRIGGER statement with new table name. */
1919 buff.length(0);
1920
1921 /* WARNING: 'on_table_name' is supposed to point inside 'def' */
1922 DBUG_ASSERT(on_table_name.str > def->str);
1923 DBUG_ASSERT(on_table_name.str < (def->str + def->length));
1924 before_on_len= on_table_name.str - def->str;
1925
1926 buff.append(def->str, before_on_len);
1927 buff.append(STRING_WITH_LEN("ON "));
1928 append_identifier(thd, &buff, new_table_name);
1929 buff.append(STRING_WITH_LEN(" "));
1930 on_q_table_name_len= buff.length() - before_on_len;
1931 buff.append(on_table_name.str + on_table_name.length,
1932 def->length - (before_on_len + on_table_name.length));
1933 /*
1934 It is OK to allocate some memory on table's MEM_ROOT since this
1935 table instance will be thrown out at the end of rename anyway.
1936 */
1937 new_def.str= (char*) memdup_root(&base->trigger_table->mem_root, buff.ptr(),
1938 buff.length());
1939 new_def.length= buff.length();
1940 on_table_name.str= new_def.str + before_on_len;
1941 on_table_name.length= on_q_table_name_len;
1942 definition= new_def;
1943 return 0;
1944}
1945
1946
1947/**
1948 Iterate though Table_triggers_list::names_list list and update
1949 .TRN files after renaming triggers' subject table.
1950
1951 @param old_db_name Old database of subject table
1952 @param new_db_name New database of subject table
1953 @param new_table_name New subject table's name
1954 @param stopper Pointer to Table_triggers_list::names_list at
1955 which we should stop updating.
1956
1957 @retval
1958 0 Success
1959 @retval
1960 non-0 Failure, pointer to Table_triggers_list::names_list element
1961 for which update failed.
1962*/
1963
1964Trigger *
1965Table_triggers_list::
1966change_table_name_in_trignames(const LEX_CSTRING *old_db_name,
1967 const LEX_CSTRING *new_db_name,
1968 const LEX_CSTRING *new_table_name,
1969 Trigger *trigger)
1970{
1971 struct change_table_name_param param;
1972 param.old_db_name= const_cast<LEX_CSTRING*>(old_db_name);
1973 param.new_db_name= const_cast<LEX_CSTRING*>(new_db_name);
1974 param.new_table_name= const_cast<LEX_CSTRING*>(new_table_name);
1975 param.stopper= trigger;
1976
1977 return for_all_triggers(&Trigger::change_on_table_name, &param);
1978}
1979
1980
1981bool Trigger::change_on_table_name(void* param_arg)
1982{
1983 change_table_name_param *param= (change_table_name_param*) param_arg;
1984
1985 char trigname_buff[FN_REFLEN];
1986 struct st_trigname trigname;
1987 LEX_CSTRING trigname_file;
1988
1989 if (param->stopper == this)
1990 return 0; // Stop processing
1991
1992 trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1,
1993 param->new_db_name->str, name.str,
1994 TRN_EXT, 0);
1995 trigname_file.str= trigname_buff;
1996
1997 trigname.trigger_table= *param->new_table_name;
1998
1999 if (base->create_lists_needed_for_files(current_thd->mem_root))
2000 return true;
2001
2002 if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type,
2003 (uchar*)&trigname, trigname_file_parameters))
2004 return true;
2005
2006 /* Remove stale .TRN file in case of database upgrade */
2007 if (param->old_db_name)
2008 {
2009 if (rm_trigname_file(trigname_buff, param->old_db_name, &name))
2010 {
2011 (void) rm_trigname_file(trigname_buff, param->new_db_name, &name);
2012 return 1;
2013 }
2014 }
2015 return 0;
2016}
2017
2018
2019/**
2020 Update .TRG and .TRN files after renaming triggers' subject table.
2021
2022 @param[in,out] thd Thread context
2023 @param[in] db Old database of subject table
2024 @param[in] old_alias Old alias of subject table
2025 @param[in] old_table Old name of subject table
2026 @param[in] new_db New database for subject table
2027 @param[in] new_table New name of subject table
2028
2029 @note
2030 This method tries to leave trigger related files in consistent state,
2031 i.e. it either will complete successfully, or will fail leaving files
2032 in their initial state.
2033 Also this method assumes that subject table is not renamed to itself.
2034 This method needs to be called under an exclusive table metadata lock.
2035
2036 @retval FALSE Success
2037 @retval TRUE Error
2038*/
2039
2040bool Table_triggers_list::change_table_name(THD *thd, const LEX_CSTRING *db,
2041 const LEX_CSTRING *old_alias,
2042 const LEX_CSTRING *old_table,
2043 const LEX_CSTRING *new_db,
2044 const LEX_CSTRING *new_table)
2045{
2046 TABLE table;
2047 bool result= 0;
2048 bool upgrading50to51= FALSE;
2049 Trigger *err_trigger;
2050 DBUG_ENTER("Triggers::change_table_name");
2051
2052 bzero(&table, sizeof(table));
2053 init_sql_alloc(&table.mem_root, "Triggers::change_table_name", 8192, 0,
2054 MYF(0));
2055
2056 /*
2057 This method interfaces the mysql server code protected by
2058 an exclusive metadata lock.
2059 */
2060 DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db->str,
2061 old_table->str,
2062 MDL_EXCLUSIVE));
2063
2064 DBUG_ASSERT(my_strcasecmp(table_alias_charset, db->str, new_db->str) ||
2065 my_strcasecmp(table_alias_charset, old_alias->str, new_table->str));
2066
2067 if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE))
2068 {
2069 result= 1;
2070 goto end;
2071 }
2072 if (table.triggers)
2073 {
2074 if (table.triggers->check_for_broken_triggers())
2075 {
2076 result= 1;
2077 goto end;
2078 }
2079 /*
2080 Since triggers should be in the same schema as their subject tables
2081 moving table with them between two schemas raises too many questions.
2082 (E.g. what should happen if in new schema we already have trigger
2083 with same name ?).
2084
2085 In case of "ALTER DATABASE `#mysql50#db1` UPGRADE DATA DIRECTORY NAME"
2086 we will be given table name with "#mysql50#" prefix
2087 To remove this prefix we use check_n_cut_mysql50_prefix().
2088 */
2089 if (my_strcasecmp(table_alias_charset, db->str, new_db->str))
2090 {
2091 char dbname[SAFE_NAME_LEN + 1];
2092 if (check_n_cut_mysql50_prefix(db->str, dbname, sizeof(dbname)) &&
2093 !my_strcasecmp(table_alias_charset, dbname, new_db->str))
2094 {
2095 upgrading50to51= TRUE;
2096 }
2097 else
2098 {
2099 my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
2100 result= 1;
2101 goto end;
2102 }
2103 }
2104 if (unlikely(table.triggers->change_table_name_in_triggers(thd, db, new_db,
2105 old_alias,
2106 new_table)))
2107 {
2108 result= 1;
2109 goto end;
2110 }
2111 if ((err_trigger= table.triggers->
2112 change_table_name_in_trignames( upgrading50to51 ? db : NULL,
2113 new_db, new_table, 0)))
2114 {
2115 /*
2116 If we were unable to update one of .TRN files properly we will
2117 revert all changes that we have done and report about error.
2118 We assume that we will be able to undo our changes without errors
2119 (we can't do much if there will be an error anyway).
2120 */
2121 (void) table.triggers->change_table_name_in_trignames(
2122 upgrading50to51 ? new_db : NULL, db,
2123 old_alias, err_trigger);
2124 (void) table.triggers->change_table_name_in_triggers(
2125 thd, db, new_db,
2126 new_table, old_alias);
2127 result= 1;
2128 goto end;
2129 }
2130 }
2131
2132end:
2133 delete table.triggers;
2134 free_root(&table.mem_root, MYF(0));
2135 DBUG_RETURN(result);
2136}
2137
2138
2139/**
2140 Execute trigger for given (event, time) pair.
2141
2142 The operation executes trigger for the specified event (insert, update,
2143 delete) and time (after, before) if it is set.
2144
2145 @param thd
2146 @param event
2147 @param time_type
2148 @param old_row_is_record1
2149
2150 @return Error status.
2151 @retval FALSE on success.
2152 @retval TRUE on error.
2153*/
2154
2155bool Table_triggers_list::process_triggers(THD *thd,
2156 trg_event_type event,
2157 trg_action_time_type time_type,
2158 bool old_row_is_record1)
2159{
2160 bool err_status;
2161 Sub_statement_state statement_state;
2162 Trigger *trigger;
2163 SELECT_LEX *save_current_select;
2164
2165 if (check_for_broken_triggers())
2166 return TRUE;
2167
2168 if (!(trigger= get_trigger(event, time_type)))
2169 return FALSE;
2170
2171 if (old_row_is_record1)
2172 {
2173 old_field= record1_field;
2174 new_field= record0_field;
2175 }
2176 else
2177 {
2178 DBUG_ASSERT(event == TRG_EVENT_DELETE);
2179 new_field= record1_field;
2180 old_field= record0_field;
2181 }
2182 /*
2183 This trigger must have been processed by the pre-locking
2184 algorithm.
2185 */
2186 DBUG_ASSERT(trigger_table->pos_in_table_list->trg_event_map &
2187 static_cast<uint>(1 << static_cast<int>(event)));
2188
2189 thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
2190
2191 /*
2192 Reset current_select before call execute_trigger() and
2193 restore it after return from one. This way error is set
2194 in case of failure during trigger execution.
2195 */
2196 save_current_select= thd->lex->current_select;
2197
2198 do {
2199 thd->lex->current_select= NULL;
2200 err_status=
2201 trigger->body->execute_trigger(thd,
2202 &trigger_table->s->db,
2203 &trigger_table->s->table_name,
2204 &trigger->subject_table_grants);
2205 status_var_increment(thd->status_var.executed_triggers);
2206 } while (!err_status && (trigger= trigger->next));
2207 thd->lex->current_select= save_current_select;
2208
2209 thd->restore_sub_statement_state(&statement_state);
2210
2211 return err_status;
2212}
2213
2214
2215/**
2216 Add triggers for table to the set of routines used by statement.
2217 Add tables used by them to statement table list. Do the same for
2218 routines used by triggers.
2219
2220 @param thd Thread context.
2221 @param prelocking_ctx Prelocking context of the statement.
2222 @param table_list Table list element for table with trigger.
2223
2224 @retval FALSE Success.
2225 @retval TRUE Failure.
2226*/
2227
2228bool
2229Table_triggers_list::
2230add_tables_and_routines_for_triggers(THD *thd,
2231 Query_tables_list *prelocking_ctx,
2232 TABLE_LIST *table_list)
2233{
2234 DBUG_ASSERT(static_cast<int>(table_list->lock_type) >=
2235 static_cast<int>(TL_WRITE_ALLOW_WRITE));
2236
2237 for (int i= 0; i < (int)TRG_EVENT_MAX; i++)
2238 {
2239 if (table_list->trg_event_map &
2240 static_cast<uint8>(1 << static_cast<int>(i)))
2241 {
2242 for (int j= 0; j < (int)TRG_ACTION_MAX; j++)
2243 {
2244 Trigger *triggers= table_list->table->triggers->get_trigger(i,j);
2245
2246 for ( ; triggers ; triggers= triggers->next)
2247 {
2248 sp_head *trigger= triggers->body;
2249
2250 if (unlikely(!triggers->body)) // Parse error
2251 continue;
2252
2253 MDL_key key(MDL_key::TRIGGER, trigger->m_db.str, trigger->m_name.str);
2254
2255 if (sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
2256 &key, &sp_handler_trigger,
2257 table_list->belong_to_view))
2258 {
2259 trigger->add_used_tables_to_table_list(thd,
2260 &prelocking_ctx->query_tables_last,
2261 table_list->belong_to_view);
2262 sp_update_stmt_used_routines(thd, prelocking_ctx,
2263 &trigger->m_sroutines,
2264 table_list->belong_to_view);
2265 trigger->propagate_attributes(prelocking_ctx);
2266 }
2267 }
2268 }
2269 }
2270 }
2271 return FALSE;
2272}
2273
2274
2275/**
2276 Mark fields of subject table which we read/set in its triggers
2277 as such.
2278
2279 This method marks fields of subject table which are read/set in its
2280 triggers as such (by properly updating TABLE::read_set/write_set)
2281 and thus informs handler that values for these fields should be
2282 retrieved/stored during execution of statement.
2283
2284 @param thd Current thread context
2285 @param event Type of event triggers for which we are going to inspect
2286*/
2287
2288void Table_triggers_list::mark_fields_used(trg_event_type event)
2289{
2290 int action_time;
2291 Item_trigger_field *trg_field;
2292 DBUG_ENTER("Table_triggers_list::mark_fields_used");
2293
2294 for (action_time= 0; action_time < (int)TRG_ACTION_MAX; action_time++)
2295 {
2296 for (Trigger *trigger= get_trigger(event,action_time);
2297 trigger ;
2298 trigger= trigger->next)
2299 {
2300 for (trg_field= trigger->trigger_fields;
2301 trg_field;
2302 trg_field= trg_field->next_trg_field)
2303 {
2304 /* We cannot mark fields which does not present in table. */
2305 if (trg_field->field_idx != (uint)-1)
2306 {
2307 DBUG_PRINT("info", ("marking field: %d", trg_field->field_idx));
2308 bitmap_set_bit(trigger_table->read_set, trg_field->field_idx);
2309 if (trg_field->get_settable_routine_parameter())
2310 bitmap_set_bit(trigger_table->write_set, trg_field->field_idx);
2311 if (trigger_table->field[trg_field->field_idx]->vcol_info)
2312 trigger_table->mark_virtual_col(trigger_table->
2313 field[trg_field->field_idx]);
2314 }
2315 }
2316 }
2317 }
2318 trigger_table->file->column_bitmaps_signal();
2319 DBUG_VOID_RETURN;
2320}
2321
2322
2323/**
2324 Signals to the Table_triggers_list that a parse error has occurred when
2325 reading a trigger from file. This makes the Table_triggers_list enter an
2326 error state flagged by m_has_unparseable_trigger == true. The error message
2327 will be used whenever a statement invoking or manipulating triggers is
2328 issued against the Table_triggers_list's table.
2329
2330 @param error_message The error message thrown by the parser.
2331 */
2332void Table_triggers_list::set_parse_error_message(char *error_message)
2333{
2334 m_has_unparseable_trigger= true;
2335 strnmov(m_parse_error_message, error_message,
2336 sizeof(m_parse_error_message)-1);
2337}
2338
2339
2340/**
2341 Trigger BUG#14090 compatibility hook.
2342
2343 @param[in,out] unknown_key reference on the line with unknown
2344 parameter and the parsing point
2345 @param[in] base base address for parameter writing
2346 (structure like TABLE)
2347 @param[in] mem_root MEM_ROOT for parameters allocation
2348 @param[in] end the end of the configuration
2349
2350 @note
2351 NOTE: this hook process back compatibility for incorrectly written
2352 sql_modes parameter (see BUG#14090).
2353
2354 @retval
2355 FALSE OK
2356 @retval
2357 TRUE Error
2358*/
2359
2360#define INVALID_SQL_MODES_LENGTH 13
2361
2362bool
2363Handle_old_incorrect_sql_modes_hook::
2364process_unknown_string(const char *&unknown_key, uchar* base,
2365 MEM_ROOT *mem_root, const char *end)
2366{
2367 DBUG_ENTER("Handle_old_incorrect_sql_modes_hook::process_unknown_string");
2368 DBUG_PRINT("info", ("unknown key: %60s", unknown_key));
2369
2370 if (unknown_key + INVALID_SQL_MODES_LENGTH + 1 < end &&
2371 unknown_key[INVALID_SQL_MODES_LENGTH] == '=' &&
2372 !memcmp(unknown_key, STRING_WITH_LEN("sql_modes")))
2373 {
2374 THD *thd= current_thd;
2375 const char *ptr= unknown_key + INVALID_SQL_MODES_LENGTH + 1;
2376
2377 DBUG_PRINT("info", ("sql_modes affected by BUG#14090 detected"));
2378 push_warning_printf(thd,
2379 Sql_condition::WARN_LEVEL_NOTE,
2380 ER_OLD_FILE_FORMAT,
2381 ER_THD(thd, ER_OLD_FILE_FORMAT),
2382 (char *)path, "TRIGGER");
2383 if (get_file_options_ulllist(ptr, end, unknown_key, base,
2384 &sql_modes_parameters, mem_root))
2385 {
2386 DBUG_RETURN(TRUE);
2387 }
2388 /*
2389 Set parsing pointer to the last symbol of string (\n)
2390 1) to avoid problem with \0 in the junk after sql_modes
2391 2) to speed up skipping this line by parser.
2392 */
2393 unknown_key= ptr-1;
2394 }
2395 DBUG_RETURN(FALSE);
2396}
2397
2398#define INVALID_TRIGGER_TABLE_LENGTH 15
2399
2400/**
2401 Trigger BUG#15921 compatibility hook. For details see
2402 Handle_old_incorrect_sql_modes_hook::process_unknown_string().
2403*/
2404bool
2405Handle_old_incorrect_trigger_table_hook::
2406process_unknown_string(const char *&unknown_key, uchar* base,
2407 MEM_ROOT *mem_root, const char *end)
2408{
2409 DBUG_ENTER("Handle_old_incorrect_trigger_table_hook::process_unknown_string");
2410 DBUG_PRINT("info", ("unknown key: %60s", unknown_key));
2411
2412 if (unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1 < end &&
2413 unknown_key[INVALID_TRIGGER_TABLE_LENGTH] == '=' &&
2414 !memcmp(unknown_key, STRING_WITH_LEN("trigger_table")))
2415 {
2416 THD *thd= current_thd;
2417 const char *ptr= unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1;
2418
2419 DBUG_PRINT("info", ("trigger_table affected by BUG#15921 detected"));
2420 push_warning_printf(thd,
2421 Sql_condition::WARN_LEVEL_NOTE,
2422 ER_OLD_FILE_FORMAT,
2423 ER_THD(thd, ER_OLD_FILE_FORMAT),
2424 (char *)path, "TRIGGER");
2425
2426 if (!(ptr= parse_escaped_string(ptr, end, mem_root, trigger_table_value)))
2427 {
2428 my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), "trigger_table",
2429 unknown_key);
2430 DBUG_RETURN(TRUE);
2431 }
2432
2433 /* Set parsing pointer to the last symbol of string (\n). */
2434 unknown_key= ptr-1;
2435 }
2436 DBUG_RETURN(FALSE);
2437}
2438
2439
2440/**
2441 Contruct path to TRN-file.
2442
2443 @param thd[in] Thread context.
2444 @param trg_name[in] Trigger name.
2445 @param trn_path[out] Variable to store constructed path
2446*/
2447
2448void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path)
2449{
2450 /* Construct path to the TRN-file. */
2451
2452 trn_path->length= build_table_filename(trn_path->str,
2453 FN_REFLEN - 1,
2454 trg_name->m_db.str,
2455 trg_name->m_name.str,
2456 TRN_EXT,
2457 0);
2458}
2459
2460
2461/**
2462 Check if TRN-file exists.
2463
2464 @return
2465 @retval TRUE if TRN-file does not exist.
2466 @retval FALSE if TRN-file exists.
2467*/
2468
2469bool check_trn_exists(const LEX_CSTRING *trn_path)
2470{
2471 return access(trn_path->str, F_OK) != 0;
2472}
2473
2474
2475/**
2476 Retrieve table name for given trigger.
2477
2478 @param thd[in] Thread context.
2479 @param trg_name[in] Trigger name.
2480 @param trn_path[in] Path to the corresponding TRN-file.
2481 @param tbl_name[out] Variable to store retrieved table name.
2482
2483 @return Error status.
2484 @retval FALSE on success.
2485 @retval TRUE if table name could not be retrieved.
2486*/
2487
2488bool load_table_name_for_trigger(THD *thd,
2489 const sp_name *trg_name,
2490 const LEX_CSTRING *trn_path,
2491 LEX_CSTRING *tbl_name)
2492{
2493 File_parser *parser;
2494 struct st_trigname trn_data;
2495 Handle_old_incorrect_trigger_table_hook trigger_table_hook(
2496 trn_path->str,
2497 &trn_data.trigger_table);
2498 DBUG_ENTER("load_table_name_for_trigger");
2499
2500 /* Parse the TRN-file. */
2501
2502 if (!(parser= sql_parse_prepare(trn_path, thd->mem_root, TRUE)))
2503 DBUG_RETURN(TRUE);
2504
2505 if (!is_equal(&trigname_file_type, parser->type()))
2506 {
2507 my_error(ER_WRONG_OBJECT, MYF(0),
2508 trg_name->m_name.str,
2509 TRN_EXT + 1,
2510 "TRIGGERNAME");
2511
2512 DBUG_RETURN(TRUE);
2513 }
2514
2515 if (parser->parse((uchar*) &trn_data, thd->mem_root,
2516 trigname_file_parameters, 1,
2517 &trigger_table_hook))
2518 DBUG_RETURN(TRUE);
2519
2520 /* Copy trigger table name. */
2521
2522 *tbl_name= trn_data.trigger_table;
2523
2524 /* That's all. */
2525
2526 DBUG_RETURN(FALSE);
2527}
2528