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.cc126
1 files changed, 52 insertions, 74 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index dc0c151114e..1fa7f59ca01 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 <my_global.h> /* NO_EMBEDDED_ACCESS_CHECKS */
#include "sql_priv.h"
#include "unireg.h"
#include "sp_head.h"
@@ -158,7 +158,7 @@ Trigger_creation_ctx::create(THD *thd,
if (invalid_creation_ctx)
{
push_warning_printf(thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
+ Sql_condition::WARN_LEVEL_WARN,
ER_TRG_INVALID_CREATION_CTX,
ER(ER_TRG_INVALID_CREATION_CTX),
(const char *) db_name,
@@ -330,9 +330,9 @@ public:
virtual bool handle_condition(THD *thd,
uint sql_errno,
const char* sqlstate,
- MYSQL_ERROR::enum_warning_level level,
+ Sql_condition::enum_warning_level level,
const char* message,
- MYSQL_ERROR ** cond_hdl)
+ Sql_condition ** cond_hdl)
{
if (sql_errno != EE_OUTOFMEMORY &&
sql_errno != ER_OUT_OF_RESOURCES)
@@ -444,7 +444,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
if (!create)
{
- bool if_exists= thd->lex->drop_if_exists;
+ bool if_exists= thd->lex->check_exists;
/*
Protect the query table list from the temporary and potentially
@@ -569,13 +569,13 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
if (result)
goto end;
- close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED);
+ close_all_tables_for_name(thd, table->s, HA_EXTRA_NOT_USED, NULL);
/*
Reopen the table if we were under LOCK TABLES.
Ignore the return value for now. It's better to
keep master/slave in consistent state.
*/
- if (thd->locked_tables_list.reopen_tables(thd))
+ if (thd->locked_tables_list.reopen_tables(thd, false))
thd->clear_error();
/*
@@ -596,7 +596,7 @@ end:
with the implicit commit.
*/
if (thd->locked_tables_mode && tables && lock_upgrade_done)
- mdl_ticket->downgrade_exclusive_lock(MDL_SHARED_NO_READ_WRITE);
+ mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
/* Restore the query table list. Used only for drop trigger. */
if (!create)
@@ -671,46 +671,8 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
return 1;
}
- if (!lex->definer)
- {
- /*
- DEFINER-clause is missing.
-
- If we are in slave thread, this means that we received CREATE TRIGGER
- from the master, that does not support definer in triggers. So, we
- should mark this trigger as non-SUID. Note that this does not happen
- when we parse triggers' definitions during opening .TRG file.
- LEX::definer is ignored in that case.
-
- Otherwise, we should use CURRENT_USER() as definer.
-
- NOTE: when CREATE TRIGGER statement is allowed to be executed in PS/SP,
- it will be required to create the definer below in persistent MEM_ROOT
- of PS/SP.
- */
-
- if (!thd->slave_thread)
- {
- if (!(lex->definer= create_default_definer(thd)))
- return 1;
- }
- }
-
- /*
- If the specified definer differs from the current user, we should check
- that the current user has SUPER privilege (in order to create trigger
- under another user one must have SUPER privilege).
- */
-
- if (lex->definer &&
- (strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
- my_strcasecmp(system_charset_info,
- lex->definer->host.str,
- thd->security_ctx->priv_host)))
- {
- if (check_global_access(thd, SUPER_ACL))
- return TRUE;
- }
+ if (sp_process_definer(thd))
+ return 1;
/*
Let us check if all references to fields in old/new versions of row in
@@ -802,29 +764,14 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*trg_sql_mode= thd->variables.sql_mode;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (lex->definer && !is_acl_user(lex->definer->host.str,
- lex->definer->user.str))
- {
- push_warning_printf(thd,
- MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_NO_SUCH_USER,
- ER(ER_NO_SUCH_USER),
- lex->definer->user.str,
- lex->definer->host.str);
- }
-#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-
- if (lex->definer)
+ if (lex->sphead->m_chistics->suid != SP_IS_NOT_SUID)
{
/* SUID trigger. */
definer_user= lex->definer->user;
definer_host= lex->definer->host;
- trg_definer->str= trg_definer_holder;
- trg_definer->length= strxmov(trg_definer->str, definer_user.str, "@",
- definer_host.str, NullS) - trg_definer->str;
+ lex->definer->set_lex_string(trg_definer, trg_definer_holder);
}
else
{
@@ -862,7 +809,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
stmt_query->append(STRING_WITH_LEN("CREATE "));
- if (trg_definer)
+ if (lex->sphead->m_chistics->suid != SP_IS_NOT_SUID)
{
/*
Append definer-clause if the trigger is SUID (a usual trigger in
@@ -1282,7 +1229,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
DBUG_RETURN(1); // EOM
}
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRG_NO_CREATION_CTX,
ER(ER_TRG_NO_CREATION_CTX),
(const char*) db,
@@ -1466,7 +1413,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
warning here.
*/
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRG_NO_DEFINER, ER(ER_TRG_NO_DEFINER),
(const char*) db,
(const char*) sp->m_name.str);
@@ -1739,7 +1686,7 @@ bool add_table_for_trigger(THD *thd,
if (if_exists)
{
push_warning_printf(thd,
- MYSQL_ERROR::WARN_LEVEL_NOTE,
+ Sql_condition::WARN_LEVEL_NOTE,
ER_TRG_DOES_NOT_EXIST,
ER(ER_TRG_DOES_NOT_EXIST));
@@ -1784,7 +1731,7 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, char *db, char *name)
DBUG_ENTER("drop_all_triggers");
bzero(&table, sizeof(table));
- init_sql_alloc(&table.mem_root, 8192, 0);
+ init_sql_alloc(&table.mem_root, 8192, 0, MYF(0));
if (Table_triggers_list::check_n_load(thd, db, name, &table, 1))
{
@@ -2004,7 +1951,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db,
DBUG_ENTER("change_table_name");
bzero(&table, sizeof(table));
- init_sql_alloc(&table.mem_root, 8192, 0);
+ init_sql_alloc(&table.mem_root, 8192, 0, MYF(0));
/*
This method interfaces the mysql server code protected by
@@ -2219,6 +2166,37 @@ add_tables_and_routines_for_triggers(THD *thd,
/**
+ Check if any of the marked fields are used in the trigger.
+
+ @param used_fields Bitmap over fields to check
+ @param event_type Type of event triggers for which we are going to inspect
+ @param action_time Type of trigger action time we are going to inspect
+*/
+
+bool Table_triggers_list::is_fields_updated_in_trigger(MY_BITMAP *used_fields,
+ trg_event_type event_type,
+ trg_action_time_type action_time)
+{
+ Item_trigger_field *trg_field;
+ sp_head *sp= bodies[event_type][action_time];
+ DBUG_ASSERT(used_fields->n_bits == trigger_table->s->fields);
+
+ for (trg_field= sp->m_trg_table_fields.first; trg_field;
+ trg_field= trg_field->next_trg_field)
+ {
+ /* We cannot check fields which does not present in table. */
+ if (trg_field->field_idx != (uint)-1)
+ {
+ if (bitmap_is_set(used_fields, trg_field->field_idx) &&
+ trg_field->get_settable_routine_parameter())
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**
Mark fields of subject table which we read/set in its triggers
as such.
@@ -2258,7 +2236,7 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
/**
- Signals to the Table_triggers_list that a parse error has occured when
+ Signals to the Table_triggers_list that a parse error has occurred when
reading a trigger from file. This makes the Table_triggers_list enter an
error state flagged by m_has_unparseable_trigger == true. The error message
will be used whenever a statement invoking or manipulating triggers is
@@ -2313,7 +2291,7 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
DBUG_PRINT("info", ("sql_modes affected by BUG#14090 detected"));
push_warning_printf(current_thd,
- MYSQL_ERROR::WARN_LEVEL_NOTE,
+ Sql_condition::WARN_LEVEL_NOTE,
ER_OLD_FILE_FORMAT,
ER(ER_OLD_FILE_FORMAT),
(char *)path, "TRIGGER");
@@ -2354,7 +2332,7 @@ process_unknown_string(char *&unknown_key, uchar* base, MEM_ROOT *mem_root,
DBUG_PRINT("info", ("trigger_table affected by BUG#15921 detected"));
push_warning_printf(current_thd,
- MYSQL_ERROR::WARN_LEVEL_NOTE,
+ Sql_condition::WARN_LEVEL_NOTE,
ER_OLD_FILE_FORMAT,
ER(ER_OLD_FILE_FORMAT),
(char *)path, "TRIGGER");