diff options
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r-- | sql/sql_trigger.cc | 133 |
1 files changed, 66 insertions, 67 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index e806dd4a3f3..6af88541c86 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -196,20 +196,26 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) DBUG_ASSERT(tables->next_global == 0); /* - TODO: We should check if user has TRIGGER privilege for table here. - Now we just require SUPER privilege for creating/dropping because - we don't have proper privilege checking for triggers in place yet. + Check that the user has TRIGGER privilege on the subject table. */ - if (check_global_access(thd, SUPER_ACL)) - DBUG_RETURN(TRUE); + { + bool err_status; + TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last; + thd->lex->query_tables_own_last= 0; + + err_status= check_table_access(thd, TRIGGER_ACL, tables, 0); + + thd->lex->query_tables_own_last= save_query_tables_own_last; + + if (err_status) + DBUG_RETURN(TRUE); + } /* There is no DETERMINISTIC clause for triggers, so can't check it. But a trigger can in theory be used to do nasty things (if it supported - DROP for example) so we do the check for privileges. For now there is - already a stronger test right above; but when this stronger test will - be removed, the test below will hold. Because triggers have the same - nature as functions regarding binlogging: their body is implicitely + DROP for example) so we do the check for privileges. Triggers have the + same nature as functions regarding binlogging: their body is implicitely binlogged, so they share the same danger, so trust_function_creators applies to them too. */ @@ -221,7 +227,7 @@ 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 && find_temporary_table(thd, tables->db, tables->table_name)) + if (create && find_temporary_table(thd, tables)) { my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); DBUG_RETURN(TRUE); @@ -357,9 +363,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, { LEX *lex= thd->lex; TABLE *table= tables->table; - char dir_buff[FN_REFLEN], file_buff[FN_REFLEN], trigname_buff[FN_REFLEN], - trigname_path[FN_REFLEN]; - LEX_STRING dir, file, trigname_file; + char file_buff[FN_REFLEN], trigname_buff[FN_REFLEN]; + LEX_STRING file, trigname_file; LEX_STRING *trg_def, *name; ulonglong *trg_sql_mode; char trg_definer_holder[USER_HOST_BUFF_SIZE]; @@ -369,7 +374,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, /* Trigger must be in the same schema as target table. */ - if (my_strcasecmp(table_alias_charset, table->s->db, lex->spname->m_db.str)) + if (my_strcasecmp(table_alias_charset, table->s->db.str, + lex->spname->m_db.str)) { my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0)); return 1; @@ -463,20 +469,18 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, sql_create_definition_file() files handles renaming and backup of older versions */ - strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", tables->db, "/", NullS); - dir.length= unpack_filename(dir_buff, dir_buff); - dir.str= dir_buff; - file.length= strxnmov(file_buff, FN_REFLEN, tables->table_name, - triggers_file_ext, NullS) - file_buff; + file.length= build_table_filename(file_buff, FN_REFLEN-1, + tables->db, tables->table_name, + triggers_file_ext); file.str= file_buff; - trigname_file.length= strxnmov(trigname_buff, FN_REFLEN, - lex->spname->m_name.str, - trigname_file_ext, NullS) - trigname_buff; + trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, + tables->db, + lex->spname->m_name.str, + trigname_file_ext); trigname_file.str= trigname_buff; - strxnmov(trigname_path, FN_REFLEN, dir_buff, trigname_buff, NullS); /* Use the filesystem to enforce trigger namespace constraints. */ - if (!access(trigname_path, F_OK)) + if (!access(trigname_buff, F_OK)) { my_error(ER_TRG_ALREADY_EXISTS, MYF(0)); return 1; @@ -485,7 +489,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trigname.trigger_table.str= tables->table_name; trigname.trigger_table.length= tables->table_name_length; - if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, + if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, (gptr)&trigname, trigname_file_parameters, 0)) return 1; @@ -550,12 +554,12 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, trg_definer->length= 0; } - if (!sql_create_definition_file(&dir, &file, &triggers_file_type, + if (!sql_create_definition_file(NULL, &file, &triggers_file_type, (gptr)this, triggers_file_parameters, 0)) return 0; err_with_cleanup: - my_delete(trigname_path, MYF(MY_WME)); + my_delete(trigname_buff, MYF(MY_WME)); return 1; } @@ -578,9 +582,7 @@ err_with_cleanup: static bool rm_trigger_file(char *path, const char *db, const char *table_name) { - strxnmov(path, FN_REFLEN, mysql_data_home, "/", db, "/", table_name, - triggers_file_ext, NullS); - unpack_filename(path, path); + build_table_filename(path, FN_REFLEN-1, db, table_name, triggers_file_ext); return my_delete(path, MYF(MY_WME)); } @@ -603,9 +605,7 @@ static bool rm_trigger_file(char *path, const char *db, static bool rm_trigname_file(char *path, const char *db, const char *trigger_name) { - strxnmov(path, FN_REFLEN, mysql_data_home, "/", db, "/", trigger_name, - trigname_file_ext, NullS); - unpack_filename(path, path); + build_table_filename(path, FN_REFLEN-1, db, trigger_name, trigname_file_ext); return my_delete(path, MYF(MY_WME)); } @@ -627,18 +627,15 @@ static bool rm_trigname_file(char *path, const char *db, static bool save_trigger_file(Table_triggers_list *triggers, const char *db, const char *table_name) { - char dir_buff[FN_REFLEN], file_buff[FN_REFLEN]; - LEX_STRING dir, file; - - strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", db, "/", NullS); - dir.length= unpack_filename(dir_buff, dir_buff); - dir.str= dir_buff; - file.length= strxnmov(file_buff, FN_REFLEN, table_name, triggers_file_ext, - NullS) - file_buff; - file.str= file_buff; + char file_buff[FN_REFLEN]; + LEX_STRING file; - return sql_create_definition_file(&dir, &file, &triggers_file_type, - (gptr)triggers, triggers_file_parameters, 0); + file.length= build_table_filename(file_buff, FN_REFLEN-1, db, table_name, + triggers_file_ext); + file.str= file_buff; + return sql_create_definition_file(NULL, &file, &triggers_file_type, + (gptr)triggers, triggers_file_parameters, + 0); } @@ -753,7 +750,7 @@ bool Table_triggers_list::prepare_record1_accessors(TABLE *table) if (!(*old_fld= (*fld)->new_field(&table->mem_root, table, table == (*fld)->table))) return 1; - (*old_fld)->move_field((my_ptrdiff_t)(table->record[1] - + (*old_fld)->move_field_offset((my_ptrdiff_t)(table->record[1] - table->record[0])); } *old_fld= 0; @@ -808,9 +805,8 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, DBUG_ENTER("Table_triggers_list::check_n_load"); - strxnmov(path_buff, FN_REFLEN, mysql_data_home, "/", db, "/", table_name, - triggers_file_ext, NullS); - path.length= unpack_filename(path_buff, path_buff); + path.length= build_table_filename(path_buff, FN_REFLEN-1, + db, table_name, triggers_file_ext); path.str= path_buff; // QQ: should we analyze errno somehow ? @@ -990,7 +986,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, schema. */ - lex.sphead->set_definer("", 0); + lex.sphead->set_definer((char*) "", 0); /* Triggers without definer information are executed under the @@ -1164,9 +1160,9 @@ static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig) DBUG_ENTER("add_table_for_trigger"); - strxnmov(path_buff, FN_REFLEN, mysql_data_home, "/", trig->m_db.str, "/", - trig->m_name.str, trigname_file_ext, NullS); - path.length= unpack_filename(path_buff, path_buff); + path.length= build_table_filename(path_buff, FN_REFLEN-1, + trig->m_db.str, trig->m_name.str, + trigname_file_ext); path.str= path_buff; if (access(path_buff, F_OK)) @@ -1363,26 +1359,24 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name, LEX_STRING *new_table_name, LEX_STRING *stopper) { - char dir_buff[FN_REFLEN], trigname_buff[FN_REFLEN]; + char trigname_buff[FN_REFLEN]; struct st_trigname trigname; - LEX_STRING dir, trigname_file; + LEX_STRING trigname_file; LEX_STRING *trigger; List_iterator_fast<LEX_STRING> it_name(names_list); - strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", db_name, "/", NullS); - dir.length= unpack_filename(dir_buff, dir_buff); - dir.str= dir_buff; - while ((trigger= it_name++) != stopper) { - trigname_file.length= strxnmov(trigname_buff, FN_REFLEN, trigger->str, - trigname_file_ext, NullS) - trigname_buff; + trigname_file.length= build_table_filename(trigname_buff, FN_REFLEN-1, + db_name, trigger->str, + trigname_file_ext); trigname_file.str= trigname_buff; trigname.trigger_table= *new_table_name; - if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, - (gptr)&trigname, trigname_file_parameters, 0)) + if (sql_create_definition_file(NULL, &trigname_file, &trigname_file_type, + (gptr)&trigname, trigname_file_parameters, + 0)) return trigger; } @@ -1437,8 +1431,8 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, } if (table.triggers) { - LEX_STRING_WITH_INIT old_table_name(old_table, strlen(old_table)); - LEX_STRING_WITH_INIT new_table_name(new_table, strlen(new_table)); + LEX_STRING old_table_name= { (char *) old_table, strlen(old_table) }; + 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. @@ -1527,12 +1521,12 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, DESCRIPTION This method marks fields of subject table which are read/set in its - triggers as such (by setting Field::query_id equal to THD::query_id) + triggers as such (by properly updating TABLE::read_set/write_set) and thus informs handler that values for these fields should be retrieved/stored during execution of statement. */ -void Table_triggers_list::mark_fields_used(THD *thd, trg_event_type event) +void Table_triggers_list::mark_fields_used(trg_event_type event) { int action_time; Item_trigger_field *trg_field; @@ -1544,9 +1538,14 @@ void Table_triggers_list::mark_fields_used(THD *thd, trg_event_type event) { /* We cannot mark fields which does not present in table. */ if (trg_field->field_idx != (uint)-1) - table->field[trg_field->field_idx]->query_id = thd->query_id; + { + bitmap_set_bit(table->read_set, trg_field->field_idx); + if (trg_field->get_settable_routine_parameter()) + bitmap_set_bit(table->write_set, trg_field->field_idx); + } } } + table->file->column_bitmaps_signal(); } |