The world's most popular open source database
#include "mysql_priv.h"#include "sp_head.h"#include "sql_trigger.h"#include "parse_file.h"Include dependency graph for sql_trigger.cc:

Go to the source code of this file.
| #define INVALID_SQL_MODES_LENGTH 13 |
Definition at line 1608 of file sql_trigger.cc.
Referenced by Handle_old_incorrect_sql_modes_hook::process_unknown_string().
| #define INVALID_TRIGGER_TABLE_LENGTH 15 |
Definition at line 1651 of file sql_trigger.cc.
Referenced by Handle_old_incorrect_trigger_table_hook::process_unknown_string().
| #define MYSQL_LEX 1 |
Definition at line 18 of file sql_trigger.cc.
| static TABLE_LIST * add_table_for_trigger | ( | THD * | thd, | |
| sp_name * | trig | |||
| ) | [static] |
Definition at line 1152 of file sql_trigger.cc.
References access, build_table_filename(), DBUG_ENTER, DBUG_RETURN, ER_TRG_DOES_NOT_EXIST, ER_WRONG_OBJECT, F_OK, FN_REFLEN, is_equal(), sp_name::m_db, sp_name::m_name, my_error(), MYF, parser, path, sp_add_to_query_tables(), sql_parse_prepare(), LEX_STRING::str, TL_IGNORE, st_trigname::trigger_table, trigname_file_ext, trigname_file_parameters, and trigname_file_type.
Referenced by mysql_create_or_drop_trigger().
01153 { 01154 LEX *lex= thd->lex; 01155 char path_buff[FN_REFLEN]; 01156 LEX_STRING path; 01157 File_parser *parser; 01158 struct st_trigname trigname; 01159 Handle_old_incorrect_trigger_table_hook trigger_table_hook( 01160 path_buff, &trigname.trigger_table); 01161 01162 DBUG_ENTER("add_table_for_trigger"); 01163 01164 path.length= build_table_filename(path_buff, FN_REFLEN-1, 01165 trig->m_db.str, trig->m_name.str, 01166 trigname_file_ext, 0); 01167 path.str= path_buff; 01168 01169 if (access(path_buff, F_OK)) 01170 { 01171 my_error(ER_TRG_DOES_NOT_EXIST, MYF(0)); 01172 DBUG_RETURN(0); 01173 } 01174 01175 if (!(parser= sql_parse_prepare(&path, thd->mem_root, 1))) 01176 DBUG_RETURN(0); 01177 01178 if (!is_equal(&trigname_file_type, parser->type())) 01179 { 01180 my_error(ER_WRONG_OBJECT, MYF(0), trig->m_name.str, trigname_file_ext+1, 01181 "TRIGGERNAME"); 01182 DBUG_RETURN(0); 01183 } 01184 01185 if (parser->parse((gptr)&trigname, thd->mem_root, 01186 trigname_file_parameters, 1, 01187 &trigger_table_hook)) 01188 DBUG_RETURN(0); 01189 01190 /* We need to reset statement table list to be PS/SP friendly. */ 01191 lex->query_tables= 0; 01192 lex->query_tables_last= &lex->query_tables; 01193 DBUG_RETURN(sp_add_to_query_tables(thd, lex, trig->m_db.str, 01194 trigname.trigger_table.str, TL_IGNORE)); 01195 }
Here is the call graph for this function:

Here is the caller graph for this function:

| bool mysql_create_or_drop_trigger | ( | THD * | thd, | |
| TABLE_LIST * | tables, | |||
| bool | create | |||
| ) |
Definition at line 157 of file sql_trigger.cc.
References add_table_for_trigger(), st_table_list::alias, String::append(), append_definer(), check_table_access(), Table_triggers_list::create_trigger(), st_table_list::db, st_table_list::db_length, DBUG_ASSERT, DBUG_ENTER, DBUG_RETURN, Table_triggers_list::drop_trigger(), ER_BINLOG_CREATE_ROUTINE_NEED_SUPER, ER_NO_DB_ERROR, ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, ER_TRG_DOES_NOT_EXIST, ER_TRG_ON_VIEW_OR_TEMP_TABLE, FALSE, find_temporary_table(), FRMTYPE_TABLE, MYSQL_LOG::is_open(), String::length(), LOCK_open, lock_table_names(), st_table::mem_root, my_error(), my_strcasecmp, MYF, mysql_bin_log, new(), st_table_list::next_global, pthread_mutex_lock, pthread_mutex_unlock, String::ptr(), reopen_name_locked_table(), st_table_list::required_type, send_ok(), String::set(), start_waiting_global_read_lock(), LEX_STRING::str, STRING_WITH_LEN, SUPER_ACL, system_charset_info, st_table_list::table, TRIGGER_ACL, st_table::triggers, TRUE, trust_function_creators, unlock_table_name(), VOID, wait_if_global_read_lock(), and MYSQL_BIN_LOG::write().
Referenced by mysql_execute_command().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool rm_trigger_file | ( | char * | path, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) | [static] |
Definition at line 582 of file sql_trigger.cc.
References build_table_filename(), FN_REFLEN, my_delete(), MY_WME, MYF, and triggers_file_ext.
Referenced by Table_triggers_list::change_table_name_in_triggers(), Table_triggers_list::drop_all_triggers(), and Table_triggers_list::drop_trigger().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool rm_trigname_file | ( | char * | path, | |
| const char * | db, | |||
| const char * | trigger_name | |||
| ) | [static] |
Definition at line 605 of file sql_trigger.cc.
References build_table_filename(), FN_REFLEN, my_delete(), MY_WME, MYF, and trigname_file_ext.
Referenced by Table_triggers_list::drop_all_triggers(), and Table_triggers_list::drop_trigger().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool save_trigger_file | ( | Table_triggers_list * | triggers, | |
| const char * | db, | |||
| const char * | table_name | |||
| ) | [static] |
Definition at line 628 of file sql_trigger.cc.
References build_table_filename(), FN_REFLEN, LEX_STRING::length, NULL, sql_create_definition_file(), LEX_STRING::str, triggers_file_ext, triggers_file_parameters, and triggers_file_type.
Referenced by Table_triggers_list::change_table_name_in_triggers(), and Table_triggers_list::drop_trigger().
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 }
Here is the call graph for this function:

