1 /*
2 Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software Foundation,
22 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
23
24 #include "my_global.h"
25 #include "sql_class.h"
26 #include "trigger.h"
27 #include "mysys_err.h" // EE_OUTOFMEMORY
28 #include "trigger_creation_ctx.h" // Trigger_creation_ctx
29 #include "sql_parse.h" // parse_sql
30 #include "sp.h" // sp_update_stmt_used_routines
31 #include "sql_table.h" // check_n_cut_mysql50_prefix
32 #include "sql_show.h" // append_identifier
33 #include "sql_db.h" // get_default_db_collation
34
35 #include "mysql/psi/mysql_sp.h"
36 ///////////////////////////////////////////////////////////////////////////
37
38 /**
39 An error handler that catches all non-OOM errors which can occur during
40 parsing of trigger body. Such errors are ignored and corresponding error
41 message is used to construct a more verbose error message which contains
42 name of problematic trigger. This error message is later emitted when
43 one tries to perform DML or some of DDL on this table.
44 Also, if possible, grabs name of the trigger being parsed so it can be
45 used to correctly drop problematic trigger.
46 */
47 class Deprecated_trigger_syntax_handler : public Internal_error_handler
48 {
49 private:
50 char m_message[MYSQL_ERRMSG_SIZE];
51 LEX_STRING *m_trigger_name;
52
53 public:
Deprecated_trigger_syntax_handler()54 Deprecated_trigger_syntax_handler() : m_trigger_name(NULL) {}
55
handle_condition(THD * thd,uint sql_errno,const char * sqlstate,Sql_condition::enum_severity_level * level,const char * message)56 virtual bool handle_condition(THD *thd,
57 uint sql_errno,
58 const char *sqlstate,
59 Sql_condition::enum_severity_level *level,
60 const char *message)
61 {
62 if (sql_errno != EE_OUTOFMEMORY &&
63 sql_errno != ER_OUT_OF_RESOURCES)
64 {
65 if (thd->lex->spname)
66 m_trigger_name= &thd->lex->spname->m_name;
67 if (m_trigger_name)
68 my_snprintf(m_message, sizeof(m_message),
69 ER(ER_ERROR_IN_TRIGGER_BODY),
70 m_trigger_name->str, message);
71 else
72 my_snprintf(m_message, sizeof(m_message),
73 ER(ER_ERROR_IN_UNKNOWN_TRIGGER_BODY), message);
74 return true;
75 }
76 return false;
77 }
78
get_trigger_name()79 LEX_STRING *get_trigger_name() { return m_trigger_name; }
get_error_message()80 const char *get_error_message() { return m_message; }
81 };
82
83 ///////////////////////////////////////////////////////////////////////////
84
85 /**
86 Constructs DEFINER clause.
87
88 @param mem_root mem-root where needed strings will be allocated
89 @param lex_definer DEFINER clause from the parser (as it is specified
90 by the user). It is NULL if DEFINER clause is
91 missing.
92 @param[out] definer_user pointer to the user part of lex_definer (if any)
93 @param[out] definer_host pointer to the host part of lex_definer (if any)
94 @param[out] definer well-formed DEFINER-clause (after successful
95 execution)
96
97 @return Operation status.
98 @retval false Success
99 @retval true Failure
100 */
101
reconstruct_definer_clause(MEM_ROOT * mem_root,const LEX_USER * lex_definer,LEX_CSTRING * definer_user,LEX_CSTRING * definer_host,LEX_STRING * definer)102 static bool reconstruct_definer_clause(MEM_ROOT *mem_root,
103 const LEX_USER *lex_definer,
104 LEX_CSTRING *definer_user,
105 LEX_CSTRING *definer_host,
106 LEX_STRING *definer)
107 {
108 if (lex_definer)
109 {
110 /* SUID trigger (DEFINER is specified by the user). */
111
112 char definer_buf[USER_HOST_BUFF_SIZE];
113
114 *definer_user= lex_definer->user;
115 *definer_host= lex_definer->host;
116
117 size_t definer_len=
118 strxmov(definer_buf,
119 lex_definer->user.str, "@", lex_definer->host.str, NullS) -
120 definer_buf;
121
122 return !lex_string_copy(mem_root, definer, definer_buf, definer_len);
123 }
124
125 /* non-SUID trigger. */
126
127 *definer_user= NULL_CSTR;
128 *definer_host= NULL_CSTR;
129 *definer= EMPTY_STR;
130
131 return false;
132 }
133
134
135 /**
136 Constructs CREATE TRIGGER statement.
137
138 The point of this method is to create two canonical forms of CREATE TRIGGER
139 statement: one for storing in the Data Dictionary, the other is for writing
140 into the binlog.
141
142 The difference between these two forms is that the Data Dictionary form must
143 not contains FOLLOWS/PRECEDES clause, while the binlog form mist preserve it
144 if it was in the original statement. The reason for that difference is this:
145
146 - the Data Dictionary preserves the trigger execution order (action_order),
147 thus FOLLOWS/PRECEDES clause is not needed.
148
149 - moreover, FOLLOWS/PRECEDES clause usually makes problem in mysqldump,
150 because CREATE TRIGGER statement will have a reference to non-yet-existing
151 trigger (which is about to be created right after this one).
152
153 - thus, FOLLOWS/PRECEDES must not be stored in the Data Dictionary.
154
155 - on the other hand, the binlog contains statements in the user order (as
156 the user executes them). Thus, it is important to preserve
157 FOLLOWS/PRECEDES clause if the user has specified it so that the trigger
158 execution order on master and slave will be the same.
159
160 Both forms of CREATE TRIGGER must have the DEFINER clause if the user
161 specified it (it is a SUID trigger). The DEFINER clause can not be reused
162 from the parser.
163
164 @param thd thread context
165 @param mem_root mem-root where needed strings will be allocated
166 @param[out] dd_query well-formed CREATE TRIGGER statement for storing
167 in the Data Dictionary (after successful execution)
168 @param[out] binlog_query well-formed CREATE TRIGGER statement for putting
169 into binlog (after successful execution)
170 @param[out] definer well-formed DEFINER-clause (after successful
171 execution)
172
173 @return Operation status.
174 @retval false Success
175 @retval true Failure
176 */
177
reconstruct_create_trigger_statement(THD * thd,MEM_ROOT * mem_root,String * binlog_query,String * dd_query,LEX_STRING * definer)178 static bool reconstruct_create_trigger_statement(THD *thd,
179 MEM_ROOT *mem_root,
180 String *binlog_query,
181 String *dd_query,
182 LEX_STRING *definer)
183 {
184 LEX *lex= thd->lex;
185
186 if (dd_query->append(STRING_WITH_LEN("CREATE ")))
187 return true; // OOM
188
189 /*
190 Append definer-clause if the trigger is SUID (a usual trigger in
191 new MySQL versions).
192 */
193
194 LEX_CSTRING definer_user;
195 LEX_CSTRING definer_host;
196
197 if (reconstruct_definer_clause(mem_root, lex->definer,
198 &definer_user, &definer_host, definer))
199 return true;
200
201 append_definer(thd, dd_query, definer_user, definer_host);
202
203 if (binlog_query->append(*dd_query))
204 return true; //OOM
205
206 LEX_STRING dd_definition;
207 LEX_STRING binlog_definition;
208
209 binlog_definition.str= (char *) lex->stmt_definition_begin;
210 binlog_definition.length= lex->stmt_definition_end -
211 lex->stmt_definition_begin;
212
213 trim_whitespace(thd->charset(), &binlog_definition);
214
215 if (lex->trg_ordering_clause_begin !=
216 lex->trg_ordering_clause_end)
217 {
218 dd_definition.str= (char *) lex->stmt_definition_begin;
219 dd_definition.length= lex->trg_ordering_clause_begin -
220 lex->stmt_definition_begin;
221
222 if (dd_query->append(dd_definition.str, dd_definition.length))
223 return true;
224
225 dd_definition.str= (char *) lex->trg_ordering_clause_end;
226 dd_definition.length= lex->stmt_definition_end -
227 lex->trg_ordering_clause_end;
228
229 trim_whitespace(thd->charset(), &dd_definition);
230 }
231 else
232 {
233 dd_definition.str= binlog_definition.str;
234 dd_definition.length= binlog_definition.length;
235 }
236
237 return dd_query->append(dd_definition.str, dd_definition.length) ||
238 binlog_query->append(binlog_definition.str, binlog_definition.length);
239 }
240
241 ///////////////////////////////////////////////////////////////////////////
242
243 /**
244 Creates a new Trigger-instance with the state from the parser. This method is
245 used to create a Trigger-object after CREATE TRIGGER statement is parsed.
246
247 @see also Trigger::create_from_dd()
248
249 @param thd Thread context with a valid LEX-tree
250 of CREATE TRIGGER statement
251 @param subject_table A valid (not fake!) subject
252 TABLE-object
253 @param [out] binlog_create_trigger_stmt Store CREATE TRIGGER appropriate to
254 writing into the binlog. It should
255 have DEFINER clause and should not
256 have FOLLOWS/PRECEDES clause.
257 */
create_from_parser(THD * thd,TABLE * subject_table,String * binlog_create_trigger_stmt)258 Trigger *Trigger::create_from_parser(THD *thd,
259 TABLE *subject_table,
260 String *binlog_create_trigger_stmt)
261 {
262 LEX *lex= thd->lex;
263
264 /*
265 Fill character set information:
266 - client character set contains charset info only;
267 - connection collation contains pair {character set, collation};
268 - database collation contains pair {character set, collation};
269
270 NOTE: we must allocate strings on Trigger's mem-root.
271 */
272
273 LEX_STRING client_cs_name;
274 LEX_STRING connection_cl_name;
275 LEX_STRING db_cl_name;
276
277 const CHARSET_INFO *default_db_cl=
278 get_default_db_collation(thd, subject_table->s->db.str);
279
280 if (!lex_string_copy(&subject_table->mem_root,
281 &client_cs_name,
282 thd->charset()->csname) ||
283 !lex_string_copy(&subject_table->mem_root,
284 &connection_cl_name,
285 thd->variables.collation_connection->name) ||
286 !lex_string_copy(&subject_table->mem_root,
287 &db_cl_name,
288 default_db_cl->name))
289 {
290 return NULL;
291 }
292
293 // Copy trigger name into the proper mem-root.
294
295 LEX_STRING trigger_name;
296 if (!lex_string_copy(&subject_table->mem_root,
297 &trigger_name,
298 lex->spname->m_name))
299 return NULL;
300
301 // Construct two CREATE TRIGGER statements, allocate DEFINER-clause.
302
303 String dd_create_trigger_stmt;
304 dd_create_trigger_stmt.set_charset(system_charset_info);
305
306 LEX_STRING definer;
307 reconstruct_create_trigger_statement(thd,
308 &subject_table->mem_root,
309 binlog_create_trigger_stmt,
310 &dd_create_trigger_stmt,
311 &definer);
312
313 // Copy CREATE TRIGGER statement for DD into the proper mem-root.
314
315 LEX_STRING definition;
316 if (!lex_string_copy(&subject_table->mem_root,
317 &definition,
318 dd_create_trigger_stmt.c_ptr(),
319 dd_create_trigger_stmt.length()))
320 return NULL;
321
322 /*
323 Calculate time stamp up to tenths of milliseconds elapsed
324 from 1 Jan 1970 00:00:00.
325 */
326 struct timeval cur_time= thd->query_start_timeval_trunc(2);
327 longlong created_timestamp= static_cast<longlong>(cur_time.tv_sec) * 100 +
328 (cur_time.tv_usec / 10000);
329
330 // Create a new Trigger instance.
331
332 Trigger *t=
333 new (&subject_table->mem_root) Trigger(
334 &subject_table->mem_root,
335 to_lex_cstring(subject_table->s->db),
336 to_lex_cstring(subject_table->s->table_name),
337 definition,
338 thd->variables.sql_mode,
339 definer,
340 client_cs_name,
341 connection_cl_name,
342 db_cl_name,
343 lex->sphead->m_trg_chistics.event,
344 lex->sphead->m_trg_chistics.action_time,
345 created_timestamp);
346
347 if (!t)
348 return NULL;
349
350 /*
351 NOTE: sp-head is not set in the new trigger object. That's Ok since we're
352 not going to execute it, but rather use it for store new trigger in the Data
353 Dictionary.
354 */
355
356 // Set trigger name.
357
358 t->set_trigger_name(trigger_name);
359
360 return t;
361 }
362
363
364 /**
365 Creates a new Trigger-instance with the state loaded from the Data Dictionary.
366
367 @note the Data Dictionary currently stores not all needed information, so the
368 complete state of Trigger-object can be obtained only after parsing the
369 definition (CREATE TRIGGER) statement. In order to do that, Trigger::parse()
370 should be called.
371
372 @see also Trigger::create_from_parser()
373 */
create_from_dd(MEM_ROOT * mem_root,const LEX_CSTRING & db_name,const LEX_CSTRING & subject_table_name,const LEX_STRING & definition,sql_mode_t sql_mode,const LEX_STRING & definer,const LEX_STRING & client_cs_name,const LEX_STRING & connection_cl_name,const LEX_STRING & db_cl_name,const longlong * created_timestamp)374 Trigger *Trigger::create_from_dd(MEM_ROOT *mem_root,
375 const LEX_CSTRING &db_name,
376 const LEX_CSTRING &subject_table_name,
377 const LEX_STRING &definition,
378 sql_mode_t sql_mode,
379 const LEX_STRING &definer,
380 const LEX_STRING &client_cs_name,
381 const LEX_STRING &connection_cl_name,
382 const LEX_STRING &db_cl_name,
383 const longlong *created_timestamp)
384 {
385 return new (mem_root) Trigger(
386 mem_root,
387 db_name,
388 subject_table_name,
389 definition,
390 sql_mode,
391 definer,
392 client_cs_name,
393 connection_cl_name,
394 db_cl_name,
395 TRG_EVENT_MAX,
396 TRG_ACTION_MAX,
397 created_timestamp ? *created_timestamp : 0);
398 }
399
400
401 /**
402 Trigger constructor.
403 */
Trigger(MEM_ROOT * mem_root,const LEX_CSTRING & db_name,const LEX_CSTRING & subject_table_name,const LEX_STRING & definition,sql_mode_t sql_mode,const LEX_STRING & definer,const LEX_STRING & client_cs_name,const LEX_STRING & connection_cl_name,const LEX_STRING & db_cl_name,enum_trigger_event_type event_type,enum_trigger_action_time_type action_time,longlong created_timestamp)404 Trigger::Trigger(MEM_ROOT *mem_root,
405 const LEX_CSTRING &db_name,
406 const LEX_CSTRING &subject_table_name,
407 const LEX_STRING &definition,
408 sql_mode_t sql_mode,
409 const LEX_STRING &definer,
410 const LEX_STRING &client_cs_name,
411 const LEX_STRING &connection_cl_name,
412 const LEX_STRING &db_cl_name,
413 enum_trigger_event_type event_type,
414 enum_trigger_action_time_type action_time,
415 longlong created_timestamp)
416 :m_mem_root(mem_root),
417 m_db_name(db_name),
418 m_subject_table_name(subject_table_name),
419 m_definition(definition),
420 m_sql_mode(sql_mode),
421 m_definer(definer),
422 m_client_cs_name(client_cs_name),
423 m_connection_cl_name(connection_cl_name),
424 m_db_cl_name(db_cl_name),
425 m_event(event_type),
426 m_action_time(action_time),
427 m_created_timestamp(created_timestamp),
428 m_action_order(0),
429 m_sp(NULL),
430 m_has_parse_error(false)
431 {
432 m_trigger_name= NULL_STR;
433 m_on_table_name= NULL_STR;
434
435 m_parse_error_message[0]= 0;
436 }
437
438
439 /**
440 Destroy associated SP (if any).
441 */
~Trigger()442 Trigger::~Trigger()
443 {
444 delete m_sp;
445 }
446
447
448 /**
449 Execute trigger's body.
450
451 @param [in] thd Thread context
452
453 @return Operation status
454 @retval true Trigger execution failed or trigger has compilation errors
455 @retval false Success
456 */
457
execute(THD * thd)458 bool Trigger::execute(THD *thd)
459 {
460 if (m_has_parse_error)
461 return true;
462
463 bool err_status;
464 Sub_statement_state statement_state;
465 SELECT_LEX *save_current_select;
466
467 thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
468
469 /*
470 Reset current_select before call execute_trigger() and
471 restore it after return from one. This way error is set
472 in case of failure during trigger execution.
473 */
474 save_current_select= thd->lex->current_select();
475 thd->lex->set_current_select(NULL);
476 err_status=
477 m_sp->execute_trigger(thd,
478 m_db_name,
479 m_subject_table_name,
480 &m_subject_table_grant);
481 thd->lex->set_current_select(save_current_select);
482
483 thd->restore_sub_statement_state(&statement_state);
484
485 return err_status;
486 }
487
488
489 /**
490 Parse CREATE TRIGGER statement.
491
492 @param [in] thd Thread context
493
494 @return true if a fatal parse error happened (the parser failed to extract
495 even the trigger name), false otherwise (Trigger::has_parse_error() might
496 still return true in this case).
497 */
498
parse(THD * thd)499 bool Trigger::parse(THD *thd)
500 {
501 sql_mode_t sql_mode_saved= thd->variables.sql_mode;
502 thd->variables.sql_mode= m_sql_mode;
503
504 Parser_state parser_state;
505 if (parser_state.init(thd, m_definition.str, m_definition.length))
506 {
507 thd->variables.sql_mode= sql_mode_saved;
508 return true;
509 }
510
511 LEX *lex_saved= thd->lex;
512
513 LEX lex;
514 thd->lex= &lex;
515 lex_start(thd);
516
517 LEX_CSTRING current_db_name_saved= thd->db();
518 thd->reset_db(m_db_name);
519
520 Deprecated_trigger_syntax_handler error_handler;
521 thd->push_internal_handler(&error_handler);
522
523 sp_rcontext *sp_runtime_ctx_saved= thd->sp_runtime_ctx;
524 thd->sp_runtime_ctx= NULL;
525
526 sql_digest_state *digest_saved= thd->m_digest;
527 PSI_statement_locker *statement_locker_saved= thd->m_statement_psi;
528 thd->m_digest= NULL;
529 thd->m_statement_psi= NULL;
530
531 Trigger_creation_ctx *creation_ctx=
532 Trigger_creation_ctx::create(thd,
533 m_db_name,
534 m_subject_table_name,
535 m_client_cs_name,
536 m_connection_cl_name,
537 m_db_cl_name);
538
539 bool parse_error= parse_sql(thd, &parser_state, creation_ctx);
540
541 thd->m_digest= digest_saved;
542 thd->m_statement_psi= statement_locker_saved;
543 thd->sp_runtime_ctx= sp_runtime_ctx_saved;
544 thd->variables.sql_mode= sql_mode_saved;
545
546 thd->pop_internal_handler();
547
548 /*
549 Not strictly necessary to invoke this method here, since we know
550 that we've parsed CREATE TRIGGER and not an
551 UPDATE/DELETE/INSERT/REPLACE/LOAD/CREATE TABLE, but we try to
552 maintain the invariant that this method is called for each
553 distinct statement, in case its logic is extended with other
554 types of analyses in future.
555 */
556 lex.set_trg_event_type_for_tables();
557
558 // Remember parse error message.
559
560 if (parse_error)
561 set_parse_error_message(error_handler.get_error_message());
562
563 // Ensure that lex.sp_head is NULL in case of parse errors.
564
565 DBUG_ASSERT(!parse_error || (parse_error && lex.sphead == NULL));
566
567 // fatal_parse_error will be returned from this method.
568
569 bool fatal_parse_error= false;
570
571 // Set trigger name.
572
573 {
574 /*
575 Get trigger name:
576 - in case of parse error, trigger name can be fetched from error
577 handler;
578 - otherwise it can be retrieved from the parser.
579 */
580
581 const LEX_STRING *trigger_name_ptr= NULL;
582
583 if (parse_error)
584 {
585 if (!error_handler.get_trigger_name())
586 {
587 // We failed to parse trigger name => fatal error.
588 fatal_parse_error= true;
589 goto cleanup;
590 }
591
592 trigger_name_ptr= error_handler.get_trigger_name();
593 }
594 else
595 {
596 trigger_name_ptr= &lex.spname->m_name;
597 }
598
599 // Make a copy of trigger name and set it.
600
601 LEX_STRING s;
602 if (!lex_string_copy(m_mem_root, &s, *trigger_name_ptr))
603 {
604 fatal_parse_error= true;
605 goto cleanup;
606 }
607
608 set_trigger_name(s);
609 }
610
611 // That's it in case of parse error.
612
613 if (parse_error)
614 goto cleanup;
615
616 // Set correct m_event and m_action_time.
617
618 DBUG_ASSERT(m_event == TRG_EVENT_MAX);
619 DBUG_ASSERT(m_action_time == TRG_ACTION_MAX);
620
621 m_event= lex.sphead->m_trg_chistics.event;
622 m_action_time= lex.sphead->m_trg_chistics.action_time;
623
624 /*
625 Remember a pointer to the "ON <table name>" part of the trigger definition.
626 Note, that it is a pointer inside m_definition.str.
627 */
628
629 m_on_table_name.str= (char*) lex.raw_trg_on_table_name_begin;
630 m_on_table_name.length= lex.raw_trg_on_table_name_end -
631 lex.raw_trg_on_table_name_begin;
632
633 // Take ownership of SP object.
634
635 DBUG_ASSERT(!m_sp);
636
637 m_sp= lex.sphead;
638 lex.sphead= NULL; /* Prevent double cleanup. */
639
640 /*
641 Set some SP attributes.
642
643 NOTE: sp_head::set_info() is required on slave.
644 */
645
646 m_sp->set_info(0, // CREATED timestamp (not used for triggers)
647 0, // MODIFIED timestamp (not used for triggers)
648 &lex.sp_chistics,
649 m_sql_mode);
650
651 DBUG_ASSERT(!m_sp->get_creation_ctx());
652 m_sp->set_creation_ctx(creation_ctx);
653
654 // Set the definer attribute in SP.
655
656 if (!m_definer.length)
657 {
658 DBUG_ASSERT(m_definer.str); // m_definer must be EMPTY_STR here.
659
660 /*
661 This trigger was created/imported in MySQL version, which does not support
662 triggers definers. We should emit warning here.
663 */
664
665 push_warning_printf(thd, Sql_condition::SL_WARNING,
666 ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER),
667 m_db_name.str,
668 m_trigger_name.str);
669
670 /*
671 Triggers without definer information are executed under the
672 authorization of the invoker.
673 */
674
675 m_sp->m_chistics->suid= SP_IS_NOT_SUID;
676 }
677
678 m_sp->set_definer(m_definer.str, m_definer.length);
679
680 #ifdef HAVE_PSI_SP_INTERFACE
681 m_sp->m_sp_share= MYSQL_GET_SP_SHARE(SP_TYPE_TRIGGER,
682 m_sp->m_db.str, m_sp->m_db.length,
683 m_sp->m_name.str, m_sp->m_name.length);
684 #endif
685
686 #ifndef DBUG_OFF
687 /*
688 Check that we correctly update trigger definitions when we rename tables
689 with triggers.
690
691 In special cases like "RENAME TABLE `#mysql50#somename` TO `somename`"
692 or "ALTER DATABASE `#mysql50#somename` UPGRADE DATA DIRECTORY NAME"
693 we might be given table or database name with "#mysql50#" prefix (and
694 trigger's definiton contains un-prefixed version of the same name).
695 To remove this prefix we use check_n_cut_mysql50_prefix().
696 */
697
698 char fname[NAME_LEN + 1];
699 DBUG_ASSERT((!my_strcasecmp(table_alias_charset,
700 lex.query_tables->db, m_db_name.str) ||
701 (check_n_cut_mysql50_prefix(m_db_name.str,
702 fname, sizeof(fname)) &&
703 !my_strcasecmp(table_alias_charset,
704 lex.query_tables->db, fname))));
705 DBUG_ASSERT((!my_strcasecmp(table_alias_charset,
706 lex.query_tables->table_name,
707 m_subject_table_name.str) ||
708 (check_n_cut_mysql50_prefix(m_subject_table_name.str,
709 fname, sizeof(fname)) &&
710 !my_strcasecmp(table_alias_charset,
711 lex.query_tables->table_name, fname))));
712 #endif
713
714 cleanup:
715 lex_end(&lex);
716 thd->reset_db(current_db_name_saved);
717 thd->lex= lex_saved;
718
719 return fatal_parse_error;
720 }
721
722
723 /**
724 Add tables and routines used by trigger to the set of elements
725 used by statement.
726
727 @param [in] thd thread handle
728 @param [in out] prelocking_ctx prelocking context of the statement
729 @param [in] table_list TABLE_LIST for the table
730 */
731
add_tables_and_routines(THD * thd,Query_tables_list * prelocking_ctx,TABLE_LIST * table_list)732 void Trigger::add_tables_and_routines(THD *thd,
733 Query_tables_list *prelocking_ctx,
734 TABLE_LIST *table_list)
735 {
736 if (has_parse_error())
737 return;
738
739 MDL_key key(MDL_key::TRIGGER, m_sp->m_db.str, m_sp->m_name.str);
740
741 if (sp_add_used_routine(prelocking_ctx, thd->stmt_arena,
742 &key, table_list->belong_to_view))
743 {
744 m_sp->add_used_tables_to_table_list(thd,
745 &prelocking_ctx->query_tables_last,
746 prelocking_ctx->sql_command,
747 table_list->belong_to_view);
748 sp_update_stmt_used_routines(thd, prelocking_ctx,
749 &m_sp->m_sroutines,
750 table_list->belong_to_view);
751 m_sp->propagate_attributes(prelocking_ctx);
752 }
753 }
754
755
756 /**
757 Print upgrade warnings (if any).
758 */
print_upgrade_warning(THD * thd)759 void Trigger::print_upgrade_warning(THD *thd)
760 {
761 if (m_created_timestamp)
762 return;
763
764 push_warning_printf(thd,
765 Sql_condition::SL_WARNING,
766 ER_WARN_TRIGGER_DOESNT_HAVE_CREATED,
767 ER(ER_WARN_TRIGGER_DOESNT_HAVE_CREATED),
768 get_db_name().str,
769 get_subject_table_name().str,
770 get_trigger_name().str);
771 }
772
773
774 /**
775 Handles renaming of the subject table.
776
777 The main duty of this method is to properly update m_definition and
778 m_on_table_name attributes.
779
780 @param thd Thread context, used for passing into
781 append_identifier() function, which uses it to know
782 the way to properly escape identifiers
783 @param new_table_name New subject table name
784 */
rename_subject_table(THD * thd,const LEX_STRING & new_table_name)785 void Trigger::rename_subject_table(THD *thd, const LEX_STRING &new_table_name)
786 {
787 /*
788 sql_mode has to be set to the trigger's sql_mode because we're going to
789 build a new CREATE TRIGGER statement and sql_mode affects the way we append
790 identifiers.
791 */
792
793 sql_mode_t sql_mode_saved= thd->variables.sql_mode;
794 thd->variables.sql_mode= get_sql_mode();
795
796 // Construct a new CREATE TRIGGER statement with the new table name.
797
798 String new_create_stmt;
799 new_create_stmt.length(0);
800
801 // NOTE: 'on_table_name' is supposed to point inside m_definition.
802
803 DBUG_ASSERT(m_on_table_name.str);
804 DBUG_ASSERT(m_on_table_name.str > m_definition.str);
805 DBUG_ASSERT(m_on_table_name.str < (m_definition.str + m_definition.length));
806
807 size_t before_on_len= m_on_table_name.str - m_definition.str;
808
809 new_create_stmt.append(m_definition.str, before_on_len);
810 new_create_stmt.append(STRING_WITH_LEN("ON "));
811
812 append_identifier(thd, &new_create_stmt,
813 new_table_name.str, new_table_name.length);
814
815 new_create_stmt.append(STRING_WITH_LEN(" "));
816
817 size_t on_q_table_name_len= new_create_stmt.length() - before_on_len;
818
819 new_create_stmt.append(
820 m_on_table_name.str + m_on_table_name.length,
821 m_definition.length - (before_on_len + m_on_table_name.length));
822
823 lex_string_copy(m_mem_root,
824 &m_definition,
825 new_create_stmt.ptr(),
826 new_create_stmt.length());
827
828 lex_string_copy(m_mem_root,
829 &m_on_table_name,
830 m_definition.str + before_on_len,
831 on_q_table_name_len);
832
833 thd->variables.sql_mode= sql_mode_saved;
834 }
835