Commit bf58b698 authored by unknown's avatar unknown
Browse files

Fix for bug#5508 after Sanja's review


mysql-test/r/view.result:
  test results for rename table view1 to view2
mysql-test/t/view.test:
  tests for rename table view1 to view2
sql/share/errmsg.txt:
  added new errormessage (schema change not allowed in rename table view)
sql/sql_rename.cc:
  added support for renaming views
sql/sql_view.cc:
  added new function mysql_rename_view
sql/sql_view.h:
  added prototype mysql_rename_view
parent b34d5bd2
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -845,6 +845,15 @@ select * from v1;
cast(1 as char(3))
1
drop view v1;
create table t1 (a int);
create view v1 as select a from t1;
create database seconddb;
rename table v1 to seconddb.v1;
ERROR HY000: Changing schema from 'test' to 'seconddb' is not allowed.
rename table v1 to v2;
drop table t1;
drop view v2;
drop database seconddb;
create view v1 as select 'a',1;
create view v2 as select * from v1 union all select * from v1;
create view v3 as select * from v2 where 1 = (select `1` from v2);
+13 −0
Original line number Diff line number Diff line
@@ -785,6 +785,19 @@ show create view v1;
select * from v1;
drop view v1;

#
# renaming views
#
create table t1 (a int);
create view v1 as select a from t1;
create database seconddb;
-- error 1450
rename table v1 to seconddb.v1;
rename table v1 to v2;
drop table t1;
drop view v2;
drop database seconddb;

#
# bug handling from VIEWs
#
+2 −0
Original line number Diff line number Diff line
@@ -5413,3 +5413,5 @@ ER_VIEW_OTHER_USER
        eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
ER_NO_SUCH_USER
        eng "There is not %-.64s@%-.64s registered"
ER_FORBID_SCHEMA_CHANGE
	eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
+26 −8
Original line number Diff line number Diff line
@@ -133,6 +133,7 @@ static TABLE_LIST *
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
{
  TABLE_LIST *ren_table,*new_table;
  frm_type_enum frm_type;
  DBUG_ENTER("rename_tables");

  for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
@@ -164,17 +165,34 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
	    ren_table->db, old_alias,
	    reg_ext);
    unpack_filename(name, name);
    if ((table_type=get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
    if ((frm_type= mysql_frm_type(name)) == FRMTYPE_TABLE &&
        (table_type= get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
    {
      my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
      if (!skip_error)
        DBUG_RETURN(ren_table);
    }
    else if (mysql_rename_table(table_type,
				ren_table->db, old_alias,
				new_table->db, new_alias))
    else {
      int rc= 1;
      switch (frm_type)
      {
      if (!skip_error)
        case FRMTYPE_TABLE:
          rc= mysql_rename_table(table_type, ren_table->db, old_alias,
                                 new_table->db, new_alias);
          break;
        case FRMTYPE_VIEW:
          /* change of schema is not allowed */
          if (strcmp(ren_table->db, new_table->db))
            my_error(ER_FORBID_SCHEMA_CHANGE, MYF(0), ren_table->db, 
                     new_table->db);
          else
            rc= mysql_rename_view(thd, new_alias, ren_table);
          break;
        case FRMTYPE_ERROR:
        default:
          my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
      }
      if (rc && !skip_error)
	    DBUG_RETURN(ren_table);
    }
  }
+99 −1
Original line number Diff line number Diff line
@@ -479,8 +479,12 @@ bool mysql_create_view(THD *thd,

/* index of revision number in following table */
static const int revision_number_position= 8;
/* index of source */
static const int source_number_position= 11;
/* index of last required parameter for making view */
static const int required_view_parameters= 10;
/* number of backups */
static const int num_view_backups= 3;

/*
  table of VIEW .frm field descriptors
@@ -708,7 +712,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
  }

  if (sql_create_definition_file(&dir, &file, view_file_type,
				 (gptr)view, view_parameters, 3))
				 (gptr)view, view_parameters, num_view_backups))
  {
    DBUG_RETURN(thd->net.report_error? -1 : 1);
  }
@@ -1367,3 +1371,97 @@ int view_checksum(THD *thd, TABLE_LIST *view)
          HA_ADMIN_WRONG_CHECKSUM :
          HA_ADMIN_OK);
}

bool rename_view_files(const char *schema, const char *old_name, 
                       const char *new_name, ulonglong revision)
{
  char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN];

  strxnmov(old_path, FN_REFLEN, mysql_data_home, "/", schema, "/",
           old_name, reg_ext, NullS);
  (void) unpack_filename(old_path, old_path);

  strxnmov(new_path, FN_REFLEN, mysql_data_home, "/", schema, "/",
           new_name, reg_ext, NullS);
  (void) unpack_filename(new_path, new_path);

  if (my_rename(old_path, new_path, MYF(MY_WME)))
    return 1;

  /* check if arc_dir exists */
  strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS);
  (void) unpack_filename(arc_path, arc_path);
  
  if (revision && !access(arc_path, F_OK))
  {
    while (revision) {
      my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu",
		  arc_path, old_name, reg_ext, (ulong)revision);
      (void) unpack_filename(old_path, old_path);
      my_snprintf(new_path, FN_REFLEN, "%s/%s%s-%04lu",
		  arc_path, new_name, reg_ext, (ulong)revision);
      (void) unpack_filename(new_path, new_path);
      if (my_rename(old_path, new_path, MYF(0)))
        return 0;
      revision--;
    }
  }
  return 0;
}

bool
mysql_rename_view(THD *thd,
		   const char *new_name,
           TABLE_LIST *view)
{
  LEX_STRING pathstr, file;
  File_parser *parser;
  char view_path[FN_REFLEN];

  DBUG_ENTER("mysql_rename_view");

  strxnmov(view_path, FN_REFLEN, mysql_data_home, "/", view->db, "/",
           view->table_name, reg_ext, NullS);
  (void) unpack_filename(view_path, view_path);

  pathstr.str= (char *)view_path;
  pathstr.length= strlen(view_path);

  if ((parser= sql_parse_prepare(&pathstr, thd->mem_root, 1)) && 
       is_equal(&view_type, parser->type())) {
    char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];

    /* get view definition and source */
    if (mysql_make_view(parser, view) ||
        parser->parse((gptr)view, thd->mem_root,
                      view_parameters + source_number_position, 1))
      DBUG_RETURN(1);

    /* rename view and it's backups */
    if (rename_view_files(view->db, view->table_name, new_name, view->revision - 1))
      DBUG_RETURN(1);

    strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS);
    (void) unpack_filename(dir_buff, dir_buff);

    pathstr.str=    (char*)dir_buff;
    pathstr.length= strlen(dir_buff);

    file.str= file_buff;
    file.length= (strxnmov(file_buff, FN_REFLEN, new_name, reg_ext, NullS) 
                  - file_buff);

    if (sql_create_definition_file(&pathstr, &file, view_file_type,
      (gptr)view, view_parameters, num_view_backups)) {
      /* restore renamed view in case of error */
      rename_view_files(view->db, new_name, view->table_name, view->revision - 1);
      DBUG_RETURN(1);
    }
  } else
    DBUG_RETURN(1);  

  /* remove cache entries */
  query_cache_invalidate3(thd, view, 0);
  sp_cache_invalidate();
  DBUG_RETURN(0);
}
Loading