Here is the caller graph for this function:

Initial value:
{
{ C_STRING_WITH_LEN("sql_modes") },
offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST
}
Definition at line 55 of file sql_trigger.cc.
Referenced by Handle_old_incorrect_sql_modes_hook::process_unknown_string().
| const LEX_STRING trg_action_time_type_names[] |
Initial value:
{
{ C_STRING_WITH_LEN("BEFORE") },
{ C_STRING_WITH_LEN("AFTER") }
}
Definition at line 96 of file sql_trigger.cc.
Referenced by store_trigger().
| const LEX_STRING trg_event_type_names[] |
Initial value:
{
{ C_STRING_WITH_LEN("INSERT") },
{ C_STRING_WITH_LEN("UPDATE") },
{ C_STRING_WITH_LEN("DELETE") }
}
Definition at line 102 of file sql_trigger.cc.
Referenced by store_trigger().
const int TRG_NUM_REQUIRED_PARAMETERS = 4 [static] |
| const char* const triggers_file_ext = ".TRG" |
Definition at line 27 of file sql_trigger.cc.
Referenced by Table_triggers_list::check_n_load(), Table_triggers_list::create_trigger(), ha_known_exts(), rm_trigger_file(), and save_trigger_file().
File_option triggers_file_parameters[] [static] |
Initial value:
{
{
{ C_STRING_WITH_LEN("triggers") },
offsetof(class Table_triggers_list, definitions_list),
FILE_OPTIONS_STRLIST
},
{
{ C_STRING_WITH_LEN("sql_modes") },
offsetof(class Table_triggers_list, definition_modes_list),
FILE_OPTIONS_ULLLIST
},
{
{ C_STRING_WITH_LEN("definers") },
offsetof(class Table_triggers_list, definers_list),
FILE_OPTIONS_STRLIST
},
{ { 0, 0 }, 0, FILE_OPTIONS_STRING }
}
Definition at line 35 of file sql_trigger.cc.
Referenced by Table_triggers_list::check_n_load(), Table_triggers_list::create_trigger(), and save_trigger_file().
const LEX_STRING triggers_file_type [static] |
Initial value:
{ C_STRING_WITH_LEN("TRIGGERS") }
Definition at line 24 of file sql_trigger.cc.
Referenced by Table_triggers_list::check_n_load(), Table_triggers_list::create_trigger(), and save_trigger_file().
| const char* const trigname_file_ext = ".TRN" |
Definition at line 83 of file sql_trigger.cc.
Referenced by add_table_for_trigger(), Table_triggers_list::change_table_name_in_trignames(), Table_triggers_list::create_trigger(), ha_known_exts(), and rm_trigname_file().
File_option trigname_file_parameters[] [static] |
Initial value:
{
{
{ C_STRING_WITH_LEN("trigger_table")},
offsetof(struct st_trigname, trigger_table),
FILE_OPTIONS_ESTRING
},
{ { 0, 0 }, 0, FILE_OPTIONS_STRING }
}
Definition at line 85 of file sql_trigger.cc.
Referenced by add_table_for_trigger(), Table_triggers_list::change_table_name_in_trignames(), and Table_triggers_list::create_trigger().
const LEX_STRING trigname_file_type [static] |
Initial value:
{ C_STRING_WITH_LEN("TRIGGERNAME") }
Definition at line 80 of file sql_trigger.cc.
Referenced by add_table_for_trigger(), Table_triggers_list::change_table_name_in_trignames(), and Table_triggers_list::create_trigger().
1.4.7

