diff options
author | unknown <bell@sanja.is.com.ua> | 2005-07-28 22:39:11 +0300 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2005-07-28 22:39:11 +0300 |
commit | a66928bb24d3f543593d092c085b915459ca5c88 (patch) | |
tree | e93bc8d2975b833cb357ca7658f47ed7c4100ac2 /sql/sql_trigger.cc | |
parent | 482cf550f9cb1bf060aba73ef64d85edee791118 (diff) | |
download | mariadb-git-a66928bb24d3f543593d092c085b915459ca5c88.tar.gz |
store/restore sql_mode which was in force during ctrigger creation (BUG#5891)
other sql_mode fixes
mysql-test/r/information_schema.result:
changes in information schema
mysql-test/r/trigger.result:
storing and restoring sql modes for triggers
mysql-test/t/trigger.test:
storing and restoring parsing modes for triggers
sql/mysqld.cc:
add length of mode names
sql/parse_file.cc:
new type of list (ulonglong)
sql/parse_file.h:
new type of list (ulonglong)
sql/set_var.cc:
mode output made as static method
sql/set_var.h:
mode output made as static method
sql/sp_head.cc:
added sql_mode storing/restoring during SP execution
optimised sql_mode printing
sql/sp_head.h:
comment fixed according this changes
sql/sql_show.cc:
added sql_mode field
sql/sql_trigger.cc:
store/restore sql_mode which was in force during ctrigger creation
sql/sql_trigger.h:
store/restore sql_mode which was in force during ctrigger creation
sql/sql_view.cc:
fixed sql_mode
Diffstat (limited to 'sql/sql_trigger.cc')
-rw-r--r-- | sql/sql_trigger.cc | 91 |
1 files changed, 76 insertions, 15 deletions
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index a7aee95197e..c739511dda0 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -32,8 +32,12 @@ const char * const triggers_file_ext= ".TRG"; */ static File_option triggers_file_parameters[]= { - {{(char*)"triggers", 8}, offsetof(class Table_triggers_list, definitions_list), - FILE_OPTIONS_STRLIST}, + {{(char*)"triggers", 8}, + offsetof(class Table_triggers_list, definitions_list), + FILE_OPTIONS_STRLIST}, + {{(char*)"sql_modes", 13}, + offsetof(class Table_triggers_list, definition_modes_list), + FILE_OPTIONS_ULLLIST}, {{0, 0}, 0, FILE_OPTIONS_STRING} }; @@ -127,12 +131,13 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) DBUG_RETURN(TRUE); /* - We do not allow creation of triggers on views or temporary tables. - We have to do this check here and not in - Table_triggers_list::create_trigger() because we want to avoid messing - with table cash for views and temporary tables. + We do not allow creation of triggers on temporary tables. We also don't + allow creation of triggers on views but fulfilment of this restriction + is guaranteed by open_ltable(). It is better to have this check here + than do it in Table_triggers_list::create_trigger() and mess with table + cache. */ - if (tables->view || table->s->tmp_table != NO_TMP_TABLE) + if (table->s->tmp_table != NO_TMP_TABLE) { my_error(ER_TRG_ON_VIEW_OR_TEMP_TABLE, MYF(0), tables->alias); DBUG_RETURN(TRUE); @@ -221,6 +226,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) trigname_path[FN_REFLEN]; LEX_STRING dir, file, trigname_file; LEX_STRING *trg_def, *name; + ulonglong *trg_sql_mode; Item_trigger_field *trg_field; struct st_trigname trigname; @@ -307,11 +313,15 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables) */ if (!(trg_def= (LEX_STRING *)alloc_root(&table->mem_root, sizeof(LEX_STRING))) || - definitions_list.push_back(trg_def, &table->mem_root)) + definitions_list.push_back(trg_def, &table->mem_root) || + !(trg_sql_mode= (ulonglong*)alloc_root(&table->mem_root, + sizeof(ulonglong))) || + definition_modes_list.push_back(trg_sql_mode, &table->mem_root)) goto err_with_cleanup; trg_def->str= thd->query; trg_def->length= thd->query_length; + *trg_sql_mode= thd->variables.sql_mode; if (!sql_create_definition_file(&dir, &file, &triggers_file_type, (gptr)this, triggers_file_parameters, 3)) @@ -390,11 +400,13 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) LEX_STRING *name; List_iterator_fast<LEX_STRING> it_name(names_list); List_iterator<LEX_STRING> it_def(definitions_list); + List_iterator<ulonglong> it_mod(definition_modes_list); char path[FN_REFLEN]; while ((name= it_name++)) { it_def++; + it_mod++; if (my_strcasecmp(system_charset_info, lex->spname->m_name.str, name->str) == 0) @@ -404,6 +416,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables) clean trigger removing since table will be reopened anyway. */ it_def.remove(); + it_mod.remove(); if (definitions_list.is_empty()) { @@ -549,10 +562,48 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, if (!triggers) DBUG_RETURN(1); + /* + We don't have sql_modes in old versions of .TRG file, so we should + initialize list for safety. + */ + triggers->definition_modes_list.empty(); + if (parser->parse((gptr)triggers, &table->mem_root, - triggers_file_parameters, 1)) + triggers_file_parameters, 2)) DBUG_RETURN(1); + List_iterator_fast<LEX_STRING> it(triggers->definitions_list); + LEX_STRING *trg_create_str, *trg_name_str; + ulonglong *trg_sql_mode; + + if (triggers->definition_modes_list.is_empty() && + !triggers->definitions_list.is_empty()) + { + /* + It is old file format => we should fill list of sql_modes. + + We use one mode (current) for all triggers, because we have not + information about mode in old format. + */ + if (!(trg_sql_mode= (ulonglong*)alloc_root(&table->mem_root, + sizeof(ulonglong)))) + { + DBUG_RETURN(1); // EOM + } + *trg_sql_mode= global_system_variables.sql_mode; + while ((trg_create_str= it++)) + { + if (triggers->definition_modes_list.push_back(trg_sql_mode, + &table->mem_root)) + { + DBUG_RETURN(1); // EOM + } + } + it.rewind(); + } + + DBUG_ASSERT(triggers->definition_modes_list.elements == + triggers->definitions_list.elements); table->triggers= triggers; /* @@ -574,15 +625,17 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, if (!names_only && triggers->prepare_record1_accessors(table)) DBUG_RETURN(1); - List_iterator_fast<LEX_STRING> it(triggers->definitions_list); - LEX_STRING *trg_create_str, *trg_name_str; char *trg_name_buff; + List_iterator_fast<ulonglong> itm(triggers->definition_modes_list); LEX *old_lex= thd->lex, lex; + ulong save_sql_mode= thd->variables.sql_mode; thd->lex= &lex; while ((trg_create_str= it++)) { + trg_sql_mode= itm++; + thd->variables.sql_mode= (ulong)*trg_sql_mode; lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length); if (yyparse((void *)thd) || thd->is_fatal_error) @@ -595,9 +648,11 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, goto err_with_lex_cleanup; } + lex.sphead->m_sql_mode= *trg_sql_mode; triggers->bodies[lex.trg_chistics.event] [lex.trg_chistics.action_time]= lex.sphead; - if (triggers->names_list.push_back(&lex.sphead->m_name, &table->mem_root)) + if (triggers->names_list.push_back(&lex.sphead->m_name, + &table->mem_root)) goto err_with_lex_cleanup; if (names_only) @@ -611,8 +666,9 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, in old/new versions of row in trigger to Field objects in table being opened. - We ignore errors here, because if even something is wrong we still will - be willing to open table to perform some operations (e.g. SELECT)... + We ignore errors here, because if even something is wrong we still + will be willing to open table to perform some operations (e.g. + SELECT)... Anyway some things can be checked only during trigger execution. */ for (Item_trigger_field *trg_field= @@ -624,6 +680,7 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db, lex_end(&lex); } thd->lex= old_lex; + thd->variables.sql_mode= save_sql_mode; DBUG_RETURN(0); @@ -631,6 +688,7 @@ err_with_lex_cleanup: // QQ: anything else ? lex_end(&lex); thd->lex= old_lex; + thd->variables.sql_mode= save_sql_mode; DBUG_RETURN(1); } @@ -657,6 +715,7 @@ err_with_lex_cleanup: time_type - trigger action time name - returns name of trigger stmt - returns statement of trigger + sql_mode - returns sql_mode of trigger RETURN VALUE False - success @@ -666,7 +725,8 @@ err_with_lex_cleanup: bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event, trg_action_time_type time_type, LEX_STRING *trigger_name, - LEX_STRING *trigger_stmt) + LEX_STRING *trigger_stmt, + ulong *sql_mode) { sp_head *body; DBUG_ENTER("get_trigger_info"); @@ -674,6 +734,7 @@ bool Table_triggers_list::get_trigger_info(THD *thd, trg_event_type event, { *trigger_name= body->m_name; *trigger_stmt= body->m_body; + *sql_mode= body->m_sql_mode; DBUG_RETURN(0); } DBUG_RETURN(1); |