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
This commit is contained in:
parent
b34d5bd247
commit
bf58b698e2
@ -845,6 +845,15 @@ select * from v1;
|
|||||||
cast(1 as char(3))
|
cast(1 as char(3))
|
||||||
1
|
1
|
||||||
drop view v1;
|
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 v1 as select 'a',1;
|
||||||
create view v2 as select * from v1 union all select * from v1;
|
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);
|
create view v3 as select * from v2 where 1 = (select `1` from v2);
|
||||||
|
@ -785,6 +785,19 @@ show create view v1;
|
|||||||
select * from v1;
|
select * from v1;
|
||||||
drop view 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
|
# bug handling from VIEWs
|
||||||
#
|
#
|
||||||
|
@ -5413,3 +5413,5 @@ ER_VIEW_OTHER_USER
|
|||||||
eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
|
eng "You need the SUPER privilege for creation view with %-.64s@%-.64s definer"
|
||||||
ER_NO_SUCH_USER
|
ER_NO_SUCH_USER
|
||||||
eng "There is not %-.64s@%-.64s registered"
|
eng "There is not %-.64s@%-.64s registered"
|
||||||
|
ER_FORBID_SCHEMA_CHANGE
|
||||||
|
eng "Changing schema from '%-.64s' to '%-.64s' is not allowed."
|
||||||
|
@ -133,6 +133,7 @@ static TABLE_LIST *
|
|||||||
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
|
||||||
{
|
{
|
||||||
TABLE_LIST *ren_table,*new_table;
|
TABLE_LIST *ren_table,*new_table;
|
||||||
|
frm_type_enum frm_type;
|
||||||
DBUG_ENTER("rename_tables");
|
DBUG_ENTER("rename_tables");
|
||||||
|
|
||||||
for (ren_table= table_list; ren_table; ren_table= new_table->next_local)
|
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,
|
ren_table->db, old_alias,
|
||||||
reg_ext);
|
reg_ext);
|
||||||
unpack_filename(name, name);
|
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);
|
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
|
||||||
if (!skip_error)
|
if (!skip_error)
|
||||||
DBUG_RETURN(ren_table);
|
DBUG_RETURN(ren_table);
|
||||||
}
|
}
|
||||||
else if (mysql_rename_table(table_type,
|
else {
|
||||||
ren_table->db, old_alias,
|
int rc= 1;
|
||||||
new_table->db, new_alias))
|
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);
|
DBUG_RETURN(ren_table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
100
sql/sql_view.cc
100
sql/sql_view.cc
@ -479,8 +479,12 @@ err:
|
|||||||
|
|
||||||
/* index of revision number in following table */
|
/* index of revision number in following table */
|
||||||
static const int revision_number_position= 8;
|
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 */
|
/* index of last required parameter for making view */
|
||||||
static const int required_view_parameters= 10;
|
static const int required_view_parameters= 10;
|
||||||
|
/* number of backups */
|
||||||
|
static const int num_view_backups= 3;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
table of VIEW .frm field descriptors
|
table of VIEW .frm field descriptors
|
||||||
@ -708,7 +712,7 @@ loop_out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sql_create_definition_file(&dir, &file, view_file_type,
|
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);
|
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_WRONG_CHECKSUM :
|
||||||
HA_ADMIN_OK);
|
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);
|
||||||
|
}
|
||||||
|
@ -34,6 +34,7 @@ int view_checksum(THD *thd, TABLE_LIST *view);
|
|||||||
extern TYPELIB updatable_views_with_limit_typelib;
|
extern TYPELIB updatable_views_with_limit_typelib;
|
||||||
|
|
||||||
bool check_duplicate_names(List<Item>& item_list, bool gen_unique_view_names);
|
bool check_duplicate_names(List<Item>& item_list, bool gen_unique_view_names);
|
||||||
|
bool mysql_rename_view(THD *thd, const char *new_name, TABLE_LIST *view);
|
||||||
|
|
||||||
#define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL)
|
#define VIEW_ANY_ACL (SELECT_ACL | UPDATE_ACL | INSERT_ACL | DELETE_ACL)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user