#include <sql_trigger.h>
Inheritance diagram for Table_triggers_list:


Definition at line 24 of file sql_trigger.h.
| Table_triggers_list::Table_triggers_list | ( | TABLE * | table_arg | ) | [inline] |
Definition at line 86 of file sql_trigger.h.
References bodies, bzero, subject_table_grants, and trigger_fields.
Referenced by check_n_load().
00086 : 00087 record1_field(0), table(table_arg) 00088 { 00089 bzero((char *)bodies, sizeof(bodies)); 00090 bzero((char *)trigger_fields, sizeof(trigger_fields)); 00091 bzero((char *)&subject_table_grants, sizeof(subject_table_grants)); 00092 } ~Table_triggers_list();
Here is the caller graph for this function:

| Table_triggers_list::~Table_triggers_list | ( | ) |
Definition at line 711 of file sql_trigger.cc.
References bodies, int(), record1_field, TRG_ACTION_MAX, and TRG_EVENT_MAX.
00712 { 00713 for (int i= 0; i < (int)TRG_EVENT_MAX; i++) 00714 for (int j= 0; j < (int)TRG_ACTION_MAX; j++) 00715 delete bodies[i][j]; 00716 00717 if (record1_field) 00718 for (Field **fld_ptr= record1_field; *fld_ptr; fld_ptr++) 00719 delete *fld_ptr; 00720 }
Here is the call graph for this function:

| bool Table_triggers_list::change_table_name | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | old_table, | |||
| const char * | new_db, | |||
| const char * | new_table | |||
| ) | [static] |
Definition at line 1410 of file sql_trigger.cc.
References bzero, check_n_load(), DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, ER_TRG_IN_WRONG_SCHEMA, free_root(), init_alloc_root(), LOCK_open, my_error(), my_strcasecmp, MYF, safe_mutex_assert_owner, strlen(), table, table_alias_charset, and TRUE.
Referenced by mysql_alter_table(), and rename_tables().
01414 { 01415 TABLE table; 01416 bool result= 0; 01417 LEX_STRING *err_trigname; 01418 DBUG_ENTER("change_table_name"); 01419 01420 bzero(&table, sizeof(table)); 01421 init_alloc_root(&table.mem_root, 8192, 0); 01422 01423 safe_mutex_assert_owner(&LOCK_open); 01424 01425 DBUG_ASSERT(my_strcasecmp(table_alias_charset, db, new_db) || 01426 my_strcasecmp(table_alias_charset, old_table, new_table)); 01427 01428 if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE)) 01429 { 01430 result= 1; 01431 goto end; 01432 } 01433 if (table.triggers) 01434 { 01435 LEX_STRING old_table_name= { (char *) old_table, strlen(old_table) }; 01436 LEX_STRING new_table_name= { (char *) new_table, strlen(new_table) }; 01437 /* 01438 Since triggers should be in the same schema as their subject tables 01439 moving table with them between two schemas raises too many questions. 01440 (E.g. what should happen if in new schema we already have trigger 01441 with same name ?). 01442 */ 01443 if (my_strcasecmp(table_alias_charset, db, new_db)) 01444 { 01445 my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0)); 01446 result= 1; 01447 goto end; 01448 } 01449 if (table.triggers->change_table_name_in_triggers(thd, db, 01450 &old_table_name, 01451 &new_table_name)) 01452 { 01453 result= 1; 01454 goto end; 01455 } 01456 if ((err_trigname= table.triggers->change_table_name_in_trignames( 01457 db, &new_table_name, 0))) 01458 { 01459 /* 01460 If we were unable to update one of .TRN files properly we will 01461 revert all changes that we have done and report about error. 01462 We assume that we will be able to undo our changes without errors 01463 (we can't do much if there will be an error anyway). 01464 */ 01465 (void) table.triggers->change_table_name_in_trignames(db, 01466 &old_table_name, 01467 err_trigname); 01468 (void) table.triggers->change_table_name_in_triggers(thd, db, 01469 &new_table_name, 01470 &old_table_name); 01471 result= 1; 01472 goto end; 01473 } 01474 } 01475 end: 01476 delete table.triggers; 01477 free_root(&table.mem_root, MYF(0)); 01478 DBUG_RETURN(result); 01479 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool Table_triggers_list::change_table_name_in_triggers | ( | THD * | thd, | |
| const char * | db_name, | |||
| LEX_STRING * | old_table_name, | |||
| LEX_STRING * | new_table_name | |||
| ) | [private] |
Definition at line 1281 of file sql_trigger.cc.
References String::append(), append_identifier(), DBUG_ASSERT, definition_modes_list, definitions_list, base_list::elements, FALSE, FN_REFLEN, LEX_STRING::length, String::length(), st_table::mem_root, memdup_root(), on_table_names_list, String::ptr(), rm_trigger_file(), save_trigger_file(), LEX_STRING::str, STRING_WITH_LEN, table, and TRUE.
01285 { 01286 char path_buff[FN_REFLEN]; 01287 LEX_STRING *def, *on_table_name, new_def; 01288 ulonglong *sql_mode; 01289 ulong save_sql_mode= thd->variables.sql_mode; 01290 List_iterator_fast<LEX_STRING> it_def(definitions_list); 01291 List_iterator_fast<LEX_STRING> it_on_table_name(on_table_names_list); 01292 List_iterator_fast<ulonglong> it_mode(definition_modes_list); 01293 uint on_q_table_name_len, before_on_len; 01294 String buff; 01295 01296 DBUG_ASSERT(definitions_list.elements == on_table_names_list.elements && 01297 definitions_list.elements == definition_modes_list.elements); 01298 01299 while ((def= it_def++)) 01300 { 01301 on_table_name= it_on_table_name++; 01302 thd->variables.sql_mode= *(it_mode++); 01303 01304 /* Construct CREATE TRIGGER statement with new table name. */ 01305 buff.length(0); 01306 before_on_len= on_table_name->str - def->str; 01307 buff.append(def->str, before_on_len); 01308 buff.append(STRING_WITH_LEN("ON ")); 01309 append_identifier(thd, &buff, new_table_name->str, new_table_name->length); 01310 buff.append(STRING_WITH_LEN(" ")); 01311 on_q_table_name_len= buff.length() - before_on_len; 01312 buff.append(on_table_name->str + on_table_name->length, 01313 def->length - (before_on_len + on_table_name->length)); 01314 /* 01315 It is OK to allocate some memory on table's MEM_ROOT since this 01316 table instance will be thrown out at the end of rename anyway. 01317 */ 01318 new_def.str= memdup_root(&table->mem_root, buff.ptr(), buff.length()); 01319 new_def.length= buff.length(); 01320 on_table_name->str= new_def.str + before_on_len; 01321 on_table_name->length= on_q_table_name_len; 01322 *def= new_def; 01323 } 01324 01325 thd->variables.sql_mode= save_sql_mode; 01326 01327 if (thd->is_fatal_error) 01328 return TRUE; /* OOM */ 01329 01330 if (save_trigger_file(this, db_name, new_table_name->str)) 01331 return TRUE; 01332 if (rm_trigger_file(path_buff, db_name, old_table_name->str)) 01333 { 01334 (void) rm_trigger_file(path_buff, db_name, new_table_name->str); 01335 return TRUE; 01336 } 01337 return FALSE; 01338 }
Here is the call graph for this function:

