1
0
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:
unknown
2005-08-15 18:15:12 +03:00
parent 7cfb6540f7
commit a914b5274f
15 changed files with 505 additions and 111 deletions

View File

@ -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,