Commit 015d55b7 authored by unknown's avatar unknown

Merge grichter@bk-internal.mysql.com:/home/bk/mysql-5.0

into lmy002.wdf.sap.corp:/home/georg/work/mysql/bugs/mysql-5.0-master


mysql-test/r/view.result:
  Auto merged
mysql-test/t/view.test:
  Auto merged
sql/sql_view.cc:
  Auto merged
parents d4da0420 458aa0e3
......@@ -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);
......
......@@ -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
#
......
......@@ -333,6 +333,59 @@ err_w_file:
DBUG_RETURN(TRUE);
}
/*
Renames a frm file (including backups) in same schema
SYNOPSIS
rename_in_schema_file
schema name of given schema
old_name original file name
new_name new file name
revision revision number
num_view_backups number of backups
RETURN
0 - OK
1 - Error (only if renaming of frm failed)
*/
my_bool rename_in_schema_file(const char *schema, const char *old_name,
const char *new_name, ulonglong revision,
uint num_view_backups)
{
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 > 0 && !access(arc_path, F_OK))
{
ulonglong limit= (revision > num_view_backups) ? revision - num_view_backups : 0;
while (revision > limit) {
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);
my_rename(old_path, new_path, MYF(0));
revision--;
}
}
return 0;
}
/*
Prepare frm to parse (read to memory)
......
......@@ -48,6 +48,9 @@ my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type,
gptr base, File_option *parameters, uint versions);
my_bool rename_in_schema_file(const char *schema, const char *old_name,
const char *new_name, ulonglong revision,
uint num_view_backups);
class File_parser: public Sql_alloc
{
......
......@@ -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."
......@@ -133,11 +133,12 @@ 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)
{
db_type table_type;
int rc= 1;
char name[FN_REFLEN];
const char *new_alias, *old_alias;
......@@ -164,19 +165,36 @@ 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)
{
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))
frm_type= mysql_frm_type(name);
switch (frm_type)
{
if (!skip_error)
DBUG_RETURN(ren_table);
case FRMTYPE_TABLE:
{
db_type table_type;
if ((table_type= get_table_type(thd, name)) == DB_TYPE_UNKNOWN)
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
else
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;
default:
DBUG_ASSERT(0); // should never happen
case FRMTYPE_ERROR:
my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
break;
}
if (rc && !skip_error)
DBUG_RETURN(ren_table);
}
DBUG_RETURN(0);
}
......@@ -479,8 +479,12 @@ err:
/* 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 @@ loop_out:
}
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);
}
......@@ -1165,7 +1169,7 @@ frm_type_enum mysql_frm_type(char *path)
int length;
DBUG_ENTER("mysql_frm_type");
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(MY_WME))) < 0)
if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
{
DBUG_RETURN(FRMTYPE_ERROR);
}
......@@ -1369,3 +1373,77 @@ int view_checksum(THD *thd, TABLE_LIST *view)
HA_ADMIN_WRONG_CHECKSUM :
HA_ADMIN_OK);
}
/*
rename view
Synopsis:
renames a view
Parameters:
thd thread handler
new_name new name of view
view view
Return values:
FALSE Ok
TRUE Error
*/
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_in_schema_file(view->db, view->table_name, new_name,
view->revision - 1, num_view_backups))
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_in_schema_file(view->db, new_name, view->table_name,
view->revision - 1, num_view_backups);
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;
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)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment