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, ...@@ -289,11 +289,15 @@ int quick_rm_table(enum db_type base,const char *db,
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
int error=0; 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); unpack_filename(path,path);
if (my_delete(path,MYF(0))) if (my_delete(path,MYF(0)))
error=1; /* purecov: inspected */ 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); unpack_filename(path,path);
return ha_delete_table(base,path) || error; return ha_delete_table(base,path) || error;
} }
...@@ -871,7 +875,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -871,7 +875,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{ {
/* not a critical problem */ /* not a critical problem */
char warn_buff[MYSQL_ERRMSG_SIZE]; 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, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff); ER_TOO_LONG_KEY, warn_buff);
} }
...@@ -908,7 +914,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -908,7 +914,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{ {
/* not a critical problem */ /* not a critical problem */
char warn_buff[MYSQL_ERRMSG_SIZE]; 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, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff); ER_TOO_LONG_KEY, warn_buff);
} }
...@@ -1072,12 +1080,16 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -1072,12 +1080,16 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
/* Check if table exists */ /* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE) if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{ {
sprintf(path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix, if (snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
current_pid, thd->thread_id, thd->tmp_table++,reg_ext); 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; create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
} }
else 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); unpack_filename(path,path);
/* Check if table already exists */ /* Check if table already exists */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
...@@ -1171,17 +1183,23 @@ static char * ...@@ -1171,17 +1183,23 @@ static char *
make_unique_key_name(const char *field_name,KEY *start,KEY *end) make_unique_key_name(const char *field_name,KEY *start,KEY *end)
{ {
char buff[MAX_FIELD_NAME],*buff_end; char buff[MAX_FIELD_NAME],*buff_end;
int remain;
if (!check_if_keyname_exists(field_name,start,end) && if (!check_if_keyname_exists(field_name,start,end) &&
my_strcasecmp(system_charset_info,field_name,primary_key_name)) my_strcasecmp(system_charset_info,field_name,primary_key_name))
return (char*) field_name; // Use fieldname return (char*) field_name; // Use fieldname
buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4); 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)) if (!check_if_keyname_exists(buff,start,end))
return sql_strdup(buff); 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, ...@@ -1279,8 +1297,12 @@ mysql_rename_table(enum db_type base,
my_casedn_str(system_charset_info, tmp_to); my_casedn_str(system_charset_info, tmp_to);
new_name= tmp_to; new_name= tmp_to;
} }
(void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name); if (snprintf(from, sizeof(from), "%s/%s/%s",
(void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name); 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(from,from,"","",4);
fn_format(to,to, "","",4); fn_format(to,to, "","",4);
...@@ -1415,7 +1437,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, ...@@ -1415,7 +1437,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
reg_ext)) reg_ext))
DBUG_RETURN(-1); // protect buffer overflow 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)) if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1); DBUG_RETURN(-1);
...@@ -1499,7 +1523,12 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, ...@@ -1499,7 +1523,12 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
if (!my_stat(from, &stat_info, MYF(0))) if (!my_stat(from, &stat_info, MYF(0)))
goto end; // Can't use USE_FRM flag 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 we could open the table, close it */
if (table_list->table) if (table_list->table)
...@@ -1634,7 +1663,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1634,7 +1663,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
protocol->store(table_name, system_charset_info); protocol->store(table_name, system_charset_info);
protocol->store(operator_name, system_charset_info); protocol->store(operator_name, system_charset_info);
protocol->store("error", 5, 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); protocol->store(buff, system_charset_info);
close_thread_tables(thd); close_thread_tables(thd);
table->table=0; // For query cache table->table=0; // For query cache
...@@ -1942,8 +1973,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -1942,8 +1973,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{ {
if (find_temporary_table(thd, db, table_name)) if (find_temporary_table(thd, db, table_name))
goto table_exists; goto table_exists;
sprintf(dst_path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix, if (snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
current_pid, thd->thread_id, thd->tmp_table++,reg_ext); 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; create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
} }
else else
...@@ -2000,7 +2034,9 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -2000,7 +2034,9 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{ {
char warn_buff[MYSQL_ERRMSG_SIZE]; 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, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TABLE_EXISTS_ERROR,warn_buff); ER_TABLE_EXISTS_ERROR,warn_buff);
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -2170,7 +2206,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) ...@@ -2170,7 +2206,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
(HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) (HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
break ; 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. */ /* Re-initialize the create_info, which was changed by prepare table. */
bzero((char*) &create_info,sizeof(create_info)); bzero((char*) &create_info,sizeof(create_info));
...@@ -2188,9 +2224,10 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) ...@@ -2188,9 +2224,10 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
else else
{ {
if (table->file->add_index(table, key_info_buffer, key_count)|| if (table->file->add_index(table, key_info_buffer, key_count)||
((void) sprintf(path, "%s/%s/%s%s", mysql_data_home, table_list->db, (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
(lower_case_table_names == 2)? table_list->alias: table_list->db, (lower_case_table_names == 2)?
table_list->real_name, reg_ext), 0)|| table_list->alias: table_list->real_name, reg_ext)>=
(int)sizeof(path))||
! unpack_filename(path, path)|| ! unpack_filename(path, path)||
mysql_create_frm(thd, path, &create_info, mysql_create_frm(thd, path, &create_info,
fields, key_count, key_info_buffer, table->file)) 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) ...@@ -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, keys, /*tmp_table*/ 0, db_options, table->file,
key_info_buffer, key_count, key_info_buffer, key_count,
/*select_field_count*/ 0)|| /*select_field_count*/ 0)||
((void) sprintf(path, "%s/%s/%s%s", mysql_data_home, table_list->db, (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
(lower_case_table_names == 2)? table_list->alias: table_list->db, (lower_case_table_names == 2)?
table_list->real_name, reg_ext), 0)|| table_list->alias: table_list->real_name, reg_ext)>=
(int)sizeof(path))||
! unpack_filename(path, path)|| ! unpack_filename(path, path)||
mysql_create_frm(thd, path, &create_info, mysql_create_frm(thd, path, &create_info,
fields, key_count, key_info_buffer, table->file)) fields, key_count, key_info_buffer, table->file))
...@@ -2358,12 +2396,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2358,12 +2396,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
{ {
DBUG_ENTER("mysql_alter_table"); 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); mysql_ha_closeall(thd, table_list);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ /* 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, ...@@ -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); db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
(void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid, if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
thd->thread_id); current_pid, thd->thread_id)>= (int)sizeof(tmp_name))
goto err;
create_info->db_type=new_db_type; create_info->db_type=new_db_type;
if (!create_info->comment) if (!create_info->comment)
create_info->comment=table->comment; create_info->comment=table->comment;
...@@ -2881,7 +2914,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2881,7 +2914,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else else
{ {
char path[FN_REFLEN]; 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); fn_format(path,path,"","",4);
new_table=open_temporary_table(thd, path, new_db, tmp_name,0); 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, ...@@ -2961,8 +2996,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/ */
thd->proc_info="rename result table"; thd->proc_info="rename result table";
sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid, if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
thd->thread_id); current_pid, thd->thread_id)>= (int)sizeof(old_name))
goto err;
if (new_name != table_name || new_db != db) if (new_name != table_name || new_db != db)
{ {
if (!access(new_name_buff,F_OK)) if (!access(new_name_buff,F_OK))
...@@ -3085,7 +3121,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3085,7 +3121,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown. shutdown.
*/ */
char path[FN_REFLEN]; 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); fn_format(path,path,"","",4);
table=open_temporary_table(thd, path, new_db, tmp_name,0); table=open_temporary_table(thd, path, new_db, tmp_name,0);
if (table) if (table)
...@@ -3103,8 +3141,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3103,8 +3141,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
query_cache_invalidate3(thd, table_list, 0); query_cache_invalidate3(thd, table_list, 0);
end_temporary: end_temporary:
sprintf(tmp_name, ER(ER_INSERT_INFO), (ulong) (copied + deleted), if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
(ulong) deleted, (ulong) thd->cuted_fields); (ulong) (copied + deleted), (ulong) deleted,
(ulong) thd->cuted_fields)>= (int)sizeof(tmp_name))
goto err;
send_ok(thd,copied+deleted,0L,tmp_name); send_ok(thd,copied+deleted,0L,tmp_name);
thd->some_tables_deleted=0; thd->some_tables_deleted=0;
DBUG_RETURN(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