Commit 81eb1ccd authored by unknown's avatar unknown
Browse files

Bug#21370: View renaming lacks tablename_to_filename encoding

  Problem: renaming of FRM file and ARC files didn't use file name
  encoding, so RENAME TABLE for views failed for views having
  "tricky" characters in their names.
  Fix: adding build_table_filename() in missing places.


mysql-test/r/view.result:
  Adding test case
mysql-test/t/view.test:
  Adding test case
sql/parse_file.cc:
  Adding build_table_filename()
sql/sql_view.cc:
  Adding build_table_filename()
parent 27bbf36f
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -2957,3 +2957,22 @@ v1 CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `
DROP VIEW v1;
DROP TABLE t1, t2;
End of 5.0 tests.
DROP DATABASE IF EXISTS `d-1`;
CREATE DATABASE `d-1`;
USE `d-1`;
CREATE TABLE `t-1` (c1 INT);
CREATE VIEW  `v-1` AS SELECT c1 FROM `t-1`;
SHOW TABLES;
Tables_in_d-1
t-1
v-1
RENAME TABLE `t-1` TO `t-2`;
RENAME TABLE `v-1` TO `v-2`;
SHOW TABLES;
Tables_in_d-1
t-2
v-2
DROP TABLE `t-2`;
DROP VIEW  `v-2`;
DROP DATABASE `d-1`;
USE test;
+19 −0
Original line number Diff line number Diff line
@@ -2885,3 +2885,22 @@ SHOW CREATE VIEW v1;
DROP VIEW v1;
DROP TABLE t1, t2;
--echo End of 5.0 tests.

#
# Bug#21370 View renaming lacks tablename_to_filename encoding
#
--disable_warnings
DROP DATABASE IF EXISTS `d-1`;
--enable_warnings
CREATE DATABASE `d-1`;
USE `d-1`;
CREATE TABLE `t-1` (c1 INT);
CREATE VIEW  `v-1` AS SELECT c1 FROM `t-1`;
SHOW TABLES;
RENAME TABLE `t-1` TO `t-2`;
RENAME TABLE `v-1` TO `v-2`;
SHOW TABLES;
DROP TABLE `t-2`;
DROP VIEW  `v-2`;
DROP DATABASE `d-1`;
USE test;
+12 −11
Original line number Diff line number Diff line
@@ -368,32 +368,33 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name,
{
  char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN];

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

  strxnmov(new_path, FN_REFLEN-1, mysql_data_home, "/", schema, "/",
           new_name, reg_ext, NullS);
  (void) unpack_filename(new_path, new_path);
  build_table_filename(old_path, sizeof(old_path) - 1,
                       schema, old_name, reg_ext, 0);
  build_table_filename(new_path, sizeof(new_path) - 1,
                       schema, new_name, reg_ext, 0);

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

  /* check if arc_dir exists */
  strxnmov(arc_path, FN_REFLEN-1, mysql_data_home, "/", schema, "/arc", NullS);
  (void) unpack_filename(arc_path, arc_path);
  build_table_filename(arc_path, sizeof(arc_path) - 1, schema, "arc", "", 0);
  
  if (revision > 0 && !access(arc_path, F_OK))
  {
    char old_name_buf[FN_REFLEN], new_name_buf[FN_REFLEN];
    ulonglong limit= ((revision > num_view_backups) ?
                      revision - num_view_backups : 0);

    VOID(tablename_to_filename(old_name, old_name_buf, sizeof(old_name_buf)));
    VOID(tablename_to_filename(new_name, new_name_buf, sizeof(new_name_buf)));

    for (; revision > limit ; revision--)
    {
      my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu",
		  arc_path, old_name, reg_ext, (ulong)revision);
		  arc_path, old_name_buf, 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);
		  arc_path, new_name_buf, reg_ext, (ulong) revision);
      (void) unpack_filename(new_path, new_path);
      my_rename(old_path, new_path, MYF(0));
    }
+17 −18
Original line number Diff line number Diff line
@@ -1655,24 +1655,23 @@ mysql_rename_view(THD *thd,
                  const char *new_name,
                  TABLE_LIST *view)
{
  LEX_STRING pathstr, file;
  LEX_STRING pathstr;
  File_parser *parser;
  char view_path[FN_REFLEN];
  char path_buff[FN_REFLEN];
  bool error= TRUE;
  DBUG_ENTER("mysql_rename_view");

  strxnmov(view_path, FN_REFLEN-1, 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);
  pathstr.str= (char *) path_buff;
  pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1,
                                       view->db, view->table_name,
                                       reg_ext, 0);

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

    /*
      To be PS-friendly we should either to restore state of
@@ -1695,18 +1694,18 @@ mysql_rename_view(THD *thd,
                              view_def.revision - 1, num_view_backups))
      goto err;

    strxnmov(dir_buff, FN_REFLEN-1, mysql_data_home, "/", view->db, "/",
             NullS);
    (void) unpack_filename(dir_buff, dir_buff);
    dir.str= dir_buff;
    dir.length= build_table_filename(dir_buff, sizeof(dir_buff) - 1,
                                     view->db, "", "", 0);

    pathstr.str=    (char*)dir_buff;
    pathstr.length= strlen(dir_buff);
    pathstr.str= path_buff;
    pathstr.length= build_table_filename(path_buff, sizeof(path_buff) - 1,
                                      view->db, new_name, reg_ext, 0);

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

    if (sql_create_definition_file(&pathstr, &file, view_file_type,
    if (sql_create_definition_file(&dir, &file, view_file_type,
                                   (gptr)&view_def, view_parameters,
                                   num_view_backups)) 
    {