2004-09-07 16:29:46 +04:00
|
|
|
/*
|
|
|
|
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];
|
|
|
|
/*
|
2005-05-24 22:19:33 +04:00
|
|
|
Copy of TABLE::Field array with field pointers set to TABLE::record[1]
|
|
|
|
buffer instead of TABLE::record[0] (used for OLD values in on UPDATE
|
|
|
|
trigger and DELETE trigger when it is called for REPLACE).
|
2004-09-07 16:29:46 +04:00
|
|
|
*/
|
2005-05-24 22:19:33 +04:00
|
|
|
Field **record1_field;
|
|
|
|
/*
|
|
|
|
During execution of trigger new_field and old_field should point to the
|
|
|
|
array of fields representing new or old version of row correspondingly
|
|
|
|
(so it can point to TABLE::field or to Tale_triggers_list::record1_field)
|
|
|
|
*/
|
|
|
|
Field **new_field;
|
2004-09-07 16:29:46 +04:00
|
|
|
Field **old_field;
|
2005-05-24 22:19:33 +04:00
|
|
|
/* TABLE instance for which this triggers list object was created */
|
|
|
|
TABLE *table;
|
2004-09-07 16:29:46 +04:00
|
|
|
/*
|
|
|
|
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;
|
|
|
|
|
2005-05-24 22:19:33 +04:00
|
|
|
Table_triggers_list(TABLE *table_arg):
|
|
|
|
record1_field(0), table(table_arg)
|
2004-09-07 16:29:46 +04:00
|
|
|
{
|
|
|
|
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,
|
2005-05-24 22:19:33 +04:00
|
|
|
trg_action_time_type time_type,
|
|
|
|
bool old_row_is_record1)
|
2004-09-07 16:29:46 +04:00
|
|
|
{
|
|
|
|
int res= 0;
|
|
|
|
|
|
|
|
if (bodies[event][time_type])
|
|
|
|
{
|
2005-06-07 14:53:08 +04:00
|
|
|
bool save_in_sub_stmt= thd->transaction.in_sub_stmt;
|
2005-03-04 16:35:28 +03:00
|
|
|
#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
|
2004-09-07 16:29:46 +04:00
|
|
|
|
2005-05-24 22:19:33 +04:00
|
|
|
if (old_row_is_record1)
|
|
|
|
{
|
|
|
|
old_field= record1_field;
|
|
|
|
new_field= table->field;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
new_field= record1_field;
|
|
|
|
old_field= table->field;
|
|
|
|
}
|
|
|
|
|
2005-03-04 16:35:28 +03:00
|
|
|
/*
|
2004-09-07 16:29:46 +04:00
|
|
|
FIXME: We should juggle with security context here (because trigger
|
|
|
|
should be invoked with creator rights).
|
|
|
|
*/
|
2005-05-06 18:52:19 +02:00
|
|
|
/*
|
2005-05-10 15:55:22 +02:00
|
|
|
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.
|
2005-05-06 18:52:19 +02:00
|
|
|
*/
|
|
|
|
tmp_disable_binlog(thd);
|
2005-06-07 14:53:08 +04:00
|
|
|
thd->transaction.in_sub_stmt= TRUE;
|
|
|
|
|
2004-09-07 16:29:46 +04:00
|
|
|
res= bodies[event][time_type]->execute_function(thd, 0, 0, 0);
|
2005-06-07 14:53:08 +04:00
|
|
|
|
|
|
|
thd->transaction.in_sub_stmt= save_in_sub_stmt;
|
2005-05-06 18:52:19 +02:00
|
|
|
reenable_binlog(thd);
|
2005-03-04 16:35:28 +03:00
|
|
|
|
|
|
|
#ifndef EMBEDDED_LIBRARY
|
|
|
|
thd->net.no_send_ok= nsok;
|
|
|
|
#endif
|
2004-09-07 16:29:46 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_n_load(THD *thd, const char *db, const char *table_name,
|
|
|
|
TABLE *table);
|
|
|
|
|
2004-11-12 17:04:07 +03:00
|
|
|
bool has_delete_triggers()
|
|
|
|
{
|
|
|
|
return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] ||
|
|
|
|
bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]);
|
|
|
|
}
|
|
|
|
|
2005-05-24 22:19:33 +04:00
|
|
|
bool has_before_update_triggers()
|
|
|
|
{
|
|
|
|
return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]);
|
|
|
|
}
|
|
|
|
|
2004-09-07 16:29:46 +04:00
|
|
|
friend class Item_trigger_field;
|
2004-11-24 12:24:02 +03:00
|
|
|
|
|
|
|
private:
|
2005-05-24 22:19:33 +04:00
|
|
|
bool prepare_record1_accessors(TABLE *table);
|
2004-09-07 16:29:46 +04:00
|
|
|
};
|