Commit e4e2e502 authored by unknown's avatar unknown
Browse files

Fix for BUG#15921: DROP TRIGGER - can't be drop trigger created

in older version.

The problem is that TRN-files created in "old" versions contain
junk in trigger_table field, which is not acceptable in "new" versions.


sql/parse_file.cc:
  1. Made parse_escaped_string() available globally;
  2. Polishing: fixing the comments.
sql/parse_file.h:
  Made parse_escaped_string() available globally.
sql/sql_trigger.cc:
  1. Polishing
  2. Removed declaration of global handle_old_incorrect_sql_modes()
     since it is not used anymore.
  3. Added a hook to support invalid "trigger_table" field in TRN-file
     from old versions.
parent ce494285
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -533,7 +533,7 @@ parse_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
  read escaped string from ptr to eol in already allocated str

  SYNOPSIS
    parse_escaped_string()
    read_escaped_string()
    ptr		- pointer on string beginning
    eol		- pointer on character after end of string
    str		- target string
@@ -604,7 +604,7 @@ read_escaped_string(char *ptr, char *eol, LEX_STRING *str)
    #	- pointer on symbol after string
*/

static char *
char *
parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
{
  char *eol= strchr(ptr, '\n');
@@ -622,7 +622,7 @@ parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str)
  parse '' delimited escaped string

  SYNOPSIS
    parse_escaped_string()
    parse_quoted_escaped_string()
    ptr		- pointer on string beginning
    end		- pointer on symbol after parsed string end (still owned
		  by buffer and can be accessed
+3 −0
Original line number Diff line number Diff line
@@ -72,6 +72,9 @@ bool get_file_options_ulllist(char *&ptr, char *end, char *line,
                              gptr base, File_option *parameter,
                              MEM_ROOT *mem_root);

char *
parse_escaped_string(char *ptr, char *end, MEM_ROOT *mem_root, LEX_STRING *str);

class File_parser;
File_parser *sql_parse_prepare(const LEX_STRING *file_name,
			       MEM_ROOT *mem_root, bool bad_format_errors);
+61 −7
Original line number Diff line number Diff line
@@ -109,10 +109,6 @@ const LEX_STRING trg_event_type_names[]=

static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig);

bool handle_old_incorrect_sql_modes(char *&unknown_key, gptr base,
                                    MEM_ROOT *mem_root,
                                    char *end, gptr hook_data);

class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook
{
private:
@@ -125,6 +121,20 @@ class Handle_old_incorrect_sql_modes_hook: public Unknown_key_hook
                                      MEM_ROOT *mem_root, char *end);
};

class Handle_old_incorrect_trigger_table_hook: public Unknown_key_hook
{
public:
  Handle_old_incorrect_trigger_table_hook(char *file_path,
                                          LEX_STRING *trigger_table_arg)
    :path(file_path), trigger_table_value(trigger_table_arg)
  {};
  virtual bool process_unknown_string(char *&unknown_key, gptr base,
                                      MEM_ROOT *mem_root, char *end);
private:
  char *path;
  LEX_STRING *trigger_table_value;
};

/*
  Create or drop trigger for table.

@@ -1130,6 +1140,9 @@ static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig)
  LEX_STRING path;
  File_parser *parser;
  struct st_trigname trigname;
  Handle_old_incorrect_trigger_table_hook trigger_table_hook(
                                          path_buff, &trigname.trigger_table);
  
  DBUG_ENTER("add_table_for_trigger");

  strxnmov(path_buff, FN_REFLEN, mysql_data_home, "/", trig->m_db.str, "/",
@@ -1155,7 +1168,7 @@ static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig)

  if (parser->parse((gptr)&trigname, thd->mem_root,
                    trigname_file_parameters, 1,
                    &file_parser_dummy_hook))
                    &trigger_table_hook))
    DBUG_RETURN(0);

  /* We need to reset statement table list to be PS/SP friendly. */
@@ -1542,7 +1555,7 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
                                                            MEM_ROOT *mem_root,
                                                            char *end)
{
  DBUG_ENTER("handle_old_incorrect_sql_modes");
  DBUG_ENTER("Handle_old_incorrect_sql_modes_hook::process_unknown_string");
  DBUG_PRINT("info", ("unknown key:%60s", unknown_key));

  if (unknown_key + INVALID_SQL_MODES_LENGTH + 1 < end &&
@@ -1571,3 +1584,44 @@ Handle_old_incorrect_sql_modes_hook::process_unknown_string(char *&unknown_key,
  }
  DBUG_RETURN(FALSE);
}

/*
  Trigger BUG#15921 compatibility hook. For details see
  Handle_old_incorrect_sql_modes_hook::process_unknown_string().
*/

#define INVALID_TRIGGER_TABLE_LENGTH 15

bool
Handle_old_incorrect_trigger_table_hook::
process_unknown_string(char *&unknown_key, gptr base, MEM_ROOT *mem_root,
                       char *end)
{
  DBUG_ENTER("Handle_old_incorrect_trigger_table_hook::process_unknown_string");
  DBUG_PRINT("info", ("unknown key:%60s", unknown_key));

  if (unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1 < end &&
      unknown_key[INVALID_TRIGGER_TABLE_LENGTH] == '=' &&
      !memcmp(unknown_key, STRING_WITH_LEN("trigger_table")))
  {
    char *ptr= unknown_key + INVALID_TRIGGER_TABLE_LENGTH + 1;

    DBUG_PRINT("info", ("trigger_table affected by BUG#15921 detected"));
    push_warning_printf(current_thd,
                        MYSQL_ERROR::WARN_LEVEL_NOTE,
                        ER_OLD_FILE_FORMAT,
                        ER(ER_OLD_FILE_FORMAT),
                        (char *)path, "TRIGGER");

    if (!(ptr= parse_escaped_string(ptr, end, mem_root, trigger_table_value)))
    {
      my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), "trigger_table",
               unknown_key);
      DBUG_RETURN(TRUE);
    }

    /* Set parsing pointer to the last symbol of string (\n). */
    unknown_key= ptr-1;
  }
  DBUG_RETURN(FALSE);
}