The world's most popular open source database
00001 /* Copyright (C) 2004-2005 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 #define MYSQL_LEX 1 00019 #include "mysql_priv.h" 00020 #include "sp_head.h" 00021 #include "sql_trigger.h" 00022 #include "parse_file.h" 00023 00024 static const LEX_STRING triggers_file_type= 00025 { C_STRING_WITH_LEN("TRIGGERS") }; 00026 00027 const char * const triggers_file_ext= ".TRG"; 00028 00029 /* 00030 Table of .TRG file field descriptors. 00031 We have here only one field now because in nearest future .TRG 00032 files will be merged into .FRM files (so we don't need something 00033 like md5 or created fields). 00034 */ 00035 static File_option triggers_file_parameters[]= 00036 { 00037 { 00038 { C_STRING_WITH_LEN("triggers") }, 00039 offsetof(class Table_triggers_list, definitions_list), 00040 FILE_OPTIONS_STRLIST 00041 }, 00042 { 00043 { C_STRING_WITH_LEN("sql_modes") }, 00044 offsetof(class Table_triggers_list, definition_modes_list), 00045 FILE_OPTIONS_ULLLIST 00046 }, 00047 { 00048 { C_STRING_WITH_LEN("definers") }, 00049 offsetof(class Table_triggers_list, definers_list), 00050 FILE_OPTIONS_STRLIST 00051 }, 00052 { { 0, 0 }, 0, FILE_OPTIONS_STRING } 00053 }; 00054 00055 File_option sql_modes_parameters= 00056 { 00057 { C_STRING_WITH_LEN("sql_modes") }, 00058 offsetof(class Table_triggers_list, definition_modes_list), 00059 FILE_OPTIONS_ULLLIST 00060 }; 00061 00062 /* 00063 This must be kept up to date whenever a new option is added to the list 00064 above, as it specifies the number of required parameters of the trigger in 00065 .trg file. 00066 */ 00067 00068 static const int TRG_NUM_REQUIRED_PARAMETERS= 4; 00069 00070 /* 00071 Structure representing contents of .TRN file which are used to support 00072 database wide trigger namespace. 00073 */ 00074 00075 struct st_trigname 00076 { 00077 LEX_STRING trigger_table; 00078 }; 00079 00080 static const LEX_STRING trigname_file_type= 00081 { C_STRING_WITH_LEN("TRIGGERNAME") }; 00082 00083 const char * const trigname_file_ext= ".TRN"; 00084 00085 static File_option trigname_file_parameters[]= 00086 { 00087 { 00088 { C_STRING_WITH_LEN("trigger_table")}, 00089 offsetof(struct st_trigname, trigger_table), 00090 FILE_OPTIONS_ESTRING 00091 }, 00092 { { 0, 0 }, 0, FILE_OPTIONS_STRING } 00093 }; 00094 00095 00096 const LEX_STRING trg_action_time_type_names[]= 00097 { 00098 { C_STRING_WITH_LEN("BEFORE") }, 00099 { C_STRING_WITH_LEN("AFTER") } 00100 }; 00101 00102 const LEX_STRING trg_event_type_names[]= 00103 { 00104 { C_STRING_WITH_LEN("INSERT") }, 00105 { C_STRING_WITH_LEN("UPDATE") }, 00106 { C_STRING_WITH_LEN("DELETE") } 00107 }; 00108 00109 00110 static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig); 00111 00112 class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook 00113 { 00114 private: 00115 char *path; 00116 public: 00117 Handle_old_incorrect_sql_modes_hook(char *file_path) 00118 :path(file_path) 00119 {}; 00120 virtual bool process_unknown_string(char *&unknown_key, gptr base, 00121 MEM_ROOT *mem_root, char *end); 00122 }; 00123 00124 class Handle_old_incorrect_trigger_table_hook: public Unknown_key_hook 00125 { 00126 public: 00127 Handle_old_incorrect_trigger_table_hook(char *file_path, 00128 LEX_STRING *trigger_table_arg) 00129 :path(file_path), trigger_table_value(trigger_table_arg) 00130 {}; 00131 virtual bool process_unknown_string(char *&unknown_key, gptr base, 00132 MEM_ROOT *mem_root, char *end); 00133 private: 00134 char *path; 00135 LEX_STRING *trigger_table_value; 00136 }; 00137 00138 /* 00139 Create or drop trigger for table. 00140 00141 SYNOPSIS 00142 mysql_create_or_drop_trigger() 00143 thd - current thread context (including trigger definition in LEX) 00144 tables - table list containing one table for which trigger is created. 00145 create - whenever we create (TRUE) or drop (FALSE) trigger 00146 00147 NOTE 00148 This function is mainly responsible for opening and locking of table and 00149 invalidation of all its instances in table cache after trigger creation. 00150 Real work on trigger creation/dropping is done inside Table_triggers_list 00151 methods. 00152 00153 RETURN VALUE 00154 FALSE Success 00155 TRUE error 00156 */ 00157 bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) 00158 { 00159 TABLE *table; 00160 bool result= TRUE; 00161 LEX_STRING definer_user; 00162 LEX_STRING definer_host; 00163 00164 DBUG_ENTER("mysql_create_or_drop_trigger"); 00165 00166 /* 00167 QQ: This function could be merged in mysql_alter_table() function 00168 But do we want this ? 00169 */ 00170 00171 /* 00172 Note that once we will have check for TRIGGER privilege in place we won't 00173 need second part of condition below, since check_access() function also 00174 checks that db is specified. 00175 */ 00176 if (!thd->lex->spname->m_db.length || create && !tables->db_length) 00177 { 00178 my_error(ER_NO_DB_ERROR, MYF(0)); 00179 DBUG_RETURN(TRUE); 00180 } 00181 00182 if (!create && 00183 !(tables= add_table_for_trigger(thd, thd->lex->spname))) 00184 DBUG_RETURN(TRUE); 00185 00186 /* 00187 We don't allow creating triggers on tables in the 'mysql' schema 00188 */ 00189 if (create && !my_strcasecmp(system_charset_info, "mysql", tables->db)) 00190 { 00191 my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0)); 00192 DBUG_RETURN(TRUE); 00193 } 00194 00195 /* We should have only one table in table list. */ 00196 DBUG_ASSERT(tables->next_global == 0); 00197 00198 /* 00199 Check that the user has TRIGGER privilege on the subject table. 00200 */ 00201 { 00202 bool err_status; 00203 TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last; 00204 thd->lex->query_tables_own_last= 0; 00205 00206 err_status= check_table_access(thd, TRIGGER_ACL, tables, 0); 00207 00208 thd->lex->query_tables_own_last= save_query_tables_own_last; 00209 00210 if (err_status) 00211 DBUG_RETURN(TRUE); 00212 } 00213 00214 /* 00215 There is no DETERMINISTIC clause for triggers, so can't check it. 00216 But a trigger can in theory be used to do nasty things (if it supported 00217 DROP for example) so we do the check for privileges. Triggers have the 00218 same nature as functions regarding binlogging: their body is implicitely 00219 binlogged, so they share the same danger, so trust_function_creators 00220 applies to them too. 00221 */ 00222 if (!trust_function_creators && mysql_bin_log.is_open() && 00223 !(thd->security_ctx->master_access & SUPER_ACL)) 00224 { 00225 my_error(ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, MYF(0)); 00226 DBUG_RETURN(TRUE); 00227 } 00228 00229 /* We do not allow creation of triggers on temporary tables. */ 00230 if (create && find_temporary_table(thd, tables)) 00231 { 00232 my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); 00233 DBUG_RETURN(TRUE); 00234 } 00235 00236 /* 00237 We don't want perform our operations while global read lock is held 00238 so we have to wait until its end and then prevent it from occuring 00239 again until we are done. (Acquiring LOCK_open is not enough because 00240 global read lock is held without helding LOCK_open). 00241 */ 00242 if (wait_if_global_read_lock(thd, 0, 1)) 00243 DBUG_RETURN(TRUE); 00244 00245 VOID(pthread_mutex_lock(&LOCK_open)); 00246 00247 if (lock_table_names(thd, tables)) 00248 goto end; 00249 00250 /* We also don't allow creation of triggers on views. */ 00251 tables->required_type= FRMTYPE_TABLE; 00252 00253 if (reopen_name_locked_table(thd, tables)) 00254 { 00255 unlock_table_name(thd, tables); 00256 goto end; 00257 } 00258 table= tables->table; 00259 00260 if (!table->triggers) 00261 { 00262 if (!create) 00263 { 00264 my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); 00265 goto end; 00266 } 00267 00268 if (!(table->triggers= new (&table->mem_root) Table_triggers_list(table))) 00269 goto end; 00270 } 00271 00272 result= (create ? 00273 table->triggers->create_trigger(thd, tables, &definer_user, &definer_host): 00274 table->triggers->drop_trigger(thd, tables)); 00275 00276 end: 00277 VOID(pthread_mutex_unlock(&LOCK_open)); 00278 start_waiting_global_read_lock(thd); 00279 00280 if (!result) 00281 { 00282 if (mysql_bin_log.is_open()) 00283 { 00284 thd->clear_error(); 00285 00286 String log_query(thd->query, thd->query_length, system_charset_info); 00287 00288 if (create) 00289 { 00290 log_query.set((char *) 0, 0, system_charset_info); /* reset log_query */ 00291 00292 log_query.append(STRING_WITH_LEN("CREATE ")); 00293 00294 if (definer_user.str && definer_host.str) 00295 { 00296 /* 00297 Append definer-clause if the trigger is SUID (a usual trigger in 00298 new MySQL versions). 00299 */ 00300 00301 append_definer(thd, &log_query, &definer_user, &definer_host); 00302 } 00303 00304 log_query.append(thd->lex->stmt_definition_begin, 00305 (char *)thd->lex->sphead->m_body_begin - 00306 thd->lex->stmt_definition_begin + 00307 thd->lex->sphead->m_body.length); 00308 } 00309 00310 /* Such a statement can always go directly to binlog, no trans cache. */ 00311 Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), 0, FALSE); 00312 mysql_bin_log.write(&qinfo); 00313 } 00314 00315 send_ok(thd); 00316 } 00317 00318 DBUG_RETURN(result); 00319 } 00320 00321 00322 /* 00323 Create trigger for table. 00324 00325 SYNOPSIS 00326 create_trigger() 00327 thd - current thread context (including trigger definition in 00328 LEX) 00329 tables - table list containing one open table for which the 00330 trigger is created. 00331 definer_user - [out] after a call it points to 0-terminated string or 00332 contains the NULL-string: 00333 - 0-terminated is returned if the trigger is SUID. The 00334 string contains user name part of the actual trigger 00335 definer. 00336 - NULL-string is returned if the trigger is non-SUID. 00337 Anyway, the caller is responsible to provide memory for 00338 storing LEX_STRING object. 00339 definer_host - [out] after a call it points to 0-terminated string or 00340 contains the NULL-string: 00341 - 0-terminated string is returned if the trigger is 00342 SUID. The string contains host name part of the 00343 actual trigger definer. 00344 - NULL-string is returned if the trigger is non-SUID. 00345 Anyway, the caller is responsible to provide memory for 00346 storing LEX_STRING object. 00347 00348 NOTE 00349 - Assumes that trigger name is fully qualified. 00350 - NULL-string means the following LEX_STRING instance: 00351 { str = 0; length = 0 }. 00352 - In other words, definer_user and definer_host should contain 00353 simultaneously NULL-strings (non-SUID/old trigger) or valid strings 00354 (SUID/new trigger). 00355 00356 RETURN VALUE 00357 False - success 00358 True - error 00359 */ 00360 bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, 00361 LEX_STRING *definer_user, 00362 LEX_STRING *definer_host) 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 } 00565 00566 00567 /* 00568 Deletes the .TRG file for a table 00569 00570 SYNOPSIS 00571 rm_trigger_file() 00572 path - char buffer of size FN_REFLEN to be used 00573 for constructing path to .TRG file. 00574 db - table's database name 00575 table_name - table's name 00576 00577 RETURN VALUE 00578 False - success 00579 True - error 00580 */ 00581 00582 static bool rm_trigger_file(char *path, const char *db, 00583 const char *table_name) 00584 { 00585 build_table_filename(path, FN_REFLEN-1, db, table_name, triggers_file_ext, 0); 00586 return my_delete(path, MYF(MY_WME)); 00587 } 00588 00589 00590 /* 00591 Deletes the .TRN file for a trigger 00592 00593 SYNOPSIS 00594 rm_trigname_file() 00595 path - char buffer of size FN_REFLEN to be used 00596 for constructing path to .TRN file. 00597 db - trigger's database name 00598 table_name - trigger's name 00599 00600 RETURN VALUE 00601 False - success 00602 True - error 00603 */ 00604 00605 static bool rm_trigname_file(char *path, const char *db, 00606 const char *trigger_name) 00607 { 00608 build_table_filename(path, FN_REFLEN-1, 00609 db, trigger_name, trigname_file_ext, 0); 00610 return my_delete(path, MYF(MY_WME)); 00611 } 00612 00613 00614 /* 00615 Helper function that saves .TRG file for Table_triggers_list object. 00616 00617 SYNOPSIS 00618 save_trigger_file() 00619 triggers Table_triggers_list object for which file should be saved 00620 db Name of database for subject table 00621 table_name Name of subject table 00622 00623 RETURN VALUE 00624 FALSE Success 00625 TRUE Error 00626 */ 00627 00628 static bool save_trigger_file(Table_triggers_list *triggers, const char *db, 00629 const char *table_name) 00630 { 00631 char file_buff[FN_REFLEN]; 00632 LEX_STRING file; 00633 00634 file.length= build_table_filename(file_buff, FN_REFLEN-1, db, table_name, 00635 triggers_file_ext, 0); 00636 file.str= file_buff; 00637 return sql_create_definition_file(NULL, &file, &triggers_file_type, 00638 (gptr)triggers, triggers_file_parameters, 00639 0); 00640 } 00641 00642 00643 /* 00644 Drop trigger for table. 00645 00646 SYNOPSIS 00647 drop_trigger() 00648 thd - current thread context (including trigger definition in LEX) 00649 tables - table list containing one open table for which trigger is 00650 dropped. 00651 00652 RETURN VALUE 00653 False - success 00654 True - error 00655 */ 00656 bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) 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 } 00709 00710 00711 Table_triggers_list::~Table_triggers_list() 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 } 00721 00722 00723 /* 00724 Prepare array of Field objects referencing to TABLE::record[1] instead 00725 of record[0] (they will represent OLD.* row values in ON UPDATE trigger 00726 and in ON DELETE trigger which will be called during REPLACE execution). 00727 00728 SYNOPSIS 00729 prepare_record1_accessors() 00730 table - pointer to TABLE object for which we are creating fields. 00731 00732 RETURN VALUE 00733 False - success 00734 True - error 00735 */ 00736 bool Table_triggers_list::prepare_record1_accessors(TABLE *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 } 00761 00762 00763 /* 00764 Adjust Table_triggers_list with new TABLE pointer. 00765 00766 SYNOPSIS 00767 set_table() 00768 new_table - new pointer to TABLE instance 00769 */ 00770 00771 void Table_triggers_list::set_table(TABLE *new_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 } 00780 00781 00782 /* 00783 Check whenever .TRG file for table exist and load all triggers it contains. 00784 00785 SYNOPSIS 00786 check_n_load() 00787 thd - current thread context 00788 db - table's database name 00789 table_name - table's name 00790 table - pointer to table object 00791 names_only - stop after loading trigger names 00792 00793 RETURN VALUE 00794 False - success 00795 True - error 00796 */ 00797 00798 bool Table_triggers_list::check_n_load(THD *thd, const char *db, 00799 const char *table_name, TABLE *table, 00800 bool names_only) 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);

