summaryrefslogtreecommitdiff
path: root/sql/sql_trigger.h
blob: 90c906fc72f85d54f3ebd4623b268dbd62b879da (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
  This class holds all information about triggers of table.

  QQ: Will it be merged into TABLE in future ?
*/
class Table_triggers_list: public Sql_alloc
{
  /* Triggers as SPs grouped by event, action_time */
  sp_head           *bodies[3][2];
  /*
    Copy of TABLE::Field array with field pointers set to old version
    of record, used for OLD values in trigger on UPDATE.
  */
  Field             **old_field;
  /*
    Names of triggers.
    Should correspond to order of triggers on definitions_list,
    used in CREATE/DROP TRIGGER for looking up trigger by name.
  */
  List<LEX_STRING>  names_list;

public:
  /*
    Field responsible for storing triggers definitions in file.
    It have to be public because we are using it directly from parser.
  */
  List<LEX_STRING>  definitions_list;

  Table_triggers_list():
    old_field(0)
  {
    bzero((char *)bodies, sizeof(bodies));
  }
  ~Table_triggers_list();

  bool create_trigger(THD *thd, TABLE_LIST *table);
  bool drop_trigger(THD *thd, TABLE_LIST *table);
  bool process_triggers(THD *thd, trg_event_type event,
                        trg_action_time_type time_type)
  {
    int res= 0;

    if (bodies[event][time_type])
    {
#ifndef EMBEDDED_LIBRARY
      /* Surpress OK packets in case if we will execute statements */
      my_bool nsok= thd->net.no_send_ok;
      thd->net.no_send_ok= TRUE;
#endif

      /*
        FIXME: We should juggle with security context here (because trigger
        should be invoked with creator rights).
      */
      /*
	We disable binlogging, as in SP/functions, even though currently
        triggers can't do updates. When triggers can do updates, someone
        should add such a trigger to rpl_sp.test to verify that the update
        does NOT go into binlog.
      */
      tmp_disable_binlog(thd);
      res= bodies[event][time_type]->execute_function(thd, 0, 0, 0);
      reenable_binlog(thd);

#ifndef EMBEDDED_LIBRARY
      thd->net.no_send_ok= nsok;
#endif
    }

    return res;
  }

  static bool check_n_load(THD *thd, const char *db, const char *table_name,
                           TABLE *table);

  bool has_delete_triggers()
  {
    return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] ||
            bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]);
  }

  friend class Item_trigger_field;

private:
  bool prepare_old_row_accessors(TABLE *table);
};