mariadb/mysql-test/r/trigger.result

2267 lines
68 KiB
Text
Raw Normal View History

Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
drop table if exists t1, t2, t3, t4;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop view if exists v1;
drop database if exists mysqltest;
Enable support of access to tables from triggers. Thus fix bug #8406 "Triggers crash if referencing a table" and several other related bugs. Fix for bug #11834 "Re-execution of prepared statement with dropped function crashes server." which was spotted during work on previous bugs. Also couple of nice cleanups: - Replaced two separate hashes for stored routines used by statement with one. - Now instead of doing one pass through all routines used in statement for caching them and then doing another pass for adding their tables to table list, we do only one pass during which do both things. mysql-test/r/sp-error.result: Added test for bug #11834 "Re-execution of prepared statement with dropped function crashes server" also covering handling of prepared statements which use stored functions but does not require prelocking. mysql-test/r/sp.result: Updated test for LOCK TABLES with views in table list. (Old version of statement used in this test will work ok now, since prelocking algorithm was tuned and will lock only one multi-set of tables for each routine even if this routine is used in several different views). mysql-test/r/trigger.result: Added several tests for triggers using tables. mysql-test/t/sp-error.test: Added test for bug #11834 "Re-execution of prepared statement with dropped function crashes server" also covering handling of prepared statements which use stored functions but does not require prelocking. mysql-test/t/sp.test: Updated comment about recursive views to reflect current situation. Updated test for LOCK TABLES with views in table list. (Old version of statement used in this test will work ok now, since prelocking algorithm was tuned and will lock only one multi-set of tables for each routine even if this routine is used in several different views). mysql-test/t/trigger.test: Added several tests for triggers using tables. sql/item_func.cc: Item_func_sp::cleanup(): By next statement execution stored function can be dropped or altered so we can't assume that sp_head object for it will be still valid. sql/sp.cc: - Added Sroutine_hash_entry structure that represents element in the set of stored routines used by statement or routine. We can't as before use LEX_STRING for this purprose because we want link all elements of this set in list. - Replaced sp_add_to_hash() with sp_add_used_routine() which takes into account that now we use one hash for stored routines used by statement instead of two and which mantains list linking all elelemnts in this hash. - Renamed sp_merge_hash() to sp_update_sp_used_routines(). - Introduced sp_update_stmt_used_routines() for adding elements to the set of routines used by statement from another similar set for statement or routine. This function will also mantain list linking elements of destination set. - Now instead of one sp_cache_routines() function we have family of sp_cache_routines_and_add_tables() functions which are also responsible for adding tables used by routines being cached to statement table list. Nice optimization - thanks to list linking all elements in the hash of routines used by statement we don't need to perform several iterations over this hash (as it was before in cases when we have added new elements to it). sql/sp.h: Added declarations of functions used for manipulations with set (hash) of stored routines used by statement. sql/sp_head.cc: sp_name::init_qname(): Now sp_name also holds key identifying routine in the set (hash) of stored routines used by statement. sp_head: Instead of two separate hashes sp_funs/m_spprocs representing sets of stored routines used by this routine we use one hash - m_sroutines. sp_instr_set_trigger_field: Added support for subqueries in assignments to row accessors in triggers. Removed definition of sp_add_sp_tables_to_table_list() and auxilary functions since now we don't have separate stage on which we add tables used by routines used by statement to table list for prelocking. We do it on the same stage as we load those routines in SP cache. So all this functionality moved to sp_cache_routines_and_add_tables() family of functions. sql/sp_head.h: sp_name: Now this class also holds key identifying routine in the set (hash) of stored routines used by statement. sp_head: Instead of two separate hashes sp_funs/m_spprocs representing sets of stored routines used by this routine we use one hash - m_sroutines. sp_instr_set_trigger_field: Added support for subqueries in assignments to row accessors in triggers. Removed declaration of sp_add_sp_tables_to_table_list() since now we don't have separate stage on which we add tables used by routines used by statement to table list for prelocking. We do it on the same stage as we load those routines in SP cache. sql/sql_base.cc: open_tables(): - LEX::spfuns/spprocs hashes were replaced with one LEX::sroutines hash. - Now instead of doing one pass through all routines used in statement for caching them and then doing another pass for adding their tables to table list, we do only one pass during which do both things. It is easy to do since all routines in the set of routines used by statement are linked in the list. This also allows us to calculate table list for prelocking more precisely. - Now triggers properly inform prelocking algorithm about tables they use. sql/sql_lex.cc: lex_start(): Replaced LEX::spfuns/spprocs with with one LEX::sroutines hash. Added LEX::sroutines_list list linking all elements in this hash. st_lex::st_lex(): Moved definition of LEX constructor to sql_lex.cc file to be able use sp_sroutine_key declaration from sp.h in it. sql/sql_lex.h: LEX: Replaced two separate hashes for stored routines used by statement with one. Added list linking all elements in this hash to be able to iterate through all elements and add new elements to this hash at the same time. Moved constructor definition to sql_lex.cc. sql/sql_parse.cc: mysql_execute_command(): Replaced LEX::spfuns/spprocs with one LEX::sroutines hash. sql/sql_trigger.cc: Added missing GNU GPL notice. Table_triggers_list::check_n_load() Added initialization of sroutines_key which stores key representing triggers of this table in the set (hash) of routines used by this statement. sql/sql_trigger.h: Added missing GNU GPL notice. Table_triggers_list: Added sroutines_key member to store key representing triggers of this table in the set (hash) of routines used by this statement. Declared sp_cache_routines_and_add_tables_for_triggers() as friend since it needs access to sroutines_key and trigger bodies. sql/sql_yacc.yy: - Now we use sp_add_used_routine() instead of sp_add_to_hash() for adding elements to the set of stored routines used in statement. - Enabled support of subqueries as right sides in assignments to triggers' row accessors.
2005-07-09 19:51:59 +02:00
drop function if exists f1;
drop function if exists f2;
Fix for bug #12280 "Triggers: crash if flush tables". We should not allow FLUSH statement to be executed inside both triggers and stored functions. mysql-test/r/sp-error.result: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/r/trigger.result: Added test for bug #12280 "Triggers: crash if flush tables" mysql-test/t/sp-error.test: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/t/trigger.test: Added test for bug #12280 "Triggers: crash if flush tables" sql/share/errmsg.txt: Removed ER_SP_NO_USE error. Now we use more general ER_SP_BADSTATEMENT in this case. Instead added error message for barking about statements which should not be allowed inside of stored functions or triggers. It is safe to do this since it is highly unprobable that someone will upgrade first to the new 5.0 release and then downgrade back to the old one. sql/sql_parse.cc: reload_acl_and_cache(): FLUSH TABLES and FLUSH PRIVILEGES should not be allowed if we are inside of stored function or trigger. sql/sql_yacc.yy: We should not allow FLUSH statement inside both triggers and stored functions. Replaced error which is thrown in this case with more specific. Also now we issue more general ER_SP_BADSTATEMENT error when one tries to use USE command inside of stored routine.
2005-08-10 08:31:32 +02:00
drop procedure if exists p1;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
create table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1;
set @a:=0;
select @a;
@a
0
insert into t1 values (1);
select @a;
@a
1
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
create trigger trg before insert on t1 for each row set @a:=new.i;
insert into t1 values (123);
select @a;
@a
123
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1;
create table t1 (i int not null, j int);
create trigger trg before insert on t1 for each row
begin
if isnull(new.j) then
set new.j:= new.i * 10;
end if;
end|
insert into t1 (i) values (1)|
insert into t1 (i,j) values (2, 3)|
select * from t1|
i j
1 10
2 3
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg|
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1|
create table t1 (i int not null primary key);
create trigger trg after insert on t1 for each row
set @a:= if(@a,concat(@a, ":", new.i), new.i);
set @a:="";
insert into t1 values (2),(3),(4),(5);
select @a;
@a
2:3:4:5
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1;
create table t1 (aid int not null primary key, balance int not null default 0);
insert into t1 values (1, 1000), (2,3000);
create trigger trg before update on t1 for each row
begin
declare loc_err varchar(255);
if abs(new.balance - old.balance) > 1000 then
set new.balance:= old.balance;
set loc_err := concat("Too big change for aid = ", new.aid);
set @update_failed:= if(@update_failed, concat(@a, ":", loc_err), loc_err);
end if;
end|
set @update_failed:=""|
update t1 set balance=1500|
select @update_failed;
select * from t1|
@update_failed
Too big change for aid = 2
aid balance
1 1500
2 3000
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg|
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1|
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
create trigger trg after update on t1 for each row
set @total_change:=@total_change + new.i - old.i;
set @total_change:=0;
update t1 set i=3;
select @total_change;
@total_change
2
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1;
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
create trigger trg before delete on t1 for each row
set @del_sum:= @del_sum + old.i;
set @del_sum:= 0;
delete from t1 where i <= 3;
select @del_sum;
@del_sum
6
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1;
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
create trigger trg after delete on t1 for each row set @del:= 1;
set @del:= 0;
delete from t1 where i <> 0;
select @del;
@del
1
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1;
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
begin
if new.j > 10 then
set new.j := 10;
end if;
end|
create trigger trg2 before update on t1 for each row
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end|
create trigger trg3 after update on t1 for each row
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end|
set @fired:="";
insert into t1 values (1,2),(2,3),(3,14);
select @fired;
@fired
select * from t1;
i j
1 2
2 3
3 10
update t1 set j= 20;
select @fired;
@fired
Yes
select * from t1;
i j
1 20
2 -1
3 20
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg1;
drop trigger trg2;
drop trigger trg3;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop table t1;
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
create table t1 (id int not null primary key, data int);
create trigger t1_bi before insert on t1 for each row
set @log:= concat(@log, "(BEFORE_INSERT: new=(id=", new.id, ", data=", new.data,"))");
create trigger t1_ai after insert on t1 for each row
set @log:= concat(@log, "(AFTER_INSERT: new=(id=", new.id, ", data=", new.data,"))");
create trigger t1_bu before update on t1 for each row
set @log:= concat(@log, "(BEFORE_UPDATE: old=(id=", old.id, ", data=", old.data,
") new=(id=", new.id, ", data=", new.data,"))");
create trigger t1_au after update on t1 for each row
set @log:= concat(@log, "(AFTER_UPDATE: old=(id=", old.id, ", data=", old.data,
") new=(id=", new.id, ", data=", new.data,"))");
create trigger t1_bd before delete on t1 for each row
set @log:= concat(@log, "(BEFORE_DELETE: old=(id=", old.id, ", data=", old.data,"))");
create trigger t1_ad after delete on t1 for each row
set @log:= concat(@log, "(AFTER_DELETE: old=(id=", old.id, ", data=", old.data,"))");
set @log:= "";
insert into t1 values (1, 1);
select @log;
@log
(BEFORE_INSERT: new=(id=1, data=1))(AFTER_INSERT: new=(id=1, data=1))
set @log:= "";
insert ignore t1 values (1, 2);
Fix for MDEV-533: Confusing error code when doing auto-increment insert for out-of-range values create table t1 (a smallint primary key auto_increment); insert into t1 values(32767); insert into t1 values(NULL); ERROR 1062 (23000): Duplicate entry '32767' for key 'PRIMARY Now on always gets error HA_ERR_AUTOINC_RANGE=167 "Out of range value for column", independent of store engine, SQL Mode or number of inserted rows. This is an unique error that is easier to test for in replication. Another bug fix is that we now get an error when trying to insert a too big auto-generated value, even in non-strict mode. Before one get insted the max column value inserted. This patch also fixes some issues with inserting negative numbers in an auto-increment column. Fixed the ER_DUP_ENTRY and HA_ERR_AUTOINC_ERANGE are compared the same between master and slave. This ensures that replication works between an old server to a new slave for auto-increment overflow errors. Added SQLSTATE errors for handler errors Smaller bug fixes: * Added warnings for duplicate key errors when using INSERT IGNORE * Fixed bug when using --skip-log-bin followed by --log-bin, which did set log-bin to "0" * Allow one to see how cmake is called by using --just-print --just-configure BUILD/FINISH.sh: --just-print --just-configure now shows how cmake would be invoked. Good for understanding parameters to cmake. cmake/configure.pl: --just-print --just-configure now shows how cmake would be invoked. Good for understanding parameters to cmake. include/CMakeLists.txt: Added handler_state.h include/handler_state.h: SQLSTATE for handler error messages. Required for HA_ERR_AUTOINC_ERANGE, but solves also some other cases. mysql-test/extra/binlog_tests/binlog.test: Fixed old wrong behaviour Added more tests mysql-test/extra/binlog_tests/binlog_insert_delayed.test: Reset binary log to only print what's necessary in show_binlog_events mysql-test/extra/rpl_tests/rpl_auto_increment.test: Update to new error codes mysql-test/extra/rpl_tests/rpl_insert_delayed.test: Ignore warnings as this depends on how the test is run mysql-test/include/strict_autoinc.inc: On now gets an error on overflow mysql-test/r/auto_increment.result: Update results after fixing error message mysql-test/r/auto_increment_ranges_innodb.result: Test new behaviour mysql-test/r/auto_increment_ranges_myisam.result: Test new behaviour mysql-test/r/commit_1innodb.result: Added warnings for duplicate key error mysql-test/r/create.result: Added warnings for duplicate key error mysql-test/r/insert.result: Added warnings for duplicate key error mysql-test/r/insert_select.result: Added warnings for duplicate key error mysql-test/r/insert_update.result: Added warnings for duplicate key error mysql-test/r/mix2_myisam.result: Added warnings for duplicate key error mysql-test/r/myisam_mrr.result: Added warnings for duplicate key error mysql-test/r/null_key.result: Added warnings for duplicate key error mysql-test/r/replace.result: Update to new error codes mysql-test/r/strict_autoinc_1myisam.result: Update to new error codes mysql-test/r/strict_autoinc_2innodb.result: Update to new error codes mysql-test/r/strict_autoinc_3heap.result: Update to new error codes mysql-test/r/trigger.result: Added warnings for duplicate key error mysql-test/r/xtradb_mrr.result: Added warnings for duplicate key error mysql-test/suite/binlog/r/binlog_innodb_row.result: Updated result mysql-test/suite/binlog/r/binlog_row_binlog.result: Out of range data for auto-increment is not inserted anymore mysql-test/suite/binlog/r/binlog_statement_insert_delayed.result: Updated result mysql-test/suite/binlog/r/binlog_stm_binlog.result: Out of range data for auto-increment is not inserted anymore mysql-test/suite/binlog/r/binlog_unsafe.result: Updated result mysql-test/suite/innodb/r/innodb-autoinc.result: Update to new error codes mysql-test/suite/innodb/r/innodb-lock.result: Updated results mysql-test/suite/innodb/r/innodb.result: Updated results mysql-test/suite/innodb/r/innodb_bug56947.result: Updated results mysql-test/suite/innodb/r/innodb_mysql.result: Updated results mysql-test/suite/innodb/t/innodb-autoinc.test: Update to new error codes mysql-test/suite/maria/maria3.result: Updated result mysql-test/suite/maria/mrr.result: Updated result mysql-test/suite/optimizer_unfixed_bugs/r/bug43617.result: Updated result mysql-test/suite/rpl/r/rpl_auto_increment.result: Update to new error codes mysql-test/suite/rpl/r/rpl_insert_delayed,stmt.rdiff: Updated results mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Updated results mysql-test/t/auto_increment.test: Update to new error codes mysql-test/t/auto_increment_ranges.inc: Test new behaviour mysql-test/t/auto_increment_ranges_innodb.test: Test new behaviour mysql-test/t/auto_increment_ranges_myisam.test: Test new behaviour mysql-test/t/replace.test: Update to new error codes mysys/my_getopt.c: Fixed bug when using --skip-log-bin followed by --log-bin, which did set log-bin to "0" sql/handler.cc: Ignore negative values for signed auto-increment columns Always give an error if we get an overflow for an auto-increment-column (instead of inserting the max value) Ensure that the row number is correct for the out-of-range-value error message. ****** Fixed wrong printing of column namn for "Out of range value" errors Fixed that INSERT_ID is correctly replicated also for out-of-range autoincrement values Fixed that print_keydup_error() can also be used to generate warnings ****** Return HA_ERR_AUTOINC_ERANGE (167) instead of ER_WARN_DATA_OUT_OF_RANGE for auto-increment overflow sql/handler.h: Allow INSERT IGNORE to continue also after out-of-range inserts. Fixed that print_keydup_error() can also be used to generate warnings sql/log_event.cc: Added DBUG_PRINT Fixed the ER_AUTOINC_READ_FAILED, ER_DUP_ENTRY and HA_ERR_AUTOINC_ERANGE are compared the same between master and slave. This ensures that replication works between an old server to a new slave for auto-increment overflow errors. sql/sql_insert.cc: Add warnings for duplicate key errors when using INSERT IGNORE sql/sql_state.c: Added handler errors sql/sql_table.cc: Update call to print_keydup_error() storage/innobase/handler/ha_innodb.cc: Fixed increment handling of auto-increment columns to be consistent with rest of MariaDB. storage/xtradb/handler/ha_innodb.cc: Fixed increment handling of auto-increment columns to be consistent with rest of MariaDB.
2012-09-18 14:14:19 +02:00
Warnings:
Warning 1062 Duplicate entry '1' for key 'PRIMARY'
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
select @log;
@log
(BEFORE_INSERT: new=(id=1, data=2))
set @log:= "";
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
insert into t1 (id, data) values (1, 3), (2, 2) on duplicate key update data= data + 1;
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
select @log;
@log
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
(BEFORE_INSERT: new=(id=1, data=3))(BEFORE_UPDATE: old=(id=1, data=1) new=(id=1, data=2))(AFTER_UPDATE: old=(id=1, data=1) new=(id=1, data=2))(BEFORE_INSERT: new=(id=2, data=2))(AFTER_INSERT: new=(id=2, data=2))
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
set @log:= "";
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
replace t1 values (1, 4), (3, 3);
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
select @log;
@log
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
(BEFORE_INSERT: new=(id=1, data=4))(BEFORE_DELETE: old=(id=1, data=2))(AFTER_DELETE: old=(id=1, data=2))(AFTER_INSERT: new=(id=1, data=4))(BEFORE_INSERT: new=(id=3, data=3))(AFTER_INSERT: new=(id=3, data=3))
drop trigger t1_bd;
drop trigger t1_ad;
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
set @log:= "";
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
replace t1 values (1, 5);
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
select @log;
@log
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
(BEFORE_INSERT: new=(id=1, data=5))(AFTER_INSERT: new=(id=1, data=5))
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
drop table t1;
Enable support of access to tables from triggers. Thus fix bug #8406 "Triggers crash if referencing a table" and several other related bugs. Fix for bug #11834 "Re-execution of prepared statement with dropped function crashes server." which was spotted during work on previous bugs. Also couple of nice cleanups: - Replaced two separate hashes for stored routines used by statement with one. - Now instead of doing one pass through all routines used in statement for caching them and then doing another pass for adding their tables to table list, we do only one pass during which do both things. mysql-test/r/sp-error.result: Added test for bug #11834 "Re-execution of prepared statement with dropped function crashes server" also covering handling of prepared statements which use stored functions but does not require prelocking. mysql-test/r/sp.result: Updated test for LOCK TABLES with views in table list. (Old version of statement used in this test will work ok now, since prelocking algorithm was tuned and will lock only one multi-set of tables for each routine even if this routine is used in several different views). mysql-test/r/trigger.result: Added several tests for triggers using tables. mysql-test/t/sp-error.test: Added test for bug #11834 "Re-execution of prepared statement with dropped function crashes server" also covering handling of prepared statements which use stored functions but does not require prelocking. mysql-test/t/sp.test: Updated comment about recursive views to reflect current situation. Updated test for LOCK TABLES with views in table list. (Old version of statement used in this test will work ok now, since prelocking algorithm was tuned and will lock only one multi-set of tables for each routine even if this routine is used in several different views). mysql-test/t/trigger.test: Added several tests for triggers using tables. sql/item_func.cc: Item_func_sp::cleanup(): By next statement execution stored function can be dropped or altered so we can't assume that sp_head object for it will be still valid. sql/sp.cc: - Added Sroutine_hash_entry structure that represents element in the set of stored routines used by statement or routine. We can't as before use LEX_STRING for this purprose because we want link all elements of this set in list. - Replaced sp_add_to_hash() with sp_add_used_routine() which takes into account that now we use one hash for stored routines used by statement instead of two and which mantains list linking all elelemnts in this hash. - Renamed sp_merge_hash() to sp_update_sp_used_routines(). - Introduced sp_update_stmt_used_routines() for adding elements to the set of routines used by statement from another similar set for statement or routine. This function will also mantain list linking elements of destination set. - Now instead of one sp_cache_routines() function we have family of sp_cache_routines_and_add_tables() functions which are also responsible for adding tables used by routines being cached to statement table list. Nice optimization - thanks to list linking all elements in the hash of routines used by statement we don't need to perform several iterations over this hash (as it was before in cases when we have added new elements to it). sql/sp.h: Added declarations of functions used for manipulations with set (hash) of stored routines used by statement. sql/sp_head.cc: sp_name::init_qname(): Now sp_name also holds key identifying routine in the set (hash) of stored routines used by statement. sp_head: Instead of two separate hashes sp_funs/m_spprocs representing sets of stored routines used by this routine we use one hash - m_sroutines. sp_instr_set_trigger_field: Added support for subqueries in assignments to row accessors in triggers. Removed definition of sp_add_sp_tables_to_table_list() and auxilary functions since now we don't have separate stage on which we add tables used by routines used by statement to table list for prelocking. We do it on the same stage as we load those routines in SP cache. So all this functionality moved to sp_cache_routines_and_add_tables() family of functions. sql/sp_head.h: sp_name: Now this class also holds key identifying routine in the set (hash) of stored routines used by statement. sp_head: Instead of two separate hashes sp_funs/m_spprocs representing sets of stored routines used by this routine we use one hash - m_sroutines. sp_instr_set_trigger_field: Added support for subqueries in assignments to row accessors in triggers. Removed declaration of sp_add_sp_tables_to_table_list() since now we don't have separate stage on which we add tables used by routines used by statement to table list for prelocking. We do it on the same stage as we load those routines in SP cache. sql/sql_base.cc: open_tables(): - LEX::spfuns/spprocs hashes were replaced with one LEX::sroutines hash. - Now instead of doing one pass through all routines used in statement for caching them and then doing another pass for adding their tables to table list, we do only one pass during which do both things. It is easy to do since all routines in the set of routines used by statement are linked in the list. This also allows us to calculate table list for prelocking more precisely. - Now triggers properly inform prelocking algorithm about tables they use. sql/sql_lex.cc: lex_start(): Replaced LEX::spfuns/spprocs with with one LEX::sroutines hash. Added LEX::sroutines_list list linking all elements in this hash. st_lex::st_lex(): Moved definition of LEX constructor to sql_lex.cc file to be able use sp_sroutine_key declaration from sp.h in it. sql/sql_lex.h: LEX: Replaced two separate hashes for stored routines used by statement with one. Added list linking all elements in this hash to be able to iterate through all elements and add new elements to this hash at the same time. Moved constructor definition to sql_lex.cc. sql/sql_parse.cc: mysql_execute_command(): Replaced LEX::spfuns/spprocs with one LEX::sroutines hash. sql/sql_trigger.cc: Added missing GNU GPL notice. Table_triggers_list::check_n_load() Added initialization of sroutines_key which stores key representing triggers of this table in the set (hash) of routines used by this statement. sql/sql_trigger.h: Added missing GNU GPL notice. Table_triggers_list: Added sroutines_key member to store key representing triggers of this table in the set (hash) of routines used by this statement. Declared sp_cache_routines_and_add_tables_for_triggers() as friend since it needs access to sroutines_key and trigger bodies. sql/sql_yacc.yy: - Now we use sp_add_used_routine() instead of sp_add_to_hash() for adding elements to the set of stored routines used in statement. - Enabled support of subqueries as right sides in assignments to triggers' row accessors.
2005-07-09 19:51:59 +02:00
create table t1 (id int primary key, data varchar(10), fk int);
create table t2 (event varchar(100));
create table t3 (id int primary key);
create trigger t1_ai after insert on t1 for each row
insert into t2 values (concat("INSERT INTO t1 id=", new.id, " data='", new.data, "'"));
insert into t1 (id, data) values (1, "one"), (2, "two");
select * from t1;
id data fk
1 one NULL
2 two NULL
select * from t2;
event
INSERT INTO t1 id=1 data='one'
INSERT INTO t1 id=2 data='two'
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger t1_ai;
Enable support of access to tables from triggers. Thus fix bug #8406 "Triggers crash if referencing a table" and several other related bugs. Fix for bug #11834 "Re-execution of prepared statement with dropped function crashes server." which was spotted during work on previous bugs. Also couple of nice cleanups: - Replaced two separate hashes for stored routines used by statement with one. - Now instead of doing one pass through all routines used in statement for caching them and then doing another pass for adding their tables to table list, we do only one pass during which do both things. mysql-test/r/sp-error.result: Added test for bug #11834 "Re-execution of prepared statement with dropped function crashes server" also covering handling of prepared statements which use stored functions but does not require prelocking. mysql-test/r/sp.result: Updated test for LOCK TABLES with views in table list. (Old version of statement used in this test will work ok now, since prelocking algorithm was tuned and will lock only one multi-set of tables for each routine even if this routine is used in several different views). mysql-test/r/trigger.result: Added several tests for triggers using tables. mysql-test/t/sp-error.test: Added test for bug #11834 "Re-execution of prepared statement with dropped function crashes server" also covering handling of prepared statements which use stored functions but does not require prelocking. mysql-test/t/sp.test: Updated comment about recursive views to reflect current situation. Updated test for LOCK TABLES with views in table list. (Old version of statement used in this test will work ok now, since prelocking algorithm was tuned and will lock only one multi-set of tables for each routine even if this routine is used in several different views). mysql-test/t/trigger.test: Added several tests for triggers using tables. sql/item_func.cc: Item_func_sp::cleanup(): By next statement execution stored function can be dropped or altered so we can't assume that sp_head object for it will be still valid. sql/sp.cc: - Added Sroutine_hash_entry structure that represents element in the set of stored routines used by statement or routine. We can't as before use LEX_STRING for this purprose because we want link all elements of this set in list. - Replaced sp_add_to_hash() with sp_add_used_routine() which takes into account that now we use one hash for stored routines used by statement instead of two and which mantains list linking all elelemnts in this hash. - Renamed sp_merge_hash() to sp_update_sp_used_routines(). - Introduced sp_update_stmt_used_routines() for adding elements to the set of routines used by statement from another similar set for statement or routine. This function will also mantain list linking elements of destination set. - Now instead of one sp_cache_routines() function we have family of sp_cache_routines_and_add_tables() functions which are also responsible for adding tables used by routines being cached to statement table list. Nice optimization - thanks to list linking all elements in the hash of routines used by statement we don't need to perform several iterations over this hash (as it was before in cases when we have added new elements to it). sql/sp.h: Added declarations of functions used for manipulations with set (hash) of stored routines used by statement. sql/sp_head.cc: sp_name::init_qname(): Now sp_name also holds key identifying routine in the set (hash) of stored routines used by statement. sp_head: Instead of two separate hashes sp_funs/m_spprocs representing sets of stored routines used by this routine we use one hash - m_sroutines. sp_instr_set_trigger_field: Added support for subqueries in assignments to row accessors in triggers. Removed definition of sp_add_sp_tables_to_table_list() and auxilary functions since now we don't have separate stage on which we add tables used by routines used by statement to table list for prelocking. We do it on the same stage as we load those routines in SP cache. So all this functionality moved to sp_cache_routines_and_add_tables() family of functions. sql/sp_head.h: sp_name: Now this class also holds key identifying routine in the set (hash) of stored routines used by statement. sp_head: Instead of two separate hashes sp_funs/m_spprocs representing sets of stored routines used by this routine we use one hash - m_sroutines. sp_instr_set_trigger_field: Added support for subqueries in assignments to row accessors in triggers. Removed declaration of sp_add_sp_tables_to_table_list() since now we don't have separate stage on which we add tables used by routines used by statement to table list for prelocking. We do it on the same stage as we load those routines in SP cache. sql/sql_base.cc: open_tables(): - LEX::spfuns/spprocs hashes were replaced with one LEX::sroutines hash. - Now instead of doing one pass through all routines used in statement for caching them and then doing another pass for adding their tables to table list, we do only one pass during which do both things. It is easy to do since all routines in the set of routines used by statement are linked in the list. This also allows us to calculate table list for prelocking more precisely. - Now triggers properly inform prelocking algorithm about tables they use. sql/sql_lex.cc: lex_start(): Replaced LEX::spfuns/spprocs with with one LEX::sroutines hash. Added LEX::sroutines_list list linking all elements in this hash. st_lex::st_lex(): Moved definition of LEX constructor to sql_lex.cc file to be able use sp_sroutine_key declaration from sp.h in it. sql/sql_lex.h: LEX: Replaced two separate hashes for stored routines used by statement with one. Added list linking all elements in this hash to be able to iterate through all elements and add new elements to this hash at the same time. Moved constructor definition to sql_lex.cc. sql/sql_parse.cc: mysql_execute_command(): Replaced LEX::spfuns/spprocs with one LEX::sroutines hash. sql/sql_trigger.cc: Added missing GNU GPL notice. Table_triggers_list::check_n_load() Added initialization of sroutines_key which stores key representing triggers of this table in the set (hash) of routines used by this statement. sql/sql_trigger.h: Added missing GNU GPL notice. Table_triggers_list: Added sroutines_key member to store key representing triggers of this table in the set (hash) of routines used by this statement. Declared sp_cache_routines_and_add_tables_for_triggers() as friend since it needs access to sroutines_key and trigger bodies. sql/sql_yacc.yy: - Now we use sp_add_used_routine() instead of sp_add_to_hash() for adding elements to the set of stored routines used in statement. - Enabled support of subqueries as right sides in assignments to triggers' row accessors.
2005-07-09 19:51:59 +02:00
create trigger t1_bi before insert on t1 for each row
begin
if exists (select id from t3 where id=new.fk) then
insert into t2 values (concat("INSERT INTO t1 id=", new.id, " data='", new.data, "' fk=", new.fk));
else
insert into t2 values (concat("INSERT INTO t1 FAILED id=", new.id, " data='", new.data, "' fk=", new.fk));
set new.id= NULL;
end if;
end|
insert into t3 values (1);
insert into t1 values (4, "four", 1), (5, "five", 2);
ERROR 23000: Column 'id' cannot be null
select * from t1;
id data fk
1 one NULL
2 two NULL
4 four 1
select * from t2;
event
INSERT INTO t1 id=1 data='one'
INSERT INTO t1 id=2 data='two'
INSERT INTO t1 id=4 data='four' fk=1
INSERT INTO t1 FAILED id=5 data='five' fk=2
drop table t1, t2, t3;
create table t1 (id int primary key, data varchar(10));
create table t2 (seq int);
insert into t2 values (10);
create function f1 () returns int return (select max(seq) from t2);
create trigger t1_bi before insert on t1 for each row
begin
if new.id > f1() then
set new.id:= f1();
end if;
end|
insert into t1 values (1, "first");
insert into t1 values (f1(), "max");
select * from t1;
id data
1 first
10 max
drop table t1, t2;
drop function f1;
create table t1 (id int primary key, fk_t2 int);
create table t2 (id int primary key, fk_t3 int);
create table t3 (id int primary key);
insert into t1 values (1,1), (2,1), (3,2);
insert into t2 values (1,1), (2,2);
insert into t3 values (1), (2);
create trigger t3_ad after delete on t3 for each row
delete from t2 where fk_t3=old.id;
create trigger t2_ad after delete on t2 for each row
delete from t1 where fk_t2=old.id;
delete from t3 where id = 1;
select * from t1 left join (t2 left join t3 on t2.fk_t3 = t3.id) on t1.fk_t2 = t2.id;
id fk_t2 id fk_t3 id
3 2 2 2 2
drop table t1, t2, t3;
create table t1 (id int primary key, copy int);
create table t2 (id int primary key, data int);
insert into t2 values (1,1), (2,2);
create trigger t1_bi before insert on t1 for each row
set new.copy= (select data from t2 where id = new.id);
create trigger t1_bu before update on t1 for each row
set new.copy= (select data from t2 where id = new.id);
insert into t1 values (1,3), (2,4), (3,3);
update t1 set copy= 1 where id = 2;
select * from t1;
id copy
1 1
2 2
3 NULL
drop table t1, t2;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
create table t1 (i int);
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
create table t3 (i int);
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
create trigger trg before insert on t1 for each row set @a:= old.i;
ERROR HY000: There is no OLD row in on INSERT trigger
create trigger trg before delete on t1 for each row set @a:= new.i;
ERROR HY000: There is no NEW row in on DELETE trigger
create trigger trg before update on t1 for each row set old.i:=1;
ERROR HY000: Updating of OLD row is not allowed in trigger
create trigger trg before delete on t1 for each row set new.i:=1;
ERROR HY000: There is no NEW row in on DELETE trigger
create trigger trg after update on t1 for each row set new.i:=1;
ERROR HY000: Updating of NEW row is not allowed in after trigger
Fix for bug #5888 "Triggers with nonexistent columns cause packets out of order". (final version) Now instead of binding Item_trigger_field to TABLE objects during trigger definition parsing at table open, we perform pass through special list of all such objects in trigger. This allows easily check all references to fields in old/new version of row in trigger during execution of CREATE TRIGGER statement (this is more courtesy for users since we can't check everything anyway). We also report that such reference is bad by returning error from Item_trigger_field::fix_fields() method (instead of setup_field()) This means that if trigger is broken we will bark during trigger execution instead of trigger definition parsing at table open. (i.e. now we allow to open tables with broken triggers). mysql-test/r/trigger.result: Added test which attempts to create trigger for table referencing to field which does not exist in this table. mysql-test/t/trigger.test: Added test which attempts to create trigger for table referencing to field which does not exist in this table. sql/item.cc: Item_trigger_field::setup_field() now returns void. If any error will occur we will report it at fix_fields() stage. sql/item.h: Item_trigger_field: - Added next_trg_field member for linking all such objects in trigger in one list. - Also setup_field() now returns void. If any error will occur we will report it at fix_fields() stage. sql/mysql_priv.h: Added SQL_LIST::push_back() method which allows to add another SQL_LIST to the end of this SQL_LIST. sql/sp_head.cc: sp_head::init()/reset_lex()/restore_lex(): In order to fill global LEX::trg_table_fields (list of all Item_trigger_field objects for trigger) we should init the same list in LEX of substatement before its parsing and merge it to global list after parsing. sql/sp_head.h: sp_instr_trigger_field: Made trigger_field member public to be able to add it more easily to global list of all Item_trigger_field objects in trigger. sql/sql_lex.cc: LEX::trg_table was removed. sql/sql_lex.h: Now we are binding Item_trigger_field's to TABLE object by passing through specially constructed list of all such objects in this trigger instead of doing this during trigger definition parsing at table open. So we no longer need LEX::trg_table, we use LEX::trg_table_fields list instead. sql/sql_parse.cc: mysql_execute_command(): Since now we use trigger body for some checks in mysql_create_or_drop_trigger() we should destroy it only after calling this function. sql/sql_trigger.cc: Now instead of binding Item_trigger_field to TABLE objects during trigger definition parsing at table open, we perform pass through special list of all such objects in trigger. This allows easily check all references to fields in old/new version of row in trigger during execution of CREATE TRIGGER statement (this is more courtesy for users since we can't check everything anyway). We also report that such reference is bad by returning error from Item_trigger_field::fix_fields() method (instead of setup_field()) This means that if trigger is broken we will bark during trigger execution instead of trigger definition parsing at table open. (i.e. now we allow to open tables with broken triggers). Table_triggers_list::prepare_old_row_accessors() method was added to be able to reuse code creating Field objects referencing TABLE::record[1] buffer instead of TABLE::record[0]. sql/sql_trigger.h: Added Table_triggers_list::prepare_old_row_accessors() method to be able to reuse code creating Field objects referencing to TABLE::record[1] instead of record[0]. sql/sql_yacc.yy: Now instead of performing binding of Item_trigger_field objects to TABLE object during trigger definition parsing at table open, we perform this binding by passing through specially constructed list of all such items in trigger. We also check value returned from memory allocation functions.
2004-11-24 10:24:02 +01:00
create trigger trg before update on t1 for each row set new.j:=1;
ERROR 42S22: Unknown column 'j' in 'NEW'
create trigger trg before update on t1 for each row set @a:=old.j;
ERROR 42S22: Unknown column 'j' in 'OLD'
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
create trigger trg before insert on t2 for each row set @a:=1;
ERROR 42S02: Table 'test.t2' doesn't exist
create trigger trg before insert on t1 for each row set @a:=1;
create trigger trg after insert on t1 for each row set @a:=1;
ERROR HY000: Trigger already exists
create trigger trg2 before insert on t1 for each row set @a:=1;
ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table'
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
create trigger trg before insert on t3 for each row set @a:=1;
ERROR HY000: Trigger already exists
create trigger trg2 before insert on t3 for each row set @a:=1;
drop trigger trg2;
drop trigger trg;
drop trigger trg;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
ERROR HY000: Trigger does not exist
create view v1 as select * from t1;
create trigger trg before insert on v1 for each row set @a:=1;
ERROR HY000: 'test.v1' is not BASE TABLE
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
drop view v1;
drop table t1;
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop table t3;
WL#1218 "Triggers". Some very preliminary version of patch. Mostly needed for Monty for him getting notion what needed for triggers from new .FRM format. Things to be done: - Right placement of trigger's invocations - Right handling of errors in triggers (including transaction rollback) - Support for priviliges - Right handling of DROP/RENAME table (hope that it will be handled automatically with merging of .TRG into .FRM file) - Saving/restoring some information critical for trigger creation and replication with their definitions (e.g. sql_mode, creator, ...) - Replication Already has some known bugs so probably not for general review. include/mysqld_error.h: Added trigger related error codes. sql/Makefile.am: Added sql_trigger.* files to list of sources from which mysqld is built. sql/item.cc: Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item.h: Added enums for describing trigger properties. (Here because of dependencies). Added Item_trigger_field class representing field of new/old version of row which is inserted/updated/deleted and for which trigger is invoked. sql/item_func.cc: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. Added comment clarifying why we don't need set no_send_ok when calling stored functions. sql/item_func.h: Added Item_func_set_user_var::print_as_stmt() for printing of assignment to ser variable from stored procedures. sql/lex.h: Symbols used in statements defining triggers were added. sql/mysql_priv.h: Exported some functions needed for triggers implementation. sql/parse_file.cc: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/parse_file.h: Cleaned up FILE_OPTIONS_STRLIST handling (needed for triggers). sql/share/czech/errmsg.txt: Added trigger related error messages. sql/share/danish/errmsg.txt: Added trigger related error messages. sql/share/dutch/errmsg.txt: Added trigger related error messages. sql/share/english/errmsg.txt: Added trigger related error messages. sql/share/estonian/errmsg.txt: Added trigger related error messages. sql/share/french/errmsg.txt: Added trigger related error messages. sql/share/german/errmsg.txt: Added trigger related error messages. sql/share/greek/errmsg.txt: Added trigger related error messages. sql/share/hungarian/errmsg.txt: Added trigger related error messages. sql/share/italian/errmsg.txt: Added trigger related error messages. sql/share/japanese/errmsg.txt: Added trigger related error messages. sql/share/korean/errmsg.txt: Added trigger related error messages. sql/share/norwegian-ny/errmsg.txt: Added trigger related error messages. sql/share/norwegian/errmsg.txt: Added trigger related error messages. sql/share/polish/errmsg.txt: Added trigger related error messages. sql/share/portuguese/errmsg.txt: Added trigger related error messages. sql/share/romanian/errmsg.txt: Added trigger related error messages. sql/share/russian/errmsg.txt: Added trigger related error messages. sql/share/serbian/errmsg.txt: Added trigger related error messages. sql/share/slovak/errmsg.txt: Added trigger related error messages. sql/share/spanish/errmsg.txt: Added trigger related error messages. sql/share/swedish/errmsg.txt: Added trigger related error messages. sql/share/ukrainian/errmsg.txt: Added trigger related error messages. sql/sp_head.cc: sp_head::init_strings(): added support for triggers (we don't have most of strings for them) sp_head::execute_function(): triggers don't require RETURN sp_head::reset_lex(): added propagation of trigger properties to LEX used for parsing of statements composing trigger body. Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sp_head.h: Added new type of sp_head object - TYPE_ENUM_TRIGGER Added two more SP instructions: - sp_instr_set_user_var for setting user variables in stored functions and triggers (we can't use sp_instr_stmt and "SET @a:=..." statement since it will close open tables and thus break execution of calling statement. - sp_instr_set_trigger_field for assignment to fields of row being updated/inserted in triggers sql/sql_base.cc: Now freeing memory occupied by trigger related structures when closing tables. open_unireg_entry(): added loading of triggers for table. find_field_in_real_table() is now public since it required by Item_trigger_field in item.cc sql/sql_delete.cc: Added triggers invocation for DELETE (should be fixed for sure :)) sql/sql_insert.cc: Added triggers invocation for INSERT (should be fixed for sure :)) sql/sql_lex.cc: Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added initialization of LEX->trg_table to lex_start(). (When triggers are parsed during opening of table it points to table object.) sql/sql_lex.h: Added trigger related commands. Added st_trg_chistics structure describing properties of trigger being created (as struct and as LEX member). Added trg_new_row_fake_var variable pointer to which is used for distinguishing between assignment to NEW row field (when parsing trigger definition) and structured variable. Added LEX::trg_table which points to table being opened when we are parsing trigger definition while opening table. sql/sql_parse.cc: Added support for CREATE/DROP TRIGGER commands. sql/sql_table.cc: Cleanup. close_cached_table() always returns 0 and its result is not analyzed in most places so chenged its return type to void. sql/sql_update.cc: Added triggers invocation for UPDATE (should be fixed for sure :)) sql/sql_yacc.yy: Added support for CREATE/DROP TRIGGER statements. Added support for OLD/NEW row identifiers in trigger. Made assignment to user variables not to break execution of stored function or trigger. sql/table.h: Added TABLE::triggers member representing triggers for this table.
2004-09-07 14:29:46 +02:00
create temporary table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1;
ERROR HY000: Trigger's 't1' is view or temporary table
drop table t1;
create table t1 (x1col char);
create trigger tx1 before insert on t1 for each row set new.x1col = 'x';
insert into t1 values ('y');
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger tx1;
drop table t1;
create table t1 (i int) engine=myisam;
insert into t1 values (1), (2);
create trigger trg1 before delete on t1 for each row set @del_before:= @del_before + old.i;
create trigger trg2 after delete on t1 for each row set @del_after:= @del_after + old.i;
set @del_before:=0, @del_after:= 0;
delete from t1;
select @del_before, @del_after;
@del_before @del_after
3 3
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger trg1;
drop trigger trg2;
drop table t1;
create table t1 (a int);
create trigger trg1 before insert on t1 for each row set new.a= 10;
drop table t1;
create table t1 (a int);
insert into t1 values ();
select * from t1;
a
NULL
drop table t1;
create database mysqltest;
use mysqltest;
create table t1 (i int);
create trigger trg1 before insert on t1 for each row set @a:= 1;
drop database mysqltest;
use test;
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
create database mysqltest;
create table mysqltest.t1 (i int);
create trigger trg1 before insert on mysqltest.t1 for each row set @a:= 1;
ERROR HY000: Trigger in wrong schema
use mysqltest;
create trigger test.trg1 before insert on t1 for each row set @a:= 1;
A fix and a test case for Bug#29050 Creation of a legal stored procedure fails if a database is not selected prior. The problem manifested itself when a user tried to create a routine that had non-fully-qualified identifiers in its bodies and there was no current database selected. This is a regression introduced by the fix for Bug 19022: The patch for Bug 19022 changes the code to always produce a warning if we can't resolve the current database in the parser. In this case this was not necessary, since even though the produced parsed tree was incorrect, we never re-use sphead that was obtained at first parsing of CREATE PROCEDURE. The sphead that is anyhow used is always obtained through db_load_routine, and there we change the current database to sphead->m_db before calling yyparse. The idea of the fix is to resolve the current database directly using lex->sphead->m_db member when parsing a stored routine body, when such is present. This patch removes the need to reset the current database when loading a trigger or routine definition into SP cache. The redundant code will be removed in 5.1. mysql-test/r/sp.result: Update test results (Bug#29050) mysql-test/r/trigger.result: Update results. mysql-test/t/sp.test: Add a test case for Bug#29050 mysql-test/t/trigger.test: Fix wrong behavior covered with tests. sql/sql_lex.cc: Implement st_lex::copy_db_to(). sql/sql_lex.h: Declare st_lex::copy_db_to(). sql/sql_parse.cc: Use st_lex::copy_db_to() in add_table_to_list, rather than THD::copy_db_to(). The former will use the database of the sphead, if we're parsing a stored routine, not the default database in THD. The default database is needed to initialize tables->db when the database part was not explicitly specified in the identifier. sql/sql_yacc.yy: Use st_lex::copy_db_to() in the parser, rather than THD::copy_db_to(). The former will use the database of the sphead, if we're parsing a stored routine, not the default database in THD.
2007-07-05 09:34:04 +02:00
ERROR 42S02: Table 'test.t1' doesn't exist
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop database mysqltest;
use test;
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
create table t1 (i int, j int default 10, k int not null, key (k));
create table t2 (i int);
insert into t1 (i, k) values (1, 1);
insert into t2 values (1);
create trigger trg1 before update on t1 for each row set @a:= @a + new.j - old.j;
create trigger trg2 after update on t1 for each row set @b:= "Fired";
set @a:= 0, @b:= "";
update t1, t2 set j = j + 10 where t1.i = t2.i;
select @a, @b;
@a @b
10 Fired
insert into t1 values (2, 13, 2);
insert into t2 values (2);
set @a:= 0, @b:= "";
update t1, t2 set j = j + 15 where t1.i = t2.i and t1.k >= 2;
select @a, @b;
@a @b
15 Fired
create trigger trg3 before delete on t1 for each row set @c:= @c + old.j;
create trigger trg4 before delete on t2 for each row set @d:= @d + old.i;
create trigger trg5 after delete on t1 for each row set @e:= "After delete t1 fired";
create trigger trg6 after delete on t2 for each row set @f:= "After delete t2 fired";
set @c:= 0, @d:= 0, @e:= "", @f:= "";
delete t1, t2 from t1, t2 where t1.i = t2.i;
select @c, @d, @e, @f;
@c @d @e @f
48 3 After delete t1 fired After delete t2 fired
drop table t1, t2;
create table t1 (i int, j int default 10)|
create table t2 (i int)|
insert into t2 values (1), (2)|
create trigger trg1 before insert on t1 for each row
begin
if new.i = 1 then
set new.j := 1;
end if;
end|
create trigger trg2 after insert on t1 for each row set @a:= 1|
set @a:= 0|
insert into t1 (i) select * from t2|
select * from t1|
i j
1 1
2 10
select @a|
@a
1
drop table t1, t2|
create table t1 (i int, j int, k int);
create trigger trg1 before insert on t1 for each row set new.k = new.i;
create trigger trg2 after insert on t1 for each row set @b:= "Fired";
set @b:="";
WL#4189 - dynamic configuration support - safe process - cleanups - create new suite for fedarated BitKeeper/deleted/.del-basic.test: Rename: mysql-test/ndb/basic.test -> BitKeeper/deleted/.del-basic.test BitKeeper/deleted/.del-basic_log.result: Rename: mysql-test/ndb/basic_log.result -> BitKeeper/deleted/.del-basic_log.result mysql-test/suite/federated/federated_transactions.result: Rename: mysql-test/r/federated_transactions.result -> mysql-test/suite/federated/federated_transactions.result BitKeeper/deleted/.del-have_bug25714.require: Rename: mysql-test/r/have_bug25714.require -> BitKeeper/deleted/.del-have_bug25714.require BitKeeper/deleted/.del-kill_master.sh: Rename: mysql-test/misc/kill_master.sh -> BitKeeper/deleted/.del-kill_master.sh BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a: Rename: mysql-test/ndb/ndb_config_4_node.ini -> BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a BitKeeper/deleted/.del-restart.result: Rename: mysql-test/ndb/restart.result -> BitKeeper/deleted/.del-restart.result mysql-test/suite/federated/federated_cleanup.inc: Rename: mysql-test/include/federated_cleanup.inc -> mysql-test/suite/federated/federated_cleanup.inc mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_rotate_logs.slave-mi -> mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt BitKeeper/deleted/.del-install_test_db.sh: Rename: mysql-test/install_test_db.sh -> BitKeeper/deleted/.del-install_test_db.sh BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16: Rename: mysql-test/ndb/ndb_config_1_node.ini -> BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16 BitKeeper/deleted/.del-mtr_timer.pl: Rename: mysql-test/lib/mtr_timer.pl -> BitKeeper/deleted/.del-mtr_timer.pl BitKeeper/deleted/.del-create-test-result: Rename: mysql-test/create-test-result -> BitKeeper/deleted/.del-create-test-result BitKeeper/deleted/.del-fix-result: Rename: mysql-test/fix-result -> BitKeeper/deleted/.del-fix-result BitKeeper/deleted/.del-mysql-test-run-shell.sh: Rename: mysql-test/mysql-test-run-shell.sh -> BitKeeper/deleted/.del-mysql-test-run-shell.sh BitKeeper/deleted/.del-mysql-test_V1.9.pl: Rename: mysql-test/misc/mysql-test_V1.9.pl -> BitKeeper/deleted/.del-mysql-test_V1.9.pl BitKeeper/deleted/.del-resolve-stack: Rename: mysql-test/resolve-stack -> BitKeeper/deleted/.del-resolve-stack BitKeeper/deleted/.del-restart_log.result: Rename: mysql-test/ndb/restart_log.result -> BitKeeper/deleted/.del-restart_log.result mysql-test/suite/rpl/t/rpl_000015-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_000015.slave-mi -> mysql-test/suite/rpl/t/rpl_000015-slave.opt BitKeeper/deleted/.del-ndb_config_2_node.ini: Rename: mysql-test/ndb/ndb_config_2_node.ini -> BitKeeper/deleted/.del-ndb_config_2_node.ini BitKeeper/deleted/.del-ndbcluster.sh: Rename: mysql-test/ndb/ndbcluster.sh -> BitKeeper/deleted/.del-ndbcluster.sh BitKeeper/deleted/.del-basic.result: Rename: mysql-test/ndb/basic.result -> BitKeeper/deleted/.del-basic.result BitKeeper/deleted/.del-restart.test: Rename: mysql-test/ndb/restart.test -> BitKeeper/deleted/.del-restart.test BitKeeper/deleted/.del-have_bug25714.inc: Rename: mysql-test/include/have_bug25714.inc -> BitKeeper/deleted/.del-have_bug25714.inc BitKeeper/deleted/.del-mtr_diff.pl: Rename: mysql-test/lib/mtr_diff.pl -> BitKeeper/deleted/.del-mtr_diff.pl mysql-test/suite/federated/federated_transactions-slave.opt: Rename: mysql-test/t/federated_transactions-slave.opt -> mysql-test/suite/federated/federated_transactions-slave.opt BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b: Rename: mysql-test/ndb/Makefile.am -> BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949: Rename: mysql-test/lib/mtr_im.pl -> BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949 mysql-test/suite/federated/federated_innodb-slave.opt: Rename: mysql-test/t/federated_innodb-slave.opt -> mysql-test/suite/federated/federated_innodb-slave.opt client/mysqltest.c: Use current files path first when looking for include file configure.in: Remove mysql-test/nbd mysql-test/Makefile.am: Cleanup mysql-test/Makefile.am mysql-test/extra/binlog_tests/blackhole.test: Use new paths mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Use new paths mysql-test/mysql-test-run.pl: Dynamic configuration support Safe process mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test: Use new paths mysql-test/extra/rpl_tests/rpl_EE_err.test: Use new paths mysql-test/extra/rpl_tests/rpl_loaddata.test: Use new paths mysql-test/extra/rpl_tests/rpl_log.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_001.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_charset.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_000001.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_charset.test: Use new paths mysql-test/include/have_blackhole.inc: Use new paths mysql-test/include/have_ndbapi_examples.inc: Use new paths mysql-test/include/loaddata_autocom.inc: Use new paths mysql-test/include/mix1.inc: Use new paths mysql-test/include/ndb_backup.inc: Use new paths mysql-test/include/ndb_restore_master.inc: Use new paths mysql-test/include/ndb_restore_slave_eoption.inc: Use new paths mysql-test/include/testdb_only.inc: Use new paths mysql-test/lib/My/Config.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_cases.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_io.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_misc.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_process.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_report.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_stress.pl: dynamic configuration safe process cleanups mysql-test/r/backup.result: Use new paths mysql-test/r/ctype_big5.result: Use new paths mysql-test/r/gis.result: Use new paths mysql-test/r/loaddata.result: Use new paths mysql-test/r/loaddata_autocom_innodb.result: Use new paths mysql-test/r/mysqlbinlog.result: Use new paths mysql-test/r/mysqlbinlog_base64.result: Use new paths mysql-test/r/outfile.result: Use new paths mysql-test/r/partition_error.result: Use new paths mysql-test/r/partition_not_windows.result: Use new paths mysql-test/r/partition_symlink.result: Use new paths mysql-test/r/query_cache.result: Use new paths mysql-test/r/sp.result: Use new paths mysql-test/r/symlink.result: Use new paths mysql-test/r/system_mysql_db.result: Use new paths mysql-test/r/trigger.result: Use new paths mysql-test/r/type_blob.result: Use new paths mysql-test/r/view.result: Use new paths mysql-test/r/warnings.result: Use new paths mysql-test/suite/binlog/r/binlog_killed_simulate.result: Use new paths mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/t/binlog_killed.test: Use new paths mysql-test/suite/binlog/t/binlog_killed_simulate.test: Use new paths mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test: Use new paths mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: Use new paths mysql-test/suite/federated/federated.inc: Use new paths mysql-test/suite/federated/federated.result: Use new paths mysql-test/suite/federated/federated.test: Use new paths mysql-test/suite/federated/federated_archive.result: Use new paths mysql-test/suite/federated/federated_archive.test: Use new paths mysql-test/suite/federated/federated_bug_13118.result: Use new paths mysql-test/suite/federated/federated_bug_13118.test: Use new paths mysql-test/suite/federated/federated_bug_25714.result: Use new paths mysql-test/suite/federated/federated_bug_25714.test: Use new paths mysql-test/suite/federated/federated_innodb.result: Use new paths mysql-test/suite/federated/federated_innodb.test: Use new paths mysql-test/suite/federated/federated_server.result: Use new paths mysql-test/suite/federated/federated_server.test: Use new paths mysql-test/suite/federated/federated_transactions.test: Use new paths mysql-test/suite/federated/have_federated_db.inc: Use new paths mysql-test/suite/ndb/r/loaddata_autocom_ndb.result: Use new paths mysql-test/suite/ndb/r/ndb_config.result: Use new paths mysql-test/suite/ndb/r/ndb_dd_backuprestore.result: Use new paths mysql-test/suite/ndb/r/ndb_load.result: Use new paths mysql-test/suite/ndb/r/ndb_loaddatalocal.result: Use new paths mysql-test/suite/ndb/r/ndb_replace.result: Use new paths mysql-test/suite/ndb/r/ndb_restore.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_partition.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_print.result: Use new paths mysql-test/suite/ndb/r/ndb_trigger.result: Use new paths mysql-test/suite/ndb/t/ndb_alter_table.test: Use new paths mysql-test/suite/ndb/t/ndb_config.test: Use new paths mysql-test/suite/ndb/t/ndb_load.test: Use new paths mysql-test/suite/ndb/t/ndb_loaddatalocal.test: Use new paths mysql-test/suite/ndb/t/ndb_replace.test: Use new paths mysql-test/suite/ndb/t/ndb_restore.test: Use new paths mysql-test/suite/ndb/t/ndb_single_user.test: Use new paths mysql-test/suite/ndb/t/ndb_trigger.test: Use new paths mysql-test/suite/ndb/t/ndbapi.test: Use new paths mysql-test/suite/rpl/include/rpl_mixed_dml.inc: Use new paths mysql-test/suite/rpl/r/rpl_LD_INFILE.result: Use new paths mysql-test/suite/rpl/r/rpl_flushlog_loop.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Use new paths mysql-test/suite/rpl/r/rpl_load_table_from_master.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_charset.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_s.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_simple.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Use new paths mysql-test/suite/rpl/r/rpl_loadfile.result: Use new paths mysql-test/suite/rpl/r/rpl_misc_functions.result: Use new paths mysql-test/suite/rpl/r/rpl_replicate_do.result: Use new paths mysql-test/suite/rpl/r/rpl_rewrt_db.result: Use new paths mysql-test/suite/rpl/r/rpl_row_001.result: Use new paths mysql-test/suite/rpl/r/rpl_row_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_row_stop_middle_update.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_000001.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_log.result: Use new paths mysql-test/suite/rpl/r/rpl_timezone.result: Use new paths mysql-test/suite/rpl/t/disabled.def: Use new paths mysql-test/suite/rpl/t/rpl000017-slave.sh: Use new paths mysql-test/suite/rpl/t/rpl_LD_INFILE.test: Use new paths mysql-test/suite/rpl/t/rpl_drop_db.test: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: Use new paths mysql-test/suite/rpl/t/rpl_load_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_load_table_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_charset.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_fatal.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_m.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_s.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_simple.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Use new paths mysql-test/suite/rpl/t/rpl_loadfile.test: Use new paths mysql-test/suite/rpl/t/rpl_misc_functions.test: Use new paths mysql-test/suite/rpl/t/rpl_replicate_do.test: Use new paths mysql-test/suite/rpl/t/rpl_rewrt_db.test: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs.test: Use new paths mysql-test/suite/rpl/t/rpl_row_charset_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test: Use new paths mysql-test/suite/rpl/t/rpl_row_stop_middle_update.test: Use new paths mysql-test/suite/rpl/t/rpl_timezone.test: Use new paths mysql-test/suite/rpl/t/rpl_trigger.test: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_innodb_trans.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_multi.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_row_001.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_sync.result: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_bank.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_dd_advance.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_load.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_sync.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndbapi_multi.test: Use new paths mysql-test/t/backup.test: Use new paths mysql-test/t/bootstrap.test: Use new paths mysql-test/t/crash_commit_before.test: Use new paths mysql-test/t/create_not_windows.test: Use new paths mysql-test/t/csv.test: Use new paths mysql-test/t/ctype_big5.test: Use new paths mysql-test/t/disabled.def: Use new paths mysql-test/t/distinct.test: Use new paths mysql-test/t/gis.test: Use new paths mysql-test/t/grant_cache_no_prot.test: Use new paths mysql-test/t/grant_cache_ps_prot.test: Use new paths mysql-test/t/information_schema_chmod.test: Use new paths mysql-test/t/loaddata.test: Use new paths mysql-test/t/log_state.test: Use new paths mysql-test/t/myisam-system.test: Use new paths mysql-test/t/mysql_upgrade.test: Use new paths mysql-test/t/mysqlbinlog-cp932.test: Use new paths mysql-test/t/mysqlbinlog.test: Use new paths mysql-test/t/mysqlbinlog2.test: Use new paths mysql-test/t/mysqlbinlog_base64.test: Use new paths mysql-test/t/mysqldump.test: Use new paths mysql-test/t/outfile.test: Use new paths mysql-test/t/partition.test: Use new paths mysql-test/t/partition_error.test: Use new paths mysql-test/t/partition_federated.test: Use new paths mysql-test/t/partition_mgm.test: Use new paths mysql-test/t/partition_not_windows.test: Use new paths mysql-test/t/partition_symlink.test: Use new paths mysql-test/t/query_cache.test: Use new paths mysql-test/t/repair.test: Use new paths mysql-test/t/show_check.test: Use new paths mysql-test/t/sp-destruct.test: Use new paths mysql-test/t/sp.test: Use new paths mysql-test/t/symlink.test: Use new paths mysql-test/t/system_mysql_db.test: Use new paths mysql-test/t/system_mysql_db_fix30020.test: Use new paths mysql-test/t/system_mysql_db_fix40123.test: Use new paths mysql-test/t/system_mysql_db_fix50030.test: Use new paths mysql-test/t/system_mysql_db_fix50117.test: Use new paths mysql-test/t/trigger-compat.test: Use new paths mysql-test/t/trigger-grant.test: Use new paths mysql-test/t/trigger.test: Use new paths mysql-test/t/type_blob.test: Use new paths mysql-test/t/type_varchar.test: Use new paths mysql-test/t/upgrade.test: Use new paths mysql-test/t/user_var-binlog.test: Use new paths mysql-test/t/varbinary.test: Use new paths mysql-test/t/view.test: Use new paths mysql-test/t/warnings.test: Use new paths mysql-test/lib/My/ConfigFactory.pm: Initial version mysql-test/lib/My/Find.pm: Initial version mysql-test/lib/My/SafeProcess.pm: Initial version mysql-test/std_data/ndb_config_config.ini: Add "old" style config.ini for ndb mysql-test/suite/federated/disabled.def: Move disabled federated to it's new suite mysql-test/suite/federated/my.cnf: Add config for federated mysql-test/suite/ndb/my.cnf: Add config for ndb mysql-test/suite/rpl/my.cnf: Add config for rpl mysql-test/suite/rpl/rpl_1slave_base.cnf: Add base config for rpl mysql-test/suite/rpl/t/rpl_000015-master.opt: Use new paths mysql-test/suite/rpl_ndb/my.cnf: Add config for rpl_ndb mysql-test/lib/My/File/Path.pm: Initial version mysql-test/lib/My/SafeProcess/Base.pm: Initial version mysql-test/lib/My/SafeProcess/safe_kill_win.cc: Initial version mysql-test/lib/My/SafeProcess/safe_process.pl: Initial version mysql-test/lib/My/SafeProcess/safe_process_win.cc: Initial version mysql-test/lib/t/Base.t: Initial version mysql-test/lib/t/Find.t: Initial version mysql-test/lib/t/SafeProcess.t: Initial version mysql-test/lib/t/SafeProcessStress.pl: Initial version mysql-test/lib/t/copytree.t: Initial version mysql-test/lib/t/dummyd.pl: Initial version mysql-test/lib/t/rmtree.t: Initial version mysql-test/lib/t/testMyConfig.t: Initial version mysql-test/lib/t/testMyConfigFactory.t: Initial version mysql-test/lib/t/test_child.pl: Initial version mysql-test/include/default_my.cnf: Add default config file used when no suite specific file is found mysql-test/include/default_mysqld.cnf: New BitKeeper file ``mysql-test/include/default_mysqld.cnf'' mysql-test/include/default_ndbd.cnf: Add default settings for all ndbds mysql-test/lib/mtr_settings.pl: Initial version
2007-12-12 18:19:24 +01:00
load data infile '../../std_data/rpl_loaddata.dat' into table t1 (@a, i);
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
select *, @b from t1;
i j k @b
10 NULL 10 Fired
15 NULL 15 Fired
set @b:="";
WL#4189 - dynamic configuration support - safe process - cleanups - create new suite for fedarated BitKeeper/deleted/.del-basic.test: Rename: mysql-test/ndb/basic.test -> BitKeeper/deleted/.del-basic.test BitKeeper/deleted/.del-basic_log.result: Rename: mysql-test/ndb/basic_log.result -> BitKeeper/deleted/.del-basic_log.result mysql-test/suite/federated/federated_transactions.result: Rename: mysql-test/r/federated_transactions.result -> mysql-test/suite/federated/federated_transactions.result BitKeeper/deleted/.del-have_bug25714.require: Rename: mysql-test/r/have_bug25714.require -> BitKeeper/deleted/.del-have_bug25714.require BitKeeper/deleted/.del-kill_master.sh: Rename: mysql-test/misc/kill_master.sh -> BitKeeper/deleted/.del-kill_master.sh BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a: Rename: mysql-test/ndb/ndb_config_4_node.ini -> BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a BitKeeper/deleted/.del-restart.result: Rename: mysql-test/ndb/restart.result -> BitKeeper/deleted/.del-restart.result mysql-test/suite/federated/federated_cleanup.inc: Rename: mysql-test/include/federated_cleanup.inc -> mysql-test/suite/federated/federated_cleanup.inc mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_rotate_logs.slave-mi -> mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt BitKeeper/deleted/.del-install_test_db.sh: Rename: mysql-test/install_test_db.sh -> BitKeeper/deleted/.del-install_test_db.sh BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16: Rename: mysql-test/ndb/ndb_config_1_node.ini -> BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16 BitKeeper/deleted/.del-mtr_timer.pl: Rename: mysql-test/lib/mtr_timer.pl -> BitKeeper/deleted/.del-mtr_timer.pl BitKeeper/deleted/.del-create-test-result: Rename: mysql-test/create-test-result -> BitKeeper/deleted/.del-create-test-result BitKeeper/deleted/.del-fix-result: Rename: mysql-test/fix-result -> BitKeeper/deleted/.del-fix-result BitKeeper/deleted/.del-mysql-test-run-shell.sh: Rename: mysql-test/mysql-test-run-shell.sh -> BitKeeper/deleted/.del-mysql-test-run-shell.sh BitKeeper/deleted/.del-mysql-test_V1.9.pl: Rename: mysql-test/misc/mysql-test_V1.9.pl -> BitKeeper/deleted/.del-mysql-test_V1.9.pl BitKeeper/deleted/.del-resolve-stack: Rename: mysql-test/resolve-stack -> BitKeeper/deleted/.del-resolve-stack BitKeeper/deleted/.del-restart_log.result: Rename: mysql-test/ndb/restart_log.result -> BitKeeper/deleted/.del-restart_log.result mysql-test/suite/rpl/t/rpl_000015-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_000015.slave-mi -> mysql-test/suite/rpl/t/rpl_000015-slave.opt BitKeeper/deleted/.del-ndb_config_2_node.ini: Rename: mysql-test/ndb/ndb_config_2_node.ini -> BitKeeper/deleted/.del-ndb_config_2_node.ini BitKeeper/deleted/.del-ndbcluster.sh: Rename: mysql-test/ndb/ndbcluster.sh -> BitKeeper/deleted/.del-ndbcluster.sh BitKeeper/deleted/.del-basic.result: Rename: mysql-test/ndb/basic.result -> BitKeeper/deleted/.del-basic.result BitKeeper/deleted/.del-restart.test: Rename: mysql-test/ndb/restart.test -> BitKeeper/deleted/.del-restart.test BitKeeper/deleted/.del-have_bug25714.inc: Rename: mysql-test/include/have_bug25714.inc -> BitKeeper/deleted/.del-have_bug25714.inc BitKeeper/deleted/.del-mtr_diff.pl: Rename: mysql-test/lib/mtr_diff.pl -> BitKeeper/deleted/.del-mtr_diff.pl mysql-test/suite/federated/federated_transactions-slave.opt: Rename: mysql-test/t/federated_transactions-slave.opt -> mysql-test/suite/federated/federated_transactions-slave.opt BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b: Rename: mysql-test/ndb/Makefile.am -> BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949: Rename: mysql-test/lib/mtr_im.pl -> BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949 mysql-test/suite/federated/federated_innodb-slave.opt: Rename: mysql-test/t/federated_innodb-slave.opt -> mysql-test/suite/federated/federated_innodb-slave.opt client/mysqltest.c: Use current files path first when looking for include file configure.in: Remove mysql-test/nbd mysql-test/Makefile.am: Cleanup mysql-test/Makefile.am mysql-test/extra/binlog_tests/blackhole.test: Use new paths mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Use new paths mysql-test/mysql-test-run.pl: Dynamic configuration support Safe process mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test: Use new paths mysql-test/extra/rpl_tests/rpl_EE_err.test: Use new paths mysql-test/extra/rpl_tests/rpl_loaddata.test: Use new paths mysql-test/extra/rpl_tests/rpl_log.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_001.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_charset.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_000001.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_charset.test: Use new paths mysql-test/include/have_blackhole.inc: Use new paths mysql-test/include/have_ndbapi_examples.inc: Use new paths mysql-test/include/loaddata_autocom.inc: Use new paths mysql-test/include/mix1.inc: Use new paths mysql-test/include/ndb_backup.inc: Use new paths mysql-test/include/ndb_restore_master.inc: Use new paths mysql-test/include/ndb_restore_slave_eoption.inc: Use new paths mysql-test/include/testdb_only.inc: Use new paths mysql-test/lib/My/Config.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_cases.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_io.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_misc.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_process.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_report.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_stress.pl: dynamic configuration safe process cleanups mysql-test/r/backup.result: Use new paths mysql-test/r/ctype_big5.result: Use new paths mysql-test/r/gis.result: Use new paths mysql-test/r/loaddata.result: Use new paths mysql-test/r/loaddata_autocom_innodb.result: Use new paths mysql-test/r/mysqlbinlog.result: Use new paths mysql-test/r/mysqlbinlog_base64.result: Use new paths mysql-test/r/outfile.result: Use new paths mysql-test/r/partition_error.result: Use new paths mysql-test/r/partition_not_windows.result: Use new paths mysql-test/r/partition_symlink.result: Use new paths mysql-test/r/query_cache.result: Use new paths mysql-test/r/sp.result: Use new paths mysql-test/r/symlink.result: Use new paths mysql-test/r/system_mysql_db.result: Use new paths mysql-test/r/trigger.result: Use new paths mysql-test/r/type_blob.result: Use new paths mysql-test/r/view.result: Use new paths mysql-test/r/warnings.result: Use new paths mysql-test/suite/binlog/r/binlog_killed_simulate.result: Use new paths mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/t/binlog_killed.test: Use new paths mysql-test/suite/binlog/t/binlog_killed_simulate.test: Use new paths mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test: Use new paths mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: Use new paths mysql-test/suite/federated/federated.inc: Use new paths mysql-test/suite/federated/federated.result: Use new paths mysql-test/suite/federated/federated.test: Use new paths mysql-test/suite/federated/federated_archive.result: Use new paths mysql-test/suite/federated/federated_archive.test: Use new paths mysql-test/suite/federated/federated_bug_13118.result: Use new paths mysql-test/suite/federated/federated_bug_13118.test: Use new paths mysql-test/suite/federated/federated_bug_25714.result: Use new paths mysql-test/suite/federated/federated_bug_25714.test: Use new paths mysql-test/suite/federated/federated_innodb.result: Use new paths mysql-test/suite/federated/federated_innodb.test: Use new paths mysql-test/suite/federated/federated_server.result: Use new paths mysql-test/suite/federated/federated_server.test: Use new paths mysql-test/suite/federated/federated_transactions.test: Use new paths mysql-test/suite/federated/have_federated_db.inc: Use new paths mysql-test/suite/ndb/r/loaddata_autocom_ndb.result: Use new paths mysql-test/suite/ndb/r/ndb_config.result: Use new paths mysql-test/suite/ndb/r/ndb_dd_backuprestore.result: Use new paths mysql-test/suite/ndb/r/ndb_load.result: Use new paths mysql-test/suite/ndb/r/ndb_loaddatalocal.result: Use new paths mysql-test/suite/ndb/r/ndb_replace.result: Use new paths mysql-test/suite/ndb/r/ndb_restore.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_partition.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_print.result: Use new paths mysql-test/suite/ndb/r/ndb_trigger.result: Use new paths mysql-test/suite/ndb/t/ndb_alter_table.test: Use new paths mysql-test/suite/ndb/t/ndb_config.test: Use new paths mysql-test/suite/ndb/t/ndb_load.test: Use new paths mysql-test/suite/ndb/t/ndb_loaddatalocal.test: Use new paths mysql-test/suite/ndb/t/ndb_replace.test: Use new paths mysql-test/suite/ndb/t/ndb_restore.test: Use new paths mysql-test/suite/ndb/t/ndb_single_user.test: Use new paths mysql-test/suite/ndb/t/ndb_trigger.test: Use new paths mysql-test/suite/ndb/t/ndbapi.test: Use new paths mysql-test/suite/rpl/include/rpl_mixed_dml.inc: Use new paths mysql-test/suite/rpl/r/rpl_LD_INFILE.result: Use new paths mysql-test/suite/rpl/r/rpl_flushlog_loop.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Use new paths mysql-test/suite/rpl/r/rpl_load_table_from_master.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_charset.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_s.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_simple.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Use new paths mysql-test/suite/rpl/r/rpl_loadfile.result: Use new paths mysql-test/suite/rpl/r/rpl_misc_functions.result: Use new paths mysql-test/suite/rpl/r/rpl_replicate_do.result: Use new paths mysql-test/suite/rpl/r/rpl_rewrt_db.result: Use new paths mysql-test/suite/rpl/r/rpl_row_001.result: Use new paths mysql-test/suite/rpl/r/rpl_row_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_row_stop_middle_update.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_000001.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_log.result: Use new paths mysql-test/suite/rpl/r/rpl_timezone.result: Use new paths mysql-test/suite/rpl/t/disabled.def: Use new paths mysql-test/suite/rpl/t/rpl000017-slave.sh: Use new paths mysql-test/suite/rpl/t/rpl_LD_INFILE.test: Use new paths mysql-test/suite/rpl/t/rpl_drop_db.test: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: Use new paths mysql-test/suite/rpl/t/rpl_load_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_load_table_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_charset.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_fatal.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_m.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_s.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_simple.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Use new paths mysql-test/suite/rpl/t/rpl_loadfile.test: Use new paths mysql-test/suite/rpl/t/rpl_misc_functions.test: Use new paths mysql-test/suite/rpl/t/rpl_replicate_do.test: Use new paths mysql-test/suite/rpl/t/rpl_rewrt_db.test: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs.test: Use new paths mysql-test/suite/rpl/t/rpl_row_charset_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test: Use new paths mysql-test/suite/rpl/t/rpl_row_stop_middle_update.test: Use new paths mysql-test/suite/rpl/t/rpl_timezone.test: Use new paths mysql-test/suite/rpl/t/rpl_trigger.test: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_innodb_trans.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_multi.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_row_001.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_sync.result: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_bank.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_dd_advance.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_load.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_sync.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndbapi_multi.test: Use new paths mysql-test/t/backup.test: Use new paths mysql-test/t/bootstrap.test: Use new paths mysql-test/t/crash_commit_before.test: Use new paths mysql-test/t/create_not_windows.test: Use new paths mysql-test/t/csv.test: Use new paths mysql-test/t/ctype_big5.test: Use new paths mysql-test/t/disabled.def: Use new paths mysql-test/t/distinct.test: Use new paths mysql-test/t/gis.test: Use new paths mysql-test/t/grant_cache_no_prot.test: Use new paths mysql-test/t/grant_cache_ps_prot.test: Use new paths mysql-test/t/information_schema_chmod.test: Use new paths mysql-test/t/loaddata.test: Use new paths mysql-test/t/log_state.test: Use new paths mysql-test/t/myisam-system.test: Use new paths mysql-test/t/mysql_upgrade.test: Use new paths mysql-test/t/mysqlbinlog-cp932.test: Use new paths mysql-test/t/mysqlbinlog.test: Use new paths mysql-test/t/mysqlbinlog2.test: Use new paths mysql-test/t/mysqlbinlog_base64.test: Use new paths mysql-test/t/mysqldump.test: Use new paths mysql-test/t/outfile.test: Use new paths mysql-test/t/partition.test: Use new paths mysql-test/t/partition_error.test: Use new paths mysql-test/t/partition_federated.test: Use new paths mysql-test/t/partition_mgm.test: Use new paths mysql-test/t/partition_not_windows.test: Use new paths mysql-test/t/partition_symlink.test: Use new paths mysql-test/t/query_cache.test: Use new paths mysql-test/t/repair.test: Use new paths mysql-test/t/show_check.test: Use new paths mysql-test/t/sp-destruct.test: Use new paths mysql-test/t/sp.test: Use new paths mysql-test/t/symlink.test: Use new paths mysql-test/t/system_mysql_db.test: Use new paths mysql-test/t/system_mysql_db_fix30020.test: Use new paths mysql-test/t/system_mysql_db_fix40123.test: Use new paths mysql-test/t/system_mysql_db_fix50030.test: Use new paths mysql-test/t/system_mysql_db_fix50117.test: Use new paths mysql-test/t/trigger-compat.test: Use new paths mysql-test/t/trigger-grant.test: Use new paths mysql-test/t/trigger.test: Use new paths mysql-test/t/type_blob.test: Use new paths mysql-test/t/type_varchar.test: Use new paths mysql-test/t/upgrade.test: Use new paths mysql-test/t/user_var-binlog.test: Use new paths mysql-test/t/varbinary.test: Use new paths mysql-test/t/view.test: Use new paths mysql-test/t/warnings.test: Use new paths mysql-test/lib/My/ConfigFactory.pm: Initial version mysql-test/lib/My/Find.pm: Initial version mysql-test/lib/My/SafeProcess.pm: Initial version mysql-test/std_data/ndb_config_config.ini: Add "old" style config.ini for ndb mysql-test/suite/federated/disabled.def: Move disabled federated to it's new suite mysql-test/suite/federated/my.cnf: Add config for federated mysql-test/suite/ndb/my.cnf: Add config for ndb mysql-test/suite/rpl/my.cnf: Add config for rpl mysql-test/suite/rpl/rpl_1slave_base.cnf: Add base config for rpl mysql-test/suite/rpl/t/rpl_000015-master.opt: Use new paths mysql-test/suite/rpl_ndb/my.cnf: Add config for rpl_ndb mysql-test/lib/My/File/Path.pm: Initial version mysql-test/lib/My/SafeProcess/Base.pm: Initial version mysql-test/lib/My/SafeProcess/safe_kill_win.cc: Initial version mysql-test/lib/My/SafeProcess/safe_process.pl: Initial version mysql-test/lib/My/SafeProcess/safe_process_win.cc: Initial version mysql-test/lib/t/Base.t: Initial version mysql-test/lib/t/Find.t: Initial version mysql-test/lib/t/SafeProcess.t: Initial version mysql-test/lib/t/SafeProcessStress.pl: Initial version mysql-test/lib/t/copytree.t: Initial version mysql-test/lib/t/dummyd.pl: Initial version mysql-test/lib/t/rmtree.t: Initial version mysql-test/lib/t/testMyConfig.t: Initial version mysql-test/lib/t/testMyConfigFactory.t: Initial version mysql-test/lib/t/test_child.pl: Initial version mysql-test/include/default_my.cnf: Add default config file used when no suite specific file is found mysql-test/include/default_mysqld.cnf: New BitKeeper file ``mysql-test/include/default_mysqld.cnf'' mysql-test/include/default_ndbd.cnf: Add default settings for all ndbds mysql-test/lib/mtr_settings.pl: Initial version
2007-12-12 18:19:24 +01:00
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, j);
Fix for bugs: #5860 "Multi-table UPDATE does not activate update triggers" #6812 "Triggers are not activated for INSERT ... SELECT" #8755 "Trigger is not activated by LOAD DATA". This patch also implements proper handling of triggers for special forms of insert like REPLACE or INSERT ... ON DUPLICATE KEY UPDATE. Also now we don't call after trigger in case when we have failed to inserted/update or delete row. Trigger failure should stop statement execution. I have not properly tested handling of errors which happen inside of triggers in this patch, since it is simplier to do this once we will be able to access tables from triggers. mysql-test/r/trigger.result: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". mysql-test/t/trigger.test: Added tests for triggers behavior for various non-standard forms of INSERT such as REPLACE and INSERT ... ON DUPLICATE KEY UPDATE. Also added tests for bugs #5860 "Multi-table UPDATE does not activate update triggers", #6812 "Triggers are not activated for INSERT ... SELECT" and #8755 "Trigger is not activated by LOAD DATA". sql/item.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field::setup_field()/fix_fields() were changed to implement this approach. sql/item.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Item_trigger_field: - Added field_idx member to store index of Field object corresponding to this Item in TABLE::field array. - Added triggers member to be able to access to parent Table_trigger_list object from fix_fields() method. - setup_field() no longer needs to know for which type of event this trigger is, since it does not make decision Field for which buffer (record[0] or record[1] is appropriate for this Item_trigger_field) sql/mysql_priv.h: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_base.cc: Added fill_record_n_invoke_before_triggers() methods. They are simple wrappers around fill_record() which invoke proper before trigger right after filling record with values. sql/sql_delete.cc: mysql_delete(): Now we stop statement execution if one of triggers failed, we also don't execute after delete trigger if we failed to delete row from the table (We also pass information about which buffer contains old version of row to process_triggers()). multi_delete::send_data()/do_deletes(): Now we also invoke triggers in case of multi-delete. sql/sql_insert.cc: mysql_insert(): Moved invocation of before triggers to fill_record_n_invoke_before_triggers() method. After triggers are now executed as part of write_record(). (as nice side effect now we also stop statement execution if one of triggers fail). write_record(): Invoke after insert trigger after performing insert. Also invoke proper triggers if insert is converted to update or conflicting row is deleted. Cleaned up error handling a bit - no sense to report error via handler::print_error if it was not generated by handler method and was reported before. Also now we will execute after trigger only if we really have written row to the table. select_insert::send_data()/store_values(): We should also execute INSERT triggers for INSERT ... SELECT statement. sql/sql_load.cc: read_fixed_length()/read_sep_field(): We should execute INSERT triggers when processing LOAD DATA statement. Small cleanup in auto-increment related code. Also moved check for thd->killed which is used to abort LOAD DATA in case of problems in 'traditional' mode to better place.. sql/sql_trigger.cc: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Table_triggers_list methods were changed to implement this approach (see also comments for sql_trigger.h). sql/sql_trigger.h: Since it turned out that at trigger loading time we can't say in which buffer TABLE::record[0] or record[1] old version of row will be stored we have to change our approach to binding of Item_trigger_field to Field instances. Now after trigger parsing (in Item_trigger_field::setup_table()) we only find index of proper Field in the TABLE::field array. Then before trigger is invoked we set Table_triggers_list::old_field/new_field so they point to arrays holding Field instances bound to buffers with proper row versions. And as last step in Item_trigger_field::fix_fields() we get pointer to Field from those arrays using saved field index. Changed Table_triggers_list to implement this new approach: - Added record1_field member to store array of Field objects bound to TABLE::record[1] buffer (instead of existing old_field member) - Added new_field member and changed meaning of old_field member. During trigger execution they should point to arrays of Field objects bound to buffers holding new and old versions of row respectively. - Added 'table' member to be able to get access to TABLE instance (for which this trigger list object was created) from process_triggers() method. - Now process_triggers() method sets old_field and new_field members properly before executing triggers body (basing on new old_row_is_record1 parameter value). - Renamed prepare_old_row_accessors_method() to prepare_record1_accessors() Also added has_before_update_triggers() method which allows to check whenever any before update triggers exist for table. sql/sql_update.cc: mysql_update(): Now we invoke before triggers in fill_record_n_invoke_before_triggers() method. Also now we abort statement execution when one of triggers fail. safe_update_on_fly(): When we are trying to understand if we can update first table in multi update on the fly we should take into account that BEFORE UPDATE trigger can change field values. multi_update::send_data()/do_updates() We should execute proper triggers when doing multi-update (in both cases when we do it on the fly and using temporary tables).
2005-05-24 20:19:33 +02:00
select *, @b from t1;
i j k @b
10 NULL 10 Fired
15 NULL 15 Fired
1 2 1 Fired
3 4 3 Fired
5 6 5 Fired
drop table t1;
create table t1 (i int, at int, k int, key(k)) engine=myisam;
create table t2 (i int);
insert into t1 values (1, 1, 1);
insert into t2 values (1), (2), (3);
create trigger ai after insert on t1 for each row set @a:= new.at;
create trigger au after update on t1 for each row set @a:= new.at;
create trigger ad after delete on t1 for each row set @a:= old.at;
alter table t1 drop column at;
select * from t1;
i k
1 1
insert into t1 values (2, 1);
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
1 1
2 1
update t1 set k = 2 where i = 2;
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
1 1
2 2
delete from t1 where i = 2;
ERROR 42S22: Unknown column 'at' in 'OLD'
select * from t1;
i k
1 1
WL#4189 - dynamic configuration support - safe process - cleanups - create new suite for fedarated BitKeeper/deleted/.del-basic.test: Rename: mysql-test/ndb/basic.test -> BitKeeper/deleted/.del-basic.test BitKeeper/deleted/.del-basic_log.result: Rename: mysql-test/ndb/basic_log.result -> BitKeeper/deleted/.del-basic_log.result mysql-test/suite/federated/federated_transactions.result: Rename: mysql-test/r/federated_transactions.result -> mysql-test/suite/federated/federated_transactions.result BitKeeper/deleted/.del-have_bug25714.require: Rename: mysql-test/r/have_bug25714.require -> BitKeeper/deleted/.del-have_bug25714.require BitKeeper/deleted/.del-kill_master.sh: Rename: mysql-test/misc/kill_master.sh -> BitKeeper/deleted/.del-kill_master.sh BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a: Rename: mysql-test/ndb/ndb_config_4_node.ini -> BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a BitKeeper/deleted/.del-restart.result: Rename: mysql-test/ndb/restart.result -> BitKeeper/deleted/.del-restart.result mysql-test/suite/federated/federated_cleanup.inc: Rename: mysql-test/include/federated_cleanup.inc -> mysql-test/suite/federated/federated_cleanup.inc mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_rotate_logs.slave-mi -> mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt BitKeeper/deleted/.del-install_test_db.sh: Rename: mysql-test/install_test_db.sh -> BitKeeper/deleted/.del-install_test_db.sh BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16: Rename: mysql-test/ndb/ndb_config_1_node.ini -> BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16 BitKeeper/deleted/.del-mtr_timer.pl: Rename: mysql-test/lib/mtr_timer.pl -> BitKeeper/deleted/.del-mtr_timer.pl BitKeeper/deleted/.del-create-test-result: Rename: mysql-test/create-test-result -> BitKeeper/deleted/.del-create-test-result BitKeeper/deleted/.del-fix-result: Rename: mysql-test/fix-result -> BitKeeper/deleted/.del-fix-result BitKeeper/deleted/.del-mysql-test-run-shell.sh: Rename: mysql-test/mysql-test-run-shell.sh -> BitKeeper/deleted/.del-mysql-test-run-shell.sh BitKeeper/deleted/.del-mysql-test_V1.9.pl: Rename: mysql-test/misc/mysql-test_V1.9.pl -> BitKeeper/deleted/.del-mysql-test_V1.9.pl BitKeeper/deleted/.del-resolve-stack: Rename: mysql-test/resolve-stack -> BitKeeper/deleted/.del-resolve-stack BitKeeper/deleted/.del-restart_log.result: Rename: mysql-test/ndb/restart_log.result -> BitKeeper/deleted/.del-restart_log.result mysql-test/suite/rpl/t/rpl_000015-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_000015.slave-mi -> mysql-test/suite/rpl/t/rpl_000015-slave.opt BitKeeper/deleted/.del-ndb_config_2_node.ini: Rename: mysql-test/ndb/ndb_config_2_node.ini -> BitKeeper/deleted/.del-ndb_config_2_node.ini BitKeeper/deleted/.del-ndbcluster.sh: Rename: mysql-test/ndb/ndbcluster.sh -> BitKeeper/deleted/.del-ndbcluster.sh BitKeeper/deleted/.del-basic.result: Rename: mysql-test/ndb/basic.result -> BitKeeper/deleted/.del-basic.result BitKeeper/deleted/.del-restart.test: Rename: mysql-test/ndb/restart.test -> BitKeeper/deleted/.del-restart.test BitKeeper/deleted/.del-have_bug25714.inc: Rename: mysql-test/include/have_bug25714.inc -> BitKeeper/deleted/.del-have_bug25714.inc BitKeeper/deleted/.del-mtr_diff.pl: Rename: mysql-test/lib/mtr_diff.pl -> BitKeeper/deleted/.del-mtr_diff.pl mysql-test/suite/federated/federated_transactions-slave.opt: Rename: mysql-test/t/federated_transactions-slave.opt -> mysql-test/suite/federated/federated_transactions-slave.opt BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b: Rename: mysql-test/ndb/Makefile.am -> BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949: Rename: mysql-test/lib/mtr_im.pl -> BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949 mysql-test/suite/federated/federated_innodb-slave.opt: Rename: mysql-test/t/federated_innodb-slave.opt -> mysql-test/suite/federated/federated_innodb-slave.opt client/mysqltest.c: Use current files path first when looking for include file configure.in: Remove mysql-test/nbd mysql-test/Makefile.am: Cleanup mysql-test/Makefile.am mysql-test/extra/binlog_tests/blackhole.test: Use new paths mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Use new paths mysql-test/mysql-test-run.pl: Dynamic configuration support Safe process mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test: Use new paths mysql-test/extra/rpl_tests/rpl_EE_err.test: Use new paths mysql-test/extra/rpl_tests/rpl_loaddata.test: Use new paths mysql-test/extra/rpl_tests/rpl_log.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_001.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_charset.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_000001.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_charset.test: Use new paths mysql-test/include/have_blackhole.inc: Use new paths mysql-test/include/have_ndbapi_examples.inc: Use new paths mysql-test/include/loaddata_autocom.inc: Use new paths mysql-test/include/mix1.inc: Use new paths mysql-test/include/ndb_backup.inc: Use new paths mysql-test/include/ndb_restore_master.inc: Use new paths mysql-test/include/ndb_restore_slave_eoption.inc: Use new paths mysql-test/include/testdb_only.inc: Use new paths mysql-test/lib/My/Config.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_cases.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_io.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_misc.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_process.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_report.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_stress.pl: dynamic configuration safe process cleanups mysql-test/r/backup.result: Use new paths mysql-test/r/ctype_big5.result: Use new paths mysql-test/r/gis.result: Use new paths mysql-test/r/loaddata.result: Use new paths mysql-test/r/loaddata_autocom_innodb.result: Use new paths mysql-test/r/mysqlbinlog.result: Use new paths mysql-test/r/mysqlbinlog_base64.result: Use new paths mysql-test/r/outfile.result: Use new paths mysql-test/r/partition_error.result: Use new paths mysql-test/r/partition_not_windows.result: Use new paths mysql-test/r/partition_symlink.result: Use new paths mysql-test/r/query_cache.result: Use new paths mysql-test/r/sp.result: Use new paths mysql-test/r/symlink.result: Use new paths mysql-test/r/system_mysql_db.result: Use new paths mysql-test/r/trigger.result: Use new paths mysql-test/r/type_blob.result: Use new paths mysql-test/r/view.result: Use new paths mysql-test/r/warnings.result: Use new paths mysql-test/suite/binlog/r/binlog_killed_simulate.result: Use new paths mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/t/binlog_killed.test: Use new paths mysql-test/suite/binlog/t/binlog_killed_simulate.test: Use new paths mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test: Use new paths mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: Use new paths mysql-test/suite/federated/federated.inc: Use new paths mysql-test/suite/federated/federated.result: Use new paths mysql-test/suite/federated/federated.test: Use new paths mysql-test/suite/federated/federated_archive.result: Use new paths mysql-test/suite/federated/federated_archive.test: Use new paths mysql-test/suite/federated/federated_bug_13118.result: Use new paths mysql-test/suite/federated/federated_bug_13118.test: Use new paths mysql-test/suite/federated/federated_bug_25714.result: Use new paths mysql-test/suite/federated/federated_bug_25714.test: Use new paths mysql-test/suite/federated/federated_innodb.result: Use new paths mysql-test/suite/federated/federated_innodb.test: Use new paths mysql-test/suite/federated/federated_server.result: Use new paths mysql-test/suite/federated/federated_server.test: Use new paths mysql-test/suite/federated/federated_transactions.test: Use new paths mysql-test/suite/federated/have_federated_db.inc: Use new paths mysql-test/suite/ndb/r/loaddata_autocom_ndb.result: Use new paths mysql-test/suite/ndb/r/ndb_config.result: Use new paths mysql-test/suite/ndb/r/ndb_dd_backuprestore.result: Use new paths mysql-test/suite/ndb/r/ndb_load.result: Use new paths mysql-test/suite/ndb/r/ndb_loaddatalocal.result: Use new paths mysql-test/suite/ndb/r/ndb_replace.result: Use new paths mysql-test/suite/ndb/r/ndb_restore.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_partition.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_print.result: Use new paths mysql-test/suite/ndb/r/ndb_trigger.result: Use new paths mysql-test/suite/ndb/t/ndb_alter_table.test: Use new paths mysql-test/suite/ndb/t/ndb_config.test: Use new paths mysql-test/suite/ndb/t/ndb_load.test: Use new paths mysql-test/suite/ndb/t/ndb_loaddatalocal.test: Use new paths mysql-test/suite/ndb/t/ndb_replace.test: Use new paths mysql-test/suite/ndb/t/ndb_restore.test: Use new paths mysql-test/suite/ndb/t/ndb_single_user.test: Use new paths mysql-test/suite/ndb/t/ndb_trigger.test: Use new paths mysql-test/suite/ndb/t/ndbapi.test: Use new paths mysql-test/suite/rpl/include/rpl_mixed_dml.inc: Use new paths mysql-test/suite/rpl/r/rpl_LD_INFILE.result: Use new paths mysql-test/suite/rpl/r/rpl_flushlog_loop.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Use new paths mysql-test/suite/rpl/r/rpl_load_table_from_master.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_charset.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_s.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_simple.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Use new paths mysql-test/suite/rpl/r/rpl_loadfile.result: Use new paths mysql-test/suite/rpl/r/rpl_misc_functions.result: Use new paths mysql-test/suite/rpl/r/rpl_replicate_do.result: Use new paths mysql-test/suite/rpl/r/rpl_rewrt_db.result: Use new paths mysql-test/suite/rpl/r/rpl_row_001.result: Use new paths mysql-test/suite/rpl/r/rpl_row_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_row_stop_middle_update.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_000001.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_log.result: Use new paths mysql-test/suite/rpl/r/rpl_timezone.result: Use new paths mysql-test/suite/rpl/t/disabled.def: Use new paths mysql-test/suite/rpl/t/rpl000017-slave.sh: Use new paths mysql-test/suite/rpl/t/rpl_LD_INFILE.test: Use new paths mysql-test/suite/rpl/t/rpl_drop_db.test: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: Use new paths mysql-test/suite/rpl/t/rpl_load_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_load_table_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_charset.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_fatal.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_m.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_s.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_simple.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Use new paths mysql-test/suite/rpl/t/rpl_loadfile.test: Use new paths mysql-test/suite/rpl/t/rpl_misc_functions.test: Use new paths mysql-test/suite/rpl/t/rpl_replicate_do.test: Use new paths mysql-test/suite/rpl/t/rpl_rewrt_db.test: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs.test: Use new paths mysql-test/suite/rpl/t/rpl_row_charset_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test: Use new paths mysql-test/suite/rpl/t/rpl_row_stop_middle_update.test: Use new paths mysql-test/suite/rpl/t/rpl_timezone.test: Use new paths mysql-test/suite/rpl/t/rpl_trigger.test: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_innodb_trans.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_multi.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_row_001.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_sync.result: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_bank.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_dd_advance.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_load.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_sync.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndbapi_multi.test: Use new paths mysql-test/t/backup.test: Use new paths mysql-test/t/bootstrap.test: Use new paths mysql-test/t/crash_commit_before.test: Use new paths mysql-test/t/create_not_windows.test: Use new paths mysql-test/t/csv.test: Use new paths mysql-test/t/ctype_big5.test: Use new paths mysql-test/t/disabled.def: Use new paths mysql-test/t/distinct.test: Use new paths mysql-test/t/gis.test: Use new paths mysql-test/t/grant_cache_no_prot.test: Use new paths mysql-test/t/grant_cache_ps_prot.test: Use new paths mysql-test/t/information_schema_chmod.test: Use new paths mysql-test/t/loaddata.test: Use new paths mysql-test/t/log_state.test: Use new paths mysql-test/t/myisam-system.test: Use new paths mysql-test/t/mysql_upgrade.test: Use new paths mysql-test/t/mysqlbinlog-cp932.test: Use new paths mysql-test/t/mysqlbinlog.test: Use new paths mysql-test/t/mysqlbinlog2.test: Use new paths mysql-test/t/mysqlbinlog_base64.test: Use new paths mysql-test/t/mysqldump.test: Use new paths mysql-test/t/outfile.test: Use new paths mysql-test/t/partition.test: Use new paths mysql-test/t/partition_error.test: Use new paths mysql-test/t/partition_federated.test: Use new paths mysql-test/t/partition_mgm.test: Use new paths mysql-test/t/partition_not_windows.test: Use new paths mysql-test/t/partition_symlink.test: Use new paths mysql-test/t/query_cache.test: Use new paths mysql-test/t/repair.test: Use new paths mysql-test/t/show_check.test: Use new paths mysql-test/t/sp-destruct.test: Use new paths mysql-test/t/sp.test: Use new paths mysql-test/t/symlink.test: Use new paths mysql-test/t/system_mysql_db.test: Use new paths mysql-test/t/system_mysql_db_fix30020.test: Use new paths mysql-test/t/system_mysql_db_fix40123.test: Use new paths mysql-test/t/system_mysql_db_fix50030.test: Use new paths mysql-test/t/system_mysql_db_fix50117.test: Use new paths mysql-test/t/trigger-compat.test: Use new paths mysql-test/t/trigger-grant.test: Use new paths mysql-test/t/trigger.test: Use new paths mysql-test/t/type_blob.test: Use new paths mysql-test/t/type_varchar.test: Use new paths mysql-test/t/upgrade.test: Use new paths mysql-test/t/user_var-binlog.test: Use new paths mysql-test/t/varbinary.test: Use new paths mysql-test/t/view.test: Use new paths mysql-test/t/warnings.test: Use new paths mysql-test/lib/My/ConfigFactory.pm: Initial version mysql-test/lib/My/Find.pm: Initial version mysql-test/lib/My/SafeProcess.pm: Initial version mysql-test/std_data/ndb_config_config.ini: Add "old" style config.ini for ndb mysql-test/suite/federated/disabled.def: Move disabled federated to it's new suite mysql-test/suite/federated/my.cnf: Add config for federated mysql-test/suite/ndb/my.cnf: Add config for ndb mysql-test/suite/rpl/my.cnf: Add config for rpl mysql-test/suite/rpl/rpl_1slave_base.cnf: Add base config for rpl mysql-test/suite/rpl/t/rpl_000015-master.opt: Use new paths mysql-test/suite/rpl_ndb/my.cnf: Add config for rpl_ndb mysql-test/lib/My/File/Path.pm: Initial version mysql-test/lib/My/SafeProcess/Base.pm: Initial version mysql-test/lib/My/SafeProcess/safe_kill_win.cc: Initial version mysql-test/lib/My/SafeProcess/safe_process.pl: Initial version mysql-test/lib/My/SafeProcess/safe_process_win.cc: Initial version mysql-test/lib/t/Base.t: Initial version mysql-test/lib/t/Find.t: Initial version mysql-test/lib/t/SafeProcess.t: Initial version mysql-test/lib/t/SafeProcessStress.pl: Initial version mysql-test/lib/t/copytree.t: Initial version mysql-test/lib/t/dummyd.pl: Initial version mysql-test/lib/t/rmtree.t: Initial version mysql-test/lib/t/testMyConfig.t: Initial version mysql-test/lib/t/testMyConfigFactory.t: Initial version mysql-test/lib/t/test_child.pl: Initial version mysql-test/include/default_my.cnf: Add default config file used when no suite specific file is found mysql-test/include/default_mysqld.cnf: New BitKeeper file ``mysql-test/include/default_mysqld.cnf'' mysql-test/include/default_ndbd.cnf: Add default settings for all ndbds mysql-test/lib/mtr_settings.pl: Initial version
2007-12-12 18:19:24 +01:00
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, k);
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
1 1
1 2
insert into t1 select 3, 3;
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
1 1
1 2
3 3
update t1, t2 set k = k + 10 where t1.i = t2.i;
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
1 11
1 2
3 3
update t1, t2 set k = k + 10 where t1.i = t2.i and k < 3;
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
1 11
1 12
3 3
delete t1, t2 from t1 straight_join t2 where t1.i = t2.i;
ERROR 42S22: Unknown column 'at' in 'OLD'
select * from t1;
i k
1 12
3 3
delete t2, t1 from t2 straight_join t1 where t1.i = t2.i;
ERROR 42S22: Unknown column 'at' in 'OLD'
select * from t1;
i k
3 3
alter table t1 add primary key (i);
insert into t1 values (3, 4) on duplicate key update k= k + 10;
ERROR 42S22: Unknown column 'at' in 'NEW'
select * from t1;
i k
3 13
replace into t1 values (3, 3);
ERROR 42S22: Unknown column 'at' in 'OLD'
select * from t1;
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
i k
drop table t1, t2;
create table t1 (i int, bt int, k int, key(k)) engine=myisam;
create table t2 (i int);
insert into t1 values (1, 1, 1), (2, 2, 2);
insert into t2 values (1), (2), (3);
create trigger bi before insert on t1 for each row set @a:= new.bt;
create trigger bu before update on t1 for each row set @a:= new.bt;
create trigger bd before delete on t1 for each row set @a:= old.bt;
alter table t1 drop column bt;
insert into t1 values (3, 3);
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
update t1 set i = 2;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
delete from t1;
ERROR 42S22: Unknown column 'bt' in 'OLD'
select * from t1;
i k
1 1
2 2
WL#4189 - dynamic configuration support - safe process - cleanups - create new suite for fedarated BitKeeper/deleted/.del-basic.test: Rename: mysql-test/ndb/basic.test -> BitKeeper/deleted/.del-basic.test BitKeeper/deleted/.del-basic_log.result: Rename: mysql-test/ndb/basic_log.result -> BitKeeper/deleted/.del-basic_log.result mysql-test/suite/federated/federated_transactions.result: Rename: mysql-test/r/federated_transactions.result -> mysql-test/suite/federated/federated_transactions.result BitKeeper/deleted/.del-have_bug25714.require: Rename: mysql-test/r/have_bug25714.require -> BitKeeper/deleted/.del-have_bug25714.require BitKeeper/deleted/.del-kill_master.sh: Rename: mysql-test/misc/kill_master.sh -> BitKeeper/deleted/.del-kill_master.sh BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a: Rename: mysql-test/ndb/ndb_config_4_node.ini -> BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a BitKeeper/deleted/.del-restart.result: Rename: mysql-test/ndb/restart.result -> BitKeeper/deleted/.del-restart.result mysql-test/suite/federated/federated_cleanup.inc: Rename: mysql-test/include/federated_cleanup.inc -> mysql-test/suite/federated/federated_cleanup.inc mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_rotate_logs.slave-mi -> mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt BitKeeper/deleted/.del-install_test_db.sh: Rename: mysql-test/install_test_db.sh -> BitKeeper/deleted/.del-install_test_db.sh BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16: Rename: mysql-test/ndb/ndb_config_1_node.ini -> BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16 BitKeeper/deleted/.del-mtr_timer.pl: Rename: mysql-test/lib/mtr_timer.pl -> BitKeeper/deleted/.del-mtr_timer.pl BitKeeper/deleted/.del-create-test-result: Rename: mysql-test/create-test-result -> BitKeeper/deleted/.del-create-test-result BitKeeper/deleted/.del-fix-result: Rename: mysql-test/fix-result -> BitKeeper/deleted/.del-fix-result BitKeeper/deleted/.del-mysql-test-run-shell.sh: Rename: mysql-test/mysql-test-run-shell.sh -> BitKeeper/deleted/.del-mysql-test-run-shell.sh BitKeeper/deleted/.del-mysql-test_V1.9.pl: Rename: mysql-test/misc/mysql-test_V1.9.pl -> BitKeeper/deleted/.del-mysql-test_V1.9.pl BitKeeper/deleted/.del-resolve-stack: Rename: mysql-test/resolve-stack -> BitKeeper/deleted/.del-resolve-stack BitKeeper/deleted/.del-restart_log.result: Rename: mysql-test/ndb/restart_log.result -> BitKeeper/deleted/.del-restart_log.result mysql-test/suite/rpl/t/rpl_000015-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_000015.slave-mi -> mysql-test/suite/rpl/t/rpl_000015-slave.opt BitKeeper/deleted/.del-ndb_config_2_node.ini: Rename: mysql-test/ndb/ndb_config_2_node.ini -> BitKeeper/deleted/.del-ndb_config_2_node.ini BitKeeper/deleted/.del-ndbcluster.sh: Rename: mysql-test/ndb/ndbcluster.sh -> BitKeeper/deleted/.del-ndbcluster.sh BitKeeper/deleted/.del-basic.result: Rename: mysql-test/ndb/basic.result -> BitKeeper/deleted/.del-basic.result BitKeeper/deleted/.del-restart.test: Rename: mysql-test/ndb/restart.test -> BitKeeper/deleted/.del-restart.test BitKeeper/deleted/.del-have_bug25714.inc: Rename: mysql-test/include/have_bug25714.inc -> BitKeeper/deleted/.del-have_bug25714.inc BitKeeper/deleted/.del-mtr_diff.pl: Rename: mysql-test/lib/mtr_diff.pl -> BitKeeper/deleted/.del-mtr_diff.pl mysql-test/suite/federated/federated_transactions-slave.opt: Rename: mysql-test/t/federated_transactions-slave.opt -> mysql-test/suite/federated/federated_transactions-slave.opt BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b: Rename: mysql-test/ndb/Makefile.am -> BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949: Rename: mysql-test/lib/mtr_im.pl -> BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949 mysql-test/suite/federated/federated_innodb-slave.opt: Rename: mysql-test/t/federated_innodb-slave.opt -> mysql-test/suite/federated/federated_innodb-slave.opt client/mysqltest.c: Use current files path first when looking for include file configure.in: Remove mysql-test/nbd mysql-test/Makefile.am: Cleanup mysql-test/Makefile.am mysql-test/extra/binlog_tests/blackhole.test: Use new paths mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Use new paths mysql-test/mysql-test-run.pl: Dynamic configuration support Safe process mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test: Use new paths mysql-test/extra/rpl_tests/rpl_EE_err.test: Use new paths mysql-test/extra/rpl_tests/rpl_loaddata.test: Use new paths mysql-test/extra/rpl_tests/rpl_log.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_001.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_charset.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_000001.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_charset.test: Use new paths mysql-test/include/have_blackhole.inc: Use new paths mysql-test/include/have_ndbapi_examples.inc: Use new paths mysql-test/include/loaddata_autocom.inc: Use new paths mysql-test/include/mix1.inc: Use new paths mysql-test/include/ndb_backup.inc: Use new paths mysql-test/include/ndb_restore_master.inc: Use new paths mysql-test/include/ndb_restore_slave_eoption.inc: Use new paths mysql-test/include/testdb_only.inc: Use new paths mysql-test/lib/My/Config.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_cases.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_io.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_misc.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_process.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_report.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_stress.pl: dynamic configuration safe process cleanups mysql-test/r/backup.result: Use new paths mysql-test/r/ctype_big5.result: Use new paths mysql-test/r/gis.result: Use new paths mysql-test/r/loaddata.result: Use new paths mysql-test/r/loaddata_autocom_innodb.result: Use new paths mysql-test/r/mysqlbinlog.result: Use new paths mysql-test/r/mysqlbinlog_base64.result: Use new paths mysql-test/r/outfile.result: Use new paths mysql-test/r/partition_error.result: Use new paths mysql-test/r/partition_not_windows.result: Use new paths mysql-test/r/partition_symlink.result: Use new paths mysql-test/r/query_cache.result: Use new paths mysql-test/r/sp.result: Use new paths mysql-test/r/symlink.result: Use new paths mysql-test/r/system_mysql_db.result: Use new paths mysql-test/r/trigger.result: Use new paths mysql-test/r/type_blob.result: Use new paths mysql-test/r/view.result: Use new paths mysql-test/r/warnings.result: Use new paths mysql-test/suite/binlog/r/binlog_killed_simulate.result: Use new paths mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/t/binlog_killed.test: Use new paths mysql-test/suite/binlog/t/binlog_killed_simulate.test: Use new paths mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test: Use new paths mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: Use new paths mysql-test/suite/federated/federated.inc: Use new paths mysql-test/suite/federated/federated.result: Use new paths mysql-test/suite/federated/federated.test: Use new paths mysql-test/suite/federated/federated_archive.result: Use new paths mysql-test/suite/federated/federated_archive.test: Use new paths mysql-test/suite/federated/federated_bug_13118.result: Use new paths mysql-test/suite/federated/federated_bug_13118.test: Use new paths mysql-test/suite/federated/federated_bug_25714.result: Use new paths mysql-test/suite/federated/federated_bug_25714.test: Use new paths mysql-test/suite/federated/federated_innodb.result: Use new paths mysql-test/suite/federated/federated_innodb.test: Use new paths mysql-test/suite/federated/federated_server.result: Use new paths mysql-test/suite/federated/federated_server.test: Use new paths mysql-test/suite/federated/federated_transactions.test: Use new paths mysql-test/suite/federated/have_federated_db.inc: Use new paths mysql-test/suite/ndb/r/loaddata_autocom_ndb.result: Use new paths mysql-test/suite/ndb/r/ndb_config.result: Use new paths mysql-test/suite/ndb/r/ndb_dd_backuprestore.result: Use new paths mysql-test/suite/ndb/r/ndb_load.result: Use new paths mysql-test/suite/ndb/r/ndb_loaddatalocal.result: Use new paths mysql-test/suite/ndb/r/ndb_replace.result: Use new paths mysql-test/suite/ndb/r/ndb_restore.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_partition.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_print.result: Use new paths mysql-test/suite/ndb/r/ndb_trigger.result: Use new paths mysql-test/suite/ndb/t/ndb_alter_table.test: Use new paths mysql-test/suite/ndb/t/ndb_config.test: Use new paths mysql-test/suite/ndb/t/ndb_load.test: Use new paths mysql-test/suite/ndb/t/ndb_loaddatalocal.test: Use new paths mysql-test/suite/ndb/t/ndb_replace.test: Use new paths mysql-test/suite/ndb/t/ndb_restore.test: Use new paths mysql-test/suite/ndb/t/ndb_single_user.test: Use new paths mysql-test/suite/ndb/t/ndb_trigger.test: Use new paths mysql-test/suite/ndb/t/ndbapi.test: Use new paths mysql-test/suite/rpl/include/rpl_mixed_dml.inc: Use new paths mysql-test/suite/rpl/r/rpl_LD_INFILE.result: Use new paths mysql-test/suite/rpl/r/rpl_flushlog_loop.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Use new paths mysql-test/suite/rpl/r/rpl_load_table_from_master.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_charset.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_s.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_simple.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Use new paths mysql-test/suite/rpl/r/rpl_loadfile.result: Use new paths mysql-test/suite/rpl/r/rpl_misc_functions.result: Use new paths mysql-test/suite/rpl/r/rpl_replicate_do.result: Use new paths mysql-test/suite/rpl/r/rpl_rewrt_db.result: Use new paths mysql-test/suite/rpl/r/rpl_row_001.result: Use new paths mysql-test/suite/rpl/r/rpl_row_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_row_stop_middle_update.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_000001.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_log.result: Use new paths mysql-test/suite/rpl/r/rpl_timezone.result: Use new paths mysql-test/suite/rpl/t/disabled.def: Use new paths mysql-test/suite/rpl/t/rpl000017-slave.sh: Use new paths mysql-test/suite/rpl/t/rpl_LD_INFILE.test: Use new paths mysql-test/suite/rpl/t/rpl_drop_db.test: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: Use new paths mysql-test/suite/rpl/t/rpl_load_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_load_table_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_charset.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_fatal.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_m.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_s.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_simple.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Use new paths mysql-test/suite/rpl/t/rpl_loadfile.test: Use new paths mysql-test/suite/rpl/t/rpl_misc_functions.test: Use new paths mysql-test/suite/rpl/t/rpl_replicate_do.test: Use new paths mysql-test/suite/rpl/t/rpl_rewrt_db.test: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs.test: Use new paths mysql-test/suite/rpl/t/rpl_row_charset_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test: Use new paths mysql-test/suite/rpl/t/rpl_row_stop_middle_update.test: Use new paths mysql-test/suite/rpl/t/rpl_timezone.test: Use new paths mysql-test/suite/rpl/t/rpl_trigger.test: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_innodb_trans.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_multi.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_row_001.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_sync.result: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_bank.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_dd_advance.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_load.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_sync.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndbapi_multi.test: Use new paths mysql-test/t/backup.test: Use new paths mysql-test/t/bootstrap.test: Use new paths mysql-test/t/crash_commit_before.test: Use new paths mysql-test/t/create_not_windows.test: Use new paths mysql-test/t/csv.test: Use new paths mysql-test/t/ctype_big5.test: Use new paths mysql-test/t/disabled.def: Use new paths mysql-test/t/distinct.test: Use new paths mysql-test/t/gis.test: Use new paths mysql-test/t/grant_cache_no_prot.test: Use new paths mysql-test/t/grant_cache_ps_prot.test: Use new paths mysql-test/t/information_schema_chmod.test: Use new paths mysql-test/t/loaddata.test: Use new paths mysql-test/t/log_state.test: Use new paths mysql-test/t/myisam-system.test: Use new paths mysql-test/t/mysql_upgrade.test: Use new paths mysql-test/t/mysqlbinlog-cp932.test: Use new paths mysql-test/t/mysqlbinlog.test: Use new paths mysql-test/t/mysqlbinlog2.test: Use new paths mysql-test/t/mysqlbinlog_base64.test: Use new paths mysql-test/t/mysqldump.test: Use new paths mysql-test/t/outfile.test: Use new paths mysql-test/t/partition.test: Use new paths mysql-test/t/partition_error.test: Use new paths mysql-test/t/partition_federated.test: Use new paths mysql-test/t/partition_mgm.test: Use new paths mysql-test/t/partition_not_windows.test: Use new paths mysql-test/t/partition_symlink.test: Use new paths mysql-test/t/query_cache.test: Use new paths mysql-test/t/repair.test: Use new paths mysql-test/t/show_check.test: Use new paths mysql-test/t/sp-destruct.test: Use new paths mysql-test/t/sp.test: Use new paths mysql-test/t/symlink.test: Use new paths mysql-test/t/system_mysql_db.test: Use new paths mysql-test/t/system_mysql_db_fix30020.test: Use new paths mysql-test/t/system_mysql_db_fix40123.test: Use new paths mysql-test/t/system_mysql_db_fix50030.test: Use new paths mysql-test/t/system_mysql_db_fix50117.test: Use new paths mysql-test/t/trigger-compat.test: Use new paths mysql-test/t/trigger-grant.test: Use new paths mysql-test/t/trigger.test: Use new paths mysql-test/t/type_blob.test: Use new paths mysql-test/t/type_varchar.test: Use new paths mysql-test/t/upgrade.test: Use new paths mysql-test/t/user_var-binlog.test: Use new paths mysql-test/t/varbinary.test: Use new paths mysql-test/t/view.test: Use new paths mysql-test/t/warnings.test: Use new paths mysql-test/lib/My/ConfigFactory.pm: Initial version mysql-test/lib/My/Find.pm: Initial version mysql-test/lib/My/SafeProcess.pm: Initial version mysql-test/std_data/ndb_config_config.ini: Add "old" style config.ini for ndb mysql-test/suite/federated/disabled.def: Move disabled federated to it's new suite mysql-test/suite/federated/my.cnf: Add config for federated mysql-test/suite/ndb/my.cnf: Add config for ndb mysql-test/suite/rpl/my.cnf: Add config for rpl mysql-test/suite/rpl/rpl_1slave_base.cnf: Add base config for rpl mysql-test/suite/rpl/t/rpl_000015-master.opt: Use new paths mysql-test/suite/rpl_ndb/my.cnf: Add config for rpl_ndb mysql-test/lib/My/File/Path.pm: Initial version mysql-test/lib/My/SafeProcess/Base.pm: Initial version mysql-test/lib/My/SafeProcess/safe_kill_win.cc: Initial version mysql-test/lib/My/SafeProcess/safe_process.pl: Initial version mysql-test/lib/My/SafeProcess/safe_process_win.cc: Initial version mysql-test/lib/t/Base.t: Initial version mysql-test/lib/t/Find.t: Initial version mysql-test/lib/t/SafeProcess.t: Initial version mysql-test/lib/t/SafeProcessStress.pl: Initial version mysql-test/lib/t/copytree.t: Initial version mysql-test/lib/t/dummyd.pl: Initial version mysql-test/lib/t/rmtree.t: Initial version mysql-test/lib/t/testMyConfig.t: Initial version mysql-test/lib/t/testMyConfigFactory.t: Initial version mysql-test/lib/t/test_child.pl: Initial version mysql-test/include/default_my.cnf: Add default config file used when no suite specific file is found mysql-test/include/default_mysqld.cnf: New BitKeeper file ``mysql-test/include/default_mysqld.cnf'' mysql-test/include/default_ndbd.cnf: Add default settings for all ndbds mysql-test/lib/mtr_settings.pl: Initial version
2007-12-12 18:19:24 +01:00
load data infile '../../std_data/loaddata5.dat' into table t1 fields terminated by '' enclosed by '' (i, k);
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
insert into t1 select 3, 3;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
update t1, t2 set k = k + 10 where t1.i = t2.i;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
update t1, t2 set k = k + 10 where t1.i = t2.i and k < 2;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
delete t1, t2 from t1 straight_join t2 where t1.i = t2.i;
ERROR 42S22: Unknown column 'bt' in 'OLD'
select * from t1;
i k
1 1
2 2
delete t2, t1 from t2 straight_join t1 where t1.i = t2.i;
ERROR 42S22: Unknown column 'bt' in 'OLD'
select * from t1;
i k
1 1
2 2
alter table t1 add primary key (i);
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger bi;
insert into t1 values (2, 4) on duplicate key update k= k + 10;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
i k
1 1
2 2
replace into t1 values (2, 4);
Fix for bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". In cases when REPLACE was internally executed via update and table had on update (on delete) triggers defined we exposed the fact that such optimization used by callng on update (not calling on delete) triggers. Such behavior contradicts our documentation which describes REPLACE as INSERT with optional DELETE. This fix just disables this optimization for tables with on delete triggers. The optimization is still applied for tables which have on update but have no on delete triggers, we just don't invoke on update triggers in this case and thus don't expose information about optimization to user. Also added test coverage for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. mysql-test/r/insert.result: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/r/trigger.result: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". mysql-test/t/insert.test: Added test for values returned by ROW_COUNT() function (and thus for values returned by mysql_affected_rows()) for various forms of INSERT. We didn't have coverage for this before and since this fix touches related code it is better to add it now. mysql-test/t/trigger.test: Adjusted test after fixing bug#13479 "REPLACE activates UPDATE trigger, not the DELETE and INSERT triggers". sql/sql_insert.cc: write_record(): We should not expose that internally we sometimes execute REPLACE via UPDATE instead of documented INSERT + DELETE pair. So we should not use this optimization for tables with on delete triggers. OTOH it is ok to use it for tables which have on update but have no on delete triggers, we just should not invoke on update triggers in this case.
2006-06-16 18:21:25 +02:00
ERROR 42S22: Unknown column 'bt' in 'OLD'
select * from t1;
i k
1 1
2 2
drop table t1, t2;
drop function if exists bug5893;
create table t1 (col1 int, col2 int);
insert into t1 values (1, 2);
create function bug5893 () returns int return 5;
create trigger t1_bu before update on t1 for each row set new.col1= bug5893();
drop function bug5893;
update t1 set col2 = 4;
ERROR 42000: FUNCTION test.bug5893 does not exist
Fix for bugs #5892/6182/8751/8758/10994 (based on Antony's patch) "Triggers have the wrong namespace" "Triggers: duplicate names allowed" "Triggers: CREATE TRIGGER does not accept fully qualified names" "SHOW TRIGGERS" mysql-test/r/information_schema.result: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/r/information_schema_db.result: INFORMATION_SCHEMA.TRIGGERS view was added. mysql-test/r/rpl_sp.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/r/trigger.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/r/view.result: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/information_schema.test: Added tests for new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. mysql-test/t/rpl_sp.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. mysql-test/t/trigger.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. Added test checking that triggers have database wide namespace. Added test for bug #8791 "Triggers: Allowed to create triggers on a subject table in a different DB". mysql-test/t/view.test: Now DROP TRIGGER interprets first part of trigger identifier as database name and not as table name. Adjusted tests properly. sql/handler.cc: Added .TRN tho the list of known file extensions assoicated with tables. sql/item.h: trg_action_time_type/trg_event_type enums: Added TRG_ACTION_MAX/TRG_EVENT_MAX elements which should be used instead of magical values in various loops where we iterate through all types of trigger action times or/and trigger event types. sql/lex.h: Added new symbol "TRIGGERS". sql/mysql_priv.h: Added declaration of constant holding extension for trigger name (.TRN) files. sql/mysqld.cc: Added statistical variable for SHOW TRIGGERS command. sql/share/errmsg.txt: Added error message saying that one attempts to create trigger in wrong schema. sql/sp.cc: Replaced magical values with TRG_EVENT_MAX/TRG_ACTION_MAX constants. sql/sql_base.cc: open_unireg_entry(): Now Table_triggers_list::check_n_load() has one more argument which controls whether we should prepare Table_triggers_list with fully functional triggers or load only their names. sql/sql_lex.h: Added element for new SHOW TRIGGERS command to enum_sql_command enum. sql/sql_parse.cc: prepare_schema_table(): Added support for SHOW TRIGGERS statement. sql/sql_show.cc: Added new INFORMATION_SCHEMA.TRIGGERS view and SHOW TRIGGERS command. sql/sql_table.cc: mysql_rm_table_part2(): Replaced simple deletion of .TRG file with call to Table_triggers_list::drop_all_triggers which will also delete .TRN files for all triggers associated with table. sql/sql_trigger.cc: Now triggers have database wide namespace. To support it we create special .TRN file with same name as trigger for each trigger. This file contains name of trigger's table so one does not need to specify it explicitly in DROP TRIGGER. Moreover DROP TRIGGER treats first part of trigger identifier as database name now. Updated mysql_create_or_drop_trigger() routine and Table_triggers_list::create_trigger()/drop_trigger()/check_n_load() methods accordingly. Added add_table_for_trigger() routine and Table_triggers_list::drop_all_triggers() method. Added Table_triggers_list::get_trigger_info() for obtaining trigger metadata. sql/sql_trigger.h: Table_triggers_list: Use TRG_EVENT_MAX, TRG_ACTION_MAX instead of magic values. Added get_trigger_info() method for obtaining trigger's meta-data. Added drop_all_triggers() method which drops all triggers for table. Added declarations of trg_action_time_type_names/trg_event_type_names arrays which hold names of triggers action time types and event types. sql/sql_yacc.yy: Changed grammar for CREATE/DROP TRIGGER to support database wide trigger namespace. Added new SHOW TRIGGERS statement. sql/table.h: enum enum_schema_tables: Added constant for new INFORMATION_SCHEMA.TRIGGERS view.
2005-07-19 18:06:49 +02:00
drop trigger t1_bu;
drop table t1;
set sql_mode='ansi';
create table t1 ("t1 column" int);
create trigger t1_bi before insert on t1 for each row set new."t1 column" = 5;
2005-07-30 08:24:51 +02:00
set sql_mode="";
insert into t1 values (0);
create trigger t1_af after insert on t1 for each row set @a=10;
insert into t1 values (0);
select * from t1;
t1 column
5
5
select @a;
@a
10
show triggers;
Patch for the following bugs: - BUG#11986: Stored routines and triggers can fail if the code has a non-ascii symbol - BUG#16291: mysqldump corrupts string-constants with non-ascii-chars - BUG#19443: INFORMATION_SCHEMA does not support charsets properly - BUG#21249: Character set of SP-var can be ignored - BUG#25212: Character set of string constant is ignored (stored routines) - BUG#25221: Character set of string constant is ignored (triggers) There were a few general problems that caused these bugs: 1. Character set information of the original (definition) query for views, triggers, stored routines and events was lost. 2. mysqldump output query in client character set, which can be inappropriate to encode definition-query. 3. INFORMATION_SCHEMA used strings with mixed encodings to display object definition; 1. No query-definition-character set. In order to compile query into execution code, some extra data (such as environment variables or the database character set) is used. The problem here was that this context was not preserved. So, on the next load it can differ from the original one, thus the result will be different. The context contains the following data: - client character set; - connection collation (character set and collation); - collation of the owner database; The fix is to store this context and use it each time we parse (compile) and execute the object (stored routine, trigger, ...). 2. Wrong mysqldump-output. The original query can contain several encodings (by means of character set introducers). The problem here was that we tried to convert original query to the mysqldump-client character set. Moreover, we stored queries in different character sets for different objects (views, for one, used UTF8, triggers used original character set). The solution is - to store definition queries in the original character set; - to change SHOW CREATE statement to output definition query in the binary character set (i.e. without any conversion); - introduce SHOW CREATE TRIGGER statement; - to dump special statements to switch the context to the original one before dumping and restore it afterwards. Note, in order to preserve the database collation at the creation time, additional ALTER DATABASE might be used (to temporary switch the database collation back to the original value). In this case, ALTER DATABASE privilege will be required. This is a backward-incompatible change. 3. INFORMATION_SCHEMA showed non-UTF8 strings The fix is to generate UTF8-query during the parsing, store it in the object and show it in the INFORMATION_SCHEMA. Basically, the idea is to create a copy of the original query convert it to UTF8. Character set introducers are removed and all text literals are converted to UTF8. This UTF8 query is intended to provide user-readable output. It must not be used to recreate the object. Specialized SHOW CREATE statements should be used for this. The reason for this limitation is the following: the original query can contain symbols from several character sets (by means of character set introducers). Example: - original query: CREATE VIEW v1 AS SELECT _cp1251 'Hello' AS c1; - UTF8 query (for INFORMATION_SCHEMA): CREATE VIEW v1 AS SELECT 'Hello' AS c1; client/mysqldump.c: Set original character set and collation before dumping definition query. include/my_sys.h: Move out-parameter to the end of list. mysql-test/lib/mtr_report.pl: Ignore server-warnings during the test case. mysql-test/r/create.result: Update result file. mysql-test/r/ctype_cp932_binlog_stm.result: Update result file. mysql-test/r/events.result: Update result file. mysql-test/r/events_bugs.result: Update result file. mysql-test/r/events_grant.result: Update result file. mysql-test/r/func_in.result: Update result file. mysql-test/r/gis.result: Update result file. mysql-test/r/grant.result: Update result file. mysql-test/r/information_schema.result: Update result file. mysql-test/r/information_schema_db.result: Update result file. mysql-test/r/lowercase_view.result: Update result file. mysql-test/r/mysqldump.result: Update result file. mysql-test/r/ndb_sp.result: Update result file. mysql-test/r/ps.result: Update result file. mysql-test/r/rpl_replicate_do.result: Update result file. mysql-test/r/rpl_sp.result: Update result file. mysql-test/r/rpl_trigger.result: Update result file. mysql-test/r/rpl_view.result: Update result file. mysql-test/r/show_check.result: Update result file. mysql-test/r/skip_grants.result: Update result file. mysql-test/r/sp-destruct.result: Update result file. mysql-test/r/sp-error.result: Update result file. mysql-test/r/sp-security.result: Update result file. mysql-test/r/sp.result: Update result file. mysql-test/r/sql_mode.result: Update result file. mysql-test/r/system_mysql_db.result: Update result file. mysql-test/r/temp_table.result: Update result file. mysql-test/r/trigger-compat.result: Update result file. mysql-test/r/trigger-grant.result: Update result file. mysql-test/r/trigger.result: Update result file. mysql-test/r/view.result: Update result file. mysql-test/r/view_grant.result: Update result file. mysql-test/t/events.test: Update test case (new columns added). mysql-test/t/information_schema.test: Update test case (new columns added). mysql-test/t/show_check.test: Test case for SHOW CREATE TRIGGER in prepared statements and stored routines. mysql-test/t/sp-destruct.test: Update test case (new columns added). mysql-test/t/sp.test: Update test case (new columns added). mysql-test/t/view.test: Update test. mysys/charset.c: Move out-parameter to the end of list. scripts/mysql_system_tables.sql: Add new columns to mysql.proc and mysql.event. scripts/mysql_system_tables_fix.sql: Add new columns to mysql.proc and mysql.event. sql/event_data_objects.cc: Support new attributes for events. sql/event_data_objects.h: Support new attributes for events. sql/event_db_repository.cc: Support new attributes for events. sql/event_db_repository.h: Support new attributes for events. sql/events.cc: Add new columns to SHOW CREATE event resultset. sql/mysql_priv.h: 1. Introduce Object_creation_ctx; 2. Introduce SHOW CREATE TRIGGER; 3. Introduce auxilary functions. sql/sp.cc: Add support for new store routines attributes. sql/sp_head.cc: Add support for new store routines attributes. sql/sp_head.h: Add support for new store routines attributes. sql/sql_lex.cc: Generate UTF8-body on parsing/lexing. sql/sql_lex.h: 1. Generate UTF8-body on parsing/lexing. 2. Introduce SHOW CREATE TRIGGER. sql/sql_parse.cc: Introduce SHOW CREATE TRIGGER. sql/sql_partition.cc: Update parse_sql(). sql/sql_prepare.cc: Update parse_sql(). sql/sql_show.cc: Support new attributes for views sql/sql_trigger.cc: Support new attributes for views sql/sql_trigger.h: Support new attributes for views sql/sql_view.cc: Support new attributes for views sql/sql_yacc.yy: 1. Add SHOW CREATE TRIGGER statement. 2. Generate UTF8-body for views, stored routines, triggers and events. sql/table.cc: Introduce Object_creation_ctx. sql/table.h: Introduce Object_creation_ctx. sql/share/errmsg.txt: Add new errors. mysql-test/include/ddl_i18n.check_events.inc: Aux file for test suite. mysql-test/include/ddl_i18n.check_sp.inc: Aux file for test suite. mysql-test/include/ddl_i18n.check_triggers.inc: Aux file for test suite. mysql-test/include/ddl_i18n.check_views.inc: Aux file for test suite. mysql-test/include/have_cp1251.inc: Aux file for test suite. mysql-test/include/have_cp866.inc: Aux file for test suite. mysql-test/include/have_koi8r.inc: Aux file for test suite. mysql-test/include/have_utf8.inc: Aux file for test suite. mysql-test/r/ddl_i18n_koi8r.result: Result file. mysql-test/r/ddl_i18n_utf8.result: Result file. mysql-test/r/have_cp1251.require: Aux file for test suite. mysql-test/r/have_cp866.require: Aux file for test suite. mysql-test/r/have_koi8r.require: Aux file for test suite. mysql-test/r/have_utf8.require: Aux file for test suite. mysql-test/t/ddl_i18n_koi8r.test: Complete koi8r test case for the CS patch. mysql-test/t/ddl_i18n_utf8.test: Complete utf8 test case for the CS patch.
2007-06-28 19:34:54 +02:00
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
t1_bi INSERT t1 set new."t1 column" = 5 BEFORE # REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
t1_af INSERT t1 set @a=10 AFTER # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
drop table t1;
set sql_mode="traditional";
create table t1 (a date);
insert into t1 values ('2004-01-00');
ERROR 22007: Incorrect date value: '2004-01-00' for column 'a' at row 1
set sql_mode="";
create trigger t1_bi before insert on t1 for each row set new.a = '2004-01-00';
set sql_mode="traditional";
insert into t1 values ('2004-01-01');
select * from t1;
a
2004-01-00
set sql_mode=default;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
Bug#10460 SHOW CREATE TABLE uses inconsistent upper/lower case mysql-test/r/alter_table.result: Update test result mysql-test/r/analyse.result: Update test result mysql-test/r/archive.result: Update test result mysql-test/r/archive_bitfield.result: Update test result mysql-test/r/archive_gis.result: Update test result mysql-test/r/bdb.result: Update test result mysql-test/r/bdb_gis.result: Update test result mysql-test/r/bigint.result: Update test result mysql-test/r/binary.result: Update test result mysql-test/r/case.result: Update test result mysql-test/r/cast.result: Update test result mysql-test/r/constraints.result: Update test result mysql-test/r/create.result: Update test result mysql-test/r/ctype_collate.result: Update test result mysql-test/r/ctype_create.result: Update test result mysql-test/r/ctype_latin1_de.result: Update test result mysql-test/r/ctype_many.result: Update test result mysql-test/r/ctype_mb.result: Update test result mysql-test/r/ctype_recoding.result: Update test result mysql-test/r/ctype_sjis.result: Update test result mysql-test/r/ctype_tis620.result: Update test result mysql-test/r/ctype_ucs.result: Update test result mysql-test/r/ctype_ujis.result: Update test result mysql-test/r/ctype_utf8.result: Update test result mysql-test/r/default.result: Update test result mysql-test/r/events.result: Update test result mysql-test/r/federated.result: Update test result mysql-test/r/fulltext.result: Update test result mysql-test/r/func_gconcat.result: Update test result mysql-test/r/func_group.result: Update test result mysql-test/r/func_math.result: Update test result mysql-test/r/func_misc.result: Update test result mysql-test/r/func_str.result: Update test result mysql-test/r/func_system.result: Update test result mysql-test/r/gis-rtree.result: Update test result mysql-test/r/heap.result: Update test result mysql-test/r/index_merge_innodb.result: Update test result mysql-test/r/information_schema.result: Update test result mysql-test/r/innodb.result: Update test result mysql-test/r/innodb_gis.result: Update test result mysql-test/r/key.result: Update test result mysql-test/r/merge.result: Update test result mysql-test/r/myisam.result: Update test result mysql-test/r/mysqldump-max.result: Update test result mysql-test/r/mysqldump.result: Update test result mysql-test/r/ndb_bitfield.result: Update test result mysql-test/r/ndb_gis.result: Update test result mysql-test/r/ndb_partition_key.result: Update test result mysql-test/r/null.result: Update test result mysql-test/r/partition.result: Update test result mysql-test/r/partition_02myisam.result: Update test result mysql-test/r/partition_mgm_err.result: Update test result mysql-test/r/partition_range.result: Update test result mysql-test/r/ps_2myisam.result: Update test result mysql-test/r/ps_3innodb.result: Update test result mysql-test/r/ps_4heap.result: Update test result mysql-test/r/ps_5merge.result: Update test result mysql-test/r/ps_6bdb.result: Update test result mysql-test/r/rpl_mixed_ddl_dml.result: Update test result mysql-test/r/rpl_multi_engine.result: Update test result mysql-test/r/rpl_ndb_UUID.result: Update test result mysql-test/r/show_check.result: Update test result mysql-test/r/sp-vars.result: Update test result mysql-test/r/sp.result: Update test result mysql-test/r/sql_mode.result: Update test result mysql-test/r/strict.result: Update test result mysql-test/r/subselect.result: Update test result mysql-test/r/symlink.result: Update test result mysql-test/r/synchronization.result: Update test result mysql-test/r/system_mysql_db.result: Update test result mysql-test/r/temp_table.result: Update test result mysql-test/r/trigger.result: Update test result mysql-test/r/type_binary.result: Update test result mysql-test/r/type_bit.result: Update test result mysql-test/r/type_bit_innodb.result: Update test result mysql-test/r/type_blob.result: Update test result mysql-test/r/type_decimal.result: Update test result mysql-test/r/type_enum.result: Update test result mysql-test/r/type_float.result: Update test result mysql-test/r/type_nchar.result: Update test result mysql-test/r/type_newdecimal.result: Update test result mysql-test/r/type_set.result: Update test result mysql-test/r/type_timestamp.result: Update test result mysql-test/r/type_varchar.result: Update test result mysql-test/r/union.result: Update test result mysql-test/r/user_var.result: Update test result mysql-test/r/variables.result: Update test result sql/sql_show.cc: Make ouput from SHOW CREATE TABLE use uppercase for "CHARACTER SET", "COLLATE", "DEFAULT", "ON UPDATE" and "AUTO_INCREMENT"
2006-02-22 10:09:59 +01:00
`a` date DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show triggers;
Patch for the following bugs: - BUG#11986: Stored routines and triggers can fail if the code has a non-ascii symbol - BUG#16291: mysqldump corrupts string-constants with non-ascii-chars - BUG#19443: INFORMATION_SCHEMA does not support charsets properly - BUG#21249: Character set of SP-var can be ignored - BUG#25212: Character set of string constant is ignored (stored routines) - BUG#25221: Character set of string constant is ignored (triggers) There were a few general problems that caused these bugs: 1. Character set information of the original (definition) query for views, triggers, stored routines and events was lost. 2. mysqldump output query in client character set, which can be inappropriate to encode definition-query. 3. INFORMATION_SCHEMA used strings with mixed encodings to display object definition; 1. No query-definition-character set. In order to compile query into execution code, some extra data (such as environment variables or the database character set) is used. The problem here was that this context was not preserved. So, on the next load it can differ from the original one, thus the result will be different. The context contains the following data: - client character set; - connection collation (character set and collation); - collation of the owner database; The fix is to store this context and use it each time we parse (compile) and execute the object (stored routine, trigger, ...). 2. Wrong mysqldump-output. The original query can contain several encodings (by means of character set introducers). The problem here was that we tried to convert original query to the mysqldump-client character set. Moreover, we stored queries in different character sets for different objects (views, for one, used UTF8, triggers used original character set). The solution is - to store definition queries in the original character set; - to change SHOW CREATE statement to output definition query in the binary character set (i.e. without any conversion); - introduce SHOW CREATE TRIGGER statement; - to dump special statements to switch the context to the original one before dumping and restore it afterwards. Note, in order to preserve the database collation at the creation time, additional ALTER DATABASE might be used (to temporary switch the database collation back to the original value). In this case, ALTER DATABASE privilege will be required. This is a backward-incompatible change. 3. INFORMATION_SCHEMA showed non-UTF8 strings The fix is to generate UTF8-query during the parsing, store it in the object and show it in the INFORMATION_SCHEMA. Basically, the idea is to create a copy of the original query convert it to UTF8. Character set introducers are removed and all text literals are converted to UTF8. This UTF8 query is intended to provide user-readable output. It must not be used to recreate the object. Specialized SHOW CREATE statements should be used for this. The reason for this limitation is the following: the original query can contain symbols from several character sets (by means of character set introducers). Example: - original query: CREATE VIEW v1 AS SELECT _cp1251 'Hello' AS c1; - UTF8 query (for INFORMATION_SCHEMA): CREATE VIEW v1 AS SELECT 'Hello' AS c1; client/mysqldump.c: Set original character set and collation before dumping definition query. include/my_sys.h: Move out-parameter to the end of list. mysql-test/lib/mtr_report.pl: Ignore server-warnings during the test case. mysql-test/r/create.result: Update result file. mysql-test/r/ctype_cp932_binlog_stm.result: Update result file. mysql-test/r/events.result: Update result file. mysql-test/r/events_bugs.result: Update result file. mysql-test/r/events_grant.result: Update result file. mysql-test/r/func_in.result: Update result file. mysql-test/r/gis.result: Update result file. mysql-test/r/grant.result: Update result file. mysql-test/r/information_schema.result: Update result file. mysql-test/r/information_schema_db.result: Update result file. mysql-test/r/lowercase_view.result: Update result file. mysql-test/r/mysqldump.result: Update result file. mysql-test/r/ndb_sp.result: Update result file. mysql-test/r/ps.result: Update result file. mysql-test/r/rpl_replicate_do.result: Update result file. mysql-test/r/rpl_sp.result: Update result file. mysql-test/r/rpl_trigger.result: Update result file. mysql-test/r/rpl_view.result: Update result file. mysql-test/r/show_check.result: Update result file. mysql-test/r/skip_grants.result: Update result file. mysql-test/r/sp-destruct.result: Update result file. mysql-test/r/sp-error.result: Update result file. mysql-test/r/sp-security.result: Update result file. mysql-test/r/sp.result: Update result file. mysql-test/r/sql_mode.result: Update result file. mysql-test/r/system_mysql_db.result: Update result file. mysql-test/r/temp_table.result: Update result file. mysql-test/r/trigger-compat.result: Update result file. mysql-test/r/trigger-grant.result: Update result file. mysql-test/r/trigger.result: Update result file. mysql-test/r/view.result: Update result file. mysql-test/r/view_grant.result: Update result file. mysql-test/t/events.test: Update test case (new columns added). mysql-test/t/information_schema.test: Update test case (new columns added). mysql-test/t/show_check.test: Test case for SHOW CREATE TRIGGER in prepared statements and stored routines. mysql-test/t/sp-destruct.test: Update test case (new columns added). mysql-test/t/sp.test: Update test case (new columns added). mysql-test/t/view.test: Update test. mysys/charset.c: Move out-parameter to the end of list. scripts/mysql_system_tables.sql: Add new columns to mysql.proc and mysql.event. scripts/mysql_system_tables_fix.sql: Add new columns to mysql.proc and mysql.event. sql/event_data_objects.cc: Support new attributes for events. sql/event_data_objects.h: Support new attributes for events. sql/event_db_repository.cc: Support new attributes for events. sql/event_db_repository.h: Support new attributes for events. sql/events.cc: Add new columns to SHOW CREATE event resultset. sql/mysql_priv.h: 1. Introduce Object_creation_ctx; 2. Introduce SHOW CREATE TRIGGER; 3. Introduce auxilary functions. sql/sp.cc: Add support for new store routines attributes. sql/sp_head.cc: Add support for new store routines attributes. sql/sp_head.h: Add support for new store routines attributes. sql/sql_lex.cc: Generate UTF8-body on parsing/lexing. sql/sql_lex.h: 1. Generate UTF8-body on parsing/lexing. 2. Introduce SHOW CREATE TRIGGER. sql/sql_parse.cc: Introduce SHOW CREATE TRIGGER. sql/sql_partition.cc: Update parse_sql(). sql/sql_prepare.cc: Update parse_sql(). sql/sql_show.cc: Support new attributes for views sql/sql_trigger.cc: Support new attributes for views sql/sql_trigger.h: Support new attributes for views sql/sql_view.cc: Support new attributes for views sql/sql_yacc.yy: 1. Add SHOW CREATE TRIGGER statement. 2. Generate UTF8-body for views, stored routines, triggers and events. sql/table.cc: Introduce Object_creation_ctx. sql/table.h: Introduce Object_creation_ctx. sql/share/errmsg.txt: Add new errors. mysql-test/include/ddl_i18n.check_events.inc: Aux file for test suite. mysql-test/include/ddl_i18n.check_sp.inc: Aux file for test suite. mysql-test/include/ddl_i18n.check_triggers.inc: Aux file for test suite. mysql-test/include/ddl_i18n.check_views.inc: Aux file for test suite. mysql-test/include/have_cp1251.inc: Aux file for test suite. mysql-test/include/have_cp866.inc: Aux file for test suite. mysql-test/include/have_koi8r.inc: Aux file for test suite. mysql-test/include/have_utf8.inc: Aux file for test suite. mysql-test/r/ddl_i18n_koi8r.result: Result file. mysql-test/r/ddl_i18n_utf8.result: Result file. mysql-test/r/have_cp1251.require: Aux file for test suite. mysql-test/r/have_cp866.require: Aux file for test suite. mysql-test/r/have_koi8r.require: Aux file for test suite. mysql-test/r/have_utf8.require: Aux file for test suite. mysql-test/t/ddl_i18n_koi8r.test: Complete koi8r test case for the CS patch. mysql-test/t/ddl_i18n_utf8.test: Complete utf8 test case for the CS patch.
2007-06-28 19:34:54 +02:00
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
t1_bi INSERT t1 set new.a = '2004-01-00' BEFORE # root@localhost latin1 latin1_swedish_ci latin1_swedish_ci
drop table t1;
Fix for bug #12280 "Triggers: crash if flush tables". We should not allow FLUSH statement to be executed inside both triggers and stored functions. mysql-test/r/sp-error.result: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/r/trigger.result: Added test for bug #12280 "Triggers: crash if flush tables" mysql-test/t/sp-error.test: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/t/trigger.test: Added test for bug #12280 "Triggers: crash if flush tables" sql/share/errmsg.txt: Removed ER_SP_NO_USE error. Now we use more general ER_SP_BADSTATEMENT in this case. Instead added error message for barking about statements which should not be allowed inside of stored functions or triggers. It is safe to do this since it is highly unprobable that someone will upgrade first to the new 5.0 release and then downgrade back to the old one. sql/sql_parse.cc: reload_acl_and_cache(): FLUSH TABLES and FLUSH PRIVILEGES should not be allowed if we are inside of stored function or trigger. sql/sql_yacc.yy: We should not allow FLUSH statement inside both triggers and stored functions. Replaced error which is thrown in this case with more specific. Also now we issue more general ER_SP_BADSTATEMENT error when one tries to use USE command inside of stored routine.
2005-08-10 08:31:32 +02:00
create table t1 (id int);
Fix for bug#21795: SP: sp_head::is_not_allowed_in_function() contains erroneous check Problem: Actually there were two problems in the server code. The check for SQLCOM_FLUSH in SF/Triggers were not according to the existing architecture which uses sp_get_flags_for_command() from sp_head.cc . This function was also missing a check for SQLCOM_FLUSH which has a problem combined with prelocking. This changeset fixes both of these deficiencies as well as the erroneous check in sp_head::is_not_allowed_in_function() which was a copy&paste error. mysql-test/r/sp-error.result: update result mysql-test/r/trigger.result: update result mysql-test/t/sp-error.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. mysql-test/t/trigger.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. sql/sp_head.cc: FLUSH and RESET are not allowed inside a SF/Trigger. Because they don't imply a COMMIT sp_head::HAS_COMMIT_OR_ROLLBACK cannot be used. Two new flags were introduced for that reason. sql/sp_head.h: Don't check m_type as this check is erroneous. This is probably a copy and paste error when moving code from somewhere else. Another fact which supports this was prefixing the enum value with the name of class sp_head. Adding two new flags HAS_SQLCOM_RESET and HAS_SQLCOM_FLUSH. The values are 2048 and 4096 because in the 5.1 branch there are already new flags which are with values up-to 1024. sql/sql_parse.cc: FLUSH can cause a problem with prelocking in SF/Trigger and therefore is already disabled. RESET is also disabled because is handled by the same code as FLUSH. We won't allow RESET inside SF/Trigger at that stage without thorough analysis. The check for them is already done in the parser by calling is_not_allowed_in_function() sql/sql_yacc.yy: By listing SQLCOM_FLUSH as command which implies COMMIT in sp_get_flags_for_command() the check in sql_yacc.yy is obsolete.
2006-08-25 15:51:29 +02:00
create trigger t1_ai after insert on t1 for each row reset query cache;
ERROR 0A000: RESET is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row reset master;
ERROR 0A000: RESET is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row reset slave;
ERROR 0A000: RESET is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush hosts;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush tables with read lock;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush logs;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush status;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush slave;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush master;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush des_key_file;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush user_resources;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
Fix for bug #12280 "Triggers: crash if flush tables". We should not allow FLUSH statement to be executed inside both triggers and stored functions. mysql-test/r/sp-error.result: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/r/trigger.result: Added test for bug #12280 "Triggers: crash if flush tables" mysql-test/t/sp-error.test: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/t/trigger.test: Added test for bug #12280 "Triggers: crash if flush tables" sql/share/errmsg.txt: Removed ER_SP_NO_USE error. Now we use more general ER_SP_BADSTATEMENT in this case. Instead added error message for barking about statements which should not be allowed inside of stored functions or triggers. It is safe to do this since it is highly unprobable that someone will upgrade first to the new 5.0 release and then downgrade back to the old one. sql/sql_parse.cc: reload_acl_and_cache(): FLUSH TABLES and FLUSH PRIVILEGES should not be allowed if we are inside of stored function or trigger. sql/sql_yacc.yy: We should not allow FLUSH statement inside both triggers and stored functions. Replaced error which is thrown in this case with more specific. Also now we issue more general ER_SP_BADSTATEMENT error when one tries to use USE command inside of stored routine.
2005-08-10 08:31:32 +02:00
create trigger t1_ai after insert on t1 for each row flush tables;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
create trigger t1_ai after insert on t1 for each row flush privileges;
ERROR 0A000: FLUSH is not allowed in stored function or trigger
Fix for bug#21795: SP: sp_head::is_not_allowed_in_function() contains erroneous check Problem: Actually there were two problems in the server code. The check for SQLCOM_FLUSH in SF/Triggers were not according to the existing architecture which uses sp_get_flags_for_command() from sp_head.cc . This function was also missing a check for SQLCOM_FLUSH which has a problem combined with prelocking. This changeset fixes both of these deficiencies as well as the erroneous check in sp_head::is_not_allowed_in_function() which was a copy&paste error. mysql-test/r/sp-error.result: update result mysql-test/r/trigger.result: update result mysql-test/t/sp-error.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. mysql-test/t/trigger.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. sql/sp_head.cc: FLUSH and RESET are not allowed inside a SF/Trigger. Because they don't imply a COMMIT sp_head::HAS_COMMIT_OR_ROLLBACK cannot be used. Two new flags were introduced for that reason. sql/sp_head.h: Don't check m_type as this check is erroneous. This is probably a copy and paste error when moving code from somewhere else. Another fact which supports this was prefixing the enum value with the name of class sp_head. Adding two new flags HAS_SQLCOM_RESET and HAS_SQLCOM_FLUSH. The values are 2048 and 4096 because in the 5.1 branch there are already new flags which are with values up-to 1024. sql/sql_parse.cc: FLUSH can cause a problem with prelocking in SF/Trigger and therefore is already disabled. RESET is also disabled because is handled by the same code as FLUSH. We won't allow RESET inside SF/Trigger at that stage without thorough analysis. The check for them is already done in the parser by calling is_not_allowed_in_function() sql/sql_yacc.yy: By listing SQLCOM_FLUSH as command which implies COMMIT in sp_get_flags_for_command() the check in sql_yacc.yy is obsolete.
2006-08-25 15:51:29 +02:00
drop procedure if exists p1;
Fix for bug #12280 "Triggers: crash if flush tables". We should not allow FLUSH statement to be executed inside both triggers and stored functions. mysql-test/r/sp-error.result: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/r/trigger.result: Added test for bug #12280 "Triggers: crash if flush tables" mysql-test/t/sp-error.test: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/t/trigger.test: Added test for bug #12280 "Triggers: crash if flush tables" sql/share/errmsg.txt: Removed ER_SP_NO_USE error. Now we use more general ER_SP_BADSTATEMENT in this case. Instead added error message for barking about statements which should not be allowed inside of stored functions or triggers. It is safe to do this since it is highly unprobable that someone will upgrade first to the new 5.0 release and then downgrade back to the old one. sql/sql_parse.cc: reload_acl_and_cache(): FLUSH TABLES and FLUSH PRIVILEGES should not be allowed if we are inside of stored function or trigger. sql/sql_yacc.yy: We should not allow FLUSH statement inside both triggers and stored functions. Replaced error which is thrown in this case with more specific. Also now we issue more general ER_SP_BADSTATEMENT error when one tries to use USE command inside of stored routine.
2005-08-10 08:31:32 +02:00
create trigger t1_ai after insert on t1 for each row call p1();
Fix for bug#21795: SP: sp_head::is_not_allowed_in_function() contains erroneous check Problem: Actually there were two problems in the server code. The check for SQLCOM_FLUSH in SF/Triggers were not according to the existing architecture which uses sp_get_flags_for_command() from sp_head.cc . This function was also missing a check for SQLCOM_FLUSH which has a problem combined with prelocking. This changeset fixes both of these deficiencies as well as the erroneous check in sp_head::is_not_allowed_in_function() which was a copy&paste error. mysql-test/r/sp-error.result: update result mysql-test/r/trigger.result: update result mysql-test/t/sp-error.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. mysql-test/t/trigger.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. sql/sp_head.cc: FLUSH and RESET are not allowed inside a SF/Trigger. Because they don't imply a COMMIT sp_head::HAS_COMMIT_OR_ROLLBACK cannot be used. Two new flags were introduced for that reason. sql/sp_head.h: Don't check m_type as this check is erroneous. This is probably a copy and paste error when moving code from somewhere else. Another fact which supports this was prefixing the enum value with the name of class sp_head. Adding two new flags HAS_SQLCOM_RESET and HAS_SQLCOM_FLUSH. The values are 2048 and 4096 because in the 5.1 branch there are already new flags which are with values up-to 1024. sql/sql_parse.cc: FLUSH can cause a problem with prelocking in SF/Trigger and therefore is already disabled. RESET is also disabled because is handled by the same code as FLUSH. We won't allow RESET inside SF/Trigger at that stage without thorough analysis. The check for them is already done in the parser by calling is_not_allowed_in_function() sql/sql_yacc.yy: By listing SQLCOM_FLUSH as command which implies COMMIT in sp_get_flags_for_command() the check in sql_yacc.yy is obsolete.
2006-08-25 15:51:29 +02:00
create procedure p1() flush tables;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() reset query cache;
insert into t1 values (0);
ERROR 0A000: RESET is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() reset master;
insert into t1 values (0);
ERROR 0A000: RESET is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() reset slave;
insert into t1 values (0);
ERROR 0A000: RESET is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush hosts;
Fix for bug #12280 "Triggers: crash if flush tables". We should not allow FLUSH statement to be executed inside both triggers and stored functions. mysql-test/r/sp-error.result: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/r/trigger.result: Added test for bug #12280 "Triggers: crash if flush tables" mysql-test/t/sp-error.test: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/t/trigger.test: Added test for bug #12280 "Triggers: crash if flush tables" sql/share/errmsg.txt: Removed ER_SP_NO_USE error. Now we use more general ER_SP_BADSTATEMENT in this case. Instead added error message for barking about statements which should not be allowed inside of stored functions or triggers. It is safe to do this since it is highly unprobable that someone will upgrade first to the new 5.0 release and then downgrade back to the old one. sql/sql_parse.cc: reload_acl_and_cache(): FLUSH TABLES and FLUSH PRIVILEGES should not be allowed if we are inside of stored function or trigger. sql/sql_yacc.yy: We should not allow FLUSH statement inside both triggers and stored functions. Replaced error which is thrown in this case with more specific. Also now we issue more general ER_SP_BADSTATEMENT error when one tries to use USE command inside of stored routine.
2005-08-10 08:31:32 +02:00
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush privileges;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
Fix for bug#21795: SP: sp_head::is_not_allowed_in_function() contains erroneous check Problem: Actually there were two problems in the server code. The check for SQLCOM_FLUSH in SF/Triggers were not according to the existing architecture which uses sp_get_flags_for_command() from sp_head.cc . This function was also missing a check for SQLCOM_FLUSH which has a problem combined with prelocking. This changeset fixes both of these deficiencies as well as the erroneous check in sp_head::is_not_allowed_in_function() which was a copy&paste error. mysql-test/r/sp-error.result: update result mysql-test/r/trigger.result: update result mysql-test/t/sp-error.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. mysql-test/t/trigger.test: FLUSH can create a problem with prelocking, hence it's disabled. There is a better way to check this than a check in the parser. Now we use sp_get_flags_for_command() and the error returned is different. sql/sp_head.cc: FLUSH and RESET are not allowed inside a SF/Trigger. Because they don't imply a COMMIT sp_head::HAS_COMMIT_OR_ROLLBACK cannot be used. Two new flags were introduced for that reason. sql/sp_head.h: Don't check m_type as this check is erroneous. This is probably a copy and paste error when moving code from somewhere else. Another fact which supports this was prefixing the enum value with the name of class sp_head. Adding two new flags HAS_SQLCOM_RESET and HAS_SQLCOM_FLUSH. The values are 2048 and 4096 because in the 5.1 branch there are already new flags which are with values up-to 1024. sql/sql_parse.cc: FLUSH can cause a problem with prelocking in SF/Trigger and therefore is already disabled. RESET is also disabled because is handled by the same code as FLUSH. We won't allow RESET inside SF/Trigger at that stage without thorough analysis. The check for them is already done in the parser by calling is_not_allowed_in_function() sql/sql_yacc.yy: By listing SQLCOM_FLUSH as command which implies COMMIT in sp_get_flags_for_command() the check in sql_yacc.yy is obsolete.
2006-08-25 15:51:29 +02:00
create procedure p1() flush tables with read lock;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush tables;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush logs;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush status;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush slave;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush master;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush des_key_file;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
create procedure p1() flush user_resources;
insert into t1 values (0);
ERROR 0A000: FLUSH is not allowed in stored function or trigger
drop procedure p1;
Fix for bug #12280 "Triggers: crash if flush tables". We should not allow FLUSH statement to be executed inside both triggers and stored functions. mysql-test/r/sp-error.result: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/r/trigger.result: Added test for bug #12280 "Triggers: crash if flush tables" mysql-test/t/sp-error.test: Updated test after replacing error, which is thrown when one uses FLUSH statement inside of stored function, with more specific. Also now we issue more general error when we barking about USE command in stored routines. mysql-test/t/trigger.test: Added test for bug #12280 "Triggers: crash if flush tables" sql/share/errmsg.txt: Removed ER_SP_NO_USE error. Now we use more general ER_SP_BADSTATEMENT in this case. Instead added error message for barking about statements which should not be allowed inside of stored functions or triggers. It is safe to do this since it is highly unprobable that someone will upgrade first to the new 5.0 release and then downgrade back to the old one. sql/sql_parse.cc: reload_acl_and_cache(): FLUSH TABLES and FLUSH PRIVILEGES should not be allowed if we are inside of stored function or trigger. sql/sql_yacc.yy: We should not allow FLUSH statement inside both triggers and stored functions. Replaced error which is thrown in this case with more specific. Also now we issue more general ER_SP_BADSTATEMENT error when one tries to use USE command inside of stored routine.
2005-08-10 08:31:32 +02:00
drop table t1;
Clumsy but working fix for bug #11973 "SELECT .. INTO var_name; in trigger cause crash on update". Let us update "thd" pointer in LEX, all its units and in LEX::result before executing statement in trigger body, since triggers are associated with TABLE object and because of this can be used in different threads. mysql-test/r/trigger.result: Added test case for bug #11973 "SELECT .. INTO var_name; in trigger cause crash on update". mysql-test/t/trigger.test: Added test case for bug #11973 "SELECT .. INTO var_name; in trigger cause crash on update". sql/item_subselect.cc: subselect_engine: Moved implementation of set_thd() method to item_subselect.cc, since now it also sets "thd" for subselect_engine::result. sql/item_subselect.h: subselect_engine: Moved implementation of set_thd() method to item_subselect.cc, since now it also sets "thd" for subselect_engine::result. sql/sql_class.h: select_result: Added set_thd() method for updating select_result::thd value (we need this in cases when statement to which this select_result belongs will be used in different threads, as it happens for statements in trigger body). multi_delete/multi_update: Got rid of redundant "thd" member (we already have it in select_result). sql/sql_delete.cc: multi_delete: Got rid of redundant "thd" member (we already have it in select_result). sql/sql_lex.h: st_select_lex_unit: Added set_thd() method for updating st_select_lex_unit::thd value (we need this in cases when statement to which this unit belongs will be used in different threads, as it happens for statements in trigger body). We don't update thd of select_result pointed by st_select_lex_unit::result in this method, since it is either have too short lifetime (i.e. created for each execution) or is accessible via Item_subquery or LEX::result and thus already taken care of. sql/sql_parse.cc: multi_delete: Got rid of redundant "thd" member (we already have it in select_result). sql/sql_prepare.cc: reinit_stmt_before_use(): We have to update "thd" pointer in LEX, all its units and in LEX::result, since statements which belong to trigger body are associated with TABLE object and because of this can be used in different threads. sql/sql_update.cc: multi_update: Got rid of redundant "thd" member (we already have it in select_result).
2005-08-09 22:23:56 +02:00
create table t1 (id int, data int, username varchar(16));
insert into t1 (id, data) values (1, 0);
create trigger t1_whoupdated before update on t1 for each row
begin
declare user varchar(32);
declare i int;
select user() into user;
set NEW.username = user;
select count(*) from ((select 1) union (select 2)) as d1 into i;
end|
update t1 set data = 1;
update t1 set data = 2;
drop table t1;
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''
2005-08-15 17:15:12 +02:00
create table t1 (c1 int, c2 datetime);
create trigger tr1 before insert on t1 for each row
begin
set new.c2= '2004-04-01';
select 'hello';
end|
ERROR 0A000: Not allowed to return a result set from a trigger
insert into t1 (c1) values (1),(2),(3);
select * from t1;
c1 c2
1 NULL
2 NULL
3 NULL
drop procedure if exists bug11587;
create procedure bug11587(x char(16))
begin
select "hello";
select "hello again";
end|
create trigger tr1 before insert on t1 for each row
begin
call bug11587();
set new.c2= '2004-04-02';
end|
insert into t1 (c1) values (4),(5),(6);
Implement WL#2661 "Prepared Statements: Dynamic SQL in Stored Procedures". The idea of the patch is to separate statement processing logic, such as parsing, validation of the parsed tree, execution and cleanup, from global query processing logic, such as logging, resetting priorities of a thread, resetting stored procedure cache, resetting thread count of errors and warnings. This makes PREPARE and EXECUTE behave similarly to the rest of SQL statements and allows their use in stored procedures. This patch contains a change in behaviour: until recently for each SQL prepared statement command, 2 queries were written to the general log, e.g. [Query] prepare stmt from @stmt_text; [Prepare] select * from t1 <-- contents of @stmt_text The chagne was necessary to prevent [Prepare] commands from being written to the general log when executing a stored procedure with Dynamic SQL. We should consider whether the old behavior is preferrable and probably restore it. This patch refixes Bug#7115, Bug#10975 (partially), Bug#10605 (various bugs in Dynamic SQL reported before it was disabled). mysql-test/r/not_embedded_server.result: Since we don't want to log Dynamic SQL in stored procedures, now the general log gets only one log entry per SQL statement. mysql-test/r/sp-error.result: - remove obsolete tests - a better error message for the case when a stored procedure that returns a result set is called from a function mysql-test/r/trigger.result: - a better error message for the case when a stored procedure that returns a result set is called from a trigger mysql-test/t/sp-error.test: - a better error message for the case when a stored procedure that returns a result set is called from a function. - move the comment to its place (end of file). mysql-test/t/trigger.test: - a better error message for the case when a stored procedure that returns a result set is called from a trigger sql/item_func.cc: - we need to pass sql_command explicitly to get_var_with_binlog, because when creating a query for SQL prepared statement thd->lex->sql_command points at SQLCOM_EXECUTE, which is not listed in the list of update queries. sql/log_event.h: - remove an extra copy of the previous sentence sql/mysql_priv.h: - fix declarations of sql_prepare.cc API sql/share/errmsg.txt: - a new error message, when one attempts to execute a prepared statement which is currently being executed (this can happen only in Dynamic SQL at the moment). sql/sp_head.cc: - extend sp_multi_results_command to return different flags for a command (and rename it) - add support for SQLCOM_PREPARE,SQLCOM_EXECUTE, SQLCOM_DEALLOCATE to sp_get_flags_for_command - replace multiple boolean sp_head members with uint m_flags - a fix for a crash when user variables are used in a stored procedure and binlog is on. A temporary fix for Bug#12637 "SP crashes the server if it has update query with user var & binlog is enabled", which actually stands for stored functions: now instead of a crash we break replication if a user variable is used in a stored function which is executed in prelocked mode. sql/sp_head.h: - replace multiple boolean flags of sp_head with uint m_flags; - add flag CONTAINS_DYNAMIC_SQL - use this flag to error if a stored procedure with Dynamic SQL is called from a function or trigger. sql/sql_class.cc: - Statement_map::insert should not delete a statement if it exists, now it's done externally to be able to handle the case when the statement being deleted is in use. - remove extra code (free_list is already reset in free_items) sql/sql_lex.cc: - add lex->stmt_prepare_mode; we can't rely on thd->command any more, because we don't reset it any more (Dynamic SQL requirement is that PS are as little intrusive as possible). sql/sql_lex.h: - declare bool LEX::stmt_prepare_mode sql/sql_parse.cc: - move prepared statement code to sql_prepare.cc - change declarations (refactored code) - better error message when one attempts to use Dynamic SQL or a stored procedure that returns a result set in a function or trigger. sql/sql_prepare.cc: - major refactoring to ensure PREPARE/EXECUTE commands do not reset global THD state and allow their use in stored procedures. - add Prepared_statement::flags and use it to ensure no recursive execution of a prepared statement is possible - better comments sql/sql_yacc.yy: - enable PREPARE/EXECUTE/DEALLOCATE in stored procedures - produce an error message on attempt to use PREPARE/EXECUTE/DEALLOCATE in a stored function or trigger mysql-test/r/sp-dynamic.result: - sp-dynamic.test results mysql-test/t/sp-dynamic.test: - a new test for PREPARE/EXECUTE/DEALLOCATE in stored procedures.
2005-09-03 01:13:18 +02:00
ERROR 0A000: Not allowed to return a result set from a trigger
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''
2005-08-15 17:15:12 +02:00
select * from t1;
c1 c2
1 NULL
2 NULL
3 NULL
drop procedure bug11587;
drop table t1;
create table t1 (f1 integer);
create table t2 (f2 integer);
create trigger t1_ai after insert on t1
for each row insert into t2 values (new.f1+1);
create trigger t2_ai after insert on t2
for each row insert into t1 values (new.f2+1);
Recursion support made for SP (BUG#10100). client/mysqltest.c: An expected error messages hiding from the log if disable_result_log is in force. mysql-test/r/sp-dynamic.result: The test expanded for case of allowed/disalowed recursion. mysql-test/r/sp-error.result: Error messages changed. Test of bug11394() made with allowed recursion. mysql-test/r/sp.result: Tests for recursion. mysql-test/r/trigger.result: Check that triggers are not affected by this patch. mysql-test/r/variables.result: Test of max_sp_recursion_depth variable. mysql-test/t/sp-dynamic.test: The test expanded for case of allowed/disalowed recursion. mysql-test/t/sp-error.test: Error messages changed. Test of bug11394() made with allowed recursion. mysql-test/t/sp.test: Tests for recursion. mysql-test/t/trigger.test: Check that triggers are not affected by this patch. mysql-test/t/variables.test: Test of max_sp_recursion_depth variable. sql/item_func.cc: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO. sql/mysqld.cc: max_sp_recursion_depth variable added. sql/set_var.cc: max_sp_recursion_depth variable added. sql/share/errmsg.txt: An error message changed. An error message added. sql/sp.cc: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO. Temory LEX is allocated on a stack, not on a heap. Recursion support added for stored procedures. sql/sp.h: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO. sql/sp_head.cc: Initialization of new sp_head fields to get correct list of instances contained one instance only. Stack requirement for SP instruction is increased. Stack free space is checked before mem root initialisation to avoid memory leak. Pointer to the free instance management added before and after SP execution. sql/sp_head.h: New sp_head variables added to support inst of instances of SP for recursion and pointer on ths first free to use instance. sql/sql_base.cc: open_table() consume a lot of stack space so we check free stack space before it. sql/sql_class.h: max_sp_recursion_depth variable added. sql/sql_parse.cc: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO.
2005-11-23 00:11:19 +01:00
set @SAVE_SP_RECURSION_LEVELS=@@max_sp_recursion_depth;
set @@max_sp_recursion_depth=100;
insert into t1 values (1);
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
Recursion support made for SP (BUG#10100). client/mysqltest.c: An expected error messages hiding from the log if disable_result_log is in force. mysql-test/r/sp-dynamic.result: The test expanded for case of allowed/disalowed recursion. mysql-test/r/sp-error.result: Error messages changed. Test of bug11394() made with allowed recursion. mysql-test/r/sp.result: Tests for recursion. mysql-test/r/trigger.result: Check that triggers are not affected by this patch. mysql-test/r/variables.result: Test of max_sp_recursion_depth variable. mysql-test/t/sp-dynamic.test: The test expanded for case of allowed/disalowed recursion. mysql-test/t/sp-error.test: Error messages changed. Test of bug11394() made with allowed recursion. mysql-test/t/sp.test: Tests for recursion. mysql-test/t/trigger.test: Check that triggers are not affected by this patch. mysql-test/t/variables.test: Test of max_sp_recursion_depth variable. sql/item_func.cc: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO. sql/mysqld.cc: max_sp_recursion_depth variable added. sql/set_var.cc: max_sp_recursion_depth variable added. sql/share/errmsg.txt: An error message changed. An error message added. sql/sp.cc: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO. Temory LEX is allocated on a stack, not on a heap. Recursion support added for stored procedures. sql/sp.h: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO. sql/sp_head.cc: Initialization of new sp_head fields to get correct list of instances contained one instance only. Stack requirement for SP instruction is increased. Stack free space is checked before mem root initialisation to avoid memory leak. Pointer to the free instance management added before and after SP execution. sql/sp_head.h: New sp_head variables added to support inst of instances of SP for recursion and pointer on ths first free to use instance. sql/sql_base.cc: open_table() consume a lot of stack space so we check free stack space before it. sql/sql_class.h: max_sp_recursion_depth variable added. sql/sql_parse.cc: sp_find_function() and sp_find_procedure() joined to sp_find_routine() function as it was mentioned in TODO.
2005-11-23 00:11:19 +01:00
set @@max_sp_recursion_depth=@SAVE_SP_RECURSION_LEVELS;
select * from t1;
f1
1
select * from t2;
f2
2
drop trigger t1_ai;
drop trigger t2_ai;
create trigger t1_bu before update on t1
for each row insert into t1 values (2);
update t1 set f1= 10;
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
select * from t1;
f1
1
drop trigger t1_bu;
create trigger t1_bu before update on t1
for each row delete from t1 where f1=new.f1;
update t1 set f1= 10;
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
select * from t1;
f1
1
drop trigger t1_bu;
create trigger t1_bi before insert on t1
for each row set new.f1=(select sum(f1) from t1);
insert into t1 values (3);
select * from t1;
f1
1
1
drop trigger t1_bi;
drop tables t1, t2;
create table t1 (id int);
create table t2 (id int);
create trigger t1_bi before insert on t1 for each row insert into t2 values (new.id);
prepare stmt1 from "insert into t1 values (10)";
create procedure p1() insert into t1 values (10);
call p1();
drop trigger t1_bi;
execute stmt1;
call p1();
deallocate prepare stmt1;
drop procedure p1;
create table t3 (id int);
create trigger t1_bi after insert on t1 for each row insert into t2 values (new.id);
prepare stmt1 from "insert into t1 values (10)";
create procedure p1() insert into t1 values (10);
call p1();
drop trigger t1_bi;
create trigger t1_bi after insert on t1 for each row insert into t3 values (new.id);
execute stmt1;
call p1();
deallocate prepare stmt1;
drop procedure p1;
drop table t1, t2, t3;
Fix for BUG#13549 "Server crash with nested stored procedures if inner routine has more local variables than outer one, and one of its last variables was used as argument to NOT operator". THD::spcont was non-0 when we were parsing stored routine/trigger definition during execution of another stored routine. This confused methods of Item_splocal and forced them use wrong runtime context. Fix ensures that we always have THD::spcont equal to zero during routine/trigger body parsing. This also allows to avoid problems with errors which occur during parsing and SQL exception handlers. mysql-test/r/sp.result: Test suite for bug#13549. mysql-test/r/trigger.result: Test suite for bug#13549. mysql-test/t/sp.test: Test suite for bug#13549. mysql-test/t/trigger.test: Test suite for bug#13549. sql/item.cc: Protection against using wrong context by SP local variable. sql/item.h: Protection against using wrong context by SP local variable. sql/protocol.cc: An incorrect macro name fixed. sql/protocol.h: An incorrect macro name fixed. sql/sp.cc: Do not allow SP which we are parsing to use other SP context (BUG#13549). sql/sp_head.cc: Protection against using wrong context by SP local variable. sql/sp_rcontext.h: Protection against using wrong context by SP local variable. sql/sql_cache.h: An incorrect macro name fixed. sql/sql_class.cc: Protection against using wrong context by SP local variable. sql/sql_class.h: Protection against using wrong context by SP local variable. sql/sql_trigger.cc: Do not allow Trigger which we are parsing to use other SP context (BUG#13549). sql/sql_yacc.yy: Protection against using wrong context by SP local variable.
2005-11-22 23:50:37 +01:00
create table t1 (a int);
Review fixes of new pushed code - Fixed tests - Optimized new code - Fixed some unlikely core dumps - Better bug fixes for: - #14397 - OPTIMIZE TABLE with an open HANDLER causes a crash - #14850 (ERROR 1062 when a quering a view using a Group By on a column that can be null mysql-test/r/create.result: Update results after removing wrong warnings for CREATE ... SELECT New tests mysql-test/r/handler.result: Drop used tables mysql-test/r/kill.result: Make test portable mysql-test/r/mysqlshow.result: Drop tables used by previous test mysql-test/r/trigger.result: Reuse old procedure name mysql-test/r/view.result: Extra tests mysql-test/t/create.test: New tests to test fix of removing wrong warnings for CREATE ... SELECT mysql-test/t/disabled.def: Enable 'kill' test (should now be portable) mysql-test/t/handler.test: Drop used tables mysql-test/t/kill.test: Make test portable even if kill doesn't work at once mysql-test/t/mysqlshow.test: Drop tables used by previous test mysql-test/t/trigger.test: Reuse old procedure name mysql-test/t/view.test: Extra tests sql/field.cc: Removed compiler warning sql/ha_federated.cc: my_snprintf -> strmake() (Simple optimization) sql/ha_ndbcluster.cc: Indentation cleanups and trival optimization sql/item.cc: Moved save_org_in_field() to item.cc to make it easier to test Remove setting of null_value as this is not needed sql/item.h: Moved save_org_in_field() to item.cc to make it easier to test sql/log_event.cc: Remove inline of slave_load_file_stem() Added 'extension' parameter to slave_load_file_stem() to get smaller code Removed not critical (or needed) DBUG_ASSERT()'s Cleaned up usage of slave_load_file_stem() to not depend on constant string lengths Indentation fixes sql/opt_range.cc: Moved code from declaration to function body (To make it more readable) sql/parse_file.cc: Fixed DBUG_PRINT sql/sp.cc: Simple cleanups - Removed not needed {} level - Ensure saved variables starts with old_ sql/sp_head.cc: Indentation fixes Remove core dump when using --debug when m_next_cached_sp == 0 Fixed compiler warnings Trivial optimizations sql/sp_head.h: Changed argument to set_definer() to const Added THD argument to recursion_level_error() to avoid call to current_thd sql/sql_acl.cc: Removed not needed test (first_not_own_table is the guard) sql/sql_base.cc: Removed extra empty line sql/sql_handler.cc: Don't test table version in mysql_ha_read() as this is already tested in lock_tables() Moved call to insert_fields to be after lock_table() to guard aganst reopen of tables (Better fix for Bug#14397 - OPTIMIZE TABLE with an open HANDLER causes a crash) sql/sql_insert.cc: Mark fields that are set in CREATE ... SELECT as used (Removed wrong warnings about field not having a default value) sql/sql_parse.cc: Removed not needed test of 'tables' (first_not_own_table is the guard) Simplify code sql/sql_select.cc: Use group->field to check if value is null instead of item called by 'save_org_in_field' This is a better bug fix for #14850 (ERROR 1062 when a quering a view using a Group By on a column that can be null) sql/sql_trigger.cc: Move sql_modes_parameters outside of function Indentation fixes Fixed compiler warning Ensure that thd->lex->query_tables_own_last is set properly before calling check_table_access() (This allows us to remove the extra test in check_grant() and check_table_access())
2006-01-05 23:47:49 +01:00
CREATE PROCEDURE `p1`()
Fix for BUG#13549 "Server crash with nested stored procedures if inner routine has more local variables than outer one, and one of its last variables was used as argument to NOT operator". THD::spcont was non-0 when we were parsing stored routine/trigger definition during execution of another stored routine. This confused methods of Item_splocal and forced them use wrong runtime context. Fix ensures that we always have THD::spcont equal to zero during routine/trigger body parsing. This also allows to avoid problems with errors which occur during parsing and SQL exception handlers. mysql-test/r/sp.result: Test suite for bug#13549. mysql-test/r/trigger.result: Test suite for bug#13549. mysql-test/t/sp.test: Test suite for bug#13549. mysql-test/t/trigger.test: Test suite for bug#13549. sql/item.cc: Protection against using wrong context by SP local variable. sql/item.h: Protection against using wrong context by SP local variable. sql/protocol.cc: An incorrect macro name fixed. sql/protocol.h: An incorrect macro name fixed. sql/sp.cc: Do not allow SP which we are parsing to use other SP context (BUG#13549). sql/sp_head.cc: Protection against using wrong context by SP local variable. sql/sp_rcontext.h: Protection against using wrong context by SP local variable. sql/sql_cache.h: An incorrect macro name fixed. sql/sql_class.cc: Protection against using wrong context by SP local variable. sql/sql_class.h: Protection against using wrong context by SP local variable. sql/sql_trigger.cc: Do not allow Trigger which we are parsing to use other SP context (BUG#13549). sql/sql_yacc.yy: Protection against using wrong context by SP local variable.
2005-11-22 23:50:37 +01:00
begin
insert into t1 values (1);
end//
create trigger trg before insert on t1 for each row
begin
declare done int default 0;
set done= not done;
end//
Review fixes of new pushed code - Fixed tests - Optimized new code - Fixed some unlikely core dumps - Better bug fixes for: - #14397 - OPTIMIZE TABLE with an open HANDLER causes a crash - #14850 (ERROR 1062 when a quering a view using a Group By on a column that can be null mysql-test/r/create.result: Update results after removing wrong warnings for CREATE ... SELECT New tests mysql-test/r/handler.result: Drop used tables mysql-test/r/kill.result: Make test portable mysql-test/r/mysqlshow.result: Drop tables used by previous test mysql-test/r/trigger.result: Reuse old procedure name mysql-test/r/view.result: Extra tests mysql-test/t/create.test: New tests to test fix of removing wrong warnings for CREATE ... SELECT mysql-test/t/disabled.def: Enable 'kill' test (should now be portable) mysql-test/t/handler.test: Drop used tables mysql-test/t/kill.test: Make test portable even if kill doesn't work at once mysql-test/t/mysqlshow.test: Drop tables used by previous test mysql-test/t/trigger.test: Reuse old procedure name mysql-test/t/view.test: Extra tests sql/field.cc: Removed compiler warning sql/ha_federated.cc: my_snprintf -> strmake() (Simple optimization) sql/ha_ndbcluster.cc: Indentation cleanups and trival optimization sql/item.cc: Moved save_org_in_field() to item.cc to make it easier to test Remove setting of null_value as this is not needed sql/item.h: Moved save_org_in_field() to item.cc to make it easier to test sql/log_event.cc: Remove inline of slave_load_file_stem() Added 'extension' parameter to slave_load_file_stem() to get smaller code Removed not critical (or needed) DBUG_ASSERT()'s Cleaned up usage of slave_load_file_stem() to not depend on constant string lengths Indentation fixes sql/opt_range.cc: Moved code from declaration to function body (To make it more readable) sql/parse_file.cc: Fixed DBUG_PRINT sql/sp.cc: Simple cleanups - Removed not needed {} level - Ensure saved variables starts with old_ sql/sp_head.cc: Indentation fixes Remove core dump when using --debug when m_next_cached_sp == 0 Fixed compiler warnings Trivial optimizations sql/sp_head.h: Changed argument to set_definer() to const Added THD argument to recursion_level_error() to avoid call to current_thd sql/sql_acl.cc: Removed not needed test (first_not_own_table is the guard) sql/sql_base.cc: Removed extra empty line sql/sql_handler.cc: Don't test table version in mysql_ha_read() as this is already tested in lock_tables() Moved call to insert_fields to be after lock_table() to guard aganst reopen of tables (Better fix for Bug#14397 - OPTIMIZE TABLE with an open HANDLER causes a crash) sql/sql_insert.cc: Mark fields that are set in CREATE ... SELECT as used (Removed wrong warnings about field not having a default value) sql/sql_parse.cc: Removed not needed test of 'tables' (first_not_own_table is the guard) Simplify code sql/sql_select.cc: Use group->field to check if value is null instead of item called by 'save_org_in_field' This is a better bug fix for #14850 (ERROR 1062 when a quering a view using a Group By on a column that can be null) sql/sql_trigger.cc: Move sql_modes_parameters outside of function Indentation fixes Fixed compiler warning Ensure that thd->lex->query_tables_own_last is set properly before calling check_table_access() (This allows us to remove the extra test in check_grant() and check_table_access())
2006-01-05 23:47:49 +01:00
CALL p1();
drop procedure p1;
Fix for BUG#13549 "Server crash with nested stored procedures if inner routine has more local variables than outer one, and one of its last variables was used as argument to NOT operator". THD::spcont was non-0 when we were parsing stored routine/trigger definition during execution of another stored routine. This confused methods of Item_splocal and forced them use wrong runtime context. Fix ensures that we always have THD::spcont equal to zero during routine/trigger body parsing. This also allows to avoid problems with errors which occur during parsing and SQL exception handlers. mysql-test/r/sp.result: Test suite for bug#13549. mysql-test/r/trigger.result: Test suite for bug#13549. mysql-test/t/sp.test: Test suite for bug#13549. mysql-test/t/trigger.test: Test suite for bug#13549. sql/item.cc: Protection against using wrong context by SP local variable. sql/item.h: Protection against using wrong context by SP local variable. sql/protocol.cc: An incorrect macro name fixed. sql/protocol.h: An incorrect macro name fixed. sql/sp.cc: Do not allow SP which we are parsing to use other SP context (BUG#13549). sql/sp_head.cc: Protection against using wrong context by SP local variable. sql/sp_rcontext.h: Protection against using wrong context by SP local variable. sql/sql_cache.h: An incorrect macro name fixed. sql/sql_class.cc: Protection against using wrong context by SP local variable. sql/sql_class.h: Protection against using wrong context by SP local variable. sql/sql_trigger.cc: Do not allow Trigger which we are parsing to use other SP context (BUG#13549). sql/sql_yacc.yy: Protection against using wrong context by SP local variable.
2005-11-22 23:50:37 +01:00
drop table t1;
create trigger t1_bi before insert on test.t1 for each row set @a:=0;
ERROR 3D000: No database selected
create trigger test.t1_bi before insert on t1 for each row set @a:=0;
A fix and a test case for Bug#29050 Creation of a legal stored procedure fails if a database is not selected prior. The problem manifested itself when a user tried to create a routine that had non-fully-qualified identifiers in its bodies and there was no current database selected. This is a regression introduced by the fix for Bug 19022: The patch for Bug 19022 changes the code to always produce a warning if we can't resolve the current database in the parser. In this case this was not necessary, since even though the produced parsed tree was incorrect, we never re-use sphead that was obtained at first parsing of CREATE PROCEDURE. The sphead that is anyhow used is always obtained through db_load_routine, and there we change the current database to sphead->m_db before calling yyparse. The idea of the fix is to resolve the current database directly using lex->sphead->m_db member when parsing a stored routine body, when such is present. This patch removes the need to reset the current database when loading a trigger or routine definition into SP cache. The redundant code will be removed in 5.1. mysql-test/r/sp.result: Update test results (Bug#29050) mysql-test/r/trigger.result: Update results. mysql-test/t/sp.test: Add a test case for Bug#29050 mysql-test/t/trigger.test: Fix wrong behavior covered with tests. sql/sql_lex.cc: Implement st_lex::copy_db_to(). sql/sql_lex.h: Declare st_lex::copy_db_to(). sql/sql_parse.cc: Use st_lex::copy_db_to() in add_table_to_list, rather than THD::copy_db_to(). The former will use the database of the sphead, if we're parsing a stored routine, not the default database in THD. The default database is needed to initialize tables->db when the database part was not explicitly specified in the identifier. sql/sql_yacc.yy: Use st_lex::copy_db_to() in the parser, rather than THD::copy_db_to(). The former will use the database of the sphead, if we're parsing a stored routine, not the default database in THD.
2007-07-05 09:34:04 +02:00
ERROR 42S02: Table 'test.t1' doesn't exist
drop trigger t1_bi;
ERROR 3D000: No database selected
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
create table t1 (id int);
create trigger t1_bi before insert on t1 for each row set @a:=new.id;
create trigger t1_ai after insert on test.t1 for each row set @b:=new.id;
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
insert into t1 values (101);
select @a, @b;
@a @b
101 101
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t1 set @a:=new.id
test t1_ai test t1 set @b:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
rename table t1 to t2;
insert into t2 values (102);
select @a, @b;
@a @b
102 102
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t2 set @a:=new.id
test t1_ai test t2 set @b:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
alter table t2 rename to t3;
insert into t3 values (103);
select @a, @b;
@a @b
103 103
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t3 set @a:=new.id
test t1_ai test t3 set @b:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
alter table t3 rename to t4, add column val int default 0;
insert into t4 values (104, 1);
select @a, @b;
@a @b
104 104
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t4 set @a:=new.id
test t1_ai test t4 set @b:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
drop trigger t1_bi;
drop trigger t1_ai;
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
drop table t4;
create database mysqltest;
use mysqltest;
create table t1 (id int);
create trigger t1_bi before insert on t1 for each row set @a:=new.id;
insert into t1 values (101);
select @a;
@a
101
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test' or event_object_schema = 'mysqltest';
trigger_schema trigger_name event_object_schema event_object_table action_statement
mysqltest t1_bi mysqltest t1 set @a:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
rename table t1 to test.t2;
ERROR HY000: Trigger in wrong schema
insert into t1 values (102);
select @a;
@a
102
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test' or event_object_schema = 'mysqltest';
trigger_schema trigger_name event_object_schema event_object_table action_statement
mysqltest t1_bi mysqltest t1 set @a:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
drop trigger test.t1_bi;
ERROR HY000: Trigger does not exist
Fix for bug #18153 "ALTER/OPTIMIZE/REPAIR on transactional tables corrupt triggers". Applying ALTER/OPTIMIZE/REPAIR TABLE statements to transactional table or to table of any type on Windows caused disappearance of its triggers. Bug was introduced in 5.0.19 by my fix for bug #13525 "Rename table does not keep info of triggers" (see comment for sql_table.cc for more info). . mysql-test/r/trigger.result: Added test-case covering handling of triggers when one does ALTER TABLE which should move table to different database. mysql-test/t/trigger.test: Added test-case covering handling of triggers when one does ALTER TABLE which should move table to different database. sql/sql_table.cc: mysql_alter_table(): Removal of strdup() which is no longer necessary allows us to preserve nice assumption that "(new_db != db || new_table != table_name) indicates that table will be renamed. So now we really can use this condition to avoid updating trigger definitions when table is not renamed. Note that we can't use (alter_info->flags & ALTER_RENAME) condition instead since it can be also true when we do "ALTER TABLE t1 RENAME TO t1". sql/sql_trigger.cc: Table_triggers_list::change_table_name(): Mentioned assumption that subject table is not renamed to itself in method description. Added DBUG_ASSERT() to catch wrong usage of this method. mysql-test/r/trigger-trans.result: New BitKeeper file ``mysql-test/r/trigger-trans.result'' mysql-test/t/trigger-trans.test: New BitKeeper file ``mysql-test/t/trigger-trans.test''
2006-03-24 12:58:18 +01:00
alter table t1 rename to test.t1;
ERROR HY000: Trigger in wrong schema
insert into t1 values (103);
select @a;
@a
103
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test' or event_object_schema = 'mysqltest';
trigger_schema trigger_name event_object_schema event_object_table action_statement
mysqltest t1_bi mysqltest t1 set @a:=new.id
drop trigger test.t1_bi;
ERROR HY000: Trigger does not exist
alter table t1 rename to test.t1, add column val int default 0;
ERROR HY000: Trigger in wrong schema
insert into t1 values (104);
select @a;
@a
104
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test' or event_object_schema = 'mysqltest';
trigger_schema trigger_name event_object_schema event_object_table action_statement
mysqltest t1_bi mysqltest t1 set @a:=new.id
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) DEFAULT NULL
Fix for bug #18153 "ALTER/OPTIMIZE/REPAIR on transactional tables corrupt triggers". Applying ALTER/OPTIMIZE/REPAIR TABLE statements to transactional table or to table of any type on Windows caused disappearance of its triggers. Bug was introduced in 5.0.19 by my fix for bug #13525 "Rename table does not keep info of triggers" (see comment for sql_table.cc for more info). . mysql-test/r/trigger.result: Added test-case covering handling of triggers when one does ALTER TABLE which should move table to different database. mysql-test/t/trigger.test: Added test-case covering handling of triggers when one does ALTER TABLE which should move table to different database. sql/sql_table.cc: mysql_alter_table(): Removal of strdup() which is no longer necessary allows us to preserve nice assumption that "(new_db != db || new_table != table_name) indicates that table will be renamed. So now we really can use this condition to avoid updating trigger definitions when table is not renamed. Note that we can't use (alter_info->flags & ALTER_RENAME) condition instead since it can be also true when we do "ALTER TABLE t1 RENAME TO t1". sql/sql_trigger.cc: Table_triggers_list::change_table_name(): Mentioned assumption that subject table is not renamed to itself in method description. Added DBUG_ASSERT() to catch wrong usage of this method. mysql-test/r/trigger-trans.result: New BitKeeper file ``mysql-test/r/trigger-trans.result'' mysql-test/t/trigger-trans.test: New BitKeeper file ``mysql-test/t/trigger-trans.test''
2006-03-24 12:58:18 +01:00
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop trigger test.t1_bi;
ERROR HY000: Trigger does not exist
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
drop trigger t1_bi;
drop table t1;
drop database mysqltest;
use test;
create table t1 (id int);
create trigger t1_bi before insert on t1 for each row set @a:=new.id;
create trigger t1_ai after insert on t1 for each row set @b:=new.id;
insert into t1 values (101);
select @a, @b;
@a @b
101 101
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t1 set @a:=new.id
test t1_ai test t1 set @b:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
rename table t1 to t2;
Fixes after Serg's review of %M extenstions - Changed output to be error "error-text" instead of error - error-text extra/perror.c: Move my_handler_errors.h into include include/my_handler_errors.h: Move my_handler_errors.h into include mysql-test/r/errors.result: Updated result mysql-test/r/innodb_mysql_sync.result: Updated result mysql-test/r/myisam-system.result: Updated result mysql-test/r/myisampack.result: Updated result mysql-test/r/partition_innodb_plugin.result: Updated result mysql-test/r/ps_1general.result: Updated result mysql-test/r/trigger.result: Updated result mysql-test/r/type_bit.result: Updated result mysql-test/r/type_bit_innodb.result: Updated result mysql-test/r/type_blob.result: Updated result mysql-test/suite/archive/archive.result: Updated result mysql-test/suite/binlog/r/binlog_index.result: Updated result mysql-test/suite/binlog/r/binlog_ioerr.result: Updated result mysql-test/suite/csv/csv.result: Updated result mysql-test/suite/engines/iuds/r/type_bit_iuds.result: Updated result mysql-test/suite/federated/federated_bug_35333.result: Updated result mysql-test/suite/innodb/r/innodb-create-options.result: Updated result mysql-test/suite/innodb/r/innodb-index.result: Updated result mysql-test/suite/innodb/r/innodb-zip.result: Updated result mysql-test/suite/innodb/r/innodb.result: Updated result mysql-test/suite/innodb/r/innodb_bug13635833.result: Updated result mysql-test/suite/innodb/r/innodb_bug21704.result: Updated result mysql-test/suite/innodb/r/innodb_bug46000.result: Updated result mysql-test/suite/parts/r/partition_bit_innodb.result: Updated result mysql-test/suite/parts/r/partition_bit_myisam.result: Updated result mysql-test/suite/percona/percona_innodb_fake_changes.result: Updated result mysql-test/suite/perfschema/r/misc.result: Updated result mysql-test/suite/perfschema/r/privilege.result: Updated result mysql-test/suite/rpl/r/rpl_EE_err.result: Updated result mysql-test/suite/rpl/r/rpl_binlog_errors.result: Updated result mysql-test/suite/rpl/r/rpl_drop_db.result: Updated result sql/share/errmsg-utf8.txt: Removed 'column' from error text that was used in different context strings/my_vsnprintf.c: Move my_handler_errors.h into include Minor cleanups Changed output of %M to be error "error-text" instead of error - error-text unittest/mysys/my_vsnprintf-t.c: Updated error text
2012-06-17 14:34:39 +02:00
ERROR HY000: Can't create/write to file './test/t1_ai.TRN~' (Errcode: 13 "Permission denied")
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
insert into t1 values (102);
select @a, @b;
@a @b
102 102
select trigger_schema, trigger_name, event_object_schema,
event_object_table, action_statement from information_schema.triggers
where event_object_schema = 'test';
trigger_schema trigger_name event_object_schema event_object_table action_statement
test t1_bi test t1 set @a:=new.id
test t1_ai test t1 set @b:=new.id
Fix for bug #13525 "Rename table does not keep info of triggers". Let us transfer triggers associated with table when we rename it (but only if we are not changing database to which table belongs, in the latter case we will emit error). mysql-test/r/trigger.result: Added test for bug #13525 "Rename table does not keep info of triggers". mysql-test/t/trigger.test: Added test for bug #13525 "Rename table does not keep info of triggers". sql/sql_rename.cc: rename_tables(): Now after renaming table's .FRM file and updating handler data we call Table_triggers_list::change_table_name() which is reponsible for updating .TRG and .TRN files. sql/sql_table.cc: mysql_alter_table(): Now in case when ALTER should rename table we call Table_triggers_list::change_table_name() which is responsible for updating .TRG and .TRN files after renaming table. sql/sql_trigger.cc: Added Table_triggers_list::change_table_name() method and change_table_name_in_triggers()/trignames() methods responsible for updating .TRG and .TRN files for table during its renaming. Two small cleanups - removed versioning for .TRG files (since it was not working before anyway) and emphasized that type of lock specified in tables list is unimportant for DROP TABLE (since this statement uses name-locking). sql/sql_trigger.h: Table_triggers_list: Added on_table_names_list member to store pointers and lenghts of "ON table_name" parts in triggers' definitions to be able easily change them during RENAME TABLE. Added change_table_name() method and change_table_name_in_trignames/triggers() helper methods responsible for updating .TRG and .TRN files. sql/sql_yacc.yy: trigger_tail: To be able properly update triggers' definitions with new table names when renaming tables we need to know where in CREATE TRIGGER statement "ON db_name.table_name" part resides. Small cleanup - let us emphasize that for CREATE TRIGGER statement lock type which is specified in table list is unimportant since name-locking is used.
2006-02-24 21:50:36 +01:00
drop trigger t1_bi;
drop trigger t1_ai;
drop table t1;
create table t1 (i int);
create trigger t1_bi before insert on t1 for each row return 0;
ERROR 42000: RETURN is only allowed in a FUNCTION
insert into t1 values (1);
drop table t1;
create table t1 (a varchar(64), b int);
create table t2 like t1;
create trigger t1_ai after insert on t1 for each row
set @a:= (select max(a) from t1);
insert into t1 (a) values
("Twas"),("brillig"),("and"),("the"),("slithy"),("toves"),
("Did"),("gyre"),("and"),("gimble"),("in"),("the"),("wabe");
create trigger t2_ai after insert on t2 for each row
set @a:= (select max(a) from t2);
insert into t2 select * from t1;
WL#4189 - dynamic configuration support - safe process - cleanups - create new suite for fedarated BitKeeper/deleted/.del-basic.test: Rename: mysql-test/ndb/basic.test -> BitKeeper/deleted/.del-basic.test BitKeeper/deleted/.del-basic_log.result: Rename: mysql-test/ndb/basic_log.result -> BitKeeper/deleted/.del-basic_log.result mysql-test/suite/federated/federated_transactions.result: Rename: mysql-test/r/federated_transactions.result -> mysql-test/suite/federated/federated_transactions.result BitKeeper/deleted/.del-have_bug25714.require: Rename: mysql-test/r/have_bug25714.require -> BitKeeper/deleted/.del-have_bug25714.require BitKeeper/deleted/.del-kill_master.sh: Rename: mysql-test/misc/kill_master.sh -> BitKeeper/deleted/.del-kill_master.sh BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a: Rename: mysql-test/ndb/ndb_config_4_node.ini -> BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a BitKeeper/deleted/.del-restart.result: Rename: mysql-test/ndb/restart.result -> BitKeeper/deleted/.del-restart.result mysql-test/suite/federated/federated_cleanup.inc: Rename: mysql-test/include/federated_cleanup.inc -> mysql-test/suite/federated/federated_cleanup.inc mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_rotate_logs.slave-mi -> mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt BitKeeper/deleted/.del-install_test_db.sh: Rename: mysql-test/install_test_db.sh -> BitKeeper/deleted/.del-install_test_db.sh BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16: Rename: mysql-test/ndb/ndb_config_1_node.ini -> BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16 BitKeeper/deleted/.del-mtr_timer.pl: Rename: mysql-test/lib/mtr_timer.pl -> BitKeeper/deleted/.del-mtr_timer.pl BitKeeper/deleted/.del-create-test-result: Rename: mysql-test/create-test-result -> BitKeeper/deleted/.del-create-test-result BitKeeper/deleted/.del-fix-result: Rename: mysql-test/fix-result -> BitKeeper/deleted/.del-fix-result BitKeeper/deleted/.del-mysql-test-run-shell.sh: Rename: mysql-test/mysql-test-run-shell.sh -> BitKeeper/deleted/.del-mysql-test-run-shell.sh BitKeeper/deleted/.del-mysql-test_V1.9.pl: Rename: mysql-test/misc/mysql-test_V1.9.pl -> BitKeeper/deleted/.del-mysql-test_V1.9.pl BitKeeper/deleted/.del-resolve-stack: Rename: mysql-test/resolve-stack -> BitKeeper/deleted/.del-resolve-stack BitKeeper/deleted/.del-restart_log.result: Rename: mysql-test/ndb/restart_log.result -> BitKeeper/deleted/.del-restart_log.result mysql-test/suite/rpl/t/rpl_000015-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_000015.slave-mi -> mysql-test/suite/rpl/t/rpl_000015-slave.opt BitKeeper/deleted/.del-ndb_config_2_node.ini: Rename: mysql-test/ndb/ndb_config_2_node.ini -> BitKeeper/deleted/.del-ndb_config_2_node.ini BitKeeper/deleted/.del-ndbcluster.sh: Rename: mysql-test/ndb/ndbcluster.sh -> BitKeeper/deleted/.del-ndbcluster.sh BitKeeper/deleted/.del-basic.result: Rename: mysql-test/ndb/basic.result -> BitKeeper/deleted/.del-basic.result BitKeeper/deleted/.del-restart.test: Rename: mysql-test/ndb/restart.test -> BitKeeper/deleted/.del-restart.test BitKeeper/deleted/.del-have_bug25714.inc: Rename: mysql-test/include/have_bug25714.inc -> BitKeeper/deleted/.del-have_bug25714.inc BitKeeper/deleted/.del-mtr_diff.pl: Rename: mysql-test/lib/mtr_diff.pl -> BitKeeper/deleted/.del-mtr_diff.pl mysql-test/suite/federated/federated_transactions-slave.opt: Rename: mysql-test/t/federated_transactions-slave.opt -> mysql-test/suite/federated/federated_transactions-slave.opt BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b: Rename: mysql-test/ndb/Makefile.am -> BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949: Rename: mysql-test/lib/mtr_im.pl -> BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949 mysql-test/suite/federated/federated_innodb-slave.opt: Rename: mysql-test/t/federated_innodb-slave.opt -> mysql-test/suite/federated/federated_innodb-slave.opt client/mysqltest.c: Use current files path first when looking for include file configure.in: Remove mysql-test/nbd mysql-test/Makefile.am: Cleanup mysql-test/Makefile.am mysql-test/extra/binlog_tests/blackhole.test: Use new paths mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Use new paths mysql-test/mysql-test-run.pl: Dynamic configuration support Safe process mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test: Use new paths mysql-test/extra/rpl_tests/rpl_EE_err.test: Use new paths mysql-test/extra/rpl_tests/rpl_loaddata.test: Use new paths mysql-test/extra/rpl_tests/rpl_log.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_001.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_charset.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_000001.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_charset.test: Use new paths mysql-test/include/have_blackhole.inc: Use new paths mysql-test/include/have_ndbapi_examples.inc: Use new paths mysql-test/include/loaddata_autocom.inc: Use new paths mysql-test/include/mix1.inc: Use new paths mysql-test/include/ndb_backup.inc: Use new paths mysql-test/include/ndb_restore_master.inc: Use new paths mysql-test/include/ndb_restore_slave_eoption.inc: Use new paths mysql-test/include/testdb_only.inc: Use new paths mysql-test/lib/My/Config.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_cases.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_io.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_misc.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_process.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_report.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_stress.pl: dynamic configuration safe process cleanups mysql-test/r/backup.result: Use new paths mysql-test/r/ctype_big5.result: Use new paths mysql-test/r/gis.result: Use new paths mysql-test/r/loaddata.result: Use new paths mysql-test/r/loaddata_autocom_innodb.result: Use new paths mysql-test/r/mysqlbinlog.result: Use new paths mysql-test/r/mysqlbinlog_base64.result: Use new paths mysql-test/r/outfile.result: Use new paths mysql-test/r/partition_error.result: Use new paths mysql-test/r/partition_not_windows.result: Use new paths mysql-test/r/partition_symlink.result: Use new paths mysql-test/r/query_cache.result: Use new paths mysql-test/r/sp.result: Use new paths mysql-test/r/symlink.result: Use new paths mysql-test/r/system_mysql_db.result: Use new paths mysql-test/r/trigger.result: Use new paths mysql-test/r/type_blob.result: Use new paths mysql-test/r/view.result: Use new paths mysql-test/r/warnings.result: Use new paths mysql-test/suite/binlog/r/binlog_killed_simulate.result: Use new paths mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/t/binlog_killed.test: Use new paths mysql-test/suite/binlog/t/binlog_killed_simulate.test: Use new paths mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test: Use new paths mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: Use new paths mysql-test/suite/federated/federated.inc: Use new paths mysql-test/suite/federated/federated.result: Use new paths mysql-test/suite/federated/federated.test: Use new paths mysql-test/suite/federated/federated_archive.result: Use new paths mysql-test/suite/federated/federated_archive.test: Use new paths mysql-test/suite/federated/federated_bug_13118.result: Use new paths mysql-test/suite/federated/federated_bug_13118.test: Use new paths mysql-test/suite/federated/federated_bug_25714.result: Use new paths mysql-test/suite/federated/federated_bug_25714.test: Use new paths mysql-test/suite/federated/federated_innodb.result: Use new paths mysql-test/suite/federated/federated_innodb.test: Use new paths mysql-test/suite/federated/federated_server.result: Use new paths mysql-test/suite/federated/federated_server.test: Use new paths mysql-test/suite/federated/federated_transactions.test: Use new paths mysql-test/suite/federated/have_federated_db.inc: Use new paths mysql-test/suite/ndb/r/loaddata_autocom_ndb.result: Use new paths mysql-test/suite/ndb/r/ndb_config.result: Use new paths mysql-test/suite/ndb/r/ndb_dd_backuprestore.result: Use new paths mysql-test/suite/ndb/r/ndb_load.result: Use new paths mysql-test/suite/ndb/r/ndb_loaddatalocal.result: Use new paths mysql-test/suite/ndb/r/ndb_replace.result: Use new paths mysql-test/suite/ndb/r/ndb_restore.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_partition.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_print.result: Use new paths mysql-test/suite/ndb/r/ndb_trigger.result: Use new paths mysql-test/suite/ndb/t/ndb_alter_table.test: Use new paths mysql-test/suite/ndb/t/ndb_config.test: Use new paths mysql-test/suite/ndb/t/ndb_load.test: Use new paths mysql-test/suite/ndb/t/ndb_loaddatalocal.test: Use new paths mysql-test/suite/ndb/t/ndb_replace.test: Use new paths mysql-test/suite/ndb/t/ndb_restore.test: Use new paths mysql-test/suite/ndb/t/ndb_single_user.test: Use new paths mysql-test/suite/ndb/t/ndb_trigger.test: Use new paths mysql-test/suite/ndb/t/ndbapi.test: Use new paths mysql-test/suite/rpl/include/rpl_mixed_dml.inc: Use new paths mysql-test/suite/rpl/r/rpl_LD_INFILE.result: Use new paths mysql-test/suite/rpl/r/rpl_flushlog_loop.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Use new paths mysql-test/suite/rpl/r/rpl_load_table_from_master.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_charset.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_s.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_simple.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Use new paths mysql-test/suite/rpl/r/rpl_loadfile.result: Use new paths mysql-test/suite/rpl/r/rpl_misc_functions.result: Use new paths mysql-test/suite/rpl/r/rpl_replicate_do.result: Use new paths mysql-test/suite/rpl/r/rpl_rewrt_db.result: Use new paths mysql-test/suite/rpl/r/rpl_row_001.result: Use new paths mysql-test/suite/rpl/r/rpl_row_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_row_stop_middle_update.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_000001.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_log.result: Use new paths mysql-test/suite/rpl/r/rpl_timezone.result: Use new paths mysql-test/suite/rpl/t/disabled.def: Use new paths mysql-test/suite/rpl/t/rpl000017-slave.sh: Use new paths mysql-test/suite/rpl/t/rpl_LD_INFILE.test: Use new paths mysql-test/suite/rpl/t/rpl_drop_db.test: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: Use new paths mysql-test/suite/rpl/t/rpl_load_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_load_table_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_charset.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_fatal.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_m.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_s.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_simple.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Use new paths mysql-test/suite/rpl/t/rpl_loadfile.test: Use new paths mysql-test/suite/rpl/t/rpl_misc_functions.test: Use new paths mysql-test/suite/rpl/t/rpl_replicate_do.test: Use new paths mysql-test/suite/rpl/t/rpl_rewrt_db.test: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs.test: Use new paths mysql-test/suite/rpl/t/rpl_row_charset_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test: Use new paths mysql-test/suite/rpl/t/rpl_row_stop_middle_update.test: Use new paths mysql-test/suite/rpl/t/rpl_timezone.test: Use new paths mysql-test/suite/rpl/t/rpl_trigger.test: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_innodb_trans.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_multi.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_row_001.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_sync.result: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_bank.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_dd_advance.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_load.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_sync.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndbapi_multi.test: Use new paths mysql-test/t/backup.test: Use new paths mysql-test/t/bootstrap.test: Use new paths mysql-test/t/crash_commit_before.test: Use new paths mysql-test/t/create_not_windows.test: Use new paths mysql-test/t/csv.test: Use new paths mysql-test/t/ctype_big5.test: Use new paths mysql-test/t/disabled.def: Use new paths mysql-test/t/distinct.test: Use new paths mysql-test/t/gis.test: Use new paths mysql-test/t/grant_cache_no_prot.test: Use new paths mysql-test/t/grant_cache_ps_prot.test: Use new paths mysql-test/t/information_schema_chmod.test: Use new paths mysql-test/t/loaddata.test: Use new paths mysql-test/t/log_state.test: Use new paths mysql-test/t/myisam-system.test: Use new paths mysql-test/t/mysql_upgrade.test: Use new paths mysql-test/t/mysqlbinlog-cp932.test: Use new paths mysql-test/t/mysqlbinlog.test: Use new paths mysql-test/t/mysqlbinlog2.test: Use new paths mysql-test/t/mysqlbinlog_base64.test: Use new paths mysql-test/t/mysqldump.test: Use new paths mysql-test/t/outfile.test: Use new paths mysql-test/t/partition.test: Use new paths mysql-test/t/partition_error.test: Use new paths mysql-test/t/partition_federated.test: Use new paths mysql-test/t/partition_mgm.test: Use new paths mysql-test/t/partition_not_windows.test: Use new paths mysql-test/t/partition_symlink.test: Use new paths mysql-test/t/query_cache.test: Use new paths mysql-test/t/repair.test: Use new paths mysql-test/t/show_check.test: Use new paths mysql-test/t/sp-destruct.test: Use new paths mysql-test/t/sp.test: Use new paths mysql-test/t/symlink.test: Use new paths mysql-test/t/system_mysql_db.test: Use new paths mysql-test/t/system_mysql_db_fix30020.test: Use new paths mysql-test/t/system_mysql_db_fix40123.test: Use new paths mysql-test/t/system_mysql_db_fix50030.test: Use new paths mysql-test/t/system_mysql_db_fix50117.test: Use new paths mysql-test/t/trigger-compat.test: Use new paths mysql-test/t/trigger-grant.test: Use new paths mysql-test/t/trigger.test: Use new paths mysql-test/t/type_blob.test: Use new paths mysql-test/t/type_varchar.test: Use new paths mysql-test/t/upgrade.test: Use new paths mysql-test/t/user_var-binlog.test: Use new paths mysql-test/t/varbinary.test: Use new paths mysql-test/t/view.test: Use new paths mysql-test/t/warnings.test: Use new paths mysql-test/lib/My/ConfigFactory.pm: Initial version mysql-test/lib/My/Find.pm: Initial version mysql-test/lib/My/SafeProcess.pm: Initial version mysql-test/std_data/ndb_config_config.ini: Add "old" style config.ini for ndb mysql-test/suite/federated/disabled.def: Move disabled federated to it's new suite mysql-test/suite/federated/my.cnf: Add config for federated mysql-test/suite/ndb/my.cnf: Add config for ndb mysql-test/suite/rpl/my.cnf: Add config for rpl mysql-test/suite/rpl/rpl_1slave_base.cnf: Add base config for rpl mysql-test/suite/rpl/t/rpl_000015-master.opt: Use new paths mysql-test/suite/rpl_ndb/my.cnf: Add config for rpl_ndb mysql-test/lib/My/File/Path.pm: Initial version mysql-test/lib/My/SafeProcess/Base.pm: Initial version mysql-test/lib/My/SafeProcess/safe_kill_win.cc: Initial version mysql-test/lib/My/SafeProcess/safe_process.pl: Initial version mysql-test/lib/My/SafeProcess/safe_process_win.cc: Initial version mysql-test/lib/t/Base.t: Initial version mysql-test/lib/t/Find.t: Initial version mysql-test/lib/t/SafeProcess.t: Initial version mysql-test/lib/t/SafeProcessStress.pl: Initial version mysql-test/lib/t/copytree.t: Initial version mysql-test/lib/t/dummyd.pl: Initial version mysql-test/lib/t/rmtree.t: Initial version mysql-test/lib/t/testMyConfig.t: Initial version mysql-test/lib/t/testMyConfigFactory.t: Initial version mysql-test/lib/t/test_child.pl: Initial version mysql-test/include/default_my.cnf: Add default config file used when no suite specific file is found mysql-test/include/default_mysqld.cnf: New BitKeeper file ``mysql-test/include/default_mysqld.cnf'' mysql-test/include/default_ndbd.cnf: Add default settings for all ndbds mysql-test/lib/mtr_settings.pl: Initial version
2007-12-12 18:19:24 +01:00
load data infile '../../std_data/words.dat' into table t1 (a);
drop trigger t1_ai;
drop trigger t2_ai;
create function f1() returns int return (select max(b) from t1);
insert into t1 values
("All",f1()),("mimsy",f1()),("were",f1()),("the",f1()),("borogoves",f1()),
("And",f1()),("the",f1()),("mome", f1()),("raths",f1()),("outgrabe",f1());
create function f2() returns int return (select max(b) from t2);
insert into t2 select a, f2() from t1;
WL#4189 - dynamic configuration support - safe process - cleanups - create new suite for fedarated BitKeeper/deleted/.del-basic.test: Rename: mysql-test/ndb/basic.test -> BitKeeper/deleted/.del-basic.test BitKeeper/deleted/.del-basic_log.result: Rename: mysql-test/ndb/basic_log.result -> BitKeeper/deleted/.del-basic_log.result mysql-test/suite/federated/federated_transactions.result: Rename: mysql-test/r/federated_transactions.result -> mysql-test/suite/federated/federated_transactions.result BitKeeper/deleted/.del-have_bug25714.require: Rename: mysql-test/r/have_bug25714.require -> BitKeeper/deleted/.del-have_bug25714.require BitKeeper/deleted/.del-kill_master.sh: Rename: mysql-test/misc/kill_master.sh -> BitKeeper/deleted/.del-kill_master.sh BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a: Rename: mysql-test/ndb/ndb_config_4_node.ini -> BitKeeper/deleted/.del-ndb_config_4_node.ini~d8e572e9b68f933a BitKeeper/deleted/.del-restart.result: Rename: mysql-test/ndb/restart.result -> BitKeeper/deleted/.del-restart.result mysql-test/suite/federated/federated_cleanup.inc: Rename: mysql-test/include/federated_cleanup.inc -> mysql-test/suite/federated/federated_cleanup.inc mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_rotate_logs.slave-mi -> mysql-test/suite/rpl/t/rpl_rotate_logs-slave.opt BitKeeper/deleted/.del-install_test_db.sh: Rename: mysql-test/install_test_db.sh -> BitKeeper/deleted/.del-install_test_db.sh BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16: Rename: mysql-test/ndb/ndb_config_1_node.ini -> BitKeeper/deleted/.del-ndb_config_1_node.ini~7ec640ed25570e16 BitKeeper/deleted/.del-mtr_timer.pl: Rename: mysql-test/lib/mtr_timer.pl -> BitKeeper/deleted/.del-mtr_timer.pl BitKeeper/deleted/.del-create-test-result: Rename: mysql-test/create-test-result -> BitKeeper/deleted/.del-create-test-result BitKeeper/deleted/.del-fix-result: Rename: mysql-test/fix-result -> BitKeeper/deleted/.del-fix-result BitKeeper/deleted/.del-mysql-test-run-shell.sh: Rename: mysql-test/mysql-test-run-shell.sh -> BitKeeper/deleted/.del-mysql-test-run-shell.sh BitKeeper/deleted/.del-mysql-test_V1.9.pl: Rename: mysql-test/misc/mysql-test_V1.9.pl -> BitKeeper/deleted/.del-mysql-test_V1.9.pl BitKeeper/deleted/.del-resolve-stack: Rename: mysql-test/resolve-stack -> BitKeeper/deleted/.del-resolve-stack BitKeeper/deleted/.del-restart_log.result: Rename: mysql-test/ndb/restart_log.result -> BitKeeper/deleted/.del-restart_log.result mysql-test/suite/rpl/t/rpl_000015-slave.opt: Rename: mysql-test/suite/rpl/t/rpl_000015.slave-mi -> mysql-test/suite/rpl/t/rpl_000015-slave.opt BitKeeper/deleted/.del-ndb_config_2_node.ini: Rename: mysql-test/ndb/ndb_config_2_node.ini -> BitKeeper/deleted/.del-ndb_config_2_node.ini BitKeeper/deleted/.del-ndbcluster.sh: Rename: mysql-test/ndb/ndbcluster.sh -> BitKeeper/deleted/.del-ndbcluster.sh BitKeeper/deleted/.del-basic.result: Rename: mysql-test/ndb/basic.result -> BitKeeper/deleted/.del-basic.result BitKeeper/deleted/.del-restart.test: Rename: mysql-test/ndb/restart.test -> BitKeeper/deleted/.del-restart.test BitKeeper/deleted/.del-have_bug25714.inc: Rename: mysql-test/include/have_bug25714.inc -> BitKeeper/deleted/.del-have_bug25714.inc BitKeeper/deleted/.del-mtr_diff.pl: Rename: mysql-test/lib/mtr_diff.pl -> BitKeeper/deleted/.del-mtr_diff.pl mysql-test/suite/federated/federated_transactions-slave.opt: Rename: mysql-test/t/federated_transactions-slave.opt -> mysql-test/suite/federated/federated_transactions-slave.opt BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b: Rename: mysql-test/ndb/Makefile.am -> BitKeeper/deleted/.del-Makefile.am~343467da4d0f211b BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949: Rename: mysql-test/lib/mtr_im.pl -> BitKeeper/deleted/.del-mtr_im.pl~9762b0336c28949 mysql-test/suite/federated/federated_innodb-slave.opt: Rename: mysql-test/t/federated_innodb-slave.opt -> mysql-test/suite/federated/federated_innodb-slave.opt client/mysqltest.c: Use current files path first when looking for include file configure.in: Remove mysql-test/nbd mysql-test/Makefile.am: Cleanup mysql-test/Makefile.am mysql-test/extra/binlog_tests/blackhole.test: Use new paths mysql-test/extra/binlog_tests/ctype_ucs_binlog.test: Use new paths mysql-test/mysql-test-run.pl: Dynamic configuration support Safe process mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test: Use new paths mysql-test/extra/rpl_tests/rpl_EE_err.test: Use new paths mysql-test/extra/rpl_tests/rpl_loaddata.test: Use new paths mysql-test/extra/rpl_tests/rpl_log.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_001.test: Use new paths mysql-test/extra/rpl_tests/rpl_row_charset.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_000001.test: Use new paths mysql-test/extra/rpl_tests/rpl_stm_charset.test: Use new paths mysql-test/include/have_blackhole.inc: Use new paths mysql-test/include/have_ndbapi_examples.inc: Use new paths mysql-test/include/loaddata_autocom.inc: Use new paths mysql-test/include/mix1.inc: Use new paths mysql-test/include/ndb_backup.inc: Use new paths mysql-test/include/ndb_restore_master.inc: Use new paths mysql-test/include/ndb_restore_slave_eoption.inc: Use new paths mysql-test/include/testdb_only.inc: Use new paths mysql-test/lib/My/Config.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_cases.pm: dynamic configuration safe process cleanups mysql-test/lib/mtr_io.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_misc.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_process.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_report.pl: dynamic configuration safe process cleanups mysql-test/lib/mtr_stress.pl: dynamic configuration safe process cleanups mysql-test/r/backup.result: Use new paths mysql-test/r/ctype_big5.result: Use new paths mysql-test/r/gis.result: Use new paths mysql-test/r/loaddata.result: Use new paths mysql-test/r/loaddata_autocom_innodb.result: Use new paths mysql-test/r/mysqlbinlog.result: Use new paths mysql-test/r/mysqlbinlog_base64.result: Use new paths mysql-test/r/outfile.result: Use new paths mysql-test/r/partition_error.result: Use new paths mysql-test/r/partition_not_windows.result: Use new paths mysql-test/r/partition_symlink.result: Use new paths mysql-test/r/query_cache.result: Use new paths mysql-test/r/sp.result: Use new paths mysql-test/r/symlink.result: Use new paths mysql-test/r/system_mysql_db.result: Use new paths mysql-test/r/trigger.result: Use new paths mysql-test/r/type_blob.result: Use new paths mysql-test/r/view.result: Use new paths mysql-test/r/warnings.result: Use new paths mysql-test/suite/binlog/r/binlog_killed_simulate.result: Use new paths mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Use new paths mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Use new paths mysql-test/suite/binlog/t/binlog_killed.test: Use new paths mysql-test/suite/binlog/t/binlog_killed_simulate.test: Use new paths mysql-test/suite/binlog/t/binlog_row_mix_innodb_myisam.test: Use new paths mysql-test/suite/binlog/t/binlog_stm_mix_innodb_myisam.test: Use new paths mysql-test/suite/federated/federated.inc: Use new paths mysql-test/suite/federated/federated.result: Use new paths mysql-test/suite/federated/federated.test: Use new paths mysql-test/suite/federated/federated_archive.result: Use new paths mysql-test/suite/federated/federated_archive.test: Use new paths mysql-test/suite/federated/federated_bug_13118.result: Use new paths mysql-test/suite/federated/federated_bug_13118.test: Use new paths mysql-test/suite/federated/federated_bug_25714.result: Use new paths mysql-test/suite/federated/federated_bug_25714.test: Use new paths mysql-test/suite/federated/federated_innodb.result: Use new paths mysql-test/suite/federated/federated_innodb.test: Use new paths mysql-test/suite/federated/federated_server.result: Use new paths mysql-test/suite/federated/federated_server.test: Use new paths mysql-test/suite/federated/federated_transactions.test: Use new paths mysql-test/suite/federated/have_federated_db.inc: Use new paths mysql-test/suite/ndb/r/loaddata_autocom_ndb.result: Use new paths mysql-test/suite/ndb/r/ndb_config.result: Use new paths mysql-test/suite/ndb/r/ndb_dd_backuprestore.result: Use new paths mysql-test/suite/ndb/r/ndb_load.result: Use new paths mysql-test/suite/ndb/r/ndb_loaddatalocal.result: Use new paths mysql-test/suite/ndb/r/ndb_replace.result: Use new paths mysql-test/suite/ndb/r/ndb_restore.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_partition.result: Use new paths mysql-test/suite/ndb/r/ndb_restore_print.result: Use new paths mysql-test/suite/ndb/r/ndb_trigger.result: Use new paths mysql-test/suite/ndb/t/ndb_alter_table.test: Use new paths mysql-test/suite/ndb/t/ndb_config.test: Use new paths mysql-test/suite/ndb/t/ndb_load.test: Use new paths mysql-test/suite/ndb/t/ndb_loaddatalocal.test: Use new paths mysql-test/suite/ndb/t/ndb_replace.test: Use new paths mysql-test/suite/ndb/t/ndb_restore.test: Use new paths mysql-test/suite/ndb/t/ndb_single_user.test: Use new paths mysql-test/suite/ndb/t/ndb_trigger.test: Use new paths mysql-test/suite/ndb/t/ndbapi.test: Use new paths mysql-test/suite/rpl/include/rpl_mixed_dml.inc: Use new paths mysql-test/suite/rpl/r/rpl_LD_INFILE.result: Use new paths mysql-test/suite/rpl/r/rpl_flushlog_loop.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Use new paths mysql-test/suite/rpl/r/rpl_load_table_from_master.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_charset.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_s.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddata_simple.result: Use new paths mysql-test/suite/rpl/r/rpl_loaddatalocal.result: Use new paths mysql-test/suite/rpl/r/rpl_loadfile.result: Use new paths mysql-test/suite/rpl/r/rpl_misc_functions.result: Use new paths mysql-test/suite/rpl/r/rpl_replicate_do.result: Use new paths mysql-test/suite/rpl/r/rpl_rewrt_db.result: Use new paths mysql-test/suite/rpl/r/rpl_row_001.result: Use new paths mysql-test/suite/rpl/r/rpl_row_loaddata_m.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log.result: Use new paths mysql-test/suite/rpl/r/rpl_row_log_innodb.result: Use new paths mysql-test/suite/rpl/r/rpl_row_stop_middle_update.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_000001.result: Use new paths mysql-test/suite/rpl/r/rpl_stm_log.result: Use new paths mysql-test/suite/rpl/r/rpl_timezone.result: Use new paths mysql-test/suite/rpl/t/disabled.def: Use new paths mysql-test/suite/rpl/t/rpl000017-slave.sh: Use new paths mysql-test/suite/rpl/t/rpl_LD_INFILE.test: Use new paths mysql-test/suite/rpl/t/rpl_drop_db.test: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop-slave.opt: Use new paths mysql-test/suite/rpl/t/rpl_flushlog_loop.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_innodb_bug30919.test: Use new paths mysql-test/suite/rpl/t/rpl_load_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_load_table_from_master.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_charset.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_fatal.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_m.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_s.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddata_simple.test: Use new paths mysql-test/suite/rpl/t/rpl_loaddatalocal.test: Use new paths mysql-test/suite/rpl/t/rpl_loadfile.test: Use new paths mysql-test/suite/rpl/t/rpl_misc_functions.test: Use new paths mysql-test/suite/rpl/t/rpl_replicate_do.test: Use new paths mysql-test/suite/rpl/t/rpl_rewrt_db.test: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs-master.opt: Use new paths mysql-test/suite/rpl/t/rpl_rotate_logs.test: Use new paths mysql-test/suite/rpl/t/rpl_row_charset_innodb.test: Use new paths mysql-test/suite/rpl/t/rpl_row_mysqlbinlog.test: Use new paths mysql-test/suite/rpl/t/rpl_row_stop_middle_update.test: Use new paths mysql-test/suite/rpl/t/rpl_timezone.test: Use new paths mysql-test/suite/rpl/t/rpl_trigger.test: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_dd_advance.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_innodb_trans.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_log.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_multi.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_row_001.result: Use new paths mysql-test/suite/rpl_ndb/r/rpl_ndb_sync.result: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_bank.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_dd_advance.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_innodb_trans.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_load.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndb_sync.test: Use new paths mysql-test/suite/rpl_ndb/t/rpl_ndbapi_multi.test: Use new paths mysql-test/t/backup.test: Use new paths mysql-test/t/bootstrap.test: Use new paths mysql-test/t/crash_commit_before.test: Use new paths mysql-test/t/create_not_windows.test: Use new paths mysql-test/t/csv.test: Use new paths mysql-test/t/ctype_big5.test: Use new paths mysql-test/t/disabled.def: Use new paths mysql-test/t/distinct.test: Use new paths mysql-test/t/gis.test: Use new paths mysql-test/t/grant_cache_no_prot.test: Use new paths mysql-test/t/grant_cache_ps_prot.test: Use new paths mysql-test/t/information_schema_chmod.test: Use new paths mysql-test/t/loaddata.test: Use new paths mysql-test/t/log_state.test: Use new paths mysql-test/t/myisam-system.test: Use new paths mysql-test/t/mysql_upgrade.test: Use new paths mysql-test/t/mysqlbinlog-cp932.test: Use new paths mysql-test/t/mysqlbinlog.test: Use new paths mysql-test/t/mysqlbinlog2.test: Use new paths mysql-test/t/mysqlbinlog_base64.test: Use new paths mysql-test/t/mysqldump.test: Use new paths mysql-test/t/outfile.test: Use new paths mysql-test/t/partition.test: Use new paths mysql-test/t/partition_error.test: Use new paths mysql-test/t/partition_federated.test: Use new paths mysql-test/t/partition_mgm.test: Use new paths mysql-test/t/partition_not_windows.test: Use new paths mysql-test/t/partition_symlink.test: Use new paths mysql-test/t/query_cache.test: Use new paths mysql-test/t/repair.test: Use new paths mysql-test/t/show_check.test: Use new paths mysql-test/t/sp-destruct.test: Use new paths mysql-test/t/sp.test: Use new paths mysql-test/t/symlink.test: Use new paths mysql-test/t/system_mysql_db.test: Use new paths mysql-test/t/system_mysql_db_fix30020.test: Use new paths mysql-test/t/system_mysql_db_fix40123.test: Use new paths mysql-test/t/system_mysql_db_fix50030.test: Use new paths mysql-test/t/system_mysql_db_fix50117.test: Use new paths mysql-test/t/trigger-compat.test: Use new paths mysql-test/t/trigger-grant.test: Use new paths mysql-test/t/trigger.test: Use new paths mysql-test/t/type_blob.test: Use new paths mysql-test/t/type_varchar.test: Use new paths mysql-test/t/upgrade.test: Use new paths mysql-test/t/user_var-binlog.test: Use new paths mysql-test/t/varbinary.test: Use new paths mysql-test/t/view.test: Use new paths mysql-test/t/warnings.test: Use new paths mysql-test/lib/My/ConfigFactory.pm: Initial version mysql-test/lib/My/Find.pm: Initial version mysql-test/lib/My/SafeProcess.pm: Initial version mysql-test/std_data/ndb_config_config.ini: Add "old" style config.ini for ndb mysql-test/suite/federated/disabled.def: Move disabled federated to it's new suite mysql-test/suite/federated/my.cnf: Add config for federated mysql-test/suite/ndb/my.cnf: Add config for ndb mysql-test/suite/rpl/my.cnf: Add config for rpl mysql-test/suite/rpl/rpl_1slave_base.cnf: Add base config for rpl mysql-test/suite/rpl/t/rpl_000015-master.opt: Use new paths mysql-test/suite/rpl_ndb/my.cnf: Add config for rpl_ndb mysql-test/lib/My/File/Path.pm: Initial version mysql-test/lib/My/SafeProcess/Base.pm: Initial version mysql-test/lib/My/SafeProcess/safe_kill_win.cc: Initial version mysql-test/lib/My/SafeProcess/safe_process.pl: Initial version mysql-test/lib/My/SafeProcess/safe_process_win.cc: Initial version mysql-test/lib/t/Base.t: Initial version mysql-test/lib/t/Find.t: Initial version mysql-test/lib/t/SafeProcess.t: Initial version mysql-test/lib/t/SafeProcessStress.pl: Initial version mysql-test/lib/t/copytree.t: Initial version mysql-test/lib/t/dummyd.pl: Initial version mysql-test/lib/t/rmtree.t: Initial version mysql-test/lib/t/testMyConfig.t: Initial version mysql-test/lib/t/testMyConfigFactory.t: Initial version mysql-test/lib/t/test_child.pl: Initial version mysql-test/include/default_my.cnf: Add default config file used when no suite specific file is found mysql-test/include/default_mysqld.cnf: New BitKeeper file ``mysql-test/include/default_mysqld.cnf'' mysql-test/include/default_ndbd.cnf: Add default settings for all ndbds mysql-test/lib/mtr_settings.pl: Initial version
2007-12-12 18:19:24 +01:00
load data infile '../../std_data/words.dat' into table t1 (a) set b:= f1();
drop function f1;
drop function f2;
2006-05-10 21:35:05 +02:00
drop table t1, t2;
create table t1(i int not null, j int not null, n numeric(15,2), primary key(i,j));
create table t2(i int not null, n numeric(15,2), primary key(i));
create trigger t1_ai after insert on t1 for each row
begin
declare sn numeric(15,2);
select sum(n) into sn from t1 where i=new.i;
replace into t2 values(new.i, sn);
end|
insert into t1 values
(1,1,10.00),(1,2,10.00),(1,3,10.00),(1,4,10.00),(1,5,10.00),
(1,6,10.00),(1,7,10.00),(1,8,10.00),(1,9,10.00),(1,10,10.00),
(1,11,10.00),(1,12,10.00),(1,13,10.00),(1,14,10.00),(1,15,10.00);
select * from t1;
i j n
1 1 10.00
1 2 10.00
1 3 10.00
1 4 10.00
1 5 10.00
1 6 10.00
1 7 10.00
1 8 10.00
1 9 10.00
1 10 10.00
1 11 10.00
1 12 10.00
1 13 10.00
1 14 10.00
1 15 10.00
select * from t2;
i n
1 150.00
drop tables t1, t2;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
conn_id INT,
trigger_conn_id INT
);
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
SET NEW.trigger_conn_id = CONNECTION_ID();
INSERT INTO t1 (conn_id, trigger_conn_id) VALUES (CONNECTION_ID(), -1);
INSERT INTO t1 (conn_id, trigger_conn_id) VALUES (CONNECTION_ID(), -1);
SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
conn_id trigger_conn_id
DROP TRIGGER t1_bi;
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i1 INT);
SET @save_sql_mode=@@sql_mode;
SET SQL_MODE='';
CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
SET @x = 5/0;
SET SQL_MODE='traditional';
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
SET @x = 5/0;
SET @x=1;
INSERT INTO t1 VALUES (@x);
SELECT @x;
@x
NULL
SET @x=2;
UPDATE t1 SET i1 = @x;
SELECT @x;
@x
NULL
SET SQL_MODE='';
SET @x=3;
INSERT INTO t1 VALUES (@x);
SELECT @x;
@x
NULL
SET @x=4;
UPDATE t1 SET i1 = @x;
SELECT @x;
@x
NULL
SET @@sql_mode=@save_sql_mode;
DROP TRIGGER t1_ai;
DROP TRIGGER t1_au;
DROP TABLE t1;
Bug#14635: Accept NEW.x as INOUT parameters to stored procedures from within triggers Add support for passing NEW.x as INOUT and OUT parameters to stored procedures. Passing NEW.x as INOUT parameter requires SELECT and UPDATE privileges on that column, and passing it as OUT parameter requires only UPDATE privilege. mysql-test/r/sp-error.result: Update the result for new message. mysql-test/r/trigger-grant.result: Add result for bug#14635. mysql-test/r/trigger.result: Add result for bug#14635. mysql-test/t/trigger-grant.test: Add test case for bug#14635. mysql-test/t/trigger.test: Add test case for bug#14635. sql/item.cc: Add implementations of set_value() and set_required_privilege() methods of Settable_routine_parameter interface. Use Item_trigger_field::want_privilege instead of Item_trigger_field::access_type. Reset privileges on Item_trigger_field::cleanup(). sql/item.h: Add interface class Settable_routine_parameter and interface query method to Item class. Item_splocal and Item_trigger_field implement this interface. For Item_trigger_field: - add read_only attribute and is_read_only() method. - remove access_type and add original_privilege and want_privilege instead. - add set_value() method. - add reset_privilege() method. sql/item_func.cc: Add implementations of set_value() method of Settable_routine_parameter interface. sql/item_func.h: Item_func_get_user_var implements Settable_routine_parameter interface. sql/share/errmsg.txt: Update english ER_SP_NOT_VAR_ARG message. sql/sp_head.cc: Use Settable_routine_parameter interface for parameter update. sql/sql_yacc.yy: Set read_only and want_privilege members in Item_trigger_field appropriately. For NEW.x trigger variable used in left-hand-side of SET statement the latter is set to UPDATE_ACL, otherwise it is set to SELECT_ACL (but see Item_trigger_field::set_required_privilege(), where it may be updated to different value).
2006-05-12 11:55:21 +02:00
DROP TABLE IF EXISTS t1;
DROP PROCEDURE IF EXISTS p1;
DROP PROCEDURE IF EXISTS p2;
CREATE TABLE t1 (i1 INT);
INSERT INTO t1 VALUES (3);
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
BEGIN
CALL p1(NEW.i1);
CALL p2(NEW.i1);
END//
UPDATE t1 SET i1 = 11 WHERE i1 = 3;
DROP TRIGGER t1_bu;
DROP PROCEDURE p2;
DROP PROCEDURE p1;
INSERT INTO t1 VALUES (13);
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
CALL p1(OLD.i1);
UPDATE t1 SET i1 = 19 WHERE i1 = 13;
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
DROP TRIGGER t1_bu;
DROP PROCEDURE p1;
INSERT INTO t1 VALUES (23);
CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
CALL p1(OLD.i1);
UPDATE t1 SET i1 = 31 WHERE i1 = 23;
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
DROP TRIGGER t1_bu;
DROP PROCEDURE p1;
INSERT INTO t1 VALUES (37);
CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
CALL p1(NEW.i1);
UPDATE t1 SET i1 = 43 WHERE i1 = 37;
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
DROP TRIGGER t1_au;
DROP PROCEDURE p1;
INSERT INTO t1 VALUES (47);
CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
CALL p1(NEW.i1);
UPDATE t1 SET i1 = 51 WHERE i1 = 47;
ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
DROP TRIGGER t1_au;
DROP PROCEDURE p1;
SELECT * FROM t1;
i1
35
13
23
43
51
DROP TABLE t1;
create trigger wont_work after update on mysql.user for each row
begin
set @a:= 1;
end|
ERROR HY000: Triggers can not be created on system tables
use mysql|
create trigger wont_work after update on event for each row
begin
set @a:= 1;
end|
ERROR HY000: Triggers can not be created on system tables
use test|
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1(c INT);
CREATE TABLE t2(c INT);
CREATE DEFINER=1234567890abcdefGHIKL@localhost
TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW SET @a = 1;
ERROR HY000: String '1234567890abcdefGHIKL' is too long for user name (should be no longer than 16)
CREATE DEFINER=some_user_name@1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY
TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW SET @a = 2;
ERROR HY000: String '1234567890abcdefghij1234567890abcdefghij1234567890abcdefghijQWERTY' is too long for host name (should be no longer than 60)
DROP TABLE t1;
DROP TABLE t2;
Fix for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop" (version for 5.0 only). UPDATE statement which WHERE clause used key and which invoked trigger that modified field in this key worked indefinetely. This problem occured because in cases when UPDATE statement was executed in update-on-the-fly mode (in which row is updated right during evaluation of select for WHERE clause) the new version of the row became visible to select representing WHERE clause and was updated again and again. We already solve this problem for UPDATE statements which does not invoke triggers by detecting the fact that we are going to update field in key used for scanning and performing update in two steps, during the first step we gather information about the rows to be updated and then doing actual updates. We also do this for MULTI-UPDATE and in its case we even detect situation when such fields are updated in triggers (actually we simply assume that we always update fields used in key if we have before update trigger). The fix simply extends this check which is done in check_if_key_used()/ QUICK_SELECT_I::check_if_keys_used() routine/method in such way that it also detects cases when field used in key is updated in trigger. As nice side-effect we have more precise and thus more optimal perfomance-wise check for the MULTI-UPDATE. Also check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() were renamed to is_key_used()/QUICK_SELECT_I::is_keys_used() in order to better reflect that boolean predicate. Note that this check is implemented in much more elegant way in 5.1 mysql-test/r/trigger.result: Added test case for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop". mysql-test/t/trigger.test: Added test case for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop". sql/key.cc: Renamed check_if_key_used() to is_key_used(). Also this routine checks if key uses field which can be updated by before update trigger defined on the table. As result we avoid using update-on-the-fly method in cases when trigger updates part of key which is used by select which filters rows to be updated and thus avoid infinite updates. By doing such check here we cover both UPDATE and MULTI-UPDATE cases. sql/mysql_priv.h: Renamed check_if_key_used() to is_key_used(). sql/opt_range.cc: Renamed check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() to is_key_used()/QUICK_SELECT_I::is_keys_used(). sql/opt_range.h: Renamed QUICK_SELECT_I::check_if_keys_used() method to is_keys_used(), also updated comment describing it to reflect its extended semantics (this change was caused by change in check_if_key_used()/is_key_used() routine semantics). sql/sql_trigger.cc: Introduced Table_triggers_list::is_updated_in_before_update_triggers() method which is needed for checking if field of subject table can be changed in before update trigger. sql/sql_trigger.h: Table_triggers_list: Removed has_before_update_triggers() method which is not used any longer. Added declaration of is_updated_in_before_update_triggers() which is needed for checking if field of subject table can be changed by before update trigger. sql/sql_update.cc: safe_update_on_fly(): check_if_key_used() routine and check_if_keys_used() method were renamed to is_key_used()/is_keys_used(). Now cases when trigger updates fields which are part of key used for filtering rows for update are caught directly in is_key_used(). This also allows to cover both UPDATE and MULTI-UPDATE cases.
2006-09-21 09:35:38 +02:00
drop table if exists t1;
drop table if exists t2;
drop table if exists t3;
drop table if exists t4;
SET @save_sql_mode=@@sql_mode;
SET sql_mode='TRADITIONAL'|
create table t1 (id int(10) not null primary key, v int(10) )|
create table t2 (id int(10) not null primary key, v int(10) )|
create table t3 (id int(10) not null primary key, v int(10) )|
create table t4 (c int)|
create trigger t4_bi before insert on t4 for each row set @t4_bi_called:=1|
create trigger t4_bu before update on t4 for each row set @t4_bu_called:=1|
insert into t1 values(10, 10)|
set @a:=1/0|
Warnings:
Warning 1365 Division by 0
select 1/0 from t1|
1/0
NULL
Warnings:
Warning 1365 Division by 0
create trigger t1_bi before insert on t1 for each row set @a:=1/0|
insert into t1 values(20, 20)|
drop trigger t1_bi|
create trigger t1_bi before insert on t1 for each row
begin
insert into t2 values (new.id, new.v);
update t2 set v=v+1 where id= new.id;
replace t3 values (new.id, 0);
update t2, t3 set t2.v=new.v, t3.v=new.v where t2.id=t3.id;
create temporary table t5 select * from t1;
delete from t5;
insert into t5 select * from t1;
insert into t4 values (0);
set @check= (select count(*) from t5);
update t4 set c= @check;
drop temporary table t5;
set @a:=1/0;
end|
set @check=0, @t4_bi_called=0, @t4_bu_called=0|
insert into t1 values(30, 30)|
select @check, @t4_bi_called, @t4_bu_called|
@check @t4_bi_called @t4_bu_called
2 1 1
SET @@sql_mode=@save_sql_mode;
drop table t1;
drop table t2;
drop table t3;
drop table t4;
drop table if exists t1;
Fix for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop" (version for 5.0 only). UPDATE statement which WHERE clause used key and which invoked trigger that modified field in this key worked indefinetely. This problem occured because in cases when UPDATE statement was executed in update-on-the-fly mode (in which row is updated right during evaluation of select for WHERE clause) the new version of the row became visible to select representing WHERE clause and was updated again and again. We already solve this problem for UPDATE statements which does not invoke triggers by detecting the fact that we are going to update field in key used for scanning and performing update in two steps, during the first step we gather information about the rows to be updated and then doing actual updates. We also do this for MULTI-UPDATE and in its case we even detect situation when such fields are updated in triggers (actually we simply assume that we always update fields used in key if we have before update trigger). The fix simply extends this check which is done in check_if_key_used()/ QUICK_SELECT_I::check_if_keys_used() routine/method in such way that it also detects cases when field used in key is updated in trigger. As nice side-effect we have more precise and thus more optimal perfomance-wise check for the MULTI-UPDATE. Also check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() were renamed to is_key_used()/QUICK_SELECT_I::is_keys_used() in order to better reflect that boolean predicate. Note that this check is implemented in much more elegant way in 5.1 mysql-test/r/trigger.result: Added test case for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop". mysql-test/t/trigger.test: Added test case for bug#20670 "UPDATE using key and invoking trigger that modifies this key does not stop". sql/key.cc: Renamed check_if_key_used() to is_key_used(). Also this routine checks if key uses field which can be updated by before update trigger defined on the table. As result we avoid using update-on-the-fly method in cases when trigger updates part of key which is used by select which filters rows to be updated and thus avoid infinite updates. By doing such check here we cover both UPDATE and MULTI-UPDATE cases. sql/mysql_priv.h: Renamed check_if_key_used() to is_key_used(). sql/opt_range.cc: Renamed check_if_key_used()/QUICK_SELECT_I::check_if_keys_used() to is_key_used()/QUICK_SELECT_I::is_keys_used(). sql/opt_range.h: Renamed QUICK_SELECT_I::check_if_keys_used() method to is_keys_used(), also updated comment describing it to reflect its extended semantics (this change was caused by change in check_if_key_used()/is_key_used() routine semantics). sql/sql_trigger.cc: Introduced Table_triggers_list::is_updated_in_before_update_triggers() method which is needed for checking if field of subject table can be changed in before update trigger. sql/sql_trigger.h: Table_triggers_list: Removed has_before_update_triggers() method which is not used any longer. Added declaration of is_updated_in_before_update_triggers() which is needed for checking if field of subject table can be changed by before update trigger. sql/sql_update.cc: safe_update_on_fly(): check_if_key_used() routine and check_if_keys_used() method were renamed to is_key_used()/is_keys_used(). Now cases when trigger updates fields which are part of key used for filtering rows for update are caught directly in is_key_used(). This also allows to cover both UPDATE and MULTI-UPDATE cases.
2006-09-21 09:35:38 +02:00
create table t1 (i int, j int key);
insert into t1 values (1,1), (2,2), (3,3);
create trigger t1_bu before update on t1 for each row
set new.j = new.j + 10;
update t1 set i= i+ 10 where j > 2;
select * from t1;
i j
1 1
2 2
13 13
drop table t1;
CREATE TABLE t1 (a INT PRIMARY KEY);
CREATE TABLE t2 (a INT PRIMARY KEY);
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
CREATE TRIGGER trg_t1 BEFORE DELETE on t1 FOR EACH ROW
INSERT INTO t2 VALUES (OLD.a);
FLUSH STATUS;
TRUNCATE t1;
SHOW STATUS LIKE 'handler_delete';
Variable_name Value
Handler_delete 0
SELECT COUNT(*) FROM t2;
COUNT(*)
0
INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8);
DELETE FROM t2;
FLUSH STATUS;
DELETE FROM t1;
SHOW STATUS LIKE 'handler_delete';
Variable_name Value
Handler_delete 8
SELECT COUNT(*) FROM t2;
COUNT(*)
8
DROP TRIGGER trg_t1;
DROP TABLE t1,t2;
drop table if exists t1;
drop function if exists f1;
create table t1 (i int);
create function f1() returns int return 10;
create trigger t1_bi before insert on t1 for each row set @a:= f1() + 10;
insert into t1 values ();
select @a;
@a
20
insert into t1 values ();
select @a;
@a
20
drop table t1;
drop function f1;
Bug#23703 (DROP TRIGGER needs an IF EXISTS) This change set implements the DROP TRIGGER IF EXISTS functionality. This fix is considered a bug and not a feature, because without it, there is no known method to write a database creation script that can create a trigger without failing, when executed on a database that may or may not contain already a trigger of the same name. Implementing this functionality closes an orthogonality gap between triggers and stored procedures / stored functions (which do support the DROP IF EXISTS syntax). In sql_trigger.cc, in mysql_create_or_drop_trigger, the code has been reordered to: - perform the tests that do not depend on the file system (access()), - get the locks (wait_if_global_read_lock, LOCK_open) - call access() - perform the operation - write to the binlog - unlock (LOCK_open, start_waiting_global_read_lock) This is to ensure that all the code that depends on the presence of the trigger file is executed in the same critical section, and prevents race conditions similar to the case fixed by Bug 14262 : - thread 1 executes DROP TRIGGER IF EXISTS, access() returns a failure - thread 2 executes CREATE TRIGGER - thread 2 logs CREATE TRIGGER - thread 1 logs DROP TRIGGER IF EXISTS The patch itself is based on code contributed by the MySQL community, under the terms of the Contributor License Agreement (See Bug 18161). mysql-test/r/rpl_trigger.result: DROP TRIGGER IF EXISTS mysql-test/r/trigger.result: DROP TRIGGER IF EXISTS mysql-test/t/rpl_trigger.test: DROP TRIGGER IF EXISTS mysql-test/t/trigger.test: DROP TRIGGER IF EXISTS sql/sql_trigger.cc: DROP TRIGGER IF EXISTS sql/sql_yacc.yy: DROP TRIGGER IF EXISTS
2006-11-13 23:40:22 +01:00
drop table if exists t1;
create table t1(a int, b varchar(50));
drop trigger not_a_trigger;
ERROR HY000: Trigger does not exist
drop trigger if exists not_a_trigger;
Warnings:
Note 1360 Trigger does not exist
create trigger t1_bi before insert on t1
for each row set NEW.b := "In trigger t1_bi";
insert into t1 values (1, "a");
drop trigger if exists t1_bi;
insert into t1 values (2, "b");
drop trigger if exists t1_bi;
Warnings:
Note 1360 Trigger does not exist
insert into t1 values (3, "c");
select * from t1;
a b
1 In trigger t1_bi
2 b
3 c
drop table t1;
CREATE TABLE t1 (
id int NOT NULL DEFAULT '0',
a varchar(10) NOT NULL,
b varchar(10),
c varchar(10),
d timestamp NOT NULL,
PRIMARY KEY (id, a)
);
CREATE TABLE t2 (
fubar_id int unsigned NOT NULL DEFAULT '0',
last_change_time datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (fubar_id)
);
CREATE TRIGGER fubar_change
AFTER UPDATE ON t1
FOR EACH ROW
BEGIN
INSERT INTO t2 (fubar_id, last_change_time)
SELECT DISTINCT NEW.id AS fubar_id, NOW() AS last_change_time
FROM t1 WHERE (id = NEW.id) AND (OLD.c != NEW.c)
ON DUPLICATE KEY UPDATE
last_change_time =
IF((fubar_id = NEW.id)AND(OLD.c != NEW.c),NOW(),last_change_time);
END
|
INSERT INTO t1 (id,a, b,c,d) VALUES
(1,'a','b','c',now()),(2,'a','b','c',now());
UPDATE t1 SET c='Bang!' WHERE id=1;
SELECT fubar_id FROM t2;
fubar_id
1
DROP TABLE t1,t2;
2007-03-06 21:46:33 +01:00
DROP TABLE IF EXISTS bug21825_A;
DROP TABLE IF EXISTS bug21825_B;
CREATE TABLE bug21825_A (id int(10));
CREATE TABLE bug21825_B (id int(10));
CREATE TRIGGER trgA AFTER INSERT ON bug21825_A
FOR EACH ROW
BEGIN
INSERT INTO bug21825_B (id) values (1);
END//
INSERT INTO bug21825_A (id) VALUES (10);
INSERT INTO bug21825_A (id) VALUES (20);
DROP TABLE bug21825_B;
DELETE FROM bug21825_A WHERE id = 20;
DROP TABLE bug21825_A;
DROP TABLE IF EXISTS bug22580_t1;
DROP PROCEDURE IF EXISTS bug22580_proc_1;
DROP PROCEDURE IF EXISTS bug22580_proc_2;
CREATE TABLE bug22580_t1 (a INT, b INT);
CREATE PROCEDURE bug22580_proc_2()
BEGIN
DROP TABLE IF EXISTS bug22580_tmp;
CREATE TEMPORARY TABLE bug22580_tmp (a INT);
DROP TABLE bug22580_tmp;
END||
CREATE PROCEDURE bug22580_proc_1()
BEGIN
CALL bug22580_proc_2();
END||
CREATE TRIGGER t1bu BEFORE UPDATE ON bug22580_t1
FOR EACH ROW
BEGIN
CALL bug22580_proc_1();
END||
INSERT INTO bug22580_t1 VALUES (1,1);
DROP TABLE bug22580_t1;
DROP PROCEDURE bug22580_proc_1;
DROP PROCEDURE bug22580_proc_2;
DROP TRIGGER IF EXISTS trg27006_a_update;
DROP TRIGGER IF EXISTS trg27006_a_insert;
CREATE TABLE t1 (
`id` int(10) unsigned NOT NULL auto_increment,
`val` varchar(10) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE t2 like t1;
CREATE TRIGGER trg27006_a_insert AFTER INSERT ON t1 FOR EACH ROW
BEGIN
insert into t2 values (NULL,new.val);
END |
CREATE TRIGGER trg27006_a_update AFTER UPDATE ON t1 FOR EACH ROW
BEGIN
insert into t2 values (NULL,new.val);
END |
INSERT INTO t1(val) VALUES ('test1'),('test2');
SELECT * FROM t1;
id val
1 test1
2 test2
SELECT * FROM t2;
id val
1 test1
2 test2
INSERT INTO t1 VALUES (2,'test2') ON DUPLICATE KEY UPDATE val=VALUES(val);
INSERT INTO t1 VALUES (2,'test3') ON DUPLICATE KEY UPDATE val=VALUES(val);
INSERT INTO t1 VALUES (3,'test4') ON DUPLICATE KEY UPDATE val=VALUES(val);
SELECT * FROM t1;
id val
1 test1
2 test3
3 test4
SELECT * FROM t2;
id val
1 test1
2 test2
3 test3
4 test4
DROP TRIGGER trg27006_a_insert;
DROP TRIGGER trg27006_a_update;
drop table t1,t2;
Fix for: Bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables" Bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" Bug #24738 "CREATE TABLE ... SELECT is not isolated properly" Bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" Deadlock occured when one tried to execute CREATE TABLE IF NOT EXISTS ... SELECT statement under LOCK TABLES which held read lock on target table. Attempt to execute the same statement for already existing target table with triggers caused server crashes. Also concurrent execution of CREATE TABLE ... SELECT statement and other statements involving target table suffered from various races (some of which might've led to deadlocks). Finally, attempt to execute CREATE TABLE ... SELECT in case when a temporary table with same name was already present led to the insertion of data into this temporary table and creation of empty non-temporary table. All above problems stemmed from the old implementation of CREATE TABLE ... SELECT in which we created, opened and locked target table without any special protection in a separate step and not with the rest of tables used by this statement. This underminded deadlock-avoidance approach used in server and created window for races. It also excluded target table from prelocking causing problems with trigger execution. The patch solves these problems by implementing new approach to handling of CREATE TABLE ... SELECT for base tables. We try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. We still use old approach for creation of temporary tables. Note that we have separate fix for 5.0 since there we use slightly different less intrusive approach. mysql-test/r/create.result: Extended test coverage for CREATE TABLE ... SELECT. In particular added tests for bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" and bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables". mysql-test/r/trigger.result: Added test case for bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" mysql-test/t/create.test: Extended test coverage for CREATE TABLE ... SELECT. In particular added tests for bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" and bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables". mysql-test/t/trigger.test: Added test case for bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" sql/lock.cc: Now for creation of name-lock placeholder lock_table_name() uses auxiliary function table_cache_insert_placeholder(). sql/mysql_priv.h: Removed declaration of non-existing build_table_path() routine. The former mysql_create_table_internal() was renamed to mysql_create_table_no_lock() and now exposed to other modules to give them opportunity of creation of tables in cases when name-lock is already obtained. reopen_name_locked_table() now has 3rd argument which controls linking in of table being opened into THD::open_tables (this is useful in cases when placeholder used for name-locking is already linked into this list). Added declaration of auxiliary function table_cache_insert_placeholder() which is used for creation of table placeholders for name-locking. Added declaration of lock_table_name_if_not_cached() which can be used to take an exclusive name-lock on table if there are no records for it in table cache. Changed signature of unlink_open_table() function to simplify its use and make it useful for table placeholders and tables that are only open. Added auxiliary drop_open_table() routine. Moved declaration of refresh_version to table.h header to make it accessible from inline methods of TABLE class. MYSQL_OPEN_IGNORE_LOCKED_TABLES flag is no longer used. Instead MYSQL_OPEN_TEMPORARY_ONLY option was added. sql/sql_base.cc: Added support for the new approach to the handling of CREATE TABLE ... SELECT for base tables. Now we try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. Note significant distinctions of this placeholder from the placeholder used for normal name-lock: 1) It is treated like open table by other name-locks so it does not allow name-lock taking operations like DROP TABLE or RENAME TABLE to proceed. 2) it is linked into THD::open_tables list and automatically removed during close_thread_tables() call open_tables(): Implemented logic described above. To do this added auxiliary check_if_table_exists() function. Removed support for MYSQL_OPEN_IGNORE_LOCKED_TABLES option which is no longer used. Added MYSQL_OPEN_TEMPORARY_ONLY which is used to restrict search for temporary tables only. close_cached_tables()/close_thread_table()/reopen_tables()/ close_old_data_files()/table_is_used()/remove_table_from_cache(): Added support for open placeholders (note that we also use them when we need to re-open tables during flush). unlink_open_table(): Changed function signature to simplify its use and to make useful for open placeholders and tables which are only open and not locked. Added auxiliary drop_open_table() routine. reopen_name_locked_table(): Now has 3rd argument which controls linking in of table being opened into THD::open_tables (this is useful in cases when placeholder used for name-locking is already linked into this list). Added auxiliary table_cache_insert_placeholder() routine which simplifies creation of placeholders used for name-locking. Added lock_table_name_if_not_cached() which can be used to take an exclusive name-lock on table if there are no records for it in table cache. sql/sql_handler.cc: Adjusted mysql_ha_mark_tables_for_reopen() routine to properly handle placeholders which now can be linked into open tables list. sql/sql_insert.cc: Introduced new approach to handling of base tables in CREATE TABLE ... SELECT statement. Now we try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. By doing this we avoid races which existed with previous approach in which we created, opened and locked target in separate step without any special protection. This also allows properly calculate prelocking set in cases when target table already exists and has some on insert triggers. Note that we don't employ the same approach for temporary tables (this is okay as such tables are unaffected by other threads). Changed create_table_from_items() and methods of select_create class to implement this approach. sql/sql_parse.cc: The new approach to handling of CREATE TABLE ... SELECT for base tables assumes that all tables (including table to be created) are opened and (or) locked at the same time. So in cases when we create base table we have to pass to open_and_lock_tables() table list which includes target table. sql/sql_prepare.cc: The new approach to handling of CREATE TABLE ... SELECT for base tables assumes that all tables (including table to be created) are opened and (or) locked at the same time. So in cases when we create base table we have to pass to open_and_lock_tables() table list which includes target table. sql/sql_table.cc: Changed mysql_create_table(), mysql_create_like_table() and mysql_alter_table() (in rename case) to obtain exclusive name-lock on the non-temporary table which is going to be created (to which we going to rename). This ensures that not only destination table doesn't exist on disk but also that there are no placeholder in table cache for it (i.e. there is no CREATE TABLE ... SELECT operation in progress for it). Note that to avoid deadlocks while taking these name-locks this code assumes that existence of any record for table in table cache (even name-lock) means that table exists. Altough such check can lead to false positives these should occur only in case of highly concurrent DDL operations on the table and should not break binary logging. Renamed mysql_create_table_internal() to mysql_create_table_no_lock() and made it accessible from other files to give them ability to create table in situation when name-lock is already obtained or not relevant. Adjusted calls to reopen_name_locked_table(), which now takes extra argument, which controls linking of open table into THD::open_tables list. Removed redundant setting of table's 'version' field before calls to close_cached_table(). This function will set it to 0 itself anyway. sql/sql_trigger.cc: reopen_name_locked_tables() now has one more argument which controls linking of opened table into the THD::open_tables list. sql/sql_yacc.yy: The new approach to handling of CREATE TABLE ... SELECT statement for base tables assumes that all tables including table to be created are open and (or) locked at the same time. Therefore we need to set correct lock for target table. sql/table.h: Moved declaration of refresh_version variable from mysql_priv.h to make it accessible from inline methods of TABLE class. Renamed TABLE::locked_by_flush member to open_placeholder since now it is also used for taking exclusive name-lock and not only by flush. Introduced TABLE::is_name_opened() helper method which can be used to distinguish TABLE instances corresponding to open tables or placeholders for them from closed instances (e.g. due to their old version). Also introduced TABLE::needs_reopen_or_name_lock() helper which allows to check if TABLE instance corresponds to outdated version of table or to name-lock placeholder. Introduced TABLE_LIST::create member which marks elements of table list corresponds to the table to be created. Adjusted TABLE_LIST::placeholder() method to take into account name-lock placeholders for tables to be created (this, for example, allows to properly handle such placeholders in lock_tables()). Finally, moved currently unused TABLE::open_next/open_prev members under ifdef NOT_YET. mysql-test/r/create_select-big.result: New BitKeeper file ``mysql-test/r/create_select-big.result'' mysql-test/t/create_select-big.test: New BitKeeper file ``mysql-test/t/create_select-big.test''
2007-05-11 19:51:03 +02:00
drop table if exists t1, t2, t3;
create table t1 (i int);
create trigger t1_bi before insert on t1 for each row set new.i = 7;
create trigger t1_ai after insert on t1 for each row set @a := 7;
create table t2 (j int);
insert into t2 values (1), (2);
set @a:="";
insert into t1 select * from t2;
Fix for: Bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables" Bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" Bug #24738 "CREATE TABLE ... SELECT is not isolated properly" Bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" Deadlock occured when one tried to execute CREATE TABLE IF NOT EXISTS ... SELECT statement under LOCK TABLES which held read lock on target table. Attempt to execute the same statement for already existing target table with triggers caused server crashes. Also concurrent execution of CREATE TABLE ... SELECT statement and other statements involving target table suffered from various races (some of which might've led to deadlocks). Finally, attempt to execute CREATE TABLE ... SELECT in case when a temporary table with same name was already present led to the insertion of data into this temporary table and creation of empty non-temporary table. All above problems stemmed from the old implementation of CREATE TABLE ... SELECT in which we created, opened and locked target table without any special protection in a separate step and not with the rest of tables used by this statement. This underminded deadlock-avoidance approach used in server and created window for races. It also excluded target table from prelocking causing problems with trigger execution. The patch solves these problems by implementing new approach to handling of CREATE TABLE ... SELECT for base tables. We try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. We still use old approach for creation of temporary tables. Note that we have separate fix for 5.0 since there we use slightly different less intrusive approach. mysql-test/r/create.result: Extended test coverage for CREATE TABLE ... SELECT. In particular added tests for bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" and bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables". mysql-test/r/trigger.result: Added test case for bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" mysql-test/t/create.test: Extended test coverage for CREATE TABLE ... SELECT. In particular added tests for bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" and bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables". mysql-test/t/trigger.test: Added test case for bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" sql/lock.cc: Now for creation of name-lock placeholder lock_table_name() uses auxiliary function table_cache_insert_placeholder(). sql/mysql_priv.h: Removed declaration of non-existing build_table_path() routine. The former mysql_create_table_internal() was renamed to mysql_create_table_no_lock() and now exposed to other modules to give them opportunity of creation of tables in cases when name-lock is already obtained. reopen_name_locked_table() now has 3rd argument which controls linking in of table being opened into THD::open_tables (this is useful in cases when placeholder used for name-locking is already linked into this list). Added declaration of auxiliary function table_cache_insert_placeholder() which is used for creation of table placeholders for name-locking. Added declaration of lock_table_name_if_not_cached() which can be used to take an exclusive name-lock on table if there are no records for it in table cache. Changed signature of unlink_open_table() function to simplify its use and make it useful for table placeholders and tables that are only open. Added auxiliary drop_open_table() routine. Moved declaration of refresh_version to table.h header to make it accessible from inline methods of TABLE class. MYSQL_OPEN_IGNORE_LOCKED_TABLES flag is no longer used. Instead MYSQL_OPEN_TEMPORARY_ONLY option was added. sql/sql_base.cc: Added support for the new approach to the handling of CREATE TABLE ... SELECT for base tables. Now we try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. Note significant distinctions of this placeholder from the placeholder used for normal name-lock: 1) It is treated like open table by other name-locks so it does not allow name-lock taking operations like DROP TABLE or RENAME TABLE to proceed. 2) it is linked into THD::open_tables list and automatically removed during close_thread_tables() call open_tables(): Implemented logic described above. To do this added auxiliary check_if_table_exists() function. Removed support for MYSQL_OPEN_IGNORE_LOCKED_TABLES option which is no longer used. Added MYSQL_OPEN_TEMPORARY_ONLY which is used to restrict search for temporary tables only. close_cached_tables()/close_thread_table()/reopen_tables()/ close_old_data_files()/table_is_used()/remove_table_from_cache(): Added support for open placeholders (note that we also use them when we need to re-open tables during flush). unlink_open_table(): Changed function signature to simplify its use and to make useful for open placeholders and tables which are only open and not locked. Added auxiliary drop_open_table() routine. reopen_name_locked_table(): Now has 3rd argument which controls linking in of table being opened into THD::open_tables (this is useful in cases when placeholder used for name-locking is already linked into this list). Added auxiliary table_cache_insert_placeholder() routine which simplifies creation of placeholders used for name-locking. Added lock_table_name_if_not_cached() which can be used to take an exclusive name-lock on table if there are no records for it in table cache. sql/sql_handler.cc: Adjusted mysql_ha_mark_tables_for_reopen() routine to properly handle placeholders which now can be linked into open tables list. sql/sql_insert.cc: Introduced new approach to handling of base tables in CREATE TABLE ... SELECT statement. Now we try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. By doing this we avoid races which existed with previous approach in which we created, opened and locked target in separate step without any special protection. This also allows properly calculate prelocking set in cases when target table already exists and has some on insert triggers. Note that we don't employ the same approach for temporary tables (this is okay as such tables are unaffected by other threads). Changed create_table_from_items() and methods of select_create class to implement this approach. sql/sql_parse.cc: The new approach to handling of CREATE TABLE ... SELECT for base tables assumes that all tables (including table to be created) are opened and (or) locked at the same time. So in cases when we create base table we have to pass to open_and_lock_tables() table list which includes target table. sql/sql_prepare.cc: The new approach to handling of CREATE TABLE ... SELECT for base tables assumes that all tables (including table to be created) are opened and (or) locked at the same time. So in cases when we create base table we have to pass to open_and_lock_tables() table list which includes target table. sql/sql_table.cc: Changed mysql_create_table(), mysql_create_like_table() and mysql_alter_table() (in rename case) to obtain exclusive name-lock on the non-temporary table which is going to be created (to which we going to rename). This ensures that not only destination table doesn't exist on disk but also that there are no placeholder in table cache for it (i.e. there is no CREATE TABLE ... SELECT operation in progress for it). Note that to avoid deadlocks while taking these name-locks this code assumes that existence of any record for table in table cache (even name-lock) means that table exists. Altough such check can lead to false positives these should occur only in case of highly concurrent DDL operations on the table and should not break binary logging. Renamed mysql_create_table_internal() to mysql_create_table_no_lock() and made it accessible from other files to give them ability to create table in situation when name-lock is already obtained or not relevant. Adjusted calls to reopen_name_locked_table(), which now takes extra argument, which controls linking of open table into THD::open_tables list. Removed redundant setting of table's 'version' field before calls to close_cached_table(). This function will set it to 0 itself anyway. sql/sql_trigger.cc: reopen_name_locked_tables() now has one more argument which controls linking of opened table into the THD::open_tables list. sql/sql_yacc.yy: The new approach to handling of CREATE TABLE ... SELECT statement for base tables assumes that all tables including table to be created are open and (or) locked at the same time. Therefore we need to set correct lock for target table. sql/table.h: Moved declaration of refresh_version variable from mysql_priv.h to make it accessible from inline methods of TABLE class. Renamed TABLE::locked_by_flush member to open_placeholder since now it is also used for taking exclusive name-lock and not only by flush. Introduced TABLE::is_name_opened() helper method which can be used to distinguish TABLE instances corresponding to open tables or placeholders for them from closed instances (e.g. due to their old version). Also introduced TABLE::needs_reopen_or_name_lock() helper which allows to check if TABLE instance corresponds to outdated version of table or to name-lock placeholder. Introduced TABLE_LIST::create member which marks elements of table list corresponds to the table to be created. Adjusted TABLE_LIST::placeholder() method to take into account name-lock placeholders for tables to be created (this, for example, allows to properly handle such placeholders in lock_tables()). Finally, moved currently unused TABLE::open_next/open_prev members under ifdef NOT_YET. mysql-test/r/create_select-big.result: New BitKeeper file ``mysql-test/r/create_select-big.result'' mysql-test/t/create_select-big.test: New BitKeeper file ``mysql-test/t/create_select-big.test''
2007-05-11 19:51:03 +02:00
select * from t1;
i
7
7
select @a;
@a
7
drop trigger t1_bi;
drop trigger t1_ai;
create table t3 (isave int);
create trigger t1_bi before insert on t1 for each row insert into t3 values (new.i);
insert into t1 select * from t2;
Fix for: Bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables" Bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" Bug #24738 "CREATE TABLE ... SELECT is not isolated properly" Bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" Deadlock occured when one tried to execute CREATE TABLE IF NOT EXISTS ... SELECT statement under LOCK TABLES which held read lock on target table. Attempt to execute the same statement for already existing target table with triggers caused server crashes. Also concurrent execution of CREATE TABLE ... SELECT statement and other statements involving target table suffered from various races (some of which might've led to deadlocks). Finally, attempt to execute CREATE TABLE ... SELECT in case when a temporary table with same name was already present led to the insertion of data into this temporary table and creation of empty non-temporary table. All above problems stemmed from the old implementation of CREATE TABLE ... SELECT in which we created, opened and locked target table without any special protection in a separate step and not with the rest of tables used by this statement. This underminded deadlock-avoidance approach used in server and created window for races. It also excluded target table from prelocking causing problems with trigger execution. The patch solves these problems by implementing new approach to handling of CREATE TABLE ... SELECT for base tables. We try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. We still use old approach for creation of temporary tables. Note that we have separate fix for 5.0 since there we use slightly different less intrusive approach. mysql-test/r/create.result: Extended test coverage for CREATE TABLE ... SELECT. In particular added tests for bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" and bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables". mysql-test/r/trigger.result: Added test case for bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" mysql-test/t/create.test: Extended test coverage for CREATE TABLE ... SELECT. In particular added tests for bug #24508 "Inconsistent results of CREATE TABLE ... SELECT when temporary table exists" and bug #20662 "Infinite loop in CREATE TABLE IF NOT EXISTS ... SELECT with locked tables". mysql-test/t/trigger.test: Added test case for bug #20903 "Crash when using CREATE TABLE .. SELECT and triggers" sql/lock.cc: Now for creation of name-lock placeholder lock_table_name() uses auxiliary function table_cache_insert_placeholder(). sql/mysql_priv.h: Removed declaration of non-existing build_table_path() routine. The former mysql_create_table_internal() was renamed to mysql_create_table_no_lock() and now exposed to other modules to give them opportunity of creation of tables in cases when name-lock is already obtained. reopen_name_locked_table() now has 3rd argument which controls linking in of table being opened into THD::open_tables (this is useful in cases when placeholder used for name-locking is already linked into this list). Added declaration of auxiliary function table_cache_insert_placeholder() which is used for creation of table placeholders for name-locking. Added declaration of lock_table_name_if_not_cached() which can be used to take an exclusive name-lock on table if there are no records for it in table cache. Changed signature of unlink_open_table() function to simplify its use and make it useful for table placeholders and tables that are only open. Added auxiliary drop_open_table() routine. Moved declaration of refresh_version to table.h header to make it accessible from inline methods of TABLE class. MYSQL_OPEN_IGNORE_LOCKED_TABLES flag is no longer used. Instead MYSQL_OPEN_TEMPORARY_ONLY option was added. sql/sql_base.cc: Added support for the new approach to the handling of CREATE TABLE ... SELECT for base tables. Now we try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. Note significant distinctions of this placeholder from the placeholder used for normal name-lock: 1) It is treated like open table by other name-locks so it does not allow name-lock taking operations like DROP TABLE or RENAME TABLE to proceed. 2) it is linked into THD::open_tables list and automatically removed during close_thread_tables() call open_tables(): Implemented logic described above. To do this added auxiliary check_if_table_exists() function. Removed support for MYSQL_OPEN_IGNORE_LOCKED_TABLES option which is no longer used. Added MYSQL_OPEN_TEMPORARY_ONLY which is used to restrict search for temporary tables only. close_cached_tables()/close_thread_table()/reopen_tables()/ close_old_data_files()/table_is_used()/remove_table_from_cache(): Added support for open placeholders (note that we also use them when we need to re-open tables during flush). unlink_open_table(): Changed function signature to simplify its use and to make useful for open placeholders and tables which are only open and not locked. Added auxiliary drop_open_table() routine. reopen_name_locked_table(): Now has 3rd argument which controls linking in of table being opened into THD::open_tables (this is useful in cases when placeholder used for name-locking is already linked into this list). Added auxiliary table_cache_insert_placeholder() routine which simplifies creation of placeholders used for name-locking. Added lock_table_name_if_not_cached() which can be used to take an exclusive name-lock on table if there are no records for it in table cache. sql/sql_handler.cc: Adjusted mysql_ha_mark_tables_for_reopen() routine to properly handle placeholders which now can be linked into open tables list. sql/sql_insert.cc: Introduced new approach to handling of base tables in CREATE TABLE ... SELECT statement. Now we try to open and lock table to be created at the same time as the rest of tables used by this statement. If such table does not exist at this moment we create and place in the table cache special placeholder for it which prevents its creation or any other usage by other threads. By doing this we avoid races which existed with previous approach in which we created, opened and locked target in separate step without any special protection. This also allows properly calculate prelocking set in cases when target table already exists and has some on insert triggers. Note that we don't employ the same approach for temporary tables (this is okay as such tables are unaffected by other threads). Changed create_table_from_items() and methods of select_create class to implement this approach. sql/sql_parse.cc: The new approach to handling of CREATE TABLE ... SELECT for base tables assumes that all tables (including table to be created) are opened and (or) locked at the same time. So in cases when we create base table we have to pass to open_and_lock_tables() table list which includes target table. sql/sql_prepare.cc: The new approach to handling of CREATE TABLE ... SELECT for base tables assumes that all tables (including table to be created) are opened and (or) locked at the same time. So in cases when we create base table we have to pass to open_and_lock_tables() table list which includes target table. sql/sql_table.cc: Changed mysql_create_table(), mysql_create_like_table() and mysql_alter_table() (in rename case) to obtain exclusive name-lock on the non-temporary table which is going to be created (to which we going to rename). This ensures that not only destination table doesn't exist on disk but also that there are no placeholder in table cache for it (i.e. there is no CREATE TABLE ... SELECT operation in progress for it). Note that to avoid deadlocks while taking these name-locks this code assumes that existence of any record for table in table cache (even name-lock) means that table exists. Altough such check can lead to false positives these should occur only in case of highly concurrent DDL operations on the table and should not break binary logging. Renamed mysql_create_table_internal() to mysql_create_table_no_lock() and made it accessible from other files to give them ability to create table in situation when name-lock is already obtained or not relevant. Adjusted calls to reopen_name_locked_table(), which now takes extra argument, which controls linking of open table into THD::open_tables list. Removed redundant setting of table's 'version' field before calls to close_cached_table(). This function will set it to 0 itself anyway. sql/sql_trigger.cc: reopen_name_locked_tables() now has one more argument which controls linking of opened table into the THD::open_tables list. sql/sql_yacc.yy: The new approach to handling of CREATE TABLE ... SELECT statement for base tables assumes that all tables including table to be created are open and (or) locked at the same time. Therefore we need to set correct lock for target table. sql/table.h: Moved declaration of refresh_version variable from mysql_priv.h to make it accessible from inline methods of TABLE class. Renamed TABLE::locked_by_flush member to open_placeholder since now it is also used for taking exclusive name-lock and not only by flush. Introduced TABLE::is_name_opened() helper method which can be used to distinguish TABLE instances corresponding to open tables or placeholders for them from closed instances (e.g. due to their old version). Also introduced TABLE::needs_reopen_or_name_lock() helper which allows to check if TABLE instance corresponds to outdated version of table or to name-lock placeholder. Introduced TABLE_LIST::create member which marks elements of table list corresponds to the table to be created. Adjusted TABLE_LIST::placeholder() method to take into account name-lock placeholders for tables to be created (this, for example, allows to properly handle such placeholders in lock_tables()). Finally, moved currently unused TABLE::open_next/open_prev members under ifdef NOT_YET. mysql-test/r/create_select-big.result: New BitKeeper file ``mysql-test/r/create_select-big.result'' mysql-test/t/create_select-big.test: New BitKeeper file ``mysql-test/t/create_select-big.test''
2007-05-11 19:51:03 +02:00
select * from t1;
i
7
7
1
2
select * from t3;
isave
1
2
drop table t1, t2, t3;
A fix and a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. Also fixes Bug#28502 Triggers that update another innodb table will block on X lock unnecessarily (duplciate). Code review fixes. Both bugs' synopses are misleading: InnoDB table is not X locked. The statements, however, cannot proceed concurrently, but this happens due to lock conflicts for tables used in triggers, not for the InnoDB table. If a user had an InnoDB table, and two triggers, AFTER UPDATE and AFTER INSERT, competing for different resources (e.g. two distinct MyISAM tables), then these two triggers would not be able to execute concurrently. Moreover, INSERTS/UPDATES of the InnoDB table would not be able to run concurrently. The problem had other side-effects (see respective bug reports). This behavior was a consequence of a shortcoming of the pre-locking algorithm, which would not distinguish between different DML operations (e.g. INSERT and DELETE) and pre-lock all the tables that are used by any trigger defined on the subject table. The idea of the fix is to extend the pre-locking algorithm to keep track, for each table, what DML operation it is used for and not load triggers that are known to never be fired. mysql-test/r/trigger-trans.result: Update results (Bug#26141) mysql-test/r/trigger.result: Update results (Bug#28502) mysql-test/t/trigger-trans.test: Add a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. mysql-test/t/trigger.test: Add a test case for Bug#28502 Triggers that update another innodb table will block echo on X lock unnecessarily. Add more test coverage for triggers. sql/item.h: enum trg_event_type is needed in table.h sql/sp.cc: Take into account table_list->trg_event_map when determining what tables to pre-lock. After this change, if we attempt to fire a trigger for which we had not pre-locked any tables, error 'Table was not locked with LOCK TABLES' will be printed. This, however, should never happen, provided the pre-locking algorithm has no programming bugs. Previously a trigger key in the sroutines hash was based on the name of the table the trigger belongs to. This was possible because we would always add to the pre-locking list all the triggers defined for a table when handling this table. Now the key is based on the name of the trigger, owing to the fact that a trigger name must be unique in the database it belongs to. sql/sp_head.cc: Generate sroutines hash key in init_spname(). This is a convenient place since there we have all the necessary information and can avoid an extra alloc. Maintain and merge trg_event_map when adding and merging elements of the pre-locking list. sql/sp_head.h: Add ,m_sroutines_key member, used when inserting the sphead for a trigger into the cache of routines used by a statement. Previously the key was based on the table name the trigger belonged to, since for a given table we would add to the sroutines list all the triggers defined on it. sql/sql_lex.cc: Introduce a new lex step: set_trg_event_type_for_tables(). It is called when we have finished parsing but before opening and locking tables. Now this step is used to evaluate for each TABLE_LIST instance which INSERT/UPDATE/DELETE operation, if any, it is used in. In future this method could be extended to aggregate other information that is hard to aggregate during parsing. sql/sql_lex.h: Add declaration for set_trg_event_type_for_tables(). sql/sql_parse.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). Remove tabs. sql/sql_prepare.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.h: Remove an obsolete member. sql/sql_view.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_yacc.yy: Move assignment of sp_head::m_type before calling sp_head::init_spname(), one is now used inside another. sql/table.cc: Implement TABLE_LIST::set_trg_event_map() - a method that calculates wh triggers may be fired on this table when executing a statement. sql/table.h: Add missing declarations. Move declaration of trg_event_type from item.h (it will be needed for trg_event_map bitmap when we start using Bitmap template instead of uint8).
2007-07-12 20:26:41 +02:00
Bug#28502 Triggers that update another innodb table will block
on X lock unnecessarily
Ensure we do not open and lock tables for triggers we do not fire.
drop table if exists t1, t2;
drop trigger if exists trg_bug28502_au;
create table t1 (id int, count int);
create table t2 (id int);
create trigger trg_bug28502_au before update on t2
for each row
begin
if (new.id is not null) then
update t1 set count= count + 1 where id = old.id;
end if;
end|
insert into t1 (id, count) values (1, 0);
lock table t1 write;
insert into t2 set id=1;
unlock tables;
update t2 set id=1 where id=1;
select * from t1;
id count
1 1
select * from t2;
id
1
drop table t1, t2;
Additionally, provide test coverage for triggers and
all MySQL data changing commands.
drop table if exists t1, t2, t1_op_log;
drop view if exists v1;
drop trigger if exists trg_bug28502_bi;
drop trigger if exists trg_bug28502_ai;
drop trigger if exists trg_bug28502_bu;
drop trigger if exists trg_bug28502_au;
drop trigger if exists trg_bug28502_bd;
drop trigger if exists trg_bug28502_ad;
create table t1 (id int primary key auto_increment, operation varchar(255));
create table t2 (id int primary key);
create table t1_op_log(operation varchar(255));
create view v1 as select * from t1;
create trigger trg_bug28502_bi before insert on t1
for each row
insert into t1_op_log (operation)
values (concat("Before INSERT, new=", new.operation));
create trigger trg_bug28502_ai after insert on t1
for each row
insert into t1_op_log (operation)
values (concat("After INSERT, new=", new.operation));
create trigger trg_bug28502_bu before update on t1
for each row
insert into t1_op_log (operation)
values (concat("Before UPDATE, new=", new.operation,
", old=", old.operation));
create trigger trg_bug28502_au after update on t1
for each row
insert into t1_op_log (operation)
values (concat("After UPDATE, new=", new.operation,
", old=", old.operation));
create trigger trg_bug28502_bd before delete on t1
for each row
insert into t1_op_log (operation)
values (concat("Before DELETE, old=", old.operation));
create trigger trg_bug28502_ad after delete on t1
for each row
insert into t1_op_log (operation)
values (concat("After DELETE, old=", old.operation));
insert into t1 (operation) values ("INSERT");
set @id=last_insert_id();
select * from t1;
id operation
1 INSERT
select * from t1_op_log;
operation
Before INSERT, new=INSERT
After INSERT, new=INSERT
truncate t1_op_log;
update t1 set operation="UPDATE" where id=@id;
select * from t1;
id operation
1 UPDATE
select * from t1_op_log;
operation
Before UPDATE, new=UPDATE, old=INSERT
After UPDATE, new=UPDATE, old=INSERT
truncate t1_op_log;
delete from t1 where id=@id;
select * from t1;
id operation
select * from t1_op_log;
operation
Before DELETE, old=UPDATE
After DELETE, old=UPDATE
truncate t1;
truncate t1_op_log;
insert into t1 (id, operation) values
(NULL, "INSERT ON DUPLICATE KEY UPDATE, inserting a new key")
on duplicate key update id=NULL, operation="Should never happen";
set @id=last_insert_id();
select * from t1;
id operation
1 INSERT ON DUPLICATE KEY UPDATE, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
After INSERT, new=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
truncate t1_op_log;
insert into t1 (id, operation) values
(@id, "INSERT ON DUPLICATE KEY UPDATE, the key value is the same")
on duplicate key update id=NULL,
operation="INSERT ON DUPLICATE KEY UPDATE, updating the duplicate";
select * from t1;
id operation
0 INSERT ON DUPLICATE KEY UPDATE, updating the duplicate
select * from t1_op_log;
operation
Before INSERT, new=INSERT ON DUPLICATE KEY UPDATE, the key value is the same
Before UPDATE, new=INSERT ON DUPLICATE KEY UPDATE, updating the duplicate, old=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
After UPDATE, new=INSERT ON DUPLICATE KEY UPDATE, updating the duplicate, old=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
truncate t1;
truncate t1_op_log;
replace into t1 values (NULL, "REPLACE, inserting a new key");
set @id=last_insert_id();
select * from t1;
id operation
1 REPLACE, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=REPLACE, inserting a new key
After INSERT, new=REPLACE, inserting a new key
truncate t1_op_log;
replace into t1 values (@id, "REPLACE, deleting the duplicate");
select * from t1;
id operation
1 REPLACE, deleting the duplicate
select * from t1_op_log;
operation
Before INSERT, new=REPLACE, deleting the duplicate
Before DELETE, old=REPLACE, inserting a new key
After DELETE, old=REPLACE, inserting a new key
After INSERT, new=REPLACE, deleting the duplicate
truncate t1;
truncate t1_op_log;
insert into t1
A fix and a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. Also fixes Bug#28502 Triggers that update another innodb table will block on X lock unnecessarily (duplciate). Code review fixes. Both bugs' synopses are misleading: InnoDB table is not X locked. The statements, however, cannot proceed concurrently, but this happens due to lock conflicts for tables used in triggers, not for the InnoDB table. If a user had an InnoDB table, and two triggers, AFTER UPDATE and AFTER INSERT, competing for different resources (e.g. two distinct MyISAM tables), then these two triggers would not be able to execute concurrently. Moreover, INSERTS/UPDATES of the InnoDB table would not be able to run concurrently. The problem had other side-effects (see respective bug reports). This behavior was a consequence of a shortcoming of the pre-locking algorithm, which would not distinguish between different DML operations (e.g. INSERT and DELETE) and pre-lock all the tables that are used by any trigger defined on the subject table. The idea of the fix is to extend the pre-locking algorithm to keep track, for each table, what DML operation it is used for and not load triggers that are known to never be fired. mysql-test/r/trigger-trans.result: Update results (Bug#26141) mysql-test/r/trigger.result: Update results (Bug#28502) mysql-test/t/trigger-trans.test: Add a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. mysql-test/t/trigger.test: Add a test case for Bug#28502 Triggers that update another innodb table will block echo on X lock unnecessarily. Add more test coverage for triggers. sql/item.h: enum trg_event_type is needed in table.h sql/sp.cc: Take into account table_list->trg_event_map when determining what tables to pre-lock. After this change, if we attempt to fire a trigger for which we had not pre-locked any tables, error 'Table was not locked with LOCK TABLES' will be printed. This, however, should never happen, provided the pre-locking algorithm has no programming bugs. Previously a trigger key in the sroutines hash was based on the name of the table the trigger belongs to. This was possible because we would always add to the pre-locking list all the triggers defined for a table when handling this table. Now the key is based on the name of the trigger, owing to the fact that a trigger name must be unique in the database it belongs to. sql/sp_head.cc: Generate sroutines hash key in init_spname(). This is a convenient place since there we have all the necessary information and can avoid an extra alloc. Maintain and merge trg_event_map when adding and merging elements of the pre-locking list. sql/sp_head.h: Add ,m_sroutines_key member, used when inserting the sphead for a trigger into the cache of routines used by a statement. Previously the key was based on the table name the trigger belonged to, since for a given table we would add to the sroutines list all the triggers defined on it. sql/sql_lex.cc: Introduce a new lex step: set_trg_event_type_for_tables(). It is called when we have finished parsing but before opening and locking tables. Now this step is used to evaluate for each TABLE_LIST instance which INSERT/UPDATE/DELETE operation, if any, it is used in. In future this method could be extended to aggregate other information that is hard to aggregate during parsing. sql/sql_lex.h: Add declaration for set_trg_event_type_for_tables(). sql/sql_parse.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). Remove tabs. sql/sql_prepare.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.h: Remove an obsolete member. sql/sql_view.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_yacc.yy: Move assignment of sp_head::m_type before calling sp_head::init_spname(), one is now used inside another. sql/table.cc: Implement TABLE_LIST::set_trg_event_map() - a method that calculates wh triggers may be fired on this table when executing a statement. sql/table.h: Add missing declarations. Move declaration of trg_event_type from item.h (it will be needed for trg_event_map bitmap when we start using Bitmap template instead of uint8).
2007-07-12 20:26:41 +02:00
select NULL, "CREATE TABLE ... SELECT, inserting a new key";
set @id=last_insert_id();
select * from t1;
id operation
1 CREATE TABLE ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=CREATE TABLE ... SELECT, inserting a new key
After INSERT, new=CREATE TABLE ... SELECT, inserting a new key
truncate t1_op_log;
replace into t1
A fix and a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. Also fixes Bug#28502 Triggers that update another innodb table will block on X lock unnecessarily (duplciate). Code review fixes. Both bugs' synopses are misleading: InnoDB table is not X locked. The statements, however, cannot proceed concurrently, but this happens due to lock conflicts for tables used in triggers, not for the InnoDB table. If a user had an InnoDB table, and two triggers, AFTER UPDATE and AFTER INSERT, competing for different resources (e.g. two distinct MyISAM tables), then these two triggers would not be able to execute concurrently. Moreover, INSERTS/UPDATES of the InnoDB table would not be able to run concurrently. The problem had other side-effects (see respective bug reports). This behavior was a consequence of a shortcoming of the pre-locking algorithm, which would not distinguish between different DML operations (e.g. INSERT and DELETE) and pre-lock all the tables that are used by any trigger defined on the subject table. The idea of the fix is to extend the pre-locking algorithm to keep track, for each table, what DML operation it is used for and not load triggers that are known to never be fired. mysql-test/r/trigger-trans.result: Update results (Bug#26141) mysql-test/r/trigger.result: Update results (Bug#28502) mysql-test/t/trigger-trans.test: Add a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. mysql-test/t/trigger.test: Add a test case for Bug#28502 Triggers that update another innodb table will block echo on X lock unnecessarily. Add more test coverage for triggers. sql/item.h: enum trg_event_type is needed in table.h sql/sp.cc: Take into account table_list->trg_event_map when determining what tables to pre-lock. After this change, if we attempt to fire a trigger for which we had not pre-locked any tables, error 'Table was not locked with LOCK TABLES' will be printed. This, however, should never happen, provided the pre-locking algorithm has no programming bugs. Previously a trigger key in the sroutines hash was based on the name of the table the trigger belongs to. This was possible because we would always add to the pre-locking list all the triggers defined for a table when handling this table. Now the key is based on the name of the trigger, owing to the fact that a trigger name must be unique in the database it belongs to. sql/sp_head.cc: Generate sroutines hash key in init_spname(). This is a convenient place since there we have all the necessary information and can avoid an extra alloc. Maintain and merge trg_event_map when adding and merging elements of the pre-locking list. sql/sp_head.h: Add ,m_sroutines_key member, used when inserting the sphead for a trigger into the cache of routines used by a statement. Previously the key was based on the table name the trigger belonged to, since for a given table we would add to the sroutines list all the triggers defined on it. sql/sql_lex.cc: Introduce a new lex step: set_trg_event_type_for_tables(). It is called when we have finished parsing but before opening and locking tables. Now this step is used to evaluate for each TABLE_LIST instance which INSERT/UPDATE/DELETE operation, if any, it is used in. In future this method could be extended to aggregate other information that is hard to aggregate during parsing. sql/sql_lex.h: Add declaration for set_trg_event_type_for_tables(). sql/sql_parse.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). Remove tabs. sql/sql_prepare.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.h: Remove an obsolete member. sql/sql_view.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_yacc.yy: Move assignment of sp_head::m_type before calling sp_head::init_spname(), one is now used inside another. sql/table.cc: Implement TABLE_LIST::set_trg_event_map() - a method that calculates wh triggers may be fired on this table when executing a statement. sql/table.h: Add missing declarations. Move declaration of trg_event_type from item.h (it will be needed for trg_event_map bitmap when we start using Bitmap template instead of uint8).
2007-07-12 20:26:41 +02:00
select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key";
select * from t1;
id operation
1 CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
select * from t1_op_log;
operation
Before INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
Before DELETE, old=CREATE TABLE ... SELECT, inserting a new key
After DELETE, old=CREATE TABLE ... SELECT, inserting a new key
After INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
truncate t1;
truncate t1_op_log;
insert into t1 (id, operation)
select NULL, "INSERT ... SELECT, inserting a new key";
set @id=last_insert_id();
select * from t1;
id operation
1 INSERT ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=INSERT ... SELECT, inserting a new key
After INSERT, new=INSERT ... SELECT, inserting a new key
truncate t1_op_log;
insert into t1 (id, operation)
select @id,
"INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate"
on duplicate key update id=NULL,
operation="INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate";
select * from t1;
id operation
0 INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate
select * from t1_op_log;
operation
Before INSERT, new=INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate
Before UPDATE, new=INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate, old=INSERT ... SELECT, inserting a new key
After UPDATE, new=INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate, old=INSERT ... SELECT, inserting a new key
truncate t1;
truncate t1_op_log;
replace into t1 (id, operation)
select NULL, "REPLACE ... SELECT, inserting a new key";
set @id=last_insert_id();
select * from t1;
id operation
1 REPLACE ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=REPLACE ... SELECT, inserting a new key
After INSERT, new=REPLACE ... SELECT, inserting a new key
truncate t1_op_log;
replace into t1 (id, operation)
select @id, "REPLACE ... SELECT, deleting a duplicate";
select * from t1;
id operation
1 REPLACE ... SELECT, deleting a duplicate
select * from t1_op_log;
operation
Before INSERT, new=REPLACE ... SELECT, deleting a duplicate
Before DELETE, old=REPLACE ... SELECT, inserting a new key
After DELETE, old=REPLACE ... SELECT, inserting a new key
After INSERT, new=REPLACE ... SELECT, deleting a duplicate
truncate t1;
truncate t1_op_log;
insert into t1 (id, operation) values (1, "INSERT for multi-DELETE");
insert into t2 (id) values (1);
delete t1.*, t2.* from t1, t2 where t1.id=1;
select * from t1;
id operation
select * from t2;
id
select * from t1_op_log;
operation
Before INSERT, new=INSERT for multi-DELETE
After INSERT, new=INSERT for multi-DELETE
Before DELETE, old=INSERT for multi-DELETE
After DELETE, old=INSERT for multi-DELETE
truncate t1;
truncate t2;
truncate t1_op_log;
insert into t1 (id, operation) values (1, "INSERT for multi-UPDATE");
insert into t2 (id) values (1);
update t1, t2 set t1.id=2, operation="multi-UPDATE" where t1.id=1;
update t1, t2
set t2.id=3, operation="multi-UPDATE, SET for t2, but the trigger is fired" where t1.id=2;
select * from t1;
id operation
2 multi-UPDATE, SET for t2, but the trigger is fired
select * from t2;
id
3
select * from t1_op_log;
operation
Before INSERT, new=INSERT for multi-UPDATE
After INSERT, new=INSERT for multi-UPDATE
Before UPDATE, new=multi-UPDATE, old=INSERT for multi-UPDATE
After UPDATE, new=multi-UPDATE, old=INSERT for multi-UPDATE
Before UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE
After UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE
truncate table t1;
truncate table t2;
truncate table t1_op_log;
Now do the same but use a view instead of the base table.
insert into v1 (operation) values ("INSERT");
set @id=last_insert_id();
select * from t1;
id operation
1 INSERT
select * from t1_op_log;
operation
Before INSERT, new=INSERT
After INSERT, new=INSERT
truncate t1_op_log;
update v1 set operation="UPDATE" where id=@id;
select * from t1;
id operation
1 UPDATE
select * from t1_op_log;
operation
Before UPDATE, new=UPDATE, old=INSERT
After UPDATE, new=UPDATE, old=INSERT
truncate t1_op_log;
delete from v1 where id=@id;
select * from t1;
id operation
select * from t1_op_log;
operation
Before DELETE, old=UPDATE
After DELETE, old=UPDATE
truncate t1;
truncate t1_op_log;
insert into v1 (id, operation) values
(NULL, "INSERT ON DUPLICATE KEY UPDATE, inserting a new key")
on duplicate key update id=NULL, operation="Should never happen";
set @id=last_insert_id();
select * from t1;
id operation
1 INSERT ON DUPLICATE KEY UPDATE, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
After INSERT, new=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
truncate t1_op_log;
insert into v1 (id, operation) values
(@id, "INSERT ON DUPLICATE KEY UPDATE, the key value is the same")
on duplicate key update id=NULL,
operation="INSERT ON DUPLICATE KEY UPDATE, updating the duplicate";
select * from t1;
id operation
0 INSERT ON DUPLICATE KEY UPDATE, updating the duplicate
select * from t1_op_log;
operation
Before INSERT, new=INSERT ON DUPLICATE KEY UPDATE, the key value is the same
Before UPDATE, new=INSERT ON DUPLICATE KEY UPDATE, updating the duplicate, old=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
After UPDATE, new=INSERT ON DUPLICATE KEY UPDATE, updating the duplicate, old=INSERT ON DUPLICATE KEY UPDATE, inserting a new key
truncate t1;
truncate t1_op_log;
replace into v1 values (NULL, "REPLACE, inserting a new key");
set @id=last_insert_id();
select * from t1;
id operation
1 REPLACE, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=REPLACE, inserting a new key
After INSERT, new=REPLACE, inserting a new key
truncate t1_op_log;
replace into v1 values (@id, "REPLACE, deleting the duplicate");
select * from t1;
id operation
1 REPLACE, deleting the duplicate
select * from t1_op_log;
operation
Before INSERT, new=REPLACE, deleting the duplicate
Before DELETE, old=REPLACE, inserting a new key
After DELETE, old=REPLACE, inserting a new key
After INSERT, new=REPLACE, deleting the duplicate
truncate t1;
truncate t1_op_log;
insert into v1
A fix and a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. Also fixes Bug#28502 Triggers that update another innodb table will block on X lock unnecessarily (duplciate). Code review fixes. Both bugs' synopses are misleading: InnoDB table is not X locked. The statements, however, cannot proceed concurrently, but this happens due to lock conflicts for tables used in triggers, not for the InnoDB table. If a user had an InnoDB table, and two triggers, AFTER UPDATE and AFTER INSERT, competing for different resources (e.g. two distinct MyISAM tables), then these two triggers would not be able to execute concurrently. Moreover, INSERTS/UPDATES of the InnoDB table would not be able to run concurrently. The problem had other side-effects (see respective bug reports). This behavior was a consequence of a shortcoming of the pre-locking algorithm, which would not distinguish between different DML operations (e.g. INSERT and DELETE) and pre-lock all the tables that are used by any trigger defined on the subject table. The idea of the fix is to extend the pre-locking algorithm to keep track, for each table, what DML operation it is used for and not load triggers that are known to never be fired. mysql-test/r/trigger-trans.result: Update results (Bug#26141) mysql-test/r/trigger.result: Update results (Bug#28502) mysql-test/t/trigger-trans.test: Add a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. mysql-test/t/trigger.test: Add a test case for Bug#28502 Triggers that update another innodb table will block echo on X lock unnecessarily. Add more test coverage for triggers. sql/item.h: enum trg_event_type is needed in table.h sql/sp.cc: Take into account table_list->trg_event_map when determining what tables to pre-lock. After this change, if we attempt to fire a trigger for which we had not pre-locked any tables, error 'Table was not locked with LOCK TABLES' will be printed. This, however, should never happen, provided the pre-locking algorithm has no programming bugs. Previously a trigger key in the sroutines hash was based on the name of the table the trigger belongs to. This was possible because we would always add to the pre-locking list all the triggers defined for a table when handling this table. Now the key is based on the name of the trigger, owing to the fact that a trigger name must be unique in the database it belongs to. sql/sp_head.cc: Generate sroutines hash key in init_spname(). This is a convenient place since there we have all the necessary information and can avoid an extra alloc. Maintain and merge trg_event_map when adding and merging elements of the pre-locking list. sql/sp_head.h: Add ,m_sroutines_key member, used when inserting the sphead for a trigger into the cache of routines used by a statement. Previously the key was based on the table name the trigger belonged to, since for a given table we would add to the sroutines list all the triggers defined on it. sql/sql_lex.cc: Introduce a new lex step: set_trg_event_type_for_tables(). It is called when we have finished parsing but before opening and locking tables. Now this step is used to evaluate for each TABLE_LIST instance which INSERT/UPDATE/DELETE operation, if any, it is used in. In future this method could be extended to aggregate other information that is hard to aggregate during parsing. sql/sql_lex.h: Add declaration for set_trg_event_type_for_tables(). sql/sql_parse.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). Remove tabs. sql/sql_prepare.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.h: Remove an obsolete member. sql/sql_view.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_yacc.yy: Move assignment of sp_head::m_type before calling sp_head::init_spname(), one is now used inside another. sql/table.cc: Implement TABLE_LIST::set_trg_event_map() - a method that calculates wh triggers may be fired on this table when executing a statement. sql/table.h: Add missing declarations. Move declaration of trg_event_type from item.h (it will be needed for trg_event_map bitmap when we start using Bitmap template instead of uint8).
2007-07-12 20:26:41 +02:00
select NULL, "CREATE TABLE ... SELECT, inserting a new key";
set @id=last_insert_id();
select * from t1;
id operation
1 CREATE TABLE ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=CREATE TABLE ... SELECT, inserting a new key
After INSERT, new=CREATE TABLE ... SELECT, inserting a new key
truncate t1_op_log;
replace into v1
A fix and a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. Also fixes Bug#28502 Triggers that update another innodb table will block on X lock unnecessarily (duplciate). Code review fixes. Both bugs' synopses are misleading: InnoDB table is not X locked. The statements, however, cannot proceed concurrently, but this happens due to lock conflicts for tables used in triggers, not for the InnoDB table. If a user had an InnoDB table, and two triggers, AFTER UPDATE and AFTER INSERT, competing for different resources (e.g. two distinct MyISAM tables), then these two triggers would not be able to execute concurrently. Moreover, INSERTS/UPDATES of the InnoDB table would not be able to run concurrently. The problem had other side-effects (see respective bug reports). This behavior was a consequence of a shortcoming of the pre-locking algorithm, which would not distinguish between different DML operations (e.g. INSERT and DELETE) and pre-lock all the tables that are used by any trigger defined on the subject table. The idea of the fix is to extend the pre-locking algorithm to keep track, for each table, what DML operation it is used for and not load triggers that are known to never be fired. mysql-test/r/trigger-trans.result: Update results (Bug#26141) mysql-test/r/trigger.result: Update results (Bug#28502) mysql-test/t/trigger-trans.test: Add a test case for Bug#26141 mixing table types in trigger causes full table lock on innodb table. mysql-test/t/trigger.test: Add a test case for Bug#28502 Triggers that update another innodb table will block echo on X lock unnecessarily. Add more test coverage for triggers. sql/item.h: enum trg_event_type is needed in table.h sql/sp.cc: Take into account table_list->trg_event_map when determining what tables to pre-lock. After this change, if we attempt to fire a trigger for which we had not pre-locked any tables, error 'Table was not locked with LOCK TABLES' will be printed. This, however, should never happen, provided the pre-locking algorithm has no programming bugs. Previously a trigger key in the sroutines hash was based on the name of the table the trigger belongs to. This was possible because we would always add to the pre-locking list all the triggers defined for a table when handling this table. Now the key is based on the name of the trigger, owing to the fact that a trigger name must be unique in the database it belongs to. sql/sp_head.cc: Generate sroutines hash key in init_spname(). This is a convenient place since there we have all the necessary information and can avoid an extra alloc. Maintain and merge trg_event_map when adding and merging elements of the pre-locking list. sql/sp_head.h: Add ,m_sroutines_key member, used when inserting the sphead for a trigger into the cache of routines used by a statement. Previously the key was based on the table name the trigger belonged to, since for a given table we would add to the sroutines list all the triggers defined on it. sql/sql_lex.cc: Introduce a new lex step: set_trg_event_type_for_tables(). It is called when we have finished parsing but before opening and locking tables. Now this step is used to evaluate for each TABLE_LIST instance which INSERT/UPDATE/DELETE operation, if any, it is used in. In future this method could be extended to aggregate other information that is hard to aggregate during parsing. sql/sql_lex.h: Add declaration for set_trg_event_type_for_tables(). sql/sql_parse.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). Remove tabs. sql/sql_prepare.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_trigger.h: Remove an obsolete member. sql/sql_view.cc: Call set_trg_event_type_for_tables() after MYSQLparse(). sql/sql_yacc.yy: Move assignment of sp_head::m_type before calling sp_head::init_spname(), one is now used inside another. sql/table.cc: Implement TABLE_LIST::set_trg_event_map() - a method that calculates wh triggers may be fired on this table when executing a statement. sql/table.h: Add missing declarations. Move declaration of trg_event_type from item.h (it will be needed for trg_event_map bitmap when we start using Bitmap template instead of uint8).
2007-07-12 20:26:41 +02:00
select @id, "CREATE TABLE ... REPLACE SELECT, deleting a duplicate key";
select * from t1;
id operation
1 CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
select * from t1_op_log;
operation
Before INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
Before DELETE, old=CREATE TABLE ... SELECT, inserting a new key
After DELETE, old=CREATE TABLE ... SELECT, inserting a new key
After INSERT, new=CREATE TABLE ... REPLACE SELECT, deleting a duplicate key
truncate t1;
truncate t1_op_log;
insert into v1 (id, operation)
select NULL, "INSERT ... SELECT, inserting a new key";
set @id=last_insert_id();
select * from t1;
id operation
1 INSERT ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=INSERT ... SELECT, inserting a new key
After INSERT, new=INSERT ... SELECT, inserting a new key
truncate t1_op_log;
insert into v1 (id, operation)
select @id,
"INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate"
on duplicate key update id=NULL,
operation="INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate";
select * from t1;
id operation
0 INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate
select * from t1_op_log;
operation
Before INSERT, new=INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate
Before UPDATE, new=INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate, old=INSERT ... SELECT, inserting a new key
After UPDATE, new=INSERT ... SELECT ... ON DUPLICATE KEY UPDATE, updating a duplicate, old=INSERT ... SELECT, inserting a new key
truncate t1;
truncate t1_op_log;
replace into v1 (id, operation)
select NULL, "REPLACE ... SELECT, inserting a new key";
set @id=last_insert_id();
select * from t1;
id operation
1 REPLACE ... SELECT, inserting a new key
select * from t1_op_log;
operation
Before INSERT, new=REPLACE ... SELECT, inserting a new key
After INSERT, new=REPLACE ... SELECT, inserting a new key
truncate t1_op_log;
replace into v1 (id, operation)
select @id, "REPLACE ... SELECT, deleting a duplicate";
select * from t1;
id operation
1 REPLACE ... SELECT, deleting a duplicate
select * from t1_op_log;
operation
Before INSERT, new=REPLACE ... SELECT, deleting a duplicate
Before DELETE, old=REPLACE ... SELECT, inserting a new key
After DELETE, old=REPLACE ... SELECT, inserting a new key
After INSERT, new=REPLACE ... SELECT, deleting a duplicate
truncate t1;
truncate t1_op_log;
insert into v1 (id, operation) values (1, "INSERT for multi-DELETE");
insert into t2 (id) values (1);
delete v1.*, t2.* from v1, t2 where v1.id=1;
select * from t1;
id operation
select * from t2;
id
select * from t1_op_log;
operation
Before INSERT, new=INSERT for multi-DELETE
After INSERT, new=INSERT for multi-DELETE
Before DELETE, old=INSERT for multi-DELETE
After DELETE, old=INSERT for multi-DELETE
truncate t1;
truncate t2;
truncate t1_op_log;
insert into v1 (id, operation) values (1, "INSERT for multi-UPDATE");
insert into t2 (id) values (1);
update v1, t2 set v1.id=2, operation="multi-UPDATE" where v1.id=1;
update v1, t2
set t2.id=3, operation="multi-UPDATE, SET for t2, but the trigger is fired" where v1.id=2;
select * from t1;
id operation
2 multi-UPDATE, SET for t2, but the trigger is fired
select * from t2;
id
3
select * from t1_op_log;
operation
Before INSERT, new=INSERT for multi-UPDATE
After INSERT, new=INSERT for multi-UPDATE
Before UPDATE, new=multi-UPDATE, old=INSERT for multi-UPDATE
After UPDATE, new=multi-UPDATE, old=INSERT for multi-UPDATE
Before UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE
After UPDATE, new=multi-UPDATE, SET for t2, but the trigger is fired, old=multi-UPDATE
drop view v1;
drop table t1, t2, t1_op_log;
Bug#27248 Triggers: error if insert affects temporary table
The bug was fixed by the fix for Bug#26141
drop table if exists t1;
drop temporary table if exists t2;
create table t1 (s1 int);
create temporary table t2 (s1 int);
create trigger t1_bi before insert on t1 for each row insert into t2 values (0);
create trigger t1_bd before delete on t1 for each row delete from t2;
insert into t1 values (0);
insert into t1 values (0);
select * from t1;
s1
0
0
select * from t2;
s1
0
0
delete from t1;
select * from t1;
s1
select * from t2;
s1
drop table t1;
drop temporary table t2;
#------------------------------------------------------------------------
# Bug#39953 Triggers are not working properly with multi table updates
#------------------------------------------------------------------------
DROP TABLE IF EXISTS t1;
DROP TRIGGER IF EXISTS t_insert;
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 (a int, date_insert timestamp, PRIMARY KEY (a));
INSERT INTO t1 (a) VALUES (2),(5);
CREATE TABLE t2 (a int, b int, PRIMARY KEY (a));
CREATE TRIGGER t_insert AFTER INSERT ON t2 FOR EACH ROW BEGIN UPDATE t1,t2 SET
date_insert=NOW() WHERE t1.a=t2.b AND t2.a=NEW.a; END |
INSERT INTO t2 (a,b) VALUES (1,2);
DROP TRIGGER t_insert;
CREATE TRIGGER t_insert AFTER INSERT ON t2 FOR EACH ROW BEGIN UPDATE t1,t2 SET
date_insert=NOW(),b=b+1 WHERE t1.a=t2.b AND t2.a=NEW.a; END |
INSERT INTO t2 (a,b) VALUES (3,5);
ERROR HY000: Can't update table 't2' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
DROP TABLE t1;
DROP TRIGGER t_insert;
DROP TABLE t2;
End of 5.0 tests
Bug#25411 (trigger code truncated), PART II Bug 28127 (Some valid identifiers names are not parsed correctly) Bug 26302 (MySQL server cuts off trailing "*/" from comments in SP/func) This patch is the second part of a major cleanup, required to fix Bug 25411 (trigger code truncated). The root cause of the issue stems from the function skip_rear_comments, which was a work around to remove "extra" "*/" characters from the query text, when parsing a query and reusing the text fragments to represent a view, trigger, function or stored procedure. The reason for this work around is that "special comments", like /*!50002 XXX */, were not parsed properly, so that a query like: AAA /*!50002 BBB */ CCC would be seen by the parser as "AAA BBB */ CCC" when the current version is greater or equal to 5.0.2 The root cause of this stems from how special comments are parsed. Special comments are really out-of-bound text that appear inside a query, that affects how the parser behave. In nature, /*!50002 XXX */ in MySQL is similar to the C concept of preprocessing : #if VERSION >= 50002 XXX #endif Depending on the current VERSION of the server, either the special comment should be expanded or it should be ignored, but in all cases the "text" of the query should be re-written to strip the "/*!50002" and "*/" markers, which does not belong to the SQL language itself. Prior to this fix, these markers would leak into : - the storage format for VIEW, - the storage format for FUNCTION, - the storage format for FUNCTION parameters, in mysql.proc (param_list), - the storage format for PROCEDURE, - the storage format for PROCEDURE parameters, in mysql.proc (param_list), - the storage format for TRIGGER, - the binary log used for replication. In all cases, not only this cause format corruption, but also provide a vector for dormant security issues, by allowing to tunnel code that will be activated after an upgrade. The proper solution is to deal with special comments strictly during parsing, when accepting a query from the outside world. Once a query is parsed and an object is created with a persistant representation, this object should not arbitrarily mutate after an upgrade. In short, special comments are a useful but limited feature for MYSQLdump, when used at an *interface* level to facilitate import/export, but bloating the server *internal* storage format is *not* the proper way to deal with configuration management of the user logic. With this fix: - the Lex_input_stream class now acts as a comment pre-processor, and either expands or ignore special comments on the fly. - MYSQLlex and sql_yacc.yy have been cleaned up to strictly use the public interface of Lex_input_stream. In particular, how the input stream accepts or rejects a character is private to Lex_input_stream, and the internal buffer pointers of that class are strictly private, and should not be tempered with during parsing. This caused many changes mostly in sql_lex.cc. During the code cleanup in case MY_LEX_NUMBER_IDENT, Bug 28127 (Some valid identifiers names are not parsed correctly) was found and fixed. By parsing special comments properly, and removing the function 'skip_rear_comments' [sic], Bug 26302 (MySQL server cuts off trailing "*/" from comments in SP/func) has been fixed as well. sql/event_data_objects.cc: Cleanup of the code that extracts the query text sql/sp.cc: Cleanup of the code that extracts the query text sql/sp_head.cc: Cleanup of the code that extracts the query text sql/sql_trigger.cc: Cleanup of the code that extracts the query text sql/sql_view.cc: Cleanup of the code that extracts the query text mysql-test/r/comments.result: Bug#25411 (trigger code truncated) mysql-test/r/sp.result: Bug#25411 (trigger code truncated) Bug 26302 (MySQL server cuts off trailing "*/" from comments in SP/func) mysql-test/r/trigger.result: Bug#25411 (trigger code truncated) mysql-test/r/varbinary.result: Bug 28127 (Some valid identifiers names are not parsed correctly) mysql-test/t/comments.test: Bug#25411 (trigger code truncated) mysql-test/t/sp.test: Bug#25411 (trigger code truncated) Bug 26302 (MySQL server cuts off trailing "*/" from comments in SP/func) mysql-test/t/trigger.test: Bug#25411 (trigger code truncated) mysql-test/t/varbinary.test: Bug 28127 (Some valid identifiers names are not parsed correctly) sql/sql_lex.cc: Implemented comment pre-processing in Lex_input_stream, major cleanup of the lex/yacc code to not use Lex_input_stream private members. sql/sql_lex.h: Implemented comment pre-processing in Lex_input_stream, major cleanup of the lex/yacc code to not use Lex_input_stream private members. sql/sql_yacc.yy: post merge fix : view_check_options must be parsed before signaling the end of the query
2007-06-12 23:23:58 +02:00
drop table if exists table_25411_a;
drop table if exists table_25411_b;
create table table_25411_a(a int);
create table table_25411_b(b int);
create trigger trg_25411a_ai after insert on table_25411_a
for each row
insert into table_25411_b select new.*;
select * from table_25411_a;
a
insert into table_25411_a values (1);
ERROR 42S02: Unknown table 'new'
select * from table_25411_a;
a
1
drop table table_25411_a;
drop table table_25411_b;
DROP TRIGGER IF EXISTS trg;
SHOW CREATE TRIGGER trg;
ERROR HY000: Trigger does not exist
Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock This bug is actually two bugs in one, one of which is CREATE TRIGGER under LOCK TABLES and the other is CREATE TRIGGER under LOCK TABLES simultaneous to a FLUSH TABLES WITH READ LOCK (global read lock). Both situations could lead to a server crash or deadlock. The first problem arises from the fact that when under LOCK TABLES, if the table is in the set of locked tables, the table is already open and it doesn't need to be reopened (not a placeholder). Also in this case, if the table is not write locked, a exclusive lock can't be acquired because of a possible deadlock with another thread also holding a (read) lock on the table. The second issue arises from the fact that one should never wait for a global read lock if it's holding any locked tables, because the global read lock is waiting for these tables and this leads to a circular wait deadlock. The solution for the first case is to check if the table is write locked and upgraded the write lock to a exclusive lock and fail otherwise for non write locked tables. Grabbin the exclusive lock in this case also means to ensure that the table is opened only by the calling thread. The second issue is partly fixed by not waiting for the global read lock if the thread is holding any locked tables. The second issue is only partly addressed in this patch because it turned out to be much wider and also affects other DDL statements. Reported as Bug#32395 mysql-test/r/trigger.result: Add test case result for Bug#23713 mysql-test/r/trigger_notembedded.result: Add test case result for Bug#23713 mysql-test/t/trigger.test: Add test case for Bug#23713 mysql-test/t/trigger_notembedded.test: Add test case for Bug#23713 sql/mysql_priv.h: Locally export wait_while_table_is_used and name_lock_locked_table and add flag to mysql_ha_rm_tables to signal that LOCK_open is locked. sql/sql_base.cc: Introduce name_lock_locked_table function and match close_old_data_files function declaration and definition. sql/sql_handler.cc: Add flag to mysql_ha_rm_tables to signal that LOCK_open is locked. sql/sql_rename.cc: Fix mysql_ha_rm_tables caller. sql/sql_table.cc: Export wait_while_table_is_used and assert that LOCK_open is locked and fix mysql_ha_rm_tables caller. sql/sql_trigger.cc: Upgrade write locked tables to a exclusive lock and fail if the table is not write locked. Also, don't wait for the global read lock if under LOCK TABLES.
2007-11-29 12:42:26 +01:00
drop table if exists t1;
create table t1 (i int, j int);
create trigger t1_bi before insert on t1 for each row begin end;
create trigger t1_bi before insert on t1 for each row begin end;
ERROR 42000: This version of MariaDB doesn't yet support 'multiple triggers with the same action time and event for one table'
Bug#23713 LOCK TABLES + CREATE TRIGGER + FLUSH TABLES WITH READ LOCK = deadlock This bug is actually two bugs in one, one of which is CREATE TRIGGER under LOCK TABLES and the other is CREATE TRIGGER under LOCK TABLES simultaneous to a FLUSH TABLES WITH READ LOCK (global read lock). Both situations could lead to a server crash or deadlock. The first problem arises from the fact that when under LOCK TABLES, if the table is in the set of locked tables, the table is already open and it doesn't need to be reopened (not a placeholder). Also in this case, if the table is not write locked, a exclusive lock can't be acquired because of a possible deadlock with another thread also holding a (read) lock on the table. The second issue arises from the fact that one should never wait for a global read lock if it's holding any locked tables, because the global read lock is waiting for these tables and this leads to a circular wait deadlock. The solution for the first case is to check if the table is write locked and upgraded the write lock to a exclusive lock and fail otherwise for non write locked tables. Grabbin the exclusive lock in this case also means to ensure that the table is opened only by the calling thread. The second issue is partly fixed by not waiting for the global read lock if the thread is holding any locked tables. The second issue is only partly addressed in this patch because it turned out to be much wider and also affects other DDL statements. Reported as Bug#32395 mysql-test/r/trigger.result: Add test case result for Bug#23713 mysql-test/r/trigger_notembedded.result: Add test case result for Bug#23713 mysql-test/t/trigger.test: Add test case for Bug#23713 mysql-test/t/trigger_notembedded.test: Add test case for Bug#23713 sql/mysql_priv.h: Locally export wait_while_table_is_used and name_lock_locked_table and add flag to mysql_ha_rm_tables to signal that LOCK_open is locked. sql/sql_base.cc: Introduce name_lock_locked_table function and match close_old_data_files function declaration and definition. sql/sql_handler.cc: Add flag to mysql_ha_rm_tables to signal that LOCK_open is locked. sql/sql_rename.cc: Fix mysql_ha_rm_tables caller. sql/sql_table.cc: Export wait_while_table_is_used and assert that LOCK_open is locked and fix mysql_ha_rm_tables caller. sql/sql_trigger.cc: Upgrade write locked tables to a exclusive lock and fail if the table is not write locked. Also, don't wait for the global read lock if under LOCK TABLES.
2007-11-29 12:42:26 +01:00
drop trigger t1_bi;
drop trigger t1_bi;
ERROR HY000: Trigger does not exist
lock tables t1 read;
create trigger t1_bi before insert on t1 for each row begin end;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
create trigger t1_bi before insert on t1 for each row begin end;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
drop trigger t1_bi;
ERROR HY000: Trigger does not exist
unlock tables;
create trigger t1_bi before insert on t1 for each row begin end;
lock tables t1 read;
create trigger t1_bi before insert on t1 for each row begin end;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
drop trigger t1_bi;
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
unlock tables;
drop trigger t1_bi;
lock tables t1 write;
create trigger b1_bi before insert on t1 for each row set new.i = new.i + 10;
insert into t1 values (10, 10);
drop trigger b1_bi;
insert into t1 values (10, 10);
select * from t1;
i j
20 10
10 10
unlock tables;
drop table t1;
drop table if exists t1, t2;
drop trigger if exists trg1;
drop trigger if exists trg2;
create table t1 (a int);
create table t2 (b int);
create trigger trg1 after update on t1 for each row set @a= @a+1;
create trigger trg2 after update on t2 for each row set @b= @b+1;
insert into t1 values (1), (2), (3);
insert into t2 values (1), (2), (3);
set @a= 0;
set @b= 0;
update t1, t2 set t1.a= t1.a, t2.b= t2.b;
select @a, @b;
@a @b
3 3
update t1, t2 set t1.a= t2.b, t2.b= t1.a;
select @a, @b;
@a @b
6 6
update t1 set a= a;
select @a, @b;
@a @b
9 6
update t2 set b= b;
select @a, @b;
@a @b
9 9
update t1 set a= 1;
select @a, @b;
@a @b
12 9
update t2 set b= 1;
select @a, @b;
@a @b
12 12
drop trigger trg1;
drop trigger trg2;
drop table t1, t2;
CREATE TABLE t1 ( a INT, b INT );
CREATE TABLE t2 ( a INT AUTO_INCREMENT KEY, b INT );
INSERT INTO t1 (a) VALUES (1);
CREATE TRIGGER tr1
BEFORE INSERT ON t2
FOR EACH ROW
BEGIN
UPDATE a_nonextisting_table SET a = 1;
END//
CREATE TABLE IF NOT EXISTS t2 ( a INT, b INT ) SELECT a, b FROM t1;
Warnings:
Note 1050 Table 't2' already exists
SELECT * FROM t2;
a b
DROP TABLE t1, t2;
#
# Bug#51650 crash with user variables and triggers
#
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (b VARCHAR(50) NOT NULL);
CREATE TABLE t2 (a VARCHAR(10) NOT NULL DEFAULT '');
CREATE TRIGGER trg1 AFTER INSERT ON t2
FOR EACH ROW BEGIN
SELECT 1 FROM t1 c WHERE
(@bug51650 IS NULL OR @bug51650 != c.b) AND c.b = NEW.a LIMIT 1 INTO @foo;
END//
SET @bug51650 = 1;
INSERT IGNORE INTO t2 VALUES();
INSERT IGNORE INTO t1 SET b = '777';
INSERT IGNORE INTO t2 SET a = '111';
SET @bug51650 = 1;
INSERT IGNORE INTO t2 SET a = '777';
DROP TRIGGER trg1;
DROP TABLE t1, t2;
CREATE TABLE t1 (id INT NOT NULL);
CREATE TABLE t2 (id INT NOT NULL);
INSERT t1 VALUES (1),(2),(3);
UPDATE t1 SET id=NULL;
Warnings:
Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null
CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
INSERT INTO t2 VALUES (3);
UPDATE t1 SET id=NULL;
Warnings:
Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null
Warning 1048 Column 'id' cannot be null
DROP TRIGGER t1_bu;
DROP TABLE t1,t2;
#
# Bug#50755: Crash if stored routine def contains version comments
#
DROP DATABASE IF EXISTS db1;
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1, t2;
CREATE DATABASE db1;
USE db1;
CREATE TABLE t1 (b INT);
CREATE TABLE t2 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t2 FOR EACH ROW INSERT/*!INTO*/t1 VALUES (1);
# Used to crash
SHOW TRIGGERS IN db1;
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
INSERT INTO t2 VALUES (1);
ERROR 42000: Trigger 'trg1' has an error in its body: 'You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'VALUES (1)' at line 1'
SELECT * FROM t1;
b
# Work around Bug#45235
DROP DATABASE db1;
USE test;
End of 5.1 tests.
create table t1 (i int);
create table t2 (i int);
flush tables;
flush status;
CREATE DEFINER=`root`@`localhost` TRIGGER trg AFTER DELETE ON t1 FOR EACH ROW BEGIN DELETE FROM t2 WHERE t2.i = OLD.i; END //
insert into t1 values (1),(2);
insert into t2 values (1),(2);
delete from t1 where i=1;
show status like 'Opened_tables';
Variable_name Value
Opened_tables 3
select * from t1;
i
2
select * from t2;
i
2
drop table t1,t2;
End of 5.2 tests.
#
# Bug#34453 Can't change size of file (Errcode: 1224)
#
DROP TRIGGER IF EXISTS t1_bi;
DROP TRIGGER IF EXISTS t1_bd;
DROP TABLE IF EXISTS t1;
DROP TEMPORARY TABLE IF EXISTS t2;
CREATE TABLE t1 (s1 INT);
CREATE TEMPORARY TABLE t2 (s1 INT);
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW INSERT INTO t2 VALUES (0);
CREATE TRIGGER t1_bd BEFORE DELETE ON t1 FOR EACH ROW DELETE FROM t2;
INSERT INTO t1 VALUES (0);
INSERT INTO t1 VALUES (0);
SELECT * FROM t1;
s1
0
0
SELECT * FROM t2;
s1
0
0
# Reported to give ERROR 14 (HY000):
# Can't change size of file (Errcode: 1224)
# on Windows
DELETE FROM t1;
DROP TABLE t1;
DROP TEMPORARY TABLE t2;
Backport of Bug#36649 to mysql-next-mr ------------------------------------------------------------ revno: 2630.39.3 revision-id: davi.arnaut@sun.com-20081210215359-i876m4zgc2d6rzs3 parent: kostja@sun.com-20081208222938-9es7wl61moli71ht committer: Davi Arnaut <Davi.Arnaut@Sun.COM> branch nick: 36649-6.0 timestamp: Wed 2008-12-10 19:53:59 -0200 message: Bug#36649: Condition area is not properly cleaned up after stored routine invocation The problem is that the diagnostics area of a trigger is not isolated from the area of the statement that caused the trigger invocation. In MySQL terms, it means that warnings generated during the execution of the trigger are not removed from the "warning area" at the end of the execution. Before this fix, the rules for MySQL message list life cycle (see manual entry for SHOW WARNINGS) did not apply to statements inside stored programs: - The manual says that the list of messages is cleared by a statement that uses a table (any table). However, such statement, if run inside a stored program did not clear the message list. - The manual says that the list is cleared by a statement that generates a new error or a warning, but this was not the case with stored program statements either and is changed to be the case as well. In other words, after this fix, a statement has the same effect on the message list regardless of whether it's executed inside a stored program/sub-statement or not. This introduces an incompatible change: - before this fix, a, e.g. statement inside a trigger could never clear the global warning list - after this fix, a trigger that generates a warning or uses a table, clears the global warning list - however, when we leave a trigger or a function, the caller's warning information is restored (see more on this below). This change is not backward compatible as it is intended to make MySQL behavior similar to the SQL standard behavior: A stored function or trigger will get its own "warning area" (or, in standard terminology, diagnostics area). At the beginning of the stored function or trigger, all messages from the caller area will be copied to the area of the trigger. During execution, the message list will be cleared according to the MySQL rules described on the manual (SHOW WARNINGS entry). At the end of the function/trigger, the "warning area" will be destroyed along with all warnings it contains, except that if the last statement of the function/trigger generated messages, these are copied into the "warning area" of the caller. Consequently, statements that use a table or generate a warning *will* clear warnings inside the trigger, but that will have no effect to the warning list of the calling (outer) statement. mysql-test/r/sp.result: Fix test case results. mysql-test/r/trigger.result: Fix test case results. mysql-test/t/sp.test: Add test case for Bug#36649 mysql-test/t/trigger.test: Add test case for Bug#36649 sql/sp_head.cc: Emulate multiple warning areas -- one per stored program instance. sql/sql_parse.cc: Message list reset rules are the same for statements inside or outside compound statements.
2009-11-10 19:11:27 +01:00
DROP TRIGGER IF EXISTS trg1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE a CHAR;
SELECT 'ab' INTO a;
SELECT 'ab' INTO a;
SELECT 'a' INTO a;
END|
INSERT INTO t1 VALUES (1);
DROP TRIGGER trg1;
DROP TABLE t1;
DROP TRIGGER IF EXISTS trg1;
DROP TRIGGER IF EXISTS trg2;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a INT);
CREATE TRIGGER trg1 BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE trg1 CHAR;
SELECT 'ab' INTO trg1;
END|
CREATE TRIGGER trg2 AFTER INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE trg2 CHAR;
SELECT 'ab' INTO trg2;
END|
INSERT INTO t1 VALUES (0);
SELECT * FROM t1;
a
0
SHOW WARNINGS;
Level Code Message
INSERT INTO t1 VALUES (1),(2);
DROP TRIGGER trg1;
DROP TRIGGER trg2;
DROP TABLE t1;
#
# Bug #46747 "Crash in MDL_ticket::upgrade_shared_lock_to_exclusive
# on TRIGGER + TEMP table".
#
drop trigger if exists t1_bi;
drop temporary table if exists t1;
drop table if exists t1;
create table t1 (i int);
create trigger t1_bi before insert on t1 for each row set @a:=1;
# Create temporary table which shadows base table with trigger.
create temporary table t1 (j int);
# Dropping of trigger should succeed.
drop trigger t1_bi;
select trigger_name from information_schema.triggers
where event_object_schema = 'test' and event_object_table = 't1';
trigger_name
# Clean-up.
drop temporary table t1;
drop table t1;
Patch for Bug#12362125 (SP INOUT HANDLING IS BROKEN FOR TEXT TYPE). Attempts to assign value to a table column from trigger by using NEW.column_name pseudo-variable might result in garbled data. That happened when: - the column had a BLOB-based type (e.g. TEXT) and - the value being assigned was retrieved from stored routine variable of the same type. The problem was that BLOB values were not copied correctly in this case. Instead of doing a copy of a real value, the value's representation in record buffer was copied. This representation is essentially a pointer to a buffer associated with the virtual table for routine variables where the real value is stored. Since this buffer got freed once trigger was left or could have changed its contents when new value was assigned to corresponding routine variable such a shallow copying resulted in garbled data in NEW.colum_name column. It worked in 5.1 due to a subtle bug in create_virtual_tmp_table(): - in 5.1 create_virtual_tmp_table() returned a table which had db_low_byte_first == false. - in 5.5 and up create_virtual_tmp_table() returns a table which has db_low_byte_first == true. Actually, db_low_byte_first == false only for ISAM storage engine, which was deprecated and removed in 5.0. Having db_low_byte_first == false led to getting false in the complex condition for the 2nd "if" in field_conv(), which in turn led to copy-blob-behavior as a fall-back strategy: - to->table->s->db_low_byte_first was true (correct value) - from->table->s->db_low_byte_first was false (incorrect value) In 5.5 and up that condition is true, which means blob-values are not copied.
2011-05-09 10:29:23 +02:00
#
# Bug #12362125: SP INOUT HANDLING IS BROKEN FOR TEXT TYPE.
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(c TEXT);
CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
BEGIN
DECLARE v TEXT;
SET v = 'aaa';
SET NEW.c = v;
END|
INSERT INTO t1 VALUES('qazwsxedc');
SELECT c FROM t1;
c
aaa
DROP TABLE t1;
End of 5.5 tests.
2012-01-13 15:50:02 +01:00
#
# BUG #910083: materialized subquery in a trigger
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch='materialization=on';
CREATE TABLE t1 (a int);
CREATE TABLE t2 (b int);
CREATE TRIGGER tr AFTER UPDATE ON t1 FOR EACH ROW
UPDATE t2 SET b = (SELECT COUNT(a) FROM t1);
INSERT INTO t1
VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9);
INSERT INTO t2
VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0);
UPDATE t1 SET a = 3;
SELECT COUNT(*) FROM t1;
COUNT(*)
9
SELECT * FROM t2;
b
9
9
9
9
9
9
9
9
9
UPDATE t1 SET a = 2;
SELECT * FROM t2;
b
9
9
9
9
9
9
9
9
9
SET optimizer_switch=@save_optimizer_switch;
DROP TRIGGER tr;
DROP TABLE t1, t2;
End of 5.3 tests.