1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

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
This commit is contained in:
unknown
2005-07-28 22:39:11 +03:00
parent 482cf550f9
commit a66928bb24
14 changed files with 345 additions and 77 deletions

View File

@ -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);