mirror of
https://github.com/MariaDB/server.git
synced 2025-07-27 18:02:13 +03:00
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()
This commit is contained in:
@ -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));
|
||||
}
|
||||
|
267
sql/sql_table.cc
267
sql/sql_table.cc
@ -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,
|
||||
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_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
|
||||
|
||||
int mysql_create_frm(THD *thd, my_string file_name,
|
||||
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
|
||||
*/
|
||||
|
||||
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 (*fmt == 'd')
|
||||
store_end= int10_to_str((long) iarg, store_start, -10);
|
||||
if (have_long)
|
||||
larg = va_arg(ap, long);
|
||||
else
|
||||
store_end= int10_to_str((long) (uint) iarg, store_start, 10);
|
||||
if (*fmt == 'd')
|
||||
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= 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;
|
||||
|
Reference in New Issue
Block a user