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) ...@@ -867,7 +867,9 @@ void ha_myisam::start_bulk_insert(ha_rows rows)
THD *thd=current_thd; THD *thd=current_thd;
ulong size= min(thd->variables.read_buff_size, table->avg_row_length*rows); 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 == can_enable_indexes= (file->s->state.key_map ==
set_bits(ulonglong, file->s->base.keys)); set_bits(ulonglong, file->s->base.keys));
......
...@@ -509,19 +509,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, ...@@ -509,19 +509,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list, List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_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,
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,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
...@@ -537,10 +525,6 @@ bool mysql_rename_table(enum db_type base, ...@@ -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_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
int mysql_drop_index(THD *thd, TABLE_LIST *table_list, int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
List<Alter_drop> &drop_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, int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &values,COND *conds, List<Item> &values,COND *conds,
uint order_num, ORDER *order, ha_rows limit, uint order_num, ORDER *order, ha_rows limit,
...@@ -944,7 +928,8 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list, ...@@ -944,7 +928,8 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
void unireg_init(ulong options); void unireg_init(ulong options);
void unireg_end(void); 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, List<create_field> &create_field,
uint key_count,KEY *key_info,handler *db_type); uint key_count,KEY *key_info,handler *db_type);
int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info, 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) ...@@ -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), THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
last_insert_id_used(0), last_insert_id_used(0),
insert_id_used(0), rand_used(0), in_lock_tables(0), insert_id_used(0), rand_used(0), in_lock_tables(0),
global_read_lock(0), bootstrap(0), global_read_lock(0), bootstrap(0)
no_table_fix_fields_cache(0)
{ {
host= user= priv_user= db= ip=0; host= user= priv_user= db= ip=0;
host_or_ip= "connecting host"; host_or_ip= "connecting host";
......
...@@ -260,7 +260,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, ...@@ -260,7 +260,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->proc_info="update"; thd->proc_info="update";
if (duplic != DUP_ERROR) if (duplic != DUP_ERROR)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); 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); table->file->start_bulk_insert(values_list.elements);
while ((values= its++)) while ((values= its++))
......
...@@ -4993,3 +4993,49 @@ Item * all_any_subquery_creator(Item *left_expr, ...@@ -4993,3 +4993,49 @@ Item * all_any_subquery_creator(Item *left_expr,
return it; /* ANY/SOME */ 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, ...@@ -289,15 +289,12 @@ 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;
if (snprintf(path, sizeof(path), "%s/%s/%s%s", my_snprintf(path, sizeof(path), "%s/%s/%s%s",
mysql_data_home, db, table_name, reg_ext)>= (int)sizeof(path)) mysql_data_home, db, table_name, reg_ext);
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 */
if (snprintf(path, sizeof(path), "%s/%s/%s", my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, db, table_name);
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;
} }
...@@ -410,7 +407,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -410,7 +407,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys, bool tmp_table, uint &db_options, List<Key> &keys, bool tmp_table, uint &db_options,
handler *file, KEY *&key_info_buffer, handler *file, KEY *&key_info_buffer,
uint &key_count, int select_field_count) uint *key_count, int select_field_count)
{ {
const char *key_name; const char *key_name;
create_field *sql_field,*dup_field; create_field *sql_field,*dup_field;
...@@ -650,7 +647,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -650,7 +647,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
uint tmp, key_number; uint tmp, key_number;
/* Calculate number of key segements */ /* Calculate number of key segements */
key_count=0; *key_count= 0;
while ((key=key_iterator++)) while ((key=key_iterator++))
{ {
...@@ -668,7 +665,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -668,7 +665,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
} }
continue; continue;
} }
key_count++; (*key_count)++;
tmp=max(file->max_key_parts(),MAX_REF_PARTS); tmp=max(file->max_key_parts(),MAX_REF_PARTS);
if (key->columns.elements > tmp) if (key->columns.elements > tmp)
{ {
...@@ -689,13 +686,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -689,13 +686,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
} }
} }
tmp=min(file->max_keys(), MAX_KEY); tmp=min(file->max_keys(), MAX_KEY);
if (key_count > tmp) if (*key_count > tmp)
{ {
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp); my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
DBUG_RETURN(-1); 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); key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
if (!key_info_buffer || ! key_part_info) if (!key_info_buffer || ! key_part_info)
DBUG_RETURN(-1); // Out of memory DBUG_RETURN(-1); // Out of memory
...@@ -907,9 +904,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -907,9 +904,8 @@ 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];
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length)>= (int)sizeof(warn_buff)) length);
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);
} }
...@@ -946,9 +942,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -946,9 +942,8 @@ 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];
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY), my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
length)>= (int)sizeof(warn_buff)) length);
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);
} }
...@@ -1026,11 +1021,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, ...@@ -1026,11 +1021,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
/* Sort keys in optimized order */ /* 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); DBUG_RETURN(0);
} }
/* /*
Create a table Create a table
...@@ -1105,23 +1102,21 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, ...@@ -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, if (mysql_prepare_table(thd, create_info, fields,
keys, tmp_table, db_options, file, keys, tmp_table, db_options, file,
key_info_buffer, key_count, key_info_buffer, &key_count,
select_field_count)) select_field_count))
DBUG_RETURN(-1); DBUG_RETURN(-1);
/* 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)
{ {
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, mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id,
thd->tmp_table++, reg_ext)>= (int)sizeof(path)) thd->tmp_table++, reg_ext);
DBUG_RETURN(-1);
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE; create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
} }
else else
if (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db, my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
alias, reg_ext)>= (int)sizeof(path)) alias, reg_ext);
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)
...@@ -1215,25 +1210,27 @@ static char * ...@@ -1215,25 +1210,27 @@ 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, sizeof(buff)-4);
/*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/
/*
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++) for (uint i=2 ; i< 100; i++)
{ {
remain= (int)sizeof(buff)- (buff_end- buff); *buff_end= '_';
if (snprintf(buff_end, remain, "_%d", i)>= remain) int10_to_str(i, buff_end+1, 10);
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 (char*) "not_specified"; // Should never happen
return NULL;
} }
/**************************************************************************** /****************************************************************************
** Create table from a list of fields and items ** Create table from a list of fields and items
****************************************************************************/ ****************************************************************************/
...@@ -1329,12 +1326,10 @@ mysql_rename_table(enum db_type base, ...@@ -1329,12 +1326,10 @@ 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;
} }
if (snprintf(from, sizeof(from), "%s/%s/%s", my_snprintf(from, sizeof(from), "%s/%s/%s",
mysql_data_home, old_db, old_name)>= (int)sizeof(from)) mysql_data_home, old_db, old_name);
DBUG_RETURN(1); my_snprintf(to, sizeof(to), "%s/%s/%s",
if (snprintf(to, sizeof(to), "%s/%s/%s", mysql_data_home, new_db, new_name);
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);
...@@ -1469,9 +1464,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, ...@@ -1469,9 +1464,8 @@ 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
if (snprintf(dst_path, sizeof(dst_path), "%s/%s/%s", my_snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
mysql_real_data_home, db, table_name)>= (int)sizeof(dst_path)) mysql_real_data_home, db, table_name);
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);
...@@ -1555,12 +1549,8 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, ...@@ -1555,12 +1549,8 @@ 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
if (snprintf(tmp, sizeof(tmp), "%s-%lx_%lx", my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
from, current_pid, thd->thread_id)>= (int)sizeof(tmp)) from, current_pid, thd->thread_id);
{
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)
...@@ -1695,9 +1685,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, ...@@ -1695,9 +1685,7 @@ 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);
if (snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY), table_name);
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
...@@ -2019,11 +2007,9 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, ...@@ -2019,11 +2007,9 @@ 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;
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, mysql_tmpdir, tmp_file_prefix, current_pid,
thd->thread_id, thd->tmp_table++, reg_ext)>= 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
...@@ -2081,9 +2067,8 @@ table_exists: ...@@ -2081,9 +2067,8 @@ table_exists:
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];
if (snprintf(warn_buff, sizeof(warn_buff), my_snprintf(warn_buff, sizeof(warn_buff),
ER(ER_TABLE_EXISTS_ERROR), table_name)>= (int)sizeof(warn_buff)) ER(ER_TABLE_EXISTS_ERROR), table_name);
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);
res= 0; res= 0;
...@@ -2194,6 +2179,8 @@ err: ...@@ -2194,6 +2179,8 @@ err:
DBUG_RETURN(error); DBUG_RETURN(error);
} }
#ifdef NOT_USED
/* /*
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with 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 the proper arguments. This isn't very fast but it should work for most
...@@ -2201,7 +2188,7 @@ err: ...@@ -2201,7 +2188,7 @@ err:
One should normally create all indexes with CREATE TABLE or ALTER TABLE. 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<create_field> fields;
List<Alter_drop> drop; List<Alter_drop> drop;
...@@ -2214,7 +2201,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) ...@@ -2214,7 +2201,7 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
TABLE *table; TABLE *table;
Field **f_ptr; Field **f_ptr;
KEY *key_info_buffer; KEY *key_info_buffer;
char path[FN_REFLEN]; char path[FN_REFLEN+1];
DBUG_ENTER("mysql_create_index"); DBUG_ENTER("mysql_create_index");
/* /*
...@@ -2272,29 +2259,29 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) ...@@ -2272,29 +2259,29 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
&create_info, table_list, table, &create_info, table_list, table,
fields, keys, drop, alter, 0, (ORDER*)0, fields, keys, drop, alter, 0, (ORDER*)0,
ALTER_ADD_INDEX, DUP_ERROR)) 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); DBUG_RETURN(-1);
} }
else else
{ {
if (table->file->add_index(table, key_info_buffer, key_count)|| if (table->file->add_index(table, key_info_buffer, key_count)||
(snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, (my_snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
table_list->db, (lower_case_table_names == 2)? table_list->db, (lower_case_table_names == 2) ?
table_list->alias: table_list->real_name, reg_ext)>= table_list->alias: table_list->real_name, reg_ext) >=
(int)sizeof(path))|| (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))
/*don't need to free((gptr) key_info_buffer);*/ /* don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
/* don't need to free((gptr) key_info_buffer);*/
/*don't need to free((gptr) key_info_buffer);*/
DBUG_RETURN(0); 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<create_field> fields;
List<Key> keys; List<Key> keys;
...@@ -2394,47 +2381,12 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) ...@@ -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);*/ /*don't need to free((gptr) key_numbers);*/
DBUG_RETURN(0); 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, Alter 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));
}
int mysql_alter_table(THD *thd,char *new_db, char *new_name, int mysql_alter_table(THD *thd,char *new_db, char *new_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
...@@ -2442,69 +2394,22 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2442,69 +2394,22 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
List<create_field> &fields, List<create_field> &fields,
List<Key> &keys,List<Alter_drop> &drop_list, List<Key> &keys,List<Alter_drop> &drop_list,
List<Alter_column> &alter_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)
{
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,
enum enum_duplicates handle_duplicates, enum enum_duplicates handle_duplicates,
enum enum_enable_or_disable keys_onoff, enum enum_enable_or_disable keys_onoff,
enum tablespace_op_type tablespace_op, enum tablespace_op_type tablespace_op,
bool simple_alter) bool simple_alter)
{ {
TABLE *new_table; TABLE *table,*new_table;
int error; int error;
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; 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 new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
char index_file[FN_REFLEN], data_file[FN_REFLEN]; char index_file[FN_REFLEN], data_file[FN_REFLEN];
bool use_timestamp=0;
ha_rows copied,deleted; ha_rows copied,deleted;
ulonglong next_insert_id; ulonglong next_insert_id;
uint db_create_options, used_fields; uint db_create_options, used_fields;
enum db_type old_db_type,new_db_type; enum db_type old_db_type,new_db_type;
DBUG_ENTER("real_alter_table"); DBUG_ENTER("mysql_alter_table");
thd->proc_info="init"; thd->proc_info="init";
table_name=table_list->real_name; table_name=table_list->real_name;
...@@ -2512,11 +2417,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2512,11 +2417,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
db=table_list->db; db=table_list->db;
if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db)) if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
{
new_db= db; new_db= db;
}
used_fields=create_info->used_fields; 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 */ /* Check that we are not trying to rename to an existing table */
if (new_name) if (new_name)
{ {
...@@ -2627,7 +2539,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2627,7 +2539,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
break; break;
} }
} }
if (error==HA_ERR_WRONG_COMMAND) if (error == HA_ERR_WRONG_COMMAND)
{ {
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
...@@ -2648,7 +2560,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2648,7 +2560,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else else
{ {
table->file->print_error(error, MYF(0)); table->file->print_error(error, MYF(0));
error=-1; error= -1;
} }
table_list->table=0; // For query cache table_list->table=0; // For query cache
query_cache_invalidate3(thd, table_list, 0); query_cache_invalidate3(thd, table_list, 0);
...@@ -2716,8 +2628,6 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2716,8 +2628,6 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
if (def) if (def)
{ // Field is changed { // Field is changed
def->field=field; def->field=field;
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
use_timestamp=1;
if (!def->after) if (!def->after)
{ {
create_list.push_back(def); create_list.push_back(def);
...@@ -2727,8 +2637,6 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2727,8 +2637,6 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else else
{ // Use old field value { // Use old field value
create_list.push_back(def=new create_field(field,field)); 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_it.rewind(); // Change default if ALTER
Alter_column *alter; Alter_column *alter;
while ((alter=alter_it++)) while ((alter=alter_it++))
...@@ -2891,9 +2799,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -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); db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix, my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
current_pid, thd->thread_id)>= (int)sizeof(tmp_name)) current_pid, thd->thread_id);
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;
...@@ -2972,9 +2879,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -2972,9 +2879,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
else else
{ {
char path[FN_REFLEN]; char path[FN_REFLEN];
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, tmp_name)>= (int)sizeof(path)) new_db, tmp_name);
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);
} }
...@@ -3057,9 +2963,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3057,9 +2963,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
*/ */
thd->proc_info="rename result table"; thd->proc_info="rename result table";
if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix, my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
current_pid, thd->thread_id)>= (int)sizeof(old_name)) current_pid, thd->thread_id);
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))
...@@ -3182,9 +3087,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3182,9 +3087,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name,
shutdown. shutdown.
*/ */
char path[FN_REFLEN]; char path[FN_REFLEN];
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home, my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
new_db, table_name)>= (int)sizeof(path)) new_db, table_name);
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)
...@@ -3202,10 +3106,9 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, ...@@ -3202,10 +3106,9 @@ 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:
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) (copied + deleted), (ulong) deleted,
(ulong) thd->cuted_fields)>= (int)sizeof(tmp_name)) (ulong) thd->cuted_fields);
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);
......
...@@ -46,8 +46,25 @@ static bool make_empty_rec(int file, enum db_type table_type, ...@@ -46,8 +46,25 @@ static bool make_empty_rec(int file, enum db_type table_type,
List<create_field> &create_fields, List<create_field> &create_fields,
uint reclength,uint null_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, HA_CREATE_INFO *create_info,
List<create_field> &create_fields, List<create_field> &create_fields,
uint keys, KEY *key_info, uint keys, KEY *key_info,
...@@ -166,9 +183,29 @@ err: ...@@ -166,9 +183,29 @@ err:
err2: err2:
VOID(my_close(file,MYF(MY_WME))); VOID(my_close(file,MYF(MY_WME)));
err3: err3:
my_delete(file_name,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} /* mysql_create_frm */ } /* 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, int rea_create_table(THD *thd, my_string file_name,
HA_CREATE_INFO *create_info, HA_CREATE_INFO *create_info,
List<create_field> &create_fields, List<create_field> &create_fields,
...@@ -179,12 +216,8 @@ int rea_create_table(THD *thd, my_string file_name, ...@@ -179,12 +216,8 @@ int rea_create_table(THD *thd, my_string file_name,
if (mysql_create_frm(thd, file_name, create_info, if (mysql_create_frm(thd, file_name, create_info,
create_fields, keys, key_info, NULL) || create_fields, keys, key_info, NULL) ||
ha_create_table(file_name,create_info,0)) 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(1);
DBUG_RETURN(0);
} /* rea_create_table */ } /* rea_create_table */
......
...@@ -25,8 +25,9 @@ ...@@ -25,8 +25,9 @@
IMPLEMENTION: IMPLEMENTION:
Supports following formats: Supports following formats:
%#d %#[l]d
%#u %#[l]u
%#[l]x
%#.#s Note #.# is skiped %#.#s Note #.# is skiped
RETURN RETURN
...@@ -47,7 +48,7 @@ int my_snprintf(char* to, size_t n, const char* fmt, ...) ...@@ -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) int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
{ {
char *start=to, *end=to+n-1; char *start=to, *end=to+n-1;
uint length, num_state, pre_zero; uint length, num_state, pre_zero, have_long;
for (; *fmt ; fmt++) for (; *fmt ; fmt++)
{ {
...@@ -62,7 +63,7 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) ...@@ -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) */ /* Read max fill size (only used with %d and %u) */
if (*fmt == '-') if (*fmt == '-')
fmt++; fmt++;
length= num_state= pre_zero= 0; length= num_state= pre_zero= have_long= 0;
for (;; fmt++) for (;; fmt++)
{ {
if (my_isdigit(&my_charset_latin1,*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) ...@@ -80,7 +81,10 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
num_state= 1; num_state= 1;
} }
if (*fmt == 'l') if (*fmt == 'l')
{
fmt++; fmt++;
have_long= 1;
}
if (*fmt == 's') /* String parameter */ if (*fmt == 's') /* String parameter */
{ {
reg2 char *par = va_arg(ap, char *); 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) ...@@ -92,20 +96,29 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap)
to=strnmov(to,par,plen); to=strnmov(to,par,plen);
continue; 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; uint res_length, to_length;
char *store_start= to, *store_end; char *store_start= to, *store_end;
char buff[16]; char buff[32];
if ((to_length= (uint) (end-to)) < 16 || length) if ((to_length= (uint) (end-to)) < 16 || length)
store_start= buff; store_start= buff;
iarg = va_arg(ap, int); if (have_long)
larg = va_arg(ap, long);
else
if (*fmt == 'd') 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 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) if ((res_length= (uint) (store_end - store_start)) > to_length)
break; /* num doesn't fit in output */ break; /* num doesn't fit in output */
/* If %#d syntax was used, we have to pre-zero/pre-space the string */ /* 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, ...) ...@@ -146,7 +159,7 @@ static void my_printf(const char * fmt, ...)
n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar); n = my_vsnprintf(buf, sizeof(buf)-1,fmt, ar);
printf(buf); printf(buf);
printf("n=%d, strlen=%d\n", n, strlen(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"); fprintf(stderr, "Buffer overrun\n");
abort(); abort();
...@@ -167,6 +180,7 @@ int main() ...@@ -167,6 +180,7 @@ int main()
my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack"); my_printf("Hello '%s' hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n", "hack");
my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1); my_printf("Hello hhhhhhhhhhhhhh %d sssssssssssssss\n", 1);
my_printf("Hello %u\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:\ my_printf("conn %ld to: '%-.64s' user: '%-.32s' host:\
`%-.64s' (%-.64s)", 1, 0,0,0,0); `%-.64s' (%-.64s)", 1, 0,0,0,0);
return 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