Commit 10e15762 authored by unknown's avatar unknown

Don't enable HA_EXTRA_WRITE_CACHE if too few rows

Revert main parts of patch for online index builds. Should be done differently
Added support for %lx in my_snprintf()


sql/ha_myisam.cc:
  Don't enable HA_EXTRA_WRITE_CACHE if too few rows
sql/handler.h:
  Indentaion fix
sql/mysql_priv.h:
  Removed real_alter_table, mysql_add_column and mysql_drop_column
sql/sql_class.cc:
  After merge fix
sql/sql_insert.cc:
  Don't user bulk_insert if only one row (common case)
sql/sql_parse.cc:
  Added mysql_create_index() and mysql_drop_index() as these are only wrappers for mysql_alter_table()
sql/sql_table.cc:
  Revert main parts of patch for online index builds
  Changed back to use tabs to make merges possible between trees
sql/unireg.cc:
  Added comments and minor cleanup
strings/my_vsnprintf.c:
  Added support for %lx.
  Proper long support
parent 46bd7be2
......@@ -867,7 +867,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
THD *thd=current_thd;
ulong size= min(thd->variables.read_buff_size, table->avg_row_length*rows);
mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*)&size);
/* don't enable row cache if too few rows */
if (!rows && rows > 10)
mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size);
can_enable_indexes= (file->s->state.key_map ==
set_bits(ulonglong, file->s->base.keys));
......
......@@ -509,19 +509,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_list,
uint order_num, ORDER *order, int alter_flags,
enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
bool simple_alter=0);
int real_alter_table(THD *thd, char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
TABLE *table,
List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_list,
uint order_num, ORDER *order, int alter_flags,
uint order_num, ORDER *order, uint alter_flags,
enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
......@@ -537,10 +525,6 @@ bool mysql_rename_table(enum db_type base,
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_list);
int mysql_add_column(THD *thd, TABLE_LIST *table_list,
List<create_field> &fields);
int mysql_drop_column(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_list);
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds,
uint order_num, ORDER *order, ha_rows limit,
......@@ -944,7 +928,8 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
void unireg_init(ulong options);
void unireg_end(void);
int mysql_create_frm(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
bool mysql_create_frm(THD *thd, my_string file_name,
HA_CREATE_INFO *create_info,
List<create_field> &create_field,
uint key_count,KEY *key_info,handler *db_type);
int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
......
......@@ -86,8 +86,7 @@ extern "C" void free_user_var(user_var_entry *entry)
THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
last_insert_id_used(0),
insert_id_used(0), rand_used(0), in_lock_tables(0),
global_read_lock(0), bootstrap(0),
no_table_fix_fields_cache(0)
global_read_lock(0), bootstrap(0)
{
host= user= priv_user= db= ip=0;
host_or_ip= "connecting host";
......
......@@ -260,7 +260,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->proc_info="update";
if (duplic != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (lock_type != TL_WRITE_DELAYED)
if (lock_type != TL_WRITE_DELAYED && values_list.elements != 1);
table->file->start_bulk_insert(values_list.elements);
while ((values= its++))
......
......@@ -4993,3 +4993,49 @@ Item * all_any_subquery_creator(Item *left_expr,
return it; /* ANY/SOME */
}
/*
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
the proper arguments. This isn't very fast but it should work for most
cases.
In the future ALTER TABLE will notice that only added indexes
and create these one by one for the existing table without having to do
a full rebuild.
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
*/
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
{
List<create_field> fields;
List<Alter_drop> drop;
List<Alter_column> alter;
HA_CREATE_INFO create_info;
DBUG_ENTER("mysql_create_index");
bzero((char*) &create_info,sizeof(create_info));
create_info.db_type=DB_TYPE_DEFAULT;
create_info.default_table_charset= thd->variables.collation_database;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
fields, keys, drop, alter, 0, (ORDER*)0,
ALTER_ADD_INDEX, DUP_ERROR));
}
int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
{
List<create_field> fields;
List<Key> keys;
List<Alter_column> alter;
HA_CREATE_INFO create_info;
DBUG_ENTER("mysql_drop_index");
bzero((char*) &create_info,sizeof(create_info));
create_info.db_type=DB_TYPE_DEFAULT;
create_info.default_table_charset= thd->variables.collation_database;
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list,
fields, keys, drop, alter, 0, (ORDER*)0,
ALTER_DROP_INDEX, DUP_ERROR));
}
......@@ -289,15 +289,12 @@ int quick_rm_table(enum db_type base,const char *db,
{
char path[FN_REFLEN];
int error=0;
if (snprintf(path, sizeof(path), "%s/%s/%s%s",
mysql_data_home, db, table_name, reg_ext)>= (int)sizeof(path))
return 1;
my_snprintf(path, sizeof(path), "%s/%s/%s%s",
mysql_data_home, db, table_name, reg_ext);
unpack_filename(path,path);
if (my_delete(path,MYF(0)))
error=1; /* purecov: inspected */
if (snprintf(path, sizeof(path), "%s/%s/%s",
mysql_data_home, db, table_name)>= (int)sizeof(path))
return 1;
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name);
unpack_filename(path,path);
return ha_delete_table(base,path) || error;
}
......@@ -410,7 +407,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List<create_field> &fields,
List<Key> &keys, bool tmp_table, uint &db_options,
handler *file, KEY *&key_info_buffer,
uint &key_count, int select_field_count)
uint *key_count, int select_field_count)
{
const char *key_name;
create_field *sql_field,*dup_field;
......@@ -650,7 +647,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
uint tmp, key_number;
/* Calculate number of key segements */
key_count=0;
*key_count= 0;
while ((key=key_iterator++))
{
......@@ -668,7 +665,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
continue;
}
key_count++;
(*key_count)++;
tmp=max(file->max_key_parts(),MAX_REF_PARTS);
if (key->columns.elements > tmp)
{
......@@ -689,13 +686,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
}
tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp)
if (*key_count > tmp)
{
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
DBUG_RETURN(-1);
}
key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)*key_count);
key_info_buffer=key_info=(KEY*) sql_calloc(sizeof(KEY)* *key_count);
key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
if (!key_info_buffer || ! key_part_info)
DBUG_RETURN(-1); // Out of memory
......@@ -907,9 +904,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
/* not a critical problem */
char warn_buff[MYSQL_ERRMSG_SIZE];
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length)>= (int)sizeof(warn_buff))
DBUG_RETURN(-1);
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff);
}
......@@ -946,9 +942,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
{
/* not a critical problem */
char warn_buff[MYSQL_ERRMSG_SIZE];
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length)>= (int)sizeof(warn_buff))
DBUG_RETURN(-1);
my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TOO_LONG_KEY, warn_buff);
}
......@@ -1026,11 +1021,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1);
}
/* Sort keys in optimized order */
qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys);
qsort((gptr) key_info_buffer, *key_count, sizeof(KEY),
(qsort_cmp) sort_keys);
DBUG_RETURN(0);
}
/*
Create a table
......@@ -1105,23 +1102,21 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
if (mysql_prepare_table(thd, create_info, fields,
keys, tmp_table, db_options, file,
key_info_buffer, key_count,
key_info_buffer, &key_count,
select_field_count))
DBUG_RETURN(-1);
/* Check if table exists */
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
{
if (snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
my_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);
thd->tmp_table++, reg_ext);
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
}
else
if (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
alias, reg_ext)>= (int)sizeof(path))
DBUG_RETURN(-1);
my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
alias, reg_ext);
unpack_filename(path,path);
/* Check if table already exists */
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
......@@ -1215,25 +1210,27 @@ 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);
/*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/
buff_end=strmake(buff,field_name, sizeof(buff)-4);
/*
Only 3 chars + '\0' left, so need to limit to 2 digit
This is ok as we can't have more than 100 keys anyway
*/
for (uint i=2 ; i< 100; i++)
{
remain= (int)sizeof(buff)- (buff_end- buff);
if (snprintf(buff_end, remain, "_%d", i)>= remain)
return NULL;
*buff_end= '_';
int10_to_str(i, buff_end+1, 10);
if (!check_if_keyname_exists(buff,start,end))
return sql_strdup(buff);
}
/*ingo 2004-04-07 dedicated return is inevitable*/
return NULL;
return (char*) "not_specified"; // Should never happen
}
/****************************************************************************
** Create table from a list of fields and items
****************************************************************************/
......@@ -1329,12 +1326,10 @@ mysql_rename_table(enum db_type base,
my_casedn_str(system_charset_info, tmp_to);
new_name= tmp_to;
}
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);
my_snprintf(from, sizeof(from), "%s/%s/%s",
mysql_data_home, old_db, old_name);
my_snprintf(to, sizeof(to), "%s/%s/%s",
mysql_data_home, new_db, new_name);
fn_format(from,from,"","",4);
fn_format(to,to, "","",4);
......@@ -1469,9 +1464,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
reg_ext))
DBUG_RETURN(-1); // protect buffer overflow
if (snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
mysql_real_data_home, db, table_name)>= (int)sizeof(dst_path))
DBUG_RETURN(-1);
my_snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
mysql_real_data_home, db, table_name);
if (lock_and_wait_for_table_name(thd,table))
DBUG_RETURN(-1);
......@@ -1555,12 +1549,8 @@ 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
if (snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
from, current_pid, thd->thread_id)>= (int)sizeof(tmp))
{
error= -1;
goto end;
}
my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
from, current_pid, thd->thread_id);
/* If we could open the table, close it */
if (table_list->table)
......@@ -1695,9 +1685,7 @@ 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);
if (snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
table_name)>= (int)sizeof(buff))
goto err;
my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), table_name);
protocol->store(buff, system_charset_info);
close_thread_tables(thd);
table->table=0; // For query cache
......@@ -2019,11 +2007,9 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
{
if (find_temporary_table(thd, db, table_name))
goto table_exists;
if (snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
my_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);
thd->thread_id, thd->tmp_table++, reg_ext);
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
}
else
......@@ -2081,9 +2067,8 @@ table_exists:
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
if (snprintf(warn_buff, sizeof(warn_buff),
ER(ER_TABLE_EXISTS_ERROR), table_name)>= (int)sizeof(warn_buff))
DBUG_RETURN(-1);
my_snprintf(warn_buff, sizeof(warn_buff),
ER(ER_TABLE_EXISTS_ERROR), table_name);
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TABLE_EXISTS_ERROR,warn_buff);
res= 0;
......@@ -2194,6 +2179,8 @@ err:
DBUG_RETURN(error);
}
#ifdef NOT_USED
/*
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
the proper arguments. This isn't very fast but it should work for most
......@@ -2201,7 +2188,7 @@ err:
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
*/
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
int mysql_create_indexes(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
{
List<create_field> fields;
List<Alter_drop> drop;
......@@ -2214,7 +2201,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
TABLE *table;
Field **f_ptr;
KEY *key_info_buffer;
char path[FN_REFLEN];
char path[FN_REFLEN+1];
DBUG_ENTER("mysql_create_index");
/*
......@@ -2272,29 +2259,29 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
&create_info, table_list, table,
fields, keys, drop, alter, 0, (ORDER*)0,
ALTER_ADD_INDEX, DUP_ERROR))
/*don't need to free((gptr) key_info_buffer);*/
/* Don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(-1);
}
else
{
if (table->file->add_index(table, key_info_buffer, key_count)||
(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)||
(my_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))
/*don't need to free((gptr) key_info_buffer);*/
/* don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(-1);
}
/*don't need to free((gptr) key_info_buffer);*/
/* don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(0);
}
int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
int mysql_drop_indexes(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop)
{
List<create_field> fields;
List<Key> keys;
......@@ -2394,47 +2381,12 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
/*don't need to free((gptr) key_numbers);*/
DBUG_RETURN(0);
}
#endif /* NOT_USED */
int mysql_add_column(THD *thd, TABLE_LIST *table_list,
List<create_field> &fields)
{
List<Alter_drop> drop;
List<Key> keys;
List<Alter_column> alter;
HA_CREATE_INFO create_info;
DBUG_ENTER("mysql_add_column");
bzero((char*) &create_info,sizeof(create_info));
create_info.db_type=DB_TYPE_DEFAULT;
create_info.default_table_charset= thd->variables.collation_database;
TABLE *table;
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list, table,
fields, keys, drop, alter, 0, (ORDER*)0,
ALTER_ADD_COLUMN, DUP_ERROR));
}
int mysql_drop_column(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
{
List<create_field> fields;
List<Key> keys;
List<Alter_column> alter;
HA_CREATE_INFO create_info;
DBUG_ENTER("mysql_drop_column");
bzero((char*) &create_info,sizeof(create_info));
create_info.db_type=DB_TYPE_DEFAULT;
create_info.default_table_charset= thd->variables.collation_database;
TABLE *table;
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name,
&create_info, table_list, table,
fields, keys, drop, alter, 0, (ORDER*)0,
ALTER_DROP_COLUMN, DUP_ERROR));
}
/*
Alter table
*/
int mysql_alter_table(THD *thd,char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
......@@ -2442,69 +2394,22 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_list,
uint order_num, ORDER *order, int alter_flags,
enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff,
enum tablespace_op_type tablespace_op,
bool simple_alter)
{
DBUG_ENTER("mysql_alter_table");
mysql_ha_closeall(thd, table_list);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (tablespace_op != NO_TABLESPACE_OP)
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
tablespace_op));
if (alter_flags == ALTER_ADD_INDEX)
DBUG_RETURN(mysql_create_index(thd, table_list, keys));
if (alter_flags == ALTER_DROP_INDEX)
DBUG_RETURN(mysql_drop_index(thd, table_list, drop_list));
if (alter_flags == ALTER_ADD_COLUMN)
DBUG_RETURN(mysql_add_column(thd, table_list, fields));
if (alter_flags == ALTER_DROP_COLUMN)
DBUG_RETURN(mysql_drop_column(thd, table_list, drop_list));
TABLE *table;
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
DBUG_RETURN(real_alter_table(thd, new_db, new_name,
create_info, table_list, table, fields,
keys, drop_list, alter_list,
order_num, order, alter_flags,
handle_duplicates, keys_onoff,
tablespace_op, simple_alter));
}
int real_alter_table(THD *thd,char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
TABLE *table,
List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_list,
uint order_num, ORDER *order, int alter_flags,
uint order_num, ORDER *order, uint alter_flags,
enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff,
enum tablespace_op_type tablespace_op,
bool simple_alter)
{
TABLE *new_table;
TABLE *table,*new_table;
int error;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN];
bool use_timestamp=0;
ha_rows copied,deleted;
ulonglong next_insert_id;
uint db_create_options, used_fields;
enum db_type old_db_type,new_db_type;
DBUG_ENTER("real_alter_table");
DBUG_ENTER("mysql_alter_table");
thd->proc_info="init";
table_name=table_list->real_name;
......@@ -2512,11 +2417,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
db=table_list->db;
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
{
new_db= db;
}
used_fields=create_info->used_fields;
mysql_ha_closeall(thd, table_list);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (tablespace_op != NO_TABLESPACE_OP)
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
tablespace_op));
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
DBUG_RETURN(-1);
/* Check that we are not trying to rename to an existing table */
if (new_name)
{
......@@ -2627,7 +2539,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
break;
}
}
if (error==HA_ERR_WRONG_COMMAND)
if (error == HA_ERR_WRONG_COMMAND)
{
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
......@@ -2648,7 +2560,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
{
table->file->print_error(error, MYF(0));
error=-1;
error= -1;
}
table_list->table=0; // For query cache
query_cache_invalidate3(thd, table_list, 0);
......@@ -2716,8 +2628,6 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if (def)
{ // Field is changed
def->field=field;
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
use_timestamp=1;
if (!def->after)
{
create_list.push_back(def);
......@@ -2727,8 +2637,6 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
{ // Use old field value
create_list.push_back(def=new create_field(field,field));
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
use_timestamp=1;
alter_it.rewind(); // Change default if ALTER
Alter_column *alter;
while ((alter=alter_it++))
......@@ -2891,9 +2799,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
}
db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
current_pid, thd->thread_id)>= (int)sizeof(tmp_name))
goto err;
my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
current_pid, thd->thread_id);
create_info->db_type=new_db_type;
if (!create_info->comment)
create_info->comment=table->comment;
......@@ -2972,9 +2879,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else
{
char path[FN_REFLEN];
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, tmp_name)>= (int)sizeof(path))
goto err;
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, tmp_name);
fn_format(path,path,"","",4);
new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
}
......@@ -3057,9 +2963,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/
thd->proc_info="rename result table";
if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
current_pid, thd->thread_id)>= (int)sizeof(old_name))
goto err;
my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
current_pid, thd->thread_id);
if (new_name != table_name || new_db != db)
{
if (!access(new_name_buff,F_OK))
......@@ -3182,9 +3087,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown.
*/
char path[FN_REFLEN];
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, table_name)>= (int)sizeof(path))
goto err;
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, table_name);
fn_format(path,path,"","",4);
table=open_temporary_table(thd, path, new_db, tmp_name,0);
if (table)
......@@ -3202,10 +3106,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
query_cache_invalidate3(thd, table_list, 0);
end_temporary:
if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
my_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;
(ulong) thd->cuted_fields);
send_ok(thd,copied+deleted,0L,tmp_name);
thd->some_tables_deleted=0;
DBUG_RETURN(0);
......
......@@ -46,8 +46,25 @@ static bool make_empty_rec(int file, enum db_type table_type,
List<create_field> &create_fields,
uint reclength,uint null_fields);
/*
Create a frm (table definition) file
SYNOPSIS
mysql_create_frm()
thd Thread handler
file_name Name of file (including database and .frm)
create_info create info parameters
create_fields Fields to create
keys number of keys to create
key_info Keys to create
db_file Handler to use. May be zero, in which case we use
create_info->db_type
RETURN
0 ok
1 error
*/
int mysql_create_frm(THD *thd, my_string file_name,
bool mysql_create_frm(THD *thd, my_string file_name,
HA_CREATE_INFO *create_info,
List<create_field> &create_fields,
uint keys, KEY *key_info,
......@@ -166,9 +183,29 @@ err:
err2:
VOID(my_close(file,MYF(MY_WME)));
err3:
my_delete(file_name,MYF(0));
DBUG_RETURN(1);
} /* mysql_create_frm */
/*
Create a frm (table definition) file and the tables
SYNOPSIS
mysql_create_frm()
thd Thread handler
file_name Name of file (including database and .frm)
create_info create info parameters
create_fields Fields to create
keys number of keys to create
key_info Keys to create
db_file Handler to use. May be zero, in which case we use
create_info->db_type
RETURN
0 ok
1 error
*/
int rea_create_table(THD *thd, my_string file_name,
HA_CREATE_INFO *create_info,
List<create_field> &create_fields,
......@@ -179,12 +216,8 @@ int rea_create_table(THD *thd, my_string file_name,
if (mysql_create_frm(thd, file_name, create_info,
create_fields, keys, key_info, NULL) ||
ha_create_table(file_name,create_info,0))
goto err;
DBUG_RETURN(0);
err:
my_delete(file_name,MYF(0));
DBUG_RETURN(1);
DBUG_RETURN(0);
} /* rea_create_table */
......
......@@ -25,8 +25,9 @@
IMPLEMENTION:
Supports following formats:
%#d
%#u
%#[l]d
%#[l]u
%#[l]x
%#.#s Note #.# is skiped
RETURN
......@@ -47,7 +48,7 @@ int my_snprintf(char* to, size_t n, const char* fmt, ...)
int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
{
char *start=to, *end=to+n-1;
uint length, num_state, pre_zero;
uint length, num_state, pre_zero, have_long;
for (; *fmt ; fmt++)
{
......@@ -62,7 +63,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
/* Read max fill size (only used with %d and %u) */
if (*fmt == '-')
fmt++;
length= num_state= pre_zero= 0;
length= num_state= pre_zero= have_long= 0;
for (;; fmt++)
{
if (my_isdigit(&my_charset_latin1,*fmt))
......@@ -80,7 +81,10 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
num_state= 1;
}
if (*fmt == 'l')
{
fmt++;
have_long= 1;
}
if (*fmt == 's') /* String parameter */
{
reg2 char *par = va_arg(ap, char *);
......@@ -92,20 +96,29 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
to=strnmov(to,par,plen);
continue;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
else if (*fmt == 'd' || *fmt == 'u'|| *fmt== 'x') /* Integer parameter */
{
register int iarg;
register long larg;
uint res_length, to_length;
char *store_start= to, *store_end;
char buff[16];
char buff[32];
if ((to_length= (uint) (end-to)) < 16 || length)
store_start= buff;
iarg = va_arg(ap, int);
if (have_long)
larg = va_arg(ap, long);
else
if (*fmt == 'd')
store_end= int10_to_str((long) iarg, store_start, -10);
larg = va_arg(ap, int);
else
larg= (long) (uint) va_arg(ap, int);
if (*fmt == 'd')
store_end= int10_to_str(larg, store_start, -10);
else
if (*fmt== 'u')
store_end= int10_to_str(larg, store_start, 10);
else
store_end= int10_to_str((long) (uint) iarg, store_start, 10);
store_end= int2str(larg, store_start, 16);
if ((res_length= (uint) (store_end - store_start)) > to_length)
break; /* num doesn't fit in output */
/* If %#d syntax was used, we have to pre-zero/pre-space the string */
......@@ -146,7 +159,7 @@ static void my_printf(const char * fmt, ...)
n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar);
printf(buf);
printf("n=%d, strlen=%d\n", n, strlen(buf));
if (buf[sizeof(buf)-1] != OVERRUN_SENTRY)
if ((uchar) buf[sizeof(buf)-1] != OVERRUN_SENTRY)
{
fprintf(stderr, "Buffer overrun\n");
abort();
......@@ -167,6 +180,7 @@ int main()
my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack");
my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1);
my_printf("Hello %u\n", 1);
my_printf("Hex: %lx '%6lx'\n", 32, 65);
my_printf("conn %ld to: '%-.64s' user: '%-.32s' host:\
`%-.64s' (%-.64s)", 1, 0,0,0,0);
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