diff options
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r-- | sql/sql_trigger.cc | 407 |
1 files changed, 209 insertions, 198 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 52817ef65ae..247055d397c 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -17,7 +17,7 @@ #define MYSQL_LEX 1 -#include <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */ +#include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */ #include "sql_priv.h" #include "unireg.h" #include "sp_head.h" @@ -38,8 +38,9 @@ #include "debug_sync.h" #endif /* WITH_WSREP */ -LEX_STRING *make_lex_string(LEX_STRING *lex_str, const char* str, uint length, - MEM_ROOT *mem_root) +LEX_CSTRING *make_lex_string(LEX_CSTRING *lex_str, + const char* str, size_t length, + MEM_ROOT *mem_root) { if (!(lex_str->str= strmake_root(mem_root, str, length))) return 0; @@ -60,9 +61,9 @@ public: static Trigger_creation_ctx *create(THD *thd, const char *db_name, const char *table_name, - const LEX_STRING *client_cs_name, - const LEX_STRING *connection_cl_name, - const LEX_STRING *db_cl_name); + const LEX_CSTRING *client_cs_name, + const LEX_CSTRING *connection_cl_name, + const LEX_CSTRING *db_cl_name); Trigger_creation_ctx(CHARSET_INFO *client_cs, CHARSET_INFO *connection_cl, @@ -96,9 +97,9 @@ Trigger_creation_ctx * Trigger_creation_ctx::create(THD *thd, const char *db_name, const char *table_name, - const LEX_STRING *client_cs_name, - const LEX_STRING *connection_cl_name, - const LEX_STRING *db_cl_name) + const LEX_CSTRING *client_cs_name, + const LEX_CSTRING *connection_cl_name, + const LEX_CSTRING *db_cl_name) { CHARSET_INFO *client_cs; CHARSET_INFO *connection_cl; @@ -166,8 +167,8 @@ Trigger_creation_ctx::create(THD *thd, /*************************************************************************/ -static const LEX_STRING triggers_file_type= - { C_STRING_WITH_LEN("TRIGGERS") }; +static const LEX_CSTRING triggers_file_type= + { STRING_WITH_LEN("TRIGGERS") }; const char * const TRG_EXT= ".TRG"; @@ -180,37 +181,37 @@ const char * const TRG_EXT= ".TRG"; static File_option triggers_file_parameters[]= { { - { C_STRING_WITH_LEN("triggers") }, + { STRING_WITH_LEN("triggers") }, my_offsetof(class Table_triggers_list, definitions_list), FILE_OPTIONS_STRLIST }, { - { C_STRING_WITH_LEN("sql_modes") }, + { STRING_WITH_LEN("sql_modes") }, my_offsetof(class Table_triggers_list, definition_modes_list), FILE_OPTIONS_ULLLIST }, { - { C_STRING_WITH_LEN("definers") }, + { STRING_WITH_LEN("definers") }, my_offsetof(class Table_triggers_list, definers_list), FILE_OPTIONS_STRLIST }, { - { C_STRING_WITH_LEN("client_cs_names") }, + { STRING_WITH_LEN("client_cs_names") }, my_offsetof(class Table_triggers_list, client_cs_names), FILE_OPTIONS_STRLIST }, { - { C_STRING_WITH_LEN("connection_cl_names") }, + { STRING_WITH_LEN("connection_cl_names") }, my_offsetof(class Table_triggers_list, connection_cl_names), FILE_OPTIONS_STRLIST }, { - { C_STRING_WITH_LEN("db_cl_names") }, + { STRING_WITH_LEN("db_cl_names") }, my_offsetof(class Table_triggers_list, db_cl_names), FILE_OPTIONS_STRLIST }, { - { C_STRING_WITH_LEN("created") }, + { STRING_WITH_LEN("created") }, my_offsetof(class Table_triggers_list, create_times), FILE_OPTIONS_ULLLIST }, @@ -219,7 +220,7 @@ static File_option triggers_file_parameters[]= File_option sql_modes_parameters= { - { C_STRING_WITH_LEN("sql_modes") }, + { STRING_WITH_LEN("sql_modes") }, my_offsetof(class Table_triggers_list, definition_modes_list), FILE_OPTIONS_ULLLIST }; @@ -242,18 +243,18 @@ static const int TRG_NUM_REQUIRED_PARAMETERS= 7; struct st_trigname { - LEX_STRING trigger_table; + LEX_CSTRING trigger_table; }; -static const LEX_STRING trigname_file_type= - { C_STRING_WITH_LEN("TRIGGERNAME") }; +static const LEX_CSTRING trigname_file_type= + { STRING_WITH_LEN("TRIGGERNAME") }; const char * const TRN_EXT= ".TRN"; static File_option trigname_file_parameters[]= { { - { C_STRING_WITH_LEN("trigger_table")}, + { STRING_WITH_LEN("trigger_table")}, offsetof(struct st_trigname, trigger_table), FILE_OPTIONS_ESTRING }, @@ -264,9 +265,9 @@ static File_option trigname_file_parameters[]= class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook { private: - char *path; + const char *path; public: - Handle_old_incorrect_sql_modes_hook(char *file_path) + Handle_old_incorrect_sql_modes_hook(const char *file_path) :path(file_path) {}; virtual bool process_unknown_string(const char *&unknown_key, uchar* base, @@ -277,15 +278,15 @@ public: class Handle_old_incorrect_trigger_table_hook: public Unknown_key_hook { public: - Handle_old_incorrect_trigger_table_hook(char *file_path, - LEX_STRING *trigger_table_arg) + Handle_old_incorrect_trigger_table_hook(const char *file_path, + LEX_CSTRING *trigger_table_arg) :path(file_path), trigger_table_value(trigger_table_arg) {}; virtual bool process_unknown_string(const char *&unknown_key, uchar* base, MEM_ROOT *mem_root, const char *end); private: - char *path; - LEX_STRING *trigger_table_value; + const char *path; + LEX_CSTRING *trigger_table_value; }; @@ -303,7 +304,7 @@ class Deprecated_trigger_syntax_handler : public Internal_error_handler private: char m_message[MYSQL_ERRMSG_SIZE]; - LEX_STRING *m_trigger_name; + LEX_CSTRING *m_trigger_name; public: @@ -333,7 +334,7 @@ public: return false; } - LEX_STRING *get_trigger_name() { return m_trigger_name; } + LEX_CSTRING *get_trigger_name() { return m_trigger_name; } char *get_error_message() { return m_message; } }; @@ -424,7 +425,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) need second part of condition below, since check_access() function also checks that db is specified. */ - if (!thd->lex->spname->m_db.length || (create && !tables->db_length)) + if (!thd->lex->spname->m_db.length || (create && !tables->db.length)) { my_error(ER_NO_DB_ERROR, MYF(0)); DBUG_RETURN(TRUE); @@ -433,7 +434,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) /* We don't allow creating triggers on tables in the 'mysql' schema */ - if (create && !my_strcasecmp(system_charset_info, "mysql", tables->db)) + if (create && lex_string_eq(&tables->db, STRING_WITH_LEN("mysql"))) { my_error(ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA, MYF(0)); DBUG_RETURN(TRUE); @@ -529,12 +530,12 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) /* We do not allow creation of triggers on temporary tables. */ if (create && thd->find_tmp_table_share(tables)) { - my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); + my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias.str); goto end; } /* We also don't allow creation of triggers on views. */ - tables->required_type= FRMTYPE_TABLE; + tables->required_type= TABLE_TYPE_NORMAL; /* Also prevent DROP TRIGGER from opening temporary table which might shadow the subject table on which trigger to be dropped is defined. @@ -547,8 +548,8 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (thd->locked_tables_mode) { /* Under LOCK TABLES we must only accept write locked tables. */ - if (!(tables->table= find_table_for_mdl_upgrade(thd, tables->db, - tables->table_name, + if (!(tables->table= find_table_for_mdl_upgrade(thd, tables->db.str, + tables->table_name.str, NULL))) goto end; } @@ -666,12 +667,12 @@ WSREP_ERROR_LABEL: static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, String *stmt_query, String *trigger_def, - LEX_STRING *trg_definer, + LEX_CSTRING *trg_definer, char trg_definer_holder[]) { - LEX_STRING stmt_definition; + LEX_CSTRING stmt_definition; LEX *lex= thd->lex; - uint prefix_trimmed, suffix_trimmed; + size_t prefix_trimmed, suffix_trimmed; size_t original_length; /* @@ -685,7 +686,7 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, if (lex->create_info.or_replace()) stmt_query->append(STRING_WITH_LEN("OR REPLACE ")); - if (lex->sphead->m_chistics->suid != SP_IS_NOT_SUID) + if (lex->sphead->suid() != SP_IS_NOT_SUID) { /* SUID trigger */ lex->definer->set_lex_string(trg_definer, trg_definer_holder); @@ -694,12 +695,12 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, } else { - *trg_definer= empty_lex_str; + *trg_definer= empty_clex_str; } /* Create statement for binary logging */ - stmt_definition.str= (char*) lex->stmt_definition_begin; + stmt_definition.str= lex->stmt_definition_begin; stmt_definition.length= (lex->stmt_definition_end - lex->stmt_definition_begin); original_length= stmt_definition.length; @@ -710,7 +711,13 @@ static void build_trig_stmt_query(THD *thd, TABLE_LIST *tables, /* Create statement for storing trigger (without trigger order) */ if (lex->trg_chistics.ordering_clause == TRG_ORDER_NONE) + { + /* + Not that here stmt_definition doesn't end with a \0, which is + normally expected from a LEX_CSTRING + */ trigger_def->append(stmt_definition.str, stmt_definition.length); + } else { /* Copy data before FOLLOWS/PRECEDES trigger_name */ @@ -759,7 +766,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, LEX *lex= thd->lex; TABLE *table= tables->table; char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN]; - LEX_STRING file, trigname_file; + LEX_CSTRING file, trigname_file; char trg_definer_holder[USER_HOST_BUFF_SIZE]; Item_trigger_field *trg_field; struct st_trigname trigname; @@ -772,8 +779,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, DBUG_RETURN(true); /* Trigger must be in the same schema as target table. */ - if (my_strcasecmp(table_alias_charset, table->s->db.str, - lex->spname->m_db.str)) + if (lex_string_cmp(table_alias_charset, &table->s->db, &lex->spname->m_db)) { my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0)); DBUG_RETURN(true); @@ -807,8 +813,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, */ trg_field->setup_field(thd, table, NULL); - if (!trg_field->fixed && - trg_field->fix_fields(thd, (Item **)0)) + if (trg_field->fix_fields_if_needed(thd, (Item **)0)) DBUG_RETURN(true); } @@ -831,11 +836,11 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, versions */ file.length= build_table_filename(file_buff, FN_REFLEN - 1, - tables->db, tables->table_name, + tables->db.str, tables->table_name.str, TRG_EXT, 0); file.str= file_buff; trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, - tables->db, + tables->db.str, lex->spname->m_name.str, TRN_EXT, 0); trigname_file.str= trigname_buff; @@ -856,11 +861,13 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, } else if (lex->create_info.if_not_exists()) { + strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db.str, ".", + lex->spname->m_name.str, NullS); push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, ER_TRG_ALREADY_EXISTS, ER_THD(thd, ER_TRG_ALREADY_EXISTS), trigname_buff); - LEX_STRING trg_definer_tmp; + LEX_CSTRING trg_definer_tmp; String trigger_def; /* @@ -873,13 +880,14 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, } else { - my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); + strxnmov(trigname_buff, sizeof(trigname_buff) - 1, tables->db.str, ".", + lex->spname->m_name.str, NullS); + my_error(ER_TRG_ALREADY_EXISTS, MYF(0), trigname_buff); DBUG_RETURN(true); } } - trigname.trigger_table.str= tables->table_name; - trigname.trigger_table.length= tables->table_name_length; + trigname.trigger_table= tables->table_name; /* We are not using lex->sphead here as an argument to Trigger() as we are @@ -914,7 +922,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, lex_string_set(&trigger->connection_cl_name, thd->variables.collation_connection->name); lex_string_set(&trigger->db_cl_name, - get_default_db_collation(thd, tables->db)->name); + get_default_db_collation(thd, tables->db.str)->name); /* Add trigger in it's correct place */ add_trigger(lex->trg_chistics.event, @@ -941,8 +949,8 @@ err_without_cleanup: if (trigger_dropped) { String drop_trg_query; - drop_trg_query.append("DROP TRIGGER /* generated by failed CREATE TRIGGER */ "); - drop_trg_query.append(lex->spname->m_name.str); + drop_trg_query.append(STRING_WITH_LEN("DROP TRIGGER /* generated by failed CREATE TRIGGER */ ")); + drop_trg_query.append(&lex->spname->m_name); /* We dropped an existing trigger and was not able to recreate it because of an internal error. Ensure it's also dropped on the slave. @@ -1022,10 +1030,10 @@ bool Trigger::add_to_file_list(void* param_arg) True error */ -static bool rm_trigger_file(char *path, const char *db, - const char *table_name) +static bool rm_trigger_file(char *path, const LEX_CSTRING *db, + const LEX_CSTRING *table_name) { - build_table_filename(path, FN_REFLEN-1, db, table_name, TRG_EXT, 0); + build_table_filename(path, FN_REFLEN-1, db->str, table_name->str, TRG_EXT, 0); return mysql_file_delete(key_file_trg, path, MYF(MY_WME)); } @@ -1044,10 +1052,10 @@ static bool rm_trigger_file(char *path, const char *db, True error */ -static bool rm_trigname_file(char *path, const char *db, - const char *trigger_name) +static bool rm_trigname_file(char *path, const LEX_CSTRING *db, + const LEX_CSTRING *trigger_name) { - build_table_filename(path, FN_REFLEN - 1, db, trigger_name, TRN_EXT, 0); + build_table_filename(path, FN_REFLEN - 1, db->str, trigger_name->str, TRN_EXT, 0); return mysql_file_delete(key_file_trn, path, MYF(MY_WME)); } @@ -1065,16 +1073,16 @@ static bool rm_trigname_file(char *path, const char *db, TRUE Error */ -bool Table_triggers_list::save_trigger_file(THD *thd, const char *db, - const char *table_name) +bool Table_triggers_list::save_trigger_file(THD *thd, const LEX_CSTRING *db, + const LEX_CSTRING *table_name) { char file_buff[FN_REFLEN]; - LEX_STRING file; + LEX_CSTRING file; if (create_lists_needed_for_files(thd->mem_root)) return true; - file.length= build_table_filename(file_buff, FN_REFLEN - 1, db, table_name, + file.length= build_table_filename(file_buff, FN_REFLEN - 1, db->str, table_name->str, TRG_EXT, 0); file.str= file_buff; return sql_create_definition_file(NULL, &file, &triggers_file_type, @@ -1089,7 +1097,7 @@ bool Table_triggers_list::save_trigger_file(THD *thd, const char *db, @param remove_from_list If set, remove trigger if found */ -Trigger *Table_triggers_list::find_trigger(const LEX_STRING *name, +Trigger *Table_triggers_list::find_trigger(const LEX_CSTRING *name, bool remove_from_list) { for (uint i= 0; i < (uint)TRG_EVENT_MAX; i++) @@ -1102,8 +1110,8 @@ Trigger *Table_triggers_list::find_trigger(const LEX_STRING *name, (trigger= *parent); parent= &trigger->next) { - if (my_strcasecmp(table_alias_charset, - trigger->name.str, name->str) == 0) + if (lex_string_cmp(table_alias_charset, + &trigger->name, name) == 0) { if (remove_from_list) { @@ -1144,7 +1152,7 @@ Trigger *Table_triggers_list::find_trigger(const LEX_STRING *name, bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables, String *stmt_query) { - const LEX_STRING *sp_name= &thd->lex->spname->m_name; // alias + const LEX_CSTRING *sp_name= &thd->lex->spname->m_name; // alias char path[FN_REFLEN]; Trigger *trigger; @@ -1166,16 +1174,16 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables, parse_file.cc functionality (because we will need it elsewhere). */ - if (rm_trigger_file(path, tables->db, tables->table_name)) + if (rm_trigger_file(path, &tables->db, &tables->table_name)) return 1; } else { - if (save_trigger_file(thd, tables->db, tables->table_name)) + if (save_trigger_file(thd, &tables->db, &tables->table_name)) return 1; } - if (rm_trigname_file(path, tables->db, sp_name->str)) + if (rm_trigname_file(path, &tables->db, sp_name)) return 1; delete trigger; @@ -1247,7 +1255,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) uchar null_bit= 1; for (fld= table->field, trg_fld= record0_field; *fld; fld++, trg_fld++) { - if (!(*fld)->null_ptr && !(*fld)->vcol_info) + if (!(*fld)->null_ptr && !(*fld)->vcol_info && !(*fld)->vers_sys_field()) { Field *f; if (!(f= *trg_fld= (*fld)->make_new_field(&table->mem_root, table, @@ -1255,6 +1263,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) return 1; f->flags= (*fld)->flags; + f->invisible= (*fld)->invisible; f->null_ptr= null_ptr; f->null_bit= null_bit; if (null_bit == 128) @@ -1270,7 +1279,9 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) bzero(extra_null_bitmap, null_bytes); } else + { record0_field= table->field; + } if (has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_BEFORE) || has_triggers(TRG_EVENT_UPDATE,TRG_ACTION_AFTER) || @@ -1318,18 +1329,18 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) True error */ -bool Table_triggers_list::check_n_load(THD *thd, const char *db, - const char *table_name, TABLE *table, +bool Table_triggers_list::check_n_load(THD *thd, const LEX_CSTRING *db, + const LEX_CSTRING *table_name, TABLE *table, bool names_only) { char path_buff[FN_REFLEN]; - LEX_STRING path; + LEX_CSTRING path; File_parser *parser; - LEX_STRING save_db; + LEX_CSTRING save_db; DBUG_ENTER("Table_triggers_list::check_n_load"); path.length= build_table_filename(path_buff, FN_REFLEN - 1, - db, table_name, TRG_EXT, 0); + db->str, table_name->str, TRG_EXT, 0); path.str= path_buff; // QQ: should we analyze errno somehow ? @@ -1343,7 +1354,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, if (is_equal(&triggers_file_type, parser->type())) { Handle_old_incorrect_sql_modes_hook sql_modes_hook(path.str); - LEX_STRING *trg_create_str; + LEX_CSTRING *trg_create_str; ulonglong *trg_sql_mode, *trg_create_time; Trigger *trigger; Table_triggers_list *trigger_list= @@ -1357,7 +1368,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, &sql_modes_hook)) goto error; - List_iterator_fast<LEX_STRING> it(trigger_list->definitions_list); + List_iterator_fast<LEX_CSTRING> it(trigger_list->definitions_list); if (!trigger_list->definitions_list.is_empty() && (trigger_list->client_cs_names.is_empty() || @@ -1368,18 +1379,18 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_TRG_NO_CREATION_CTX, ER_THD(thd, ER_TRG_NO_CREATION_CTX), - (const char*) db, - (const char*) table_name); + db->str, + table_name->str); } table->triggers= trigger_list; status_var_increment(thd->status_var.feature_trigger); List_iterator_fast<ulonglong> itm(trigger_list->definition_modes_list); - List_iterator_fast<LEX_STRING> it_definer(trigger_list->definers_list); - List_iterator_fast<LEX_STRING> it_client_cs_name(trigger_list->client_cs_names); - List_iterator_fast<LEX_STRING> it_connection_cl_name(trigger_list->connection_cl_names); - List_iterator_fast<LEX_STRING> it_db_cl_name(trigger_list->db_cl_names); + List_iterator_fast<LEX_CSTRING> it_definer(trigger_list->definers_list); + List_iterator_fast<LEX_CSTRING> it_client_cs_name(trigger_list->client_cs_names); + List_iterator_fast<LEX_CSTRING> it_connection_cl_name(trigger_list->connection_cl_names); + List_iterator_fast<LEX_CSTRING> it_db_cl_name(trigger_list->db_cl_names); List_iterator_fast<ulonglong> it_create_times(trigger_list->create_times); LEX *old_lex= thd->lex; LEX lex; @@ -1388,14 +1399,13 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, thd->lex= &lex; - save_db.str= thd->db; - save_db.length= thd->db_length; - thd->reset_db((char*) db, strlen(db)); + save_db= thd->db; + thd->reset_db(db); while ((trg_create_str= it++)) { sp_head *sp; sql_mode_t sql_mode; - LEX_STRING *trg_definer; + LEX_CSTRING *trg_definer; Trigger_creation_ctx *creation_ctx; /* @@ -1412,13 +1422,14 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, thd->variables.sql_mode= sql_mode; Parser_state parser_state; - if (parser_state.init(thd, trg_create_str->str, trg_create_str->length)) + if (parser_state.init(thd, (char*) trg_create_str->str, + trg_create_str->length)) goto err_with_lex_cleanup; if (!trigger_list->client_cs_names.is_empty()) creation_ctx= Trigger_creation_ctx::create(thd, - db, - table_name, + db->str, + table_name->str, it_client_cs_name++, it_connection_cl_name++, it_db_cl_name++); @@ -1455,7 +1466,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, lex.set_trg_event_type_for_tables(); if (lex.sphead) - lex.sphead->set_info(0, 0, &lex.sp_chistics, sql_mode); + lex.sphead->m_sql_mode= sql_mode; if (unlikely(!(trigger= (new (&table->mem_root) Trigger(trigger_list, lex.sphead))))) @@ -1467,7 +1478,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, trigger->sql_mode= sql_mode; trigger->definition= *trg_create_str; trigger->create_time= trg_create_time ? *trg_create_time : 0; - trigger->name= sp ? sp->m_name : empty_lex_str; + trigger->name= sp ? sp->m_name : empty_clex_str; trigger->on_table_name.str= (char*) lex.raw_trg_on_table_name_begin; trigger->on_table_name.length= (lex.raw_trg_on_table_name_end - lex.raw_trg_on_table_name_begin); @@ -1488,9 +1499,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, &lex.trg_chistics.anchor_trigger_name, trigger); - if (parse_error) + if (unlikely(parse_error)) { - LEX_STRING *name; + LEX_CSTRING *name; /* In case of errors, disable all triggers for the table, but keep @@ -1502,18 +1513,18 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, DBUG_ASSERT(lex.sphead == 0); lex_end(&lex); - if ((name= error_handler.get_trigger_name())) + if (likely((name= error_handler.get_trigger_name()))) { - if (!(make_lex_string(&trigger->name, name->str, - name->length, &table->mem_root))) + if (unlikely(!(make_lex_string(&trigger->name, name->str, + name->length, &table->mem_root)))) goto err_with_lex_cleanup; } trigger->definer= ((!trg_definer || !trg_definer->length) ? - empty_lex_str : *trg_definer); + empty_clex_str : *trg_definer); continue; } - sp->set_info(0, 0, &lex.sp_chistics, sql_mode); + sp->m_sql_mode= sql_mode; sp->set_creation_ctx(creation_ctx); if (!trg_definer || !trg_definer->length) @@ -1527,23 +1538,22 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, ER_TRG_NO_DEFINER, ER_THD(thd, ER_TRG_NO_DEFINER), - (const char*) db, - (const char*) sp->m_name.str); + db->str, sp->m_name.str); /* Set definer to the '' to correct displaying in the information schema. */ - sp->set_definer((char*) "", 0); - trigger->definer= empty_lex_str; + sp->set_definer("", 0); + trigger->definer= empty_clex_str; /* trigger_list without definer information are executed under the authorization of the invoker. */ - sp->m_chistics->suid= SP_IS_NOT_SUID; + sp->set_suid(SP_IS_NOT_SUID); } else { @@ -1564,12 +1574,12 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, */ char fname[SAFE_NAME_LEN + 1]; - DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) || - (check_n_cut_mysql50_prefix(db, fname, sizeof(fname)) && - !my_strcasecmp(table_alias_charset, lex.query_tables->db, fname)))); - DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name, table_name) || - (check_n_cut_mysql50_prefix(table_name, fname, sizeof(fname)) && - !my_strcasecmp(table_alias_charset, lex.query_tables->table_name, fname)))); + DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->db.str, db->str) || + (check_n_cut_mysql50_prefix(db->str, fname, sizeof(fname)) && + !my_strcasecmp(table_alias_charset, lex.query_tables->db.str, fname)))); + DBUG_ASSERT((!my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, table_name->str) || + (check_n_cut_mysql50_prefix(table_name->str, fname, sizeof(fname)) && + !my_strcasecmp(table_alias_charset, lex.query_tables->table_name.str, fname)))); #endif if (names_only) { @@ -1602,7 +1612,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, lex_end(&lex); } - thd->reset_db(save_db.str, save_db.length); + thd->reset_db(&save_db); thd->lex= old_lex; thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; @@ -1619,20 +1629,20 @@ err_with_lex_cleanup: thd->lex= old_lex; thd->spcont= save_spcont; thd->variables.sql_mode= save_sql_mode; - thd->reset_db(save_db.str, save_db.length); - /* Fall through to error */ + thd->reset_db(&save_db); + /* Fall trough to error */ } } error: - if (!thd->is_error()) + if (unlikely(!thd->is_error())) { /* We don't care about this error message much because .TRG files will be merged into .FRM anyway. */ my_error(ER_WRONG_OBJECT, MYF(0), - table_name, TRG_EXT + 1, "TRIGGER"); + table_name->str, TRG_EXT + 1, "TRIGGER"); } DBUG_RETURN(1); } @@ -1648,7 +1658,7 @@ error: void Table_triggers_list::add_trigger(trg_event_type event, trg_action_time_type action_time, trigger_order_type ordering_clause, - LEX_STRING *anchor_trigger_name, + LEX_CSTRING *anchor_trigger_name, Trigger *trigger) { Trigger **parent= &triggers[event][action_time]; @@ -1657,8 +1667,8 @@ void Table_triggers_list::add_trigger(trg_event_type event, for ( ; *parent ; parent= &(*parent)->next, position++) { if (ordering_clause != TRG_ORDER_NONE && - !my_strcasecmp(table_alias_charset, anchor_trigger_name->str, - (*parent)->name.str)) + !lex_string_cmp(table_alias_charset, anchor_trigger_name, + &(*parent)->name)) { if (ordering_clause == TRG_ORDER_FOLLOWS) { @@ -1687,8 +1697,8 @@ void Table_triggers_list::add_trigger(trg_event_type event, /** Obtains and returns trigger metadata. - @param thd current thread context @param trigger_stmt returns statement of trigger + @param body returns body of trigger @param definer returns definer/creator of trigger. The caller is responsible to allocate enough space for storing definer information. @@ -1699,8 +1709,9 @@ void Table_triggers_list::add_trigger(trg_event_type event, True error */ -void Trigger::get_trigger_info(LEX_STRING *trigger_stmt, - LEX_STRING *trigger_body, LEX_STRING *definer) +void Trigger::get_trigger_info(LEX_CSTRING *trigger_stmt, + LEX_CSTRING *trigger_body, + LEX_STRING *definer) { DBUG_ENTER("get_trigger_info"); @@ -1714,14 +1725,14 @@ void Trigger::get_trigger_info(LEX_STRING *trigger_stmt, } *trigger_body= body->m_body_utf8; - if (body->m_chistics->suid == SP_IS_NOT_SUID) + if (body->suid() == SP_IS_NOT_SUID) { *definer= empty_lex_str; } else { - definer->length= strxmov(definer->str, body->m_definer_user.str, "@", - body->m_definer_host.str, NullS) - definer->str; + definer->length= strxmov(definer->str, body->m_definer.user.str, "@", + body->m_definer.host.str, NullS) - definer->str; } DBUG_VOID_RETURN; } @@ -1751,12 +1762,12 @@ bool add_table_for_trigger(THD *thd, { LEX *lex= thd->lex; char trn_path_buff[FN_REFLEN]; - LEX_STRING trn_path= { trn_path_buff, 0 }; - LEX_STRING tbl_name= null_lex_str; + LEX_CSTRING trn_path= { trn_path_buff, 0 }; + LEX_CSTRING tbl_name= null_clex_str; DBUG_ENTER("add_table_for_trigger"); - build_trn_path(thd, trg_name, &trn_path); + build_trn_path(thd, trg_name, (LEX_STRING*) &trn_path); if (check_trn_exists(&trn_path)) { @@ -1779,8 +1790,8 @@ bool add_table_for_trigger(THD *thd, if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name)) DBUG_RETURN(TRUE); - *table= sp_add_to_query_tables(thd, lex, trg_name->m_db.str, - tbl_name.str, TL_IGNORE, + *table= sp_add_to_query_tables(thd, lex, &trg_name->m_db, + &tbl_name, TL_IGNORE, MDL_SHARED_NO_WRITE); DBUG_RETURN(*table ? FALSE : TRUE); @@ -1800,15 +1811,17 @@ bool add_table_for_trigger(THD *thd, True error */ -bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name) +bool Table_triggers_list::drop_all_triggers(THD *thd, const LEX_CSTRING *db, + const LEX_CSTRING *name) { TABLE table; char path[FN_REFLEN]; bool result= 0; - DBUG_ENTER("drop_all_triggers"); + DBUG_ENTER("Triggers::drop_all_triggers"); table.reset(); - init_sql_alloc(&table.mem_root, 8192, 0, MYF(0)); + init_sql_alloc(&table.mem_root, "Triggers::drop_all_triggers", 8192, 0, + MYF(0)); if (Table_triggers_list::check_n_load(thd, db, name, &table, 1)) { @@ -1832,7 +1845,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name) Such triggers have zero-length name and are skipped here. */ if (trigger->name.length && - rm_trigname_file(path, db, trigger->name.str)) + rm_trigname_file(path, db, &trigger->name)) { /* Instead of immediately bailing out with error if we were unable @@ -1872,40 +1885,41 @@ end: struct change_table_name_param { THD *thd; - const char *old_db_name; - const char *new_db_name; - LEX_STRING *new_table_name; + LEX_CSTRING *old_db_name; + LEX_CSTRING *new_db_name; + LEX_CSTRING *new_table_name; Trigger *stopper; }; bool -Table_triggers_list::change_table_name_in_triggers(THD *thd, - const char *old_db_name, - const char *new_db_name, - LEX_STRING *old_table_name, - LEX_STRING *new_table_name) +Table_triggers_list:: +change_table_name_in_triggers(THD *thd, + const LEX_CSTRING *old_db_name, + const LEX_CSTRING *new_db_name, + const LEX_CSTRING *old_table_name, + const LEX_CSTRING *new_table_name) { struct change_table_name_param param; sql_mode_t save_sql_mode= thd->variables.sql_mode; char path_buff[FN_REFLEN]; param.thd= thd; - param.new_table_name= new_table_name; + param.new_table_name= const_cast<LEX_CSTRING*>(new_table_name); for_all_triggers(&Trigger::change_table_name, ¶m); thd->variables.sql_mode= save_sql_mode; - if (thd->is_fatal_error) + if (unlikely(thd->is_fatal_error)) return TRUE; /* OOM */ - if (save_trigger_file(thd, new_db_name, new_table_name->str)) + if (save_trigger_file(thd, new_db_name, new_table_name)) return TRUE; - if (rm_trigger_file(path_buff, old_db_name, old_table_name->str)) + if (rm_trigger_file(path_buff, old_db_name, old_table_name)) { - (void) rm_trigger_file(path_buff, new_db_name, new_table_name->str); + (void) rm_trigger_file(path_buff, new_db_name, new_table_name); return TRUE; } return FALSE; @@ -1916,9 +1930,8 @@ bool Trigger::change_table_name(void* param_arg) { change_table_name_param *param= (change_table_name_param*) param_arg; THD *thd= param->thd; - LEX_STRING *new_table_name= param->new_table_name; - - LEX_STRING *def= &definition, new_def; + LEX_CSTRING *new_table_name= param->new_table_name; + LEX_CSTRING *def= &definition, new_def; size_t on_q_table_name_len, before_on_len; String buff; @@ -1934,7 +1947,7 @@ bool Trigger::change_table_name(void* param_arg) buff.append(def->str, before_on_len); buff.append(STRING_WITH_LEN("ON ")); - append_identifier(thd, &buff, new_table_name->str, new_table_name->length); + append_identifier(thd, &buff, new_table_name); buff.append(STRING_WITH_LEN(" ")); on_q_table_name_len= buff.length() - before_on_len; buff.append(on_table_name.str + on_table_name.length, @@ -1971,15 +1984,16 @@ bool Trigger::change_table_name(void* param_arg) */ Trigger * -Table_triggers_list::change_table_name_in_trignames(const char *old_db_name, - const char *new_db_name, - LEX_STRING *new_table_name, - Trigger *trigger) +Table_triggers_list:: +change_table_name_in_trignames(const LEX_CSTRING *old_db_name, + const LEX_CSTRING *new_db_name, + const LEX_CSTRING *new_table_name, + Trigger *trigger) { struct change_table_name_param param; - param.old_db_name= old_db_name; - param.new_db_name= new_db_name; - param.new_table_name= new_table_name; + param.old_db_name= const_cast<LEX_CSTRING*>(old_db_name); + param.new_db_name= const_cast<LEX_CSTRING*>(new_db_name); + param.new_table_name= const_cast<LEX_CSTRING*>(new_table_name); param.stopper= trigger; return for_all_triggers(&Trigger::change_on_table_name, ¶m); @@ -1992,13 +2006,13 @@ bool Trigger::change_on_table_name(void* param_arg) char trigname_buff[FN_REFLEN]; struct st_trigname trigname; - LEX_STRING trigname_file; + LEX_CSTRING trigname_file; if (param->stopper == this) return 0; // Stop processing trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, - param->new_db_name, name.str, + param->new_db_name->str, name.str, TRN_EXT, 0); trigname_file.str= trigname_buff; @@ -2014,9 +2028,9 @@ bool Trigger::change_on_table_name(void* param_arg) /* Remove stale .TRN file in case of database upgrade */ if (param->old_db_name) { - if (rm_trigname_file(trigname_buff, param->old_db_name, name.str)) + if (rm_trigname_file(trigname_buff, param->old_db_name, &name)) { - (void) rm_trigname_file(trigname_buff, param->new_db_name, name.str); + (void) rm_trigname_file(trigname_buff, param->new_db_name, &name); return 1; } } @@ -2045,30 +2059,32 @@ bool Trigger::change_on_table_name(void* param_arg) @retval TRUE Error */ -bool Table_triggers_list::change_table_name(THD *thd, const char *db, - const char *old_alias, - const char *old_table, - const char *new_db, - const char *new_table) +bool Table_triggers_list::change_table_name(THD *thd, const LEX_CSTRING *db, + const LEX_CSTRING *old_alias, + const LEX_CSTRING *old_table, + const LEX_CSTRING *new_db, + const LEX_CSTRING *new_table) { TABLE table; bool result= 0; bool upgrading50to51= FALSE; Trigger *err_trigger; - DBUG_ENTER("change_table_name"); + DBUG_ENTER("Triggers::change_table_name"); table.reset(); - init_sql_alloc(&table.mem_root, 8192, 0, MYF(0)); + init_sql_alloc(&table.mem_root, "Triggers::change_table_name", 8192, 0, + MYF(0)); /* This method interfaces the mysql server code protected by an exclusive metadata lock. */ - DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db, old_table, + DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, db->str, + old_table->str, MDL_EXCLUSIVE)); - DBUG_ASSERT(my_strcasecmp(table_alias_charset, db, new_db) || - my_strcasecmp(table_alias_charset, old_alias, new_table)); + DBUG_ASSERT(my_strcasecmp(table_alias_charset, db->str, new_db->str) || + my_strcasecmp(table_alias_charset, old_alias->str, new_table->str)); if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE)) { @@ -2082,8 +2098,6 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, result= 1; goto end; } - LEX_STRING old_table_name= { (char *) old_alias, strlen(old_alias) }; - LEX_STRING new_table_name= { (char *) new_table, strlen(new_table) }; /* Since triggers should be in the same schema as their subject tables moving table with them between two schemas raises too many questions. @@ -2094,11 +2108,11 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, we will be given table name with "#mysql50#" prefix To remove this prefix we use check_n_cut_mysql50_prefix(). */ - if (my_strcasecmp(table_alias_charset, db, new_db)) + if (my_strcasecmp(table_alias_charset, db->str, new_db->str)) { char dbname[SAFE_NAME_LEN + 1]; - if (check_n_cut_mysql50_prefix(db, dbname, sizeof(dbname)) && - !my_strcasecmp(table_alias_charset, dbname, new_db)) + if (check_n_cut_mysql50_prefix(db->str, dbname, sizeof(dbname)) && + !my_strcasecmp(table_alias_charset, dbname, new_db->str)) { upgrading50to51= TRUE; } @@ -2109,16 +2123,16 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, goto end; } } - if (table.triggers->change_table_name_in_triggers(thd, db, new_db, - &old_table_name, - &new_table_name)) + if (unlikely(table.triggers->change_table_name_in_triggers(thd, db, new_db, + old_alias, + new_table))) { result= 1; goto end; } if ((err_trigger= table.triggers-> change_table_name_in_trignames( upgrading50to51 ? db : NULL, - new_db, &new_table_name, 0))) + new_db, new_table, 0))) { /* If we were unable to update one of .TRN files properly we will @@ -2128,10 +2142,10 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, */ (void) table.triggers->change_table_name_in_trignames( upgrading50to51 ? new_db : NULL, db, - &old_table_name, err_trigger); + old_alias, err_trigger); (void) table.triggers->change_table_name_in_triggers( thd, db, new_db, - &new_table_name, &old_table_name); + new_table, old_alias); result= 1; goto end; } @@ -2191,8 +2205,7 @@ bool Table_triggers_list::process_triggers(THD *thd, This trigger must have been processed by the pre-locking algorithm. */ - DBUG_ASSERT(trigger_table->pos_in_table_list->trg_event_map & - static_cast<uint>(1 << static_cast<int>(event))); + DBUG_ASSERT(trigger_table->pos_in_table_list->trg_event_map & trg2bit(event)); thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER); @@ -2244,8 +2257,7 @@ add_tables_and_routines_for_triggers(THD *thd, for (int i= 0; i < (int)TRG_EVENT_MAX; i++) { - if (table_list->trg_event_map & - static_cast<uint8>(1 << static_cast<int>(i))) + if (table_list->trg_event_map & trg2bit(static_cast<trg_event_type>(i))) { for (int j= 0; j < (int)TRG_ACTION_MAX; j++) { @@ -2255,13 +2267,14 @@ add_tables_and_routines_for_triggers(THD *thd, { sp_head *trigger= triggers->body; - if (!triggers->body) // Parse error + if (unlikely(!triggers->body)) // Parse error continue; MDL_key key(MDL_key::TRIGGER, trigger->m_db.str, trigger->m_name.str); if (sp_add_used_routine(prelocking_ctx, thd->stmt_arena, - &key, table_list->belong_to_view)) + &key, &sp_handler_trigger, + table_list->belong_to_view)) { trigger->add_used_tables_to_table_list(thd, &prelocking_ctx->query_tables_last, @@ -2473,7 +2486,7 @@ void build_trn_path(THD *thd, const sp_name *trg_name, LEX_STRING *trn_path) @retval FALSE if TRN-file exists. */ -bool check_trn_exists(const LEX_STRING *trn_path) +bool check_trn_exists(const LEX_CSTRING *trn_path) { return access(trn_path->str, F_OK) != 0; } @@ -2494,16 +2507,14 @@ bool check_trn_exists(const LEX_STRING *trn_path) bool load_table_name_for_trigger(THD *thd, const sp_name *trg_name, - const LEX_STRING *trn_path, - LEX_STRING *tbl_name) + const LEX_CSTRING *trn_path, + LEX_CSTRING *tbl_name) { File_parser *parser; struct st_trigname trn_data; - Handle_old_incorrect_trigger_table_hook trigger_table_hook( trn_path->str, &trn_data.trigger_table); - DBUG_ENTER("load_table_name_for_trigger"); /* Parse the TRN-file. */ |