mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
Save and clear run context before executing a stored function or trigger and restore it afterwards.
This allows us to use statement replication with functions and triggers The following things are fixed with this patch: - NOW() and automatic timestamps takes the value from the main event for functions and triggers (which allows these to replicate with statement level logging) - No side effects for triggers or functions with auto-increment values(), last_insert_id(), rand() or found_rows() - Triggers can't return result sets Fixes bugs: #12480: NOW() is not constant in a trigger #12481: Using NOW() in a stored function breaks statement based replication #12482: Triggers has side effects with auto_increment values #11587: trigger causes lost connection error mysql-test/r/trigger.result: Added test fpr big mysql-test/t/sp-error.test: Changed error message numbers mysql-test/t/trigger.test: Added test for trigger returning result (#11587) sql/item_func.cc: Store the first used seed value for RAND() value. (This makes rand() replicatable in functions and triggers) Save and clear run context before executing a stored function and restore it afterwards. This removes side effects of stored functions for RAND(), auto-increment values and NOW() and makes most stored function replicatable sql/share/errmsg.txt: Reuse error message also for triggers sql/sp_head.cc: If in function or trigger, don't change value of NOW() (This allows us to use statement replication with functions that directly or indirectly uses timestamps) sql/sql_class.cc: Added framework for storing and retrieving run context while exceuting triggers or stored functions. sql/sql_class.h: Added framework for storing and retrieving run context while exceuting triggers or stored functions. sql/sql_parse.cc: If in function or trigger, don't change value of NOW() (This allows us to use statement replication with functions that directly or indirectly uses timestamps) sql/sql_trigger.cc: Moved process_triggers function from sql_trigger.h Use reset/restore sub_statement_state while executing triggers to avoid side effects and make them replicatable sql/sql_trigger.h: Moved process_triggers function from sql_trigger.h Use reset/restore sub_statement_state while executing triggers to avoid side effects and make them replicatable sql/sql_yacc.yy: Give error message if trigger can return a result set (Bug #11587) tests/fork_big2.pl: Removed return from end of lines mysql-test/r/rpl_trigger.result: New BitKeeper file ``mysql-test/r/rpl_trigger.result'' mysql-test/t/rpl_trigger.test: New BitKeeper file ``mysql-test/t/rpl_trigger.test''
This commit is contained in:
@ -20,6 +20,7 @@
|
||||
|
||||
QQ: Will it be merged into TABLE in future ?
|
||||
*/
|
||||
|
||||
class Table_triggers_list: public Sql_alloc
|
||||
{
|
||||
/* Triggers as SPs grouped by event, action_time */
|
||||
@ -76,55 +77,7 @@ public:
|
||||
bool drop_trigger(THD *thd, TABLE_LIST *table);
|
||||
bool process_triggers(THD *thd, trg_event_type event,
|
||||
trg_action_time_type time_type,
|
||||
bool old_row_is_record1)
|
||||
{
|
||||
int res= 0;
|
||||
|
||||
if (bodies[event][time_type])
|
||||
{
|
||||
bool save_in_sub_stmt= thd->in_sub_stmt;
|
||||
#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
|
||||
|
||||
if (old_row_is_record1)
|
||||
{
|
||||
old_field= record1_field;
|
||||
new_field= table->field;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_field= record1_field;
|
||||
old_field= table->field;
|
||||
}
|
||||
|
||||
/*
|
||||
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);
|
||||
thd->in_sub_stmt= TRUE;
|
||||
|
||||
res= bodies[event][time_type]->execute_function(thd, 0, 0, 0);
|
||||
|
||||
thd->in_sub_stmt= save_in_sub_stmt;
|
||||
reenable_binlog(thd);
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
thd->net.no_send_ok= nsok;
|
||||
#endif
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
bool old_row_is_record1);
|
||||
bool get_trigger_info(THD *thd, trg_event_type event,
|
||||
trg_action_time_type time_type,
|
||||
LEX_STRING *trigger_name, LEX_STRING *trigger_stmt,
|
||||
|
Reference in New Issue
Block a user