summaryrefslogtreecommitdiff
path: root/sql/sql_trigger.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r--sql/sql_trigger.cc133
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();
}