Commit ce816b35 authored by ingo@mysql.com's avatar ingo@mysql.com

Worklog#1563 - Support of on-line CREATE/DROP INDEX.

Corrected minor problems of the preceding changeset 1.1705.
parent 85ec87a0
......@@ -289,11 +289,15 @@ int quick_rm_table(enum db_type base,const char *db,
{
char path[FN_REFLEN];
int error=0;
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext);
if (snprintf(path, sizeof(path), "%s/%s/%s%s",
mysql_data_home, db, table_name, reg_ext)>= (int)sizeof(path))
return 1;
unpack_filename(path,path);
if (my_delete(path,MYF(0)))
error=1; /* purecov: inspected */
sprintf(path,"%s/%s/%s",mysql_data_home,db,table_name);
if (snprintf(path, sizeof(path), "%s/%s/%s",
mysql_data_home, db, table_name)>= (int)sizeof(path))
return 1;
unpack_filename(path,path);
return ha_delete_table(base,path) || error;
}
......@@ -871,7 +875,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
/* not a critical problem */
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff,ER(ER_TOO_LONG_KEY),length);
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length)>= (int)sizeof(warn_buff))
DBUG_RETURN(-1);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff);
}
......@@ -908,7 +914,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
/* not a critical problem */
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff,ER(ER_TOO_LONG_KEY),length);
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length)>= (int)sizeof(warn_buff))
DBUG_RETURN(-1);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff);
}
......@@ -1072,12 +1080,16 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
/* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
sprintf(path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix,
current_pid, thd->thread_id, thd->tmp_table++,reg_ext);
if (snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id,
thd->tmp_table++, reg_ext)>= (int)sizeof(path))
DBUG_RETURN(-1);
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
}
else
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,alias,reg_ext);
if (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
alias, reg_ext)>= (int)sizeof(path))
DBUG_RETURN(-1);
unpack_filename(path,path);
/* Check if table already exists */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
......@@ -1171,17 +1183,23 @@ static char *
make_unique_key_name(const char *field_name,KEY *start,KEY *end)
{
char buff[MAX_FIELD_NAME],*buff_end;
int remain;
if (!check_if_keyname_exists(field_name,start,end) &&
my_strcasecmp(system_charset_info,field_name,primary_key_name))
return (char*) field_name; // Use fieldname
buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4);
for (uint i=2 ; ; i++)
/*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/
for (uint i=2 ; i< 100; i++)
{
sprintf(buff_end,"_%d",i);
remain= (int)sizeof(buff)- (buff_end- buff);
if (snprintf(buff_end, remain, "_%d", i)>= remain)
return NULL;
if (!check_if_keyname_exists(buff,start,end))
return sql_strdup(buff);
}
/*ingo 2004-04-07 dedicated return is inevitable*/
return NULL;
}
/****************************************************************************
......@@ -1279,8 +1297,12 @@ mysql_rename_table(enum db_type base,
my_casedn_str(system_charset_info, tmp_to);
new_name= tmp_to;
}
(void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name);
(void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name);
if (snprintf(from, sizeof(from), "%s/%s/%s",
mysql_data_home, old_db, old_name)>= (int)sizeof(from))
DBUG_RETURN(1);
if (snprintf(to, sizeof(to), "%s/%s/%s",
mysql_data_home, new_db, new_name)>= (int)sizeof(to))
DBUG_RETURN(1);
fn_format(from,from,"","",4);
fn_format(to,to, "","",4);
......@@ -1415,7 +1437,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
reg_ext))
DBUG_RETURN(-1); // protect buffer overflow
sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
if (snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
mysql_real_data_home, db, table_name)>= (int)sizeof(dst_path))
DBUG_RETURN(-1);
if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1);
......@@ -1499,7 +1523,12 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
if (!my_stat(from, &stat_info, MYF(0)))
goto end; // Can't use USE_FRM flag
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
if (snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
from, current_pid, thd->thread_id)>= (int)sizeof(tmp))
{
error= -1;
goto end;
}
/* If we could open the table, close it */
if (table_list->table)
......@@ -1634,7 +1663,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol->store(table_name, system_charset_info);
protocol->store(operator_name, system_charset_info);
protocol->store("error", 5, system_charset_info);
sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name);
if (snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
table_name)>= (int)sizeof(buff))
goto err;
protocol->store(buff, system_charset_info);
close_thread_tables(thd);
table->table=0; // For query cache
......@@ -1942,8 +1973,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
if (find_temporary_table(thd, db, table_name))
goto table_exists;
sprintf(dst_path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix,
current_pid, thd->thread_id, thd->tmp_table++,reg_ext);
if (snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
mysql_tmpdir, tmp_file_prefix, current_pid,
thd->thread_id, thd->tmp_table++, reg_ext)>=
(int)sizeof(dst_path))
DBUG_RETURN(-1);
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
}
else
......@@ -2000,7 +2034,9 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
sprintf(warn_buff,ER(ER_TABLE_EXISTS_ERROR),table_name);
if (snprintf(warn_buff, sizeof(warn_buff),
ER(ER_TABLE_EXISTS_ERROR), table_name)>= (int)sizeof(warn_buff))
DBUG_RETURN(-1);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TABLE_EXISTS_ERROR,warn_buff);
DBUG_RETURN(0);
......@@ -2170,7 +2206,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
(HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
break ;
}
if ((idx < key_count)|| (key_count<= 0))
if ((idx < key_count)|| !key_count)
{
/* Re-initialize the create_info, which was changed by prepare table. */
bzero((char*) &create_info,sizeof(create_info));
......@@ -2188,9 +2224,10 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
else
{
if (table->file->add_index(table, key_info_buffer, key_count)||
((void) sprintf(path, "%s/%s/%s%s", mysql_data_home, table_list->db,
(lower_case_table_names == 2)? table_list->alias:
table_list->real_name, reg_ext), 0)||
(snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
table_list->db, (lower_case_table_names == 2)?
table_list->alias: table_list->real_name, reg_ext)>=
(int)sizeof(path))||
! unpack_filename(path, path)||
mysql_create_frm(thd, path, &create_info,
fields, key_count, key_info_buffer, table->file))
......@@ -2289,9 +2326,10 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
keys, /*tmp_table*/ 0, db_options, table->file,
key_info_buffer, key_count,
/*select_field_count*/ 0)||
((void) sprintf(path, "%s/%s/%s%s", mysql_data_home, table_list->db,
(lower_case_table_names == 2)? table_list->alias:
table_list->real_name, reg_ext), 0)||
(snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
table_list->db, (lower_case_table_names == 2)?
table_list->alias: table_list->real_name, reg_ext)>=
(int)sizeof(path))||
! unpack_filename(path, path)||
mysql_create_frm(thd, path, &create_info,
fields, key_count, key_info_buffer, table->file))
......@@ -2358,12 +2396,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{
DBUG_ENTER("mysql_alter_table");
/* !!!!!!!! WARNING: This comment must be removed after a decision !!!!!!!!!
I'm not sure if the next two commands are at the right place here.
I guess that closing all is necessary before table dropping which is
part of alter table, but may be harmful before online DDLs.
So I would put both behind the DDL branches right before open_ltable.
!!!!!!!! WARNING: This comment must be removed after a decision !!!!!! */
mysql_ha_closeall(thd, table_list);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
......@@ -2801,8 +2833,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
(void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid,
thd->thread_id);
if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
current_pid, thd->thread_id)>= (int)sizeof(tmp_name))
goto err;
create_info->db_type=new_db_type;
if (!create_info->comment)
create_info->comment=table->comment;
......@@ -2881,7 +2914,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
{
char path[FN_REFLEN];
(void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,tmp_name);
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, tmp_name)>= (int)sizeof(path))
goto err;
fn_format(path,path,"","",4);
new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
}
......@@ -2961,8 +2996,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/
thd->proc_info="rename result table";
sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid,
thd->thread_id);
if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
current_pid, thd->thread_id)>= (int)sizeof(old_name))
goto err;
if (new_name != table_name || new_db != db)
{
if (!access(new_name_buff,F_OK))
......@@ -3085,7 +3121,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown.
*/
char path[FN_REFLEN];
(void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,table_name);
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, table_name)>= (int)sizeof(path))
goto err;
fn_format(path,path,"","",4);
table=open_temporary_table(thd, path, new_db, tmp_name,0);
if (table)
......@@ -3103,8 +3141,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
query_cache_invalidate3(thd, table_list, 0);
end_temporary:
sprintf(tmp_name, ER(ER_INSERT_INFO), (ulong) (copied + deleted),
(ulong) deleted, (ulong) thd->cuted_fields);
if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) (copied + deleted), (ulong) deleted,
(ulong) thd->cuted_fields)>= (int)sizeof(tmp_name))
goto err;
send_ok(thd,copied+deleted,0L,tmp_name);
thd->some_tables_deleted=0;
DBUG_RETURN(0);
......
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