Commit 505df896 authored by Joerg Bruehe's avatar Joerg Bruehe

Backport of a 5.0.74 fix into 5.0.72sp1:

Bug #40021: Renaming view fails, archived .frm for view is
            missing after downgrade

Original changeset:
> revision-id: gshchepa@mysql.com-20081114172557-xh0jlzwal8ze3cy6
> parent: ramil@mysql.com-20081114074229-vj4fvfrpmz8jfub9
> committer: Gleb Shchepa <gshchepa@mysql.com>
> branch nick: mysql-5.0-bugteam
> timestamp: Fri 2008-11-14 21:25:57 +0400
parent cafe06c2
...@@ -88,7 +88,6 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) ...@@ -88,7 +88,6 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
file pointer to IO_CACHE structure for writing file pointer to IO_CACHE structure for writing
base pointer to data structure base pointer to data structure
parameter pointer to parameter descriptor parameter pointer to parameter descriptor
old_version for returning back old version number value
RETURN RETURN
FALSE - OK FALSE - OK
...@@ -96,8 +95,7 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s) ...@@ -96,8 +95,7 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
*/ */
static my_bool static my_bool
write_parameter(IO_CACHE *file, gptr base, File_option *parameter, write_parameter(IO_CACHE *file, gptr base, File_option *parameter)
ulonglong *old_version)
{ {
char num_buf[20]; // buffer for numeric operations char num_buf[20]; // buffer for numeric operations
// string for numeric operations // string for numeric operations
...@@ -125,15 +123,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, ...@@ -125,15 +123,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
break; break;
} }
case FILE_OPTIONS_REV:
{
ulonglong *val_i= (ulonglong *)(base + parameter->offset);
*old_version= (*val_i)++;
num.set(*val_i, &my_charset_bin);
if (my_b_append(file, (const byte *)num.ptr(), num.length()))
DBUG_RETURN(TRUE);
break;
}
case FILE_OPTIONS_TIMESTAMP: case FILE_OPTIONS_TIMESTAMP:
{ {
/* string have to be allocated already */ /* string have to be allocated already */
...@@ -205,7 +194,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, ...@@ -205,7 +194,6 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter,
base base address for parameter reading (structure like base base address for parameter reading (structure like
TABLE) TABLE)
parameters parameters description parameters parameters description
max_versions number of versions to save
RETURN RETURN
FALSE - OK FALSE - OK
...@@ -215,13 +203,11 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter, ...@@ -215,13 +203,11 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter,
my_bool my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type, const LEX_STRING *type,
gptr base, File_option *parameters, gptr base, File_option *parameters)
uint max_versions)
{ {
File handler; File handler;
IO_CACHE file; IO_CACHE file;
char path[FN_REFLEN+1]; // +1 to put temporary file name for sure char path[FN_REFLEN+1]; // +1 to put temporary file name for sure
ulonglong old_version= ULONGLONG_MAX;
int path_end; int path_end;
File_option *param; File_option *param;
DBUG_ENTER("sql_create_definition_file"); DBUG_ENTER("sql_create_definition_file");
...@@ -255,7 +241,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, ...@@ -255,7 +241,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
if (my_b_append(&file, (const byte *)param->name.str, if (my_b_append(&file, (const byte *)param->name.str,
param->name.length) || param->name.length) ||
my_b_append(&file, (const byte *)STRING_WITH_LEN("=")) || my_b_append(&file, (const byte *)STRING_WITH_LEN("=")) ||
write_parameter(&file, base, param, &old_version) || write_parameter(&file, base, param) ||
my_b_append(&file, (const byte *)STRING_WITH_LEN("\n"))) my_b_append(&file, (const byte *)STRING_WITH_LEN("\n")))
goto err_w_cache; goto err_w_cache;
} }
...@@ -269,55 +255,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, ...@@ -269,55 +255,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
} }
path[path_end]='\0'; path[path_end]='\0';
#ifdef FRM_ARCHIVE
// archive copies management: disabled unused feature (see bug #17823).
if (!access(path, F_OK))
{
if (old_version != ULONGLONG_MAX && max_versions != 0)
{
// save backup
char path_arc[FN_REFLEN];
// backup old version
char path_to[FN_REFLEN];
// check archive directory existence
fn_format(path_arc, "arc", dir->str, "", MY_UNPACK_FILENAME);
if (access(path_arc, F_OK))
{
if (my_mkdir(path_arc, 0777, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
}
my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu",
path_arc, file_name->str, (ulong) old_version);
if (my_rename(path, path_to, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
// remove very old version
if (old_version > max_versions)
{
my_snprintf(path_to, FN_REFLEN, "%s/%s-%04lu",
path_arc, file_name->str,
(ulong)(old_version - max_versions));
if (!access(path_arc, F_OK) && my_delete(path_to, MYF(MY_WME)))
{
DBUG_RETURN(TRUE);
}
}
}
else
{
if (my_delete(path, MYF(MY_WME))) // no backups
{
DBUG_RETURN(TRUE);
}
}
}
#endif//FRM_ARCHIVE
{ {
// rename temporary file // rename temporary file
...@@ -346,8 +283,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, ...@@ -346,8 +283,6 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
schema name of given schema schema name of given schema
old_name original file name old_name original file name
new_name new file name new_name new file name
revision revision number
num_view_backups number of backups
RETURN RETURN
0 - OK 0 - OK
...@@ -356,8 +291,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, ...@@ -356,8 +291,7 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
*/ */
my_bool rename_in_schema_file(THD *thd, my_bool rename_in_schema_file(THD *thd,
const char *schema, const char *old_name, const char *schema, const char *old_name,
const char *new_name, ulonglong revision, const char *new_name)
uint num_view_backups)
{ {
char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN]; char old_path[FN_REFLEN], new_path[FN_REFLEN], arc_path[FN_REFLEN];
...@@ -376,23 +310,6 @@ my_bool rename_in_schema_file(THD *thd, ...@@ -376,23 +310,6 @@ my_bool rename_in_schema_file(THD *thd,
strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS); strxnmov(arc_path, FN_REFLEN, mysql_data_home, "/", schema, "/arc", NullS);
(void) unpack_filename(arc_path, arc_path); (void) unpack_filename(arc_path, arc_path);
#ifdef FRM_ARCHIVE
if (revision > 0 && !access(arc_path, F_OK))
{
ulonglong limit= ((revision > num_view_backups) ?
revision - num_view_backups : 0);
for (; revision > limit ; 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);
my_rename(old_path, new_path, MYF(0));
}
}
#else//FRM_ARCHIVE
{ // remove obsolete 'arc' directory and files if any { // remove obsolete 'arc' directory and files if any
MY_DIR *new_dirp; MY_DIR *new_dirp;
if ((new_dirp = my_dir(arc_path, MYF(MY_DONT_SORT)))) if ((new_dirp = my_dir(arc_path, MYF(MY_DONT_SORT))))
...@@ -401,7 +318,6 @@ my_bool rename_in_schema_file(THD *thd, ...@@ -401,7 +318,6 @@ my_bool rename_in_schema_file(THD *thd,
(void) mysql_rm_arc_files(thd, new_dirp, arc_path); (void) mysql_rm_arc_files(thd, new_dirp, arc_path);
} }
} }
#endif//FRM_ARCHIVE
return 0; return 0;
} }
...@@ -838,7 +754,6 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root, ...@@ -838,7 +754,6 @@ File_parser::parse(gptr base, MEM_ROOT *mem_root,
break; break;
} }
case FILE_OPTIONS_ULONGLONG: case FILE_OPTIONS_ULONGLONG:
case FILE_OPTIONS_REV:
if (!(eol= strchr(ptr, '\n'))) if (!(eol= strchr(ptr, '\n')))
{ {
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
......
...@@ -23,7 +23,6 @@ enum file_opt_type { ...@@ -23,7 +23,6 @@ enum file_opt_type {
FILE_OPTIONS_STRING, /* String (LEX_STRING) */ FILE_OPTIONS_STRING, /* String (LEX_STRING) */
FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */ FILE_OPTIONS_ESTRING, /* Escaped string (LEX_STRING) */
FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */ FILE_OPTIONS_ULONGLONG, /* ulonglong parameter (ulonglong) */
FILE_OPTIONS_REV, /* Revision version number (ulonglong) */
FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be FILE_OPTIONS_TIMESTAMP, /* timestamp (LEX_STRING have to be
allocated with length 20 (19+1) */ allocated with length 20 (19+1) */
FILE_OPTIONS_STRLIST, /* list of escaped strings FILE_OPTIONS_STRLIST, /* list of escaped strings
...@@ -81,11 +80,10 @@ File_parser *sql_parse_prepare(const LEX_STRING *file_name, ...@@ -81,11 +80,10 @@ File_parser *sql_parse_prepare(const LEX_STRING *file_name,
my_bool my_bool
sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name, sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
const LEX_STRING *type, const LEX_STRING *type,
gptr base, File_option *parameters, uint versions); gptr base, File_option *parameters);
my_bool rename_in_schema_file(THD *thd, my_bool rename_in_schema_file(THD *thd,
const char *schema, const char *old_name, const char *schema, const char *old_name,
const char *new_name, ulonglong revision, const char *new_name);
uint num_view_backups);
class File_parser: public Sql_alloc class File_parser: public Sql_alloc
{ {
......
...@@ -909,7 +909,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, ...@@ -909,7 +909,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
/* .frm archive: /* .frm archive:
Those archives are obsolete, but following code should Those archives are obsolete, but following code should
exist to remove existent "arc" directories. exist to remove existent "arc" directories.
See #ifdef FRM_ARCHIVE directives for obsolete code.
*/ */
char newpath[FN_REFLEN]; char newpath[FN_REFLEN];
MY_DIR *new_dirp; MY_DIR *new_dirp;
...@@ -1069,7 +1068,6 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) ...@@ -1069,7 +1068,6 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error)
NOTE NOTE
A support of "arc" directories is obsolete, however this A support of "arc" directories is obsolete, however this
function should exist to remove existent "arc" directories. function should exist to remove existent "arc" directories.
See #ifdef FRM_ARCHIVE directives for obsolete code.
*/ */
long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path)
{ {
......
...@@ -479,7 +479,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, ...@@ -479,7 +479,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
trigname.trigger_table.length= tables->table_name_length; trigname.trigger_table.length= tables->table_name_length;
if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type,
(gptr)&trigname, trigname_file_parameters, 0)) (gptr)&trigname, trigname_file_parameters))
return 1; return 1;
/* /*
...@@ -569,7 +569,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables, ...@@ -569,7 +569,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
/* Create trigger definition file. */ /* Create trigger definition file. */
if (!sql_create_definition_file(&dir, &file, &triggers_file_type, if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)this, triggers_file_parameters, 0)) (gptr)this, triggers_file_parameters))
return 0; return 0;
err_with_cleanup: err_with_cleanup:
...@@ -656,7 +656,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db, ...@@ -656,7 +656,7 @@ static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
file.str= file_buff; file.str= file_buff;
return sql_create_definition_file(&dir, &file, &triggers_file_type, return sql_create_definition_file(&dir, &file, &triggers_file_type,
(gptr)triggers, triggers_file_parameters, 0); (gptr)triggers, triggers_file_parameters);
} }
...@@ -1427,7 +1427,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name, ...@@ -1427,7 +1427,7 @@ Table_triggers_list::change_table_name_in_trignames(const char *db_name,
trigname.trigger_table= *new_table_name; trigname.trigger_table= *new_table_name;
if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type, if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type,
(gptr)&trigname, trigname_file_parameters, 0)) (gptr)&trigname, trigname_file_parameters))
return trigger; return trigger;
} }
......
...@@ -660,7 +660,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, ...@@ -660,7 +660,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
} }
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
if (view->revision != 1) if (mode != VIEW_CREATE_NEW)
query_cache_invalidate3(thd, view, 0); query_cache_invalidate3(thd, view, 0);
start_waiting_global_read_lock(thd); start_waiting_global_read_lock(thd);
if (res) if (res)
...@@ -678,12 +678,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, ...@@ -678,12 +678,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
} }
/* index of revision number in following table */ /* number of required parameters for making view */
static const int revision_number_position= 8; static const int required_view_parameters= 9;
/* 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 table of VIEW .frm field descriptors
...@@ -716,9 +712,6 @@ static File_option view_parameters[]= ...@@ -716,9 +712,6 @@ static File_option view_parameters[]=
{{(char*) STRING_WITH_LEN("with_check_option")}, {{(char*) STRING_WITH_LEN("with_check_option")},
my_offsetof(TABLE_LIST, with_check), my_offsetof(TABLE_LIST, with_check),
FILE_OPTIONS_ULONGLONG}, FILE_OPTIONS_ULONGLONG},
{{(char*) STRING_WITH_LEN("revision")},
my_offsetof(TABLE_LIST, revision),
FILE_OPTIONS_REV},
{{(char*) STRING_WITH_LEN("timestamp")}, {{(char*) STRING_WITH_LEN("timestamp")},
my_offsetof(TABLE_LIST, timestamp), my_offsetof(TABLE_LIST, timestamp),
FILE_OPTIONS_TIMESTAMP}, FILE_OPTIONS_TIMESTAMP},
...@@ -870,18 +863,9 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -870,18 +863,9 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
} }
/* /*
read revision number
TODO: read dependence list, too, to process cascade/restrict TODO: read dependence list, too, to process cascade/restrict
TODO: special cascade/restrict procedure for alter? TODO: special cascade/restrict procedure for alter?
*/ */
if (parser->parse((gptr)view, thd->mem_root,
view_parameters + revision_number_position, 1,
&file_parser_dummy_hook))
{
error= thd->net.report_error? -1 : 0;
goto err;
}
} }
else else
{ {
...@@ -923,7 +907,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, ...@@ -923,7 +907,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
} }
if (sql_create_definition_file(&dir, &file, view_file_type, if (sql_create_definition_file(&dir, &file, view_file_type,
(gptr)view, view_parameters, num_view_backups)) (gptr)view, view_parameters))
{ {
error= thd->net.report_error? -1 : 1; error= thd->net.report_error? -1 : 1;
goto err; goto err;
...@@ -1858,8 +1842,7 @@ mysql_rename_view(THD *thd, ...@@ -1858,8 +1842,7 @@ mysql_rename_view(THD *thd,
goto err; goto err;
/* rename view and it's backups */ /* rename view and it's backups */
if (rename_in_schema_file(thd, view->db, view->table_name, new_name, if (rename_in_schema_file(thd, view->db, view->table_name, new_name))
view_def.revision - 1, num_view_backups))
goto err; goto err;
strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS); strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", view->db, "/", NullS);
...@@ -1873,12 +1856,10 @@ mysql_rename_view(THD *thd, ...@@ -1873,12 +1856,10 @@ mysql_rename_view(THD *thd,
- file_buff); - file_buff);
if (sql_create_definition_file(&pathstr, &file, view_file_type, if (sql_create_definition_file(&pathstr, &file, view_file_type,
(gptr)&view_def, view_parameters, (gptr)&view_def, view_parameters))
num_view_backups))
{ {
/* restore renamed view in case of error */ /* restore renamed view in case of error */
rename_in_schema_file(thd, view->db, new_name, view->table_name, rename_in_schema_file(thd, view->db, new_name, view->table_name);
view_def.revision - 1, num_view_backups);
goto err; goto err;
} }
} else } else
......
...@@ -657,7 +657,6 @@ struct TABLE_LIST ...@@ -657,7 +657,6 @@ struct TABLE_LIST
st_lex_user definer; /* definer of view */ st_lex_user definer; /* definer of view */
ulonglong file_version; /* version of file's field set */ ulonglong file_version; /* version of file's field set */
ulonglong updatable_view; /* VIEW can be updated */ ulonglong updatable_view; /* VIEW can be updated */
ulonglong revision; /* revision control number */
ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */ ulonglong algorithm; /* 0 any, 1 tmp tables , 2 merging */
ulonglong view_suid; /* view is suid (TRUE dy default) */ ulonglong view_suid; /* view is suid (TRUE dy default) */
ulonglong with_check; /* WITH CHECK OPTION */ ulonglong with_check; /* WITH CHECK OPTION */
......
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