| LEX_STRING * Table_triggers_list::change_table_name_in_trignames | ( | const char * | db_name, | |
| LEX_STRING * | new_table_name, | |||
| LEX_STRING * | stopper | |||
| ) | [private] |
Definition at line 1359 of file sql_trigger.cc.
References build_table_filename(), FN_REFLEN, names_list, NULL, sql_create_definition_file(), LEX_STRING::str, st_trigname::trigger_table, trigname_file_ext, trigname_file_parameters, and trigname_file_type.
01362 { 01363 char trigname_buff[FN_REFLEN]; 01364 struct st_trigname trigname; 01365 LEX_STRING trigname_file; 01366 LEX_STRING *trigger; 01367 List_iterator_fast<LEX_STRING> it_name(names_list); 01368 01369 while ((trigger= it_name++) != stopper) 01370 { 01371 trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, 01372 db_name, trigger->str, 01373 trigname_file_ext, 0); 01374 trigname_file.str= trigname_buff; 01375 01376 trigname.trigger_table= *new_table_name; 01377 01378 if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, 01379 (gptr)&trigname, trigname_file_parameters, 01380 0)) 01381 return trigger; 01382 } 01383 01384 return 0; 01385 }
Here is the call graph for this function:

| bool Table_triggers_list::check_n_load | ( | THD * | thd, | |
| const char * | db, | |||
| const char * | table_name, | |||
| TABLE * | table, | |||
| bool | names_only | |||
| ) | [static] |
Definition at line 798 of file sql_trigger.cc.
References access, alloc_root(), build_table_filename(), DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, definers_list, definition_modes_list, base_list::empty(), ER, ER_TRG_NO_DEFINER, ER_WRONG_OBJECT, F_OK, FN_REFLEN, global_system_variables, is_equal(), LEX_STRING::length, lex_end(), lex_start(), st_table::mem_root, my_error(), my_strcasecmp, MYF, NullS, parser, path, push_warning_printf(), List_iterator_fast< T >::rewind(), system_variables::sql_mode, sql_parse_prepare(), sroutines_key, LEX_STRING::str, strlen(), strxmov(), table, table_alias_charset, Table_triggers_list(), TRG_NUM_REQUIRED_PARAMETERS, st_table::triggers, triggers_file_ext, triggers_file_parameters, triggers_file_type, TYPE_ENUM_TRIGGER, and MYSQL_ERROR::WARN_LEVEL_WARN.
Referenced by change_table_name(), drop_all_triggers(), and open_unireg_entry().
00801 { 00802 char path_buff[FN_REFLEN]; 00803 LEX_STRING path; 00804 File_parser *parser; 00805 LEX_STRING save_db; 00806 00807 DBUG_ENTER("Table_triggers_list::check_n_load"); 00808 00809 path.length= build_table_filename(path_buff, FN_REFLEN-1, 00810 db, table_name, triggers_file_ext, 0); 00811 path.str= path_buff; 00812 00813 // QQ: should we analyze errno somehow ? 00814 if (access(path_buff, F_OK)) 00815 DBUG_RETURN(0); 00816 00817 /* 00818 File exists so we got to load triggers. 00819 FIXME: A lot of things to do here e.g. how about other funcs and being 00820 more paranoical ? 00821 */ 00822 00823 if ((parser= sql_parse_prepare(&path, &table->mem_root, 1))) 00824 { 00825 if (is_equal(&triggers_file_type, parser->type())) 00826 { 00827 Table_triggers_list *triggers= 00828 new (&table->mem_root) Table_triggers_list(table); 00829 Handle_old_incorrect_sql_modes_hook sql_modes_hook(path.str); 00830 00831 if (!triggers) 00832 DBUG_RETURN(1); 00833 00834 /* 00835 We don't have the following attributes in old versions of .TRG file, so 00836 we should initialize the list for safety: 00837 - sql_modes; 00838 - definers; 00839 */ 00840 triggers->definition_modes_list.empty(); 00841 triggers->definers_list.empty(); 00842 00843 if (parser->parse((gptr)triggers, &table->mem_root, 00844 triggers_file_parameters, 00845 TRG_NUM_REQUIRED_PARAMETERS, 00846 &sql_modes_hook)) 00847 DBUG_RETURN(1); 00848 00849 List_iterator_fast<LEX_STRING> it(triggers->definitions_list); 00850 LEX_STRING *trg_create_str, *trg_name_str; 00851 ulonglong *trg_sql_mode; 00852 00853 if (triggers->definition_modes_list.is_empty() && 00854 !triggers->definitions_list.is_empty()) 00855 { 00856 /* 00857 It is old file format => we should fill list of sql_modes. 00858 00859 We use one mode (current) for all triggers, because we have not 00860 information about mode in old format. 00861 */ 00862 if (!(trg_sql_mode= (ulonglong*)alloc_root(&table->mem_root, 00863 sizeof(ulonglong)))) 00864 { 00865 DBUG_RETURN(1); // EOM 00866 } 00867 *trg_sql_mode= global_system_variables.sql_mode; 00868 while (it++) 00869 { 00870 if (triggers->definition_modes_list.push_back(trg_sql_mode, 00871 &table->mem_root)) 00872 { 00873 DBUG_RETURN(1); // EOM 00874 } 00875 } 00876 it.rewind(); 00877 } 00878 00879 if (triggers->definers_list.is_empty() && 00880 !triggers->definitions_list.is_empty()) 00881 { 00882 /* 00883 It is old file format => we should fill list of definers. 00884 00885 If there is no definer information, we should not switch context to 00886 definer when checking privileges. I.e. privileges for such triggers 00887 are checked for "invoker" rather than for "definer". 00888 */ 00889 00890 LEX_STRING *trg_definer; 00891 00892 if (! (trg_definer= (LEX_STRING*)alloc_root(&table->mem_root, 00893 sizeof(LEX_STRING)))) 00894 DBUG_RETURN(1); // EOM 00895 00896 trg_definer->str= (char*) ""; 00897 trg_definer->length= 0; 00898 00899 while (it++) 00900 { 00901 if (triggers->definers_list.push_back(trg_definer, 00902 &table->mem_root)) 00903 { 00904 DBUG_RETURN(1); // EOM 00905 } 00906 } 00907 00908 it.rewind(); 00909 } 00910 00911 DBUG_ASSERT(triggers->definition_modes_list.elements == 00912 triggers->definitions_list.elements); 00913 DBUG_ASSERT(triggers->definers_list.elements == 00914 triggers->definitions_list.elements); 00915 00916 table->triggers= triggers; 00917 00918 /* 00919 Construct key that will represent triggers for this table in the set 00920 of routines used by statement. 00921 */ 00922 triggers->sroutines_key.length= 1+strlen(db)+1+strlen(table_name)+1; 00923 if (!(triggers->sroutines_key.str= 00924 alloc_root(&table->mem_root, triggers->sroutines_key.length))) 00925 DBUG_RETURN(1); 00926 triggers->sroutines_key.str[0]= TYPE_ENUM_TRIGGER; 00927 strxmov(triggers->sroutines_key.str+1, db, ".", table_name, NullS); 00928 00929 /* 00930 TODO: This could be avoided if there is no triggers 00931 for UPDATE and DELETE. 00932 */ 00933 if (!names_only && triggers->prepare_record1_accessors(table)) 00934 DBUG_RETURN(1); 00935 00936 List_iterator_fast<ulonglong> itm(triggers->definition_modes_list); 00937 List_iterator_fast<LEX_STRING> it_definer(triggers->definers_list); 00938 LEX *old_lex= thd->lex, lex; 00939 sp_rcontext *save_spcont= thd->spcont; 00940 ulong save_sql_mode= thd->variables.sql_mode; 00941 LEX_STRING *on_table_name; 00942 00943 thd->lex= &lex; 00944 00945 save_db.str= thd->db; 00946 save_db.length= thd->db_length; 00947 thd->reset_db((char*) db, strlen(db)); 00948 while ((trg_create_str= it++)) 00949 { 00950 trg_sql_mode= itm++; 00951 LEX_STRING *trg_definer= it_definer++; 00952 00953 thd->variables.sql_mode= (ulong)*trg_sql_mode; 00954 lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length); 00955 00956 thd->spcont= 0; 00957 if (MYSQLparse((void *)thd) || thd->is_fatal_error) 00958 { 00959 /* 00960 Free lex associated resources. 00961 QQ: Do we really need all this stuff here ? 00962 */ 00963 delete lex.sphead; 00964 goto err_with_lex_cleanup; 00965 } 00966 00967 lex.sphead->set_info(0, 0, &lex.sp_chistics, *trg_sql_mode); 00968 00969 triggers->bodies[lex.trg_chistics.event] 00970 [lex.trg_chistics.action_time]= lex.sphead; 00971 00972 if (!trg_definer->length) 00973 { 00974 /* 00975 This trigger was created/imported from the previous version of 00976 MySQL, which does not support triggers definers. We should emit 00977 warning here. 00978 */ 00979 00980 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 00981 ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER), 00982 (const char*) db, 00983 (const char*) lex.sphead->m_name.str); 00984 00985 /* 00986 Set definer to the '' to correct displaying in the information 00987 schema. 00988 */ 00989 00990 lex.sphead->set_definer((char*) "", 0); 00991 00992 /* 00993 Triggers without definer information are executed under the 00994 authorization of the invoker. 00995 */ 00996 00997 lex.sphead->m_chistics->suid= SP_IS_NOT_SUID; 00998 } 00999 else 01000 lex.sphead->set_definer(trg_definer->str, trg_definer->length); 01001 01002 if (triggers->names_list.push_back(&lex.sphead->m_name, 01003 &table->mem_root)) 01004 goto err_with_lex_cleanup; 01005 01006 if (!(on_table_name= (LEX_STRING*) alloc_root(&table->mem_root, 01007 sizeof(LEX_STRING)))) 01008 goto err_with_lex_cleanup; 01009 *on_table_name= lex.ident; 01010 if (triggers->on_table_names_list.push_back(on_table_name, &table->mem_root)) 01011 goto err_with_lex_cleanup; 01012 01013 /* 01014 Let us check that we correctly update trigger definitions when we 01015 rename tables with triggers. 01016 */ 01017 DBUG_ASSERT(!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) && 01018 !my_strcasecmp(table_alias_charset, lex.query_tables->table_name, 01019 table_name)); 01020 01021 if (names_only) 01022 { 01023 lex_end(&lex); 01024 continue; 01025 } 01026 01027 /* 01028 Gather all Item_trigger_field objects representing access to fields 01029 in old/new versions of row in trigger into lists containing all such 01030 objects for the triggers with same action and timing. 01031 */ 01032 triggers->trigger_fields[lex.trg_chistics.event] 01033 [lex.trg_chistics.action_time]= 01034 (Item_trigger_field *)(lex.trg_table_fields.first); 01035 /* 01036 Also let us bind these objects to Field objects in table being 01037 opened. 01038 01039 We ignore errors here, because if even something is wrong we still 01040 will be willing to open table to perform some operations (e.g. 01041 SELECT)... 01042 Anyway some things can be checked only during trigger execution. 01043 */ 01044 for (Item_trigger_field *trg_field= 01045 (Item_trigger_field *)(lex.trg_table_fields.first); 01046 trg_field; 01047 trg_field= trg_field->next_trg_field) 01048 { 01049 trg_field->setup_field(thd, table, 01050 &triggers->subject_table_grants[lex.trg_chistics.event] 01051 [lex.trg_chistics.action_time]); 01052 } 01053 01054 lex_end(&lex); 01055 } 01056 thd->reset_db(save_db.str, save_db.length); 01057 thd->lex= old_lex; 01058 thd->spcont= save_spcont; 01059 thd->variables.sql_mode= save_sql_mode; 01060 01061 DBUG_RETURN(0); 01062 01063 err_with_lex_cleanup: 01064 // QQ: anything else ? 01065 lex_end(&lex); 01066 thd->lex= old_lex; 01067 thd->spcont= save_spcont; 01068 thd->variables.sql_mode= save_sql_mode; 01069 thd->reset_db(save_db.str, save_db.length); 01070 DBUG_RETURN(1); 01071 } 01072 01073 /* 01074 We don't care about this error message much because .TRG files will 01075 be merged into .FRM anyway. 01076 */ 01077 my_error(ER_WRONG_OBJECT, MYF(0), 01078 table_name, triggers_file_ext+1, "TRIGGER"); 01079 DBUG_RETURN(1); 01080 } 01081 01082 DBUG_RETURN(1); 01083 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool Table_triggers_list::create_trigger | ( | THD * | thd, | |
| TABLE_LIST * | table, | |||
| LEX_STRING * | definer_user, | |||
| LEX_STRING * | definer_host | |||
| ) |
Definition at line 360 of file sql_trigger.cc.
References access, alloc_root(), bodies, build_table_filename(), check_global_access(), create_default_definer(), st_table_list::db, st_table_share::db, definers_list, definition_modes_list, definitions_list, ER, ER_NO_SUCH_USER, ER_NOT_SUPPORTED_YET, ER_SPECIFIC_ACCESS_DENIED_ERROR, ER_TRG_ALREADY_EXISTS, ER_TRG_IN_WRONG_SCHEMA, F_OK, st_table::field, Item_trigger_field::fix_fields(), Item::fixed, FN_REFLEN, is_acl_user(), LEX_STRING::length, st_table::mem_root, my_delete(), my_error(), my_strcasecmp, MY_WME, MYF, name, new_field, Item_trigger_field::next_trg_field, NULL, NullS, old_field, List< T >::push_back(), push_warning_printf(), st_table::s, Item_trigger_field::setup_field(), sql_create_definition_file(), LEX_STRING::str, strcmp(), strxmov(), SUPER_ACL, system_charset_info, st_table_list::table, table, table_alias_charset, st_table_list::table_name, st_table_list::table_name_length, st_trigname::trigger_table, triggers_file_ext, triggers_file_parameters, triggers_file_type, trigname_file_ext, trigname_file_parameters, trigname_file_type, TRUE, USER_HOST_BUFF_SIZE, and MYSQL_ERROR::WARN_LEVEL_NOTE.
Referenced by mysql_create_or_drop_trigger().
00363 { 00364 LEX *lex= thd->lex; 00365 TABLE *table= tables->table; 00366 char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN]; 00367 LEX_STRING file, trigname_file; 00368 LEX_STRING *trg_def, *name; 00369 ulonglong *trg_sql_mode; 00370 char trg_definer_holder[USER_HOST_BUFF_SIZE]; 00371 LEX_STRING *trg_definer; 00372 Item_trigger_field *trg_field; 00373 struct st_trigname trigname; 00374 00375 00376 /* Trigger must be in the same schema as target table. */ 00377 if (my_strcasecmp(table_alias_charset, table->s->db.str, 00378 lex->spname->m_db.str)) 00379 { 00380 my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0)); 00381 return 1; 00382 } 00383 00384 /* We don't allow creation of several triggers of the same type yet */ 00385 if (bodies[lex->trg_chistics.event][lex->trg_chistics.action_time]) 00386 { 00387 my_error(ER_NOT_SUPPORTED_YET, MYF(0), 00388 "multiple triggers with the same action time" 00389 " and event for one table"); 00390 return 1; 00391 } 00392 00393 if (!lex->definer) 00394 { 00395 /* 00396 DEFINER-clause is missing. 00397 00398 If we are in slave thread, this means that we received CREATE TRIGGER 00399 from the master, that does not support definer in triggers. So, we 00400 should mark this trigger as non-SUID. Note that this does not happen 00401 when we parse triggers' definitions during opening .TRG file. 00402 LEX::definer is ignored in that case. 00403 00404 Otherwise, we should use CURRENT_USER() as definer. 00405 00406 NOTE: when CREATE TRIGGER statement is allowed to be executed in PS/SP, 00407 it will be required to create the definer below in persistent MEM_ROOT 00408 of PS/SP. 00409 */ 00410 00411 if (!thd->slave_thread) 00412 { 00413 if (!(lex->definer= create_default_definer(thd))) 00414 return 1; 00415 } 00416 } 00417 00418 /* 00419 If the specified definer differs from the current user, we should check 00420 that the current user has SUPER privilege (in order to create trigger 00421 under another user one must have SUPER privilege). 00422 */ 00423 00424 if (lex->definer && 00425 (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) || 00426 my_strcasecmp(system_charset_info, 00427 lex->definer->host.str, 00428 thd->security_ctx->priv_host))) 00429 { 00430 if (check_global_access(thd, SUPER_ACL)) 00431 { 00432 my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER"); 00433 return TRUE; 00434 } 00435 } 00436 00437 /* 00438 Let us check if all references to fields in old/new versions of row in 00439 this trigger are ok. 00440 00441 NOTE: We do it here more from ease of use standpoint. We still have to 00442 do some checks on each execution. E.g. we can catch privilege changes 00443 only during execution. Also in near future, when we will allow access 00444 to other tables from trigger we won't be able to catch changes in other 00445 tables... 00446 00447 Since we don't plan to access to contents of the fields it does not 00448 matter that we choose for both OLD and NEW values the same versions 00449 of Field objects here. 00450 */ 00451 old_field= new_field= table->field; 00452 00453 for (trg_field= (Item_trigger_field *)(lex->trg_table_fields.first); 00454 trg_field; trg_field= trg_field->next_trg_field) 00455 { 00456 /* 00457 NOTE: now we do not check privileges at CREATE TRIGGER time. This will 00458 be changed in the future. 00459 */ 00460 trg_field->setup_field(thd, table, NULL); 00461 00462 if (!trg_field->fixed && 00463 trg_field->fix_fields(thd, (Item **)0)) 00464 return 1; 00465 } 00466 00467 /* 00468 Here we are creating file with triggers and save all triggers in it. 00469 sql_create_definition_file() files handles renaming and backup of older 00470 versions 00471 */ 00472 file.length= build_table_filename(file_buff, FN_REFLEN-1, 00473 tables->db, tables->table_name, 00474 triggers_file_ext, 0); 00475 file.str= file_buff; 00476 trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, 00477 tables->db, 00478 lex->spname->m_name.str, 00479 trigname_file_ext, 0); 00480 trigname_file.str= trigname_buff; 00481 00482 /* Use the filesystem to enforce trigger namespace constraints. */ 00483 if (!access(trigname_buff, F_OK)) 00484 { 00485 my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); 00486 return 1; 00487 } 00488 00489 trigname.trigger_table.str= tables->table_name; 00490 trigname.trigger_table.length= tables->table_name_length; 00491 00492 if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, 00493 (gptr)&trigname, trigname_file_parameters, 0)) 00494 return 1; 00495 00496 /* 00497 Soon we will invalidate table object and thus Table_triggers_list object 00498 so don't care about place to which trg_def->ptr points and other 00499 invariants (e.g. we don't bother to update names_list) 00500 00501 QQ: Hmm... probably we should not care about setting up active thread 00502 mem_root too. 00503 */ 00504 if (!(trg_def= (LEX_STRING *)alloc_root(&table->mem_root, 00505 sizeof(LEX_STRING))) || 00506 definitions_list.push_back(trg_def, &table->mem_root) || 00507 !(trg_sql_mode= (ulonglong*)alloc_root(&table->mem_root, 00508 sizeof(ulonglong))) || 00509 definition_modes_list.push_back(trg_sql_mode, &table->mem_root) || 00510 !(trg_definer= (LEX_STRING*) alloc_root(&table->mem_root, 00511 sizeof(LEX_STRING))) || 00512 definers_list.push_back(trg_definer, &table->mem_root)) 00513 goto err_with_cleanup; 00514 00515 trg_def->str= thd->query; 00516 trg_def->length= thd->query_length; 00517 *trg_sql_mode= thd->variables.sql_mode; 00518 00519 #ifndef NO_EMBEDDED_ACCESS_CHECKS 00520 if (lex->definer && !is_acl_user(lex->definer->host.str, 00521 lex->definer->user.str)) 00522 { 00523 push_warning_printf(thd, 00524 MYSQL_ERROR::WARN_LEVEL_NOTE, 00525 ER_NO_SUCH_USER, 00526 ER(ER_NO_SUCH_USER), 00527 lex->definer->user.str, 00528 lex->definer->host.str); 00529 } 00530 #endif /* NO_EMBEDDED_ACCESS_CHECKS */ 00531 00532 if (lex->definer) 00533 { 00534 /* SUID trigger. */ 00535 00536 *definer_user= lex->definer->user; 00537 *definer_host= lex->definer->host; 00538 00539 trg_definer->str= trg_definer_holder; 00540 trg_definer->length= strxmov(trg_definer->str, definer_user->str, "@", 00541 definer_host->str, NullS) - trg_definer->str; 00542 } 00543 else 00544 { 00545 /* non-SUID trigger. */ 00546 00547 definer_user->str= 0; 00548 definer_user->length= 0; 00549 00550 definer_host->str= 0; 00551 definer_host->length= 0; 00552 00553 trg_definer->str= (char*) ""; 00554 trg_definer->length= 0; 00555 } 00556 00557 if (!sql_create_definition_file(NULL, &file, &triggers_file_type, 00558 (gptr)this, triggers_file_parameters, 0)) 00559 return 0; 00560 00561 err_with_cleanup: 00562 my_delete(trigname_buff, MYF(MY_WME)); 00563 return 1; 00564 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool Table_triggers_list::drop_all_triggers | ( | THD * | thd, | |
| char * | db, | |||
| char * | table_name | |||
| ) | [static] |
Definition at line 1215 of file sql_trigger.cc.
References bzero, check_n_load(), DBUG_ENTER, DBUG_RETURN, FN_REFLEN, free_root(), init_alloc_root(), LOCK_open, MYF, path, rm_trigger_file(), rm_trigname_file(), safe_mutex_assert_owner, LEX_STRING::str, and table.
Referenced by mysql_rm_table_part2().
01216 { 01217 TABLE table; 01218 char path[FN_REFLEN]; 01219 bool result= 0; 01220 DBUG_ENTER("drop_all_triggers"); 01221 01222 bzero(&table, sizeof(table)); 01223 init_alloc_root(&table.mem_root, 8192, 0); 01224 01225 safe_mutex_assert_owner(&LOCK_open); 01226 01227 if (Table_triggers_list::check_n_load(thd, db, name, &table, 1)) 01228 { 01229 result= 1; 01230 goto end; 01231 } 01232 if (table.triggers) 01233 { 01234 LEX_STRING *trigger; 01235 List_iterator_fast<LEX_STRING> it_name(table.triggers->names_list); 01236 01237 while ((trigger= it_name++)) 01238 { 01239 if (rm_trigname_file(path, db, trigger->str)) 01240 { 01241 /* 01242 Instead of immediately bailing out with error if we were unable 01243 to remove .TRN file we will try to drop other files. 01244 */ 01245 result= 1; 01246 continue; 01247 } 01248 } 01249 01250 if (rm_trigger_file(path, db, name)) 01251 { 01252 result= 1; 01253 goto end; 01254 } 01255 } 01256 end: 01257 if (table.triggers) 01258 delete table.triggers; 01259 free_root(&table.mem_root, MYF(0)); 01260 DBUG_RETURN(result); 01261 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool Table_triggers_list::drop_trigger | ( | THD * | thd, | |
| TABLE_LIST * | table | |||
| ) |
Definition at line 656 of file sql_trigger.cc.
References st_table_list::db, definers_list, definition_modes_list, definitions_list, ER, ER_TRG_DOES_NOT_EXIST, FN_REFLEN, base_list::is_empty(), my_message(), my_strcasecmp, MYF, name, names_list, path, List_iterator< T >::remove(), rm_trigger_file(), rm_trigname_file(), save_trigger_file(), table_alias_charset, and st_table_list::table_name.
Referenced by mysql_create_or_drop_trigger().
00657 { 00658 LEX *lex= thd->lex; 00659 LEX_STRING *name; 00660 List_iterator_fast<LEX_STRING> it_name(names_list); 00661 List_iterator<LEX_STRING> it_def(definitions_list); 00662 List_iterator<ulonglong> it_mod(definition_modes_list); 00663 List_iterator<LEX_STRING> it_definer(definers_list); 00664 char path[FN_REFLEN]; 00665 00666 while ((name= it_name++)) 00667 { 00668 it_def++; 00669 it_mod++; 00670 it_definer++; 00671 00672 if (my_strcasecmp(table_alias_charset, lex->spname->m_name.str, 00673 name->str) == 0) 00674 { 00675 /* 00676 Again we don't care much about other things required for 00677 clean trigger removing since table will be reopened anyway. 00678 */ 00679 it_def.remove(); 00680 it_mod.remove(); 00681 it_definer.remove(); 00682 00683 if (definitions_list.is_empty()) 00684 { 00685 /* 00686 TODO: Probably instead of removing .TRG file we should move 00687 to archive directory but this should be done as part of 00688 parse_file.cc functionality (because we will need it 00689 elsewhere). 00690 */ 00691 if (rm_trigger_file(path, tables->db, tables->table_name)) 00692 return 1; 00693 } 00694 else 00695 { 00696 if (save_trigger_file(this, tables->db, tables->table_name)) 00697 return 1; 00698 } 00699 00700 if (rm_trigname_file(path, tables->db, lex->spname->m_name.str)) 00701 return 1; 00702 return 0; 00703 } 00704 } 00705 00706 my_message(ER_TRG_DOES_NOT_EXIST, ER(ER_TRG_DOES_NOT_EXIST), MYF(0)); 00707 return 1; 00708 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool Table_triggers_list::get_trigger_info | ( | THD * | thd, | |
| trg_event_type | event, | |||
| trg_action_time_type | time_type, | |||
| LEX_STRING * | trigger_name, | |||
| LEX_STRING * | trigger_stmt, | |||
| ulong * | sql_mode, | |||
| LEX_STRING * | definer | |||
| ) |
Definition at line 1106 of file sql_trigger.cc.
References bodies, DBUG_ENTER, DBUG_RETURN, LEX_STRING::length, sp_head::m_body, sp_head::m_chistics, sp_head::m_definer_host, sp_head::m_definer_user, sp_head::m_name, sp_head::m_sql_mode, NullS, LEX_STRING::str, and strxmov().
Referenced by get_schema_triggers_record().
01112 { 01113 sp_head *body; 01114 DBUG_ENTER("get_trigger_info"); 01115 if ((body= bodies[event][time_type])) 01116 { 01117 *trigger_name= body->m_name; 01118 *trigger_stmt= body->m_body; 01119 *sql_mode= body->m_sql_mode; 01120 01121 if (body->m_chistics->suid == SP_IS_NOT_SUID) 01122 { 01123 definer->str[0]= 0; 01124 definer->length= 0; 01125 } 01126 else 01127 { 01128 definer->length= strxmov(definer->str, body->m_definer_user.str, "@", 01129 body->m_definer_host.str, NullS) - definer->str; 01130 } 01131 01132 DBUG_RETURN(0); 01133 } 01134 DBUG_RETURN(1); 01135 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool Table_triggers_list::has_before_update_triggers | ( | ) | [inline] |
Definition at line 121 of file sql_trigger.h.
References bodies, test, TRG_ACTION_BEFORE, and TRG_EVENT_UPDATE.
Referenced by safe_update_on_fly().
00122 { 00123 return test(bodies[TRG_EVENT_UPDATE][TRG_ACTION_BEFORE]); 00124 }
Here is the caller graph for this function:

| bool Table_triggers_list::has_delete_triggers | ( | ) | [inline] |
Definition at line 115 of file sql_trigger.h.
References bodies, TRG_ACTION_AFTER, TRG_ACTION_BEFORE, and TRG_EVENT_DELETE.
Referenced by delayed_insert::handle_inserts(), mysql_delete(), mysql_insert(), mysql_load(), and write_record().
00116 { 00117 return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || 00118 bodies[TRG_EVENT_DELETE][TRG_ACTION_AFTER]); 00119 }
Here is the caller graph for this function:

| void Table_triggers_list::mark_fields_used | ( | trg_event_type | event | ) |
Definition at line 1565 of file sql_trigger.cc.
References bitmap_set_bit(), Item_trigger_field::field_idx, Item_trigger_field::get_settable_routine_parameter(), int(), Item_trigger_field::next_trg_field, st_table::read_set, table, TRG_ACTION_MAX, trigger_fields, and st_table::write_set.
Referenced by st_table::mark_columns_needed_for_delete(), st_table::mark_columns_needed_for_insert(), and st_table::mark_columns_needed_for_update().
01566 { 01567 int action_time; 01568 Item_trigger_field *trg_field; 01569 01570 for (action_time= 0; action_time < (int)TRG_ACTION_MAX; action_time++) 01571 { 01572 for (trg_field= trigger_fields[event][action_time]; trg_field; 01573 trg_field= trg_field->next_trg_field) 01574 { 01575 /* We cannot mark fields which does not present in table. */ 01576 if (trg_field->field_idx != (uint)-1) 01577 { 01578 bitmap_set_bit(table->read_set, trg_field->field_idx); 01579 if (trg_field->get_settable_routine_parameter()) 01580 bitmap_set_bit(table->write_set, trg_field->field_idx); 01581 } 01582 } 01583 } 01584 table->file->column_bitmaps_signal(); 01585 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 736 of file sql_trigger.cc.
References alloc_root(), st_table::field, st_table_share::fields, st_table::mem_root, Field::new_field(), st_table::record, record1_field, st_table::s, and table.
00737 { 00738 Field **fld, **old_fld; 00739 00740 if (!(record1_field= (Field **)alloc_root(&table->mem_root, 00741 (table->s->fields + 1) * 00742 sizeof(Field*)))) 00743 return 1; 00744 00745 for (fld= table->field, old_fld= record1_field; *fld; fld++, old_fld++) 00746 { 00747 /* 00748 QQ: it is supposed that it is ok to use this function for field 00749 cloning... 00750 */ 00751 if (!(*old_fld= (*fld)->new_field(&table->mem_root, table, 00752 table == (*fld)->table))) 00753 return 1; 00754 (*old_fld)->move_field_offset((my_ptrdiff_t)(table->record[1] - 00755 table->record[0])); 00756 } 00757 *old_fld= 0; 00758 00759 return 0; 00760 }
Here is the call graph for this function:

| bool Table_triggers_list::process_triggers | ( | THD * | thd, | |
| trg_event_type | event, | |||
| trg_action_time_type | time_type, | |||
| bool | old_row_is_record1 | |||
| ) |
Definition at line 1482 of file sql_trigger.cc.
References bodies, st_table_share::db, ER_TABLEACCESS_DENIED_ERROR, sp_head::execute_trigger(), FALSE, st_table::field, fill_effective_table_privileges(), get_privilege_desc(), my_error(), MYF, new_field, old_field, record1_field, st_table::s, sp_change_security_context(), sp_restore_security_context(), LEX_STRING::str, subject_table_grants, table, st_table_share::table_name, TRIGGER_ACL, and TRUE.
Referenced by fill_record_n_invoke_before_triggers(), mysql_delete(), and write_record().
01485 { 01486 bool err_status= FALSE; 01487 sp_head *sp_trigger= bodies[event][time_type]; 01488 01489 if (sp_trigger) 01490 { 01491 Sub_statement_state statement_state; 01492 01493 if (old_row_is_record1) 01494 { 01495 old_field= record1_field; 01496 new_field= table->field; 01497 } 01498 else 01499 { 01500 new_field= record1_field; 01501 old_field= table->field; 01502 } 01503 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01504 Security_context *save_ctx; 01505 01506 if (sp_change_security_context(thd, sp_trigger, &save_ctx)) 01507 return TRUE; 01508 01509 /* 01510 Fetch information about table-level privileges to GRANT_INFO structure for 01511 subject table. Check of privileges that will use it and information about 01512 column-level privileges will happen in Item_trigger_field::fix_fields(). 01513 */ 01514 01515 fill_effective_table_privileges(thd, 01516 &subject_table_grants[event][time_type], 01517 table->s->db.str, table->s->table_name.str); 01518 01519 /* Check that the definer has TRIGGER privilege on the subject table. */ 01520 01521 if (!(subject_table_grants[event][time_type].privilege & TRIGGER_ACL)) 01522 { 01523 char priv_desc[128]; 01524 get_privilege_desc(priv_desc, sizeof(priv_desc), TRIGGER_ACL); 01525 01526 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), priv_desc, 01527 thd->security_ctx->priv_user, thd->security_ctx->host_or_ip, 01528 table->s->table_name.str); 01529 01530 sp_restore_security_context(thd, save_ctx); 01531 return TRUE; 01532 } 01533 #endif // NO_EMBEDDED_ACCESS_CHECKS 01534 01535 thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER); 01536 err_status= sp_trigger->execute_trigger 01537 (thd, table->s->db.str, table->s->table_name.str, 01538 &subject_table_grants[event][time_type]); 01539 thd->restore_sub_statement_state(&statement_state); 01540 01541 #ifndef NO_EMBEDDED_ACCESS_CHECKS 01542 sp_restore_security_context(thd, save_ctx); 01543 #endif // NO_EMBEDDED_ACCESS_CHECKS 01544 } 01545 01546 return err_status; 01547 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void Table_triggers_list::set_table | ( | TABLE * | new_table | ) |
Definition at line 771 of file sql_trigger.cc.
References st_table::alias, record1_field, table, and st_table::triggers.
Referenced by reopen_table().
00772 { 00773 table= new_table; 00774 for (Field **field= table->triggers->record1_field ; *field ; field++) 00775 { 00776 (*field)->table= (*field)->orig_table= new_table; 00777 (*field)->table_name= &new_table->alias; 00778 } 00779 }
Here is the caller graph for this function:

friend class Item_trigger_field [friend] |
Definition at line 130 of file sql_trigger.h.
| int sp_cache_routines_and_add_tables_for_triggers | ( | THD * | thd, | |
| LEX * | lex, | |||
| TABLE_LIST * | table | |||
| ) | [friend] |
Definition at line 1722 of file sp.cc.
01724 { 01725 int ret= 0; 01726 Table_triggers_list *triggers= table->table->triggers; 01727 if (add_used_routine(lex, thd->stmt_arena, &triggers->sroutines_key, 01728 table->belong_to_view)) 01729 { 01730 Sroutine_hash_entry **last_cached_routine_ptr= 01731 (Sroutine_hash_entry **)lex->sroutines_list.next; 01732 for (int i= 0; i < (int)TRG_EVENT_MAX; i++) 01733 { 01734 for (int j= 0; j < (int)TRG_ACTION_MAX; j++) 01735 { 01736 sp_head *trigger_body= triggers->bodies[i][j]; 01737 if (trigger_body) 01738 { 01739 (void)trigger_body-> 01740 add_used_tables_to_table_list(thd, &lex->query_tables_last, 01741 table->belong_to_view); 01742 sp_update_stmt_used_routines(thd, lex, 01743 &trigger_body->m_sroutines, 01744 table->belong_to_view); 01745 trigger_body->propagate_attributes(lex); 01746 } 01747 } 01748 } 01749 ret= sp_cache_routines_and_add_tables_aux(thd, lex, 01750 *last_cached_routine_ptr, FALSE); 01751 } 01752 return ret; 01753 }
sp_head* Table_triggers_list::bodies[TRG_EVENT_MAX][TRG_ACTION_MAX] [private] |
Definition at line 27 of file sql_trigger.h.
Referenced by create_trigger(), get_trigger_info(), has_before_update_triggers(), has_delete_triggers(), process_triggers(), sp_cache_routines_and_add_tables_for_triggers(), Table_triggers_list(), and ~Table_triggers_list().
Definition at line 84 of file sql_trigger.h.
Referenced by check_n_load(), create_trigger(), and drop_trigger().
Definition at line 82 of file sql_trigger.h.
Referenced by change_table_name_in_triggers(), check_n_load(), create_trigger(), and drop_trigger().
Definition at line 78 of file sql_trigger.h.
Referenced by change_table_name_in_triggers(), create_trigger(), and drop_trigger().
List<LEX_STRING> Table_triggers_list::names_list [private] |
Definition at line 53 of file sql_trigger.h.
Referenced by change_table_name_in_trignames(), and drop_trigger().
Field** Table_triggers_list::new_field [private] |
Definition at line 44 of file sql_trigger.h.
Referenced by create_trigger(), Item_trigger_field::fix_fields(), and process_triggers().
Field** Table_triggers_list::old_field [private] |
Definition at line 45 of file sql_trigger.h.
Referenced by create_trigger(), Item_trigger_field::fix_fields(), and process_triggers().
Field** Table_triggers_list::record1_field [private] |
Definition at line 38 of file sql_trigger.h.
Referenced by prepare_record1_accessors(), process_triggers(), set_table(), and ~Table_triggers_list().
LEX_STRING Table_triggers_list::sroutines_key [private] |
Definition at line 66 of file sql_trigger.h.
Referenced by check_n_load(), and sp_cache_routines_and_add_tables_for_triggers().
GRANT_INFO Table_triggers_list::subject_table_grants[TRG_EVENT_MAX][TRG_ACTION_MAX] [private] |
Definition at line 71 of file sql_trigger.h.
Referenced by process_triggers(), and Table_triggers_list().
TABLE* Table_triggers_list::table [private] |
Definition at line 47 of file sql_trigger.h.
Referenced by change_table_name(), change_table_name_in_triggers(), check_n_load(), create_trigger(), drop_all_triggers(), Item_trigger_field::fix_fields(), mark_fields_used(), prepare_record1_accessors(), process_triggers(), and set_table().
Item_trigger_field* Table_triggers_list::trigger_fields[TRG_EVENT_MAX][TRG_ACTION_MAX] [private] |
Definition at line 32 of file sql_trigger.h.
Referenced by mark_fields_used(), and Table_triggers_list().
1.4.7

