~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to sql/sql_trigger.cc

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

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