diff options
-rw-r--r-- | sql/ha_myisam.cc | 4 | ||||
-rw-r--r-- | sql/handler.h | 8 | ||||
-rw-r--r-- | sql/mysql_priv.h | 25 | ||||
-rw-r--r-- | sql/sql_class.cc | 3 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 46 | ||||
-rw-r--r-- | sql/sql_table.cc | 1895 | ||||
-rw-r--r-- | sql/unireg.cc | 53 | ||||
-rw-r--r-- | strings/my_vsnprintf.c | 36 |
9 files changed, 1027 insertions, 1045 deletions
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index c56009dc0aa..ca264f500a6 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -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)); diff --git a/sql/handler.h b/sql/handler.h index f1bce5950c4..4cb6ab86a37 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -92,10 +92,10 @@ /* - Bits in index_ddl_flags(KEY *wanted_index) - for what ddl you can do with index - If none is set, the wanted type of index is not supported - by the handler at all. See WorkLog 1563. + Bits in index_ddl_flags(KEY *wanted_index) + for what ddl you can do with index + If none is set, the wanted type of index is not supported + by the handler at all. See WorkLog 1563. */ #define HA_DDL_SUPPORT 1 /* Supported by handler */ #define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8c22aa6a110..bd9a94a969b 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -509,23 +509,11 @@ 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=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_enable_or_disable keys_onoff=LEAVE_AS_IS, - enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, - bool simple_alter=0); int mysql_create_like_table(THD *thd, TABLE_LIST *table, HA_CREATE_INFO *create_info, Table_ident *src_table); @@ -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,9 +928,10 @@ 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, - List<create_field> &create_field, - uint key_count,KEY *key_info,handler *db_type); +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, List<create_field> &create_field, uint key_count,KEY *key_info); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 5cad16f31df..1b4c8bec416 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -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"; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index c6aff403f5b..6333beb5cb8 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -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++)) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 37e0ca7a0c5..f88c8c12448 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -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)); +} diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 17ea4cd540e..d5f77bf545d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -34,19 +34,19 @@ const char *primary_key_name= "PRIMARY"; static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end); static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end); static int copy_data_between_tables(TABLE *from,TABLE *to, - List<create_field> &create, - enum enum_duplicates handle_duplicates, - uint order_num, ORDER *order, - ha_rows *copied,ha_rows *deleted); + List<create_field> &create, + enum enum_duplicates handle_duplicates, + uint order_num, ORDER *order, + ha_rows *copied,ha_rows *deleted); /* delete (drop) tables. SYNOPSIS mysql_rm_table() - thd Thread handle - tables List of tables to delete - if_exists If 1, don't give error if one table doesn't exists + thd Thread handle + tables List of tables to delete + if_exists If 1, don't give error if one table doesn't exists NOTES Will delete all tables that can be deleted and give a compact error @@ -57,13 +57,13 @@ static int copy_data_between_tables(TABLE *from,TABLE *to, Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set. RETURN - 0 ok. In this case ok packet is sent to user - -1 Error (Error message given but not sent to user) + 0 ok. In this case ok packet is sent to user + -1 Error (Error message given but not sent to user) */ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, - my_bool drop_temporary) + my_bool drop_temporary) { int error= 0; DBUG_ENTER("mysql_rm_table"); @@ -79,7 +79,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, if (thd->global_read_lock) { my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0), - tables->real_name); + tables->real_name); error= 1; goto err; } @@ -111,23 +111,23 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists, SYNOPSIS mysql_rm_table_part2_with_lock() - thd Thread handle - tables List of tables to delete - if_exists If 1, don't give error if one table doesn't exists - dont_log_query Don't write query to log files + thd Thread handle + tables List of tables to delete + if_exists If 1, don't give error if one table doesn't exists + dont_log_query Don't write query to log files NOTES Works like documented in mysql_rm_table(), but don't check global_read_lock and don't send_ok packet to server. RETURN - 0 ok - 1 error + 0 ok + 1 error */ int mysql_rm_table_part2_with_lock(THD *thd, - TABLE_LIST *tables, bool if_exists, - bool drop_temporary, bool dont_log_query) + TABLE_LIST *tables, bool if_exists, + bool drop_temporary, bool dont_log_query) { int error; thd->mysys_var->current_mutex= &LOCK_open; @@ -135,7 +135,7 @@ int mysql_rm_table_part2_with_lock(THD *thd, VOID(pthread_mutex_lock(&LOCK_open)); error=mysql_rm_table_part2(thd,tables, if_exists, drop_temporary, - dont_log_query); + dont_log_query); pthread_mutex_unlock(&LOCK_open); @@ -152,12 +152,12 @@ int mysql_rm_table_part2_with_lock(THD *thd, SYNOPSIS mysql_rm_table_part2() - thd Thread handler - tables Tables to drop - if_exists If set, don't give an error if table doesn't exists. - In this case we give an warning of level 'NOTE' - drop_temporary Only drop temporary tables - dont_log_query Don't log the query + thd Thread handler + tables Tables to drop + if_exists If set, don't give an error if table doesn't exists. + In this case we give an warning of level 'NOTE' + drop_temporary Only drop temporary tables + dont_log_query Don't log the query TODO: When logging to the binary log, we should log @@ -170,16 +170,16 @@ int mysql_rm_table_part2_with_lock(THD *thd, not all. RETURN - 0 ok - 1 Error - -1 Thread was killed + 0 ok + 1 Error + -1 Thread was killed */ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, - bool drop_temporary, bool dont_log_query) + bool drop_temporary, bool dont_log_query) { TABLE_LIST *table; - char path[FN_REFLEN], *alias; + char path[FN_REFLEN], *alias; String wrong_tables; int error; bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0; @@ -195,7 +195,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (!close_temporary_table(thd, db, table->real_name)) { tmp_table_deleted=1; - continue; // removed temporary table + continue; // removed temporary table } error=0; @@ -204,13 +204,13 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, abort_locked_tables(thd,db,table->real_name); while (remove_table_from_cache(thd,db,table->real_name) && !thd->killed) { - dropping_tables++; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - dropping_tables--; + dropping_tables++; + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + dropping_tables--; } drop_locked_tables(thd,db,table->real_name); if (thd->killed) - DBUG_RETURN(-1); + DBUG_RETURN(-1); alias= (lower_case_table_names == 2) ? table->alias : table->real_name; /* remove form file and isam files */ strxmov(path, mysql_data_home, "/", db, "/", alias, reg_ext, NullS); @@ -219,37 +219,37 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (drop_temporary || access(path,F_OK)) { if (if_exists) - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), - table->real_name); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), + table->real_name); else - error= 1; + error= 1; } else { char *end; db_type table_type= get_table_type(path); - *(end=fn_ext(path))=0; // Remove extension for delete + *(end=fn_ext(path))=0; // Remove extension for delete error=ha_delete_table(table_type, path); if (error == ENOENT && if_exists) - error = 0; + error = 0; if (error == HA_ERR_ROW_IS_REFERENCED) { - /* the table is referenced by a foreign key constraint */ - foreign_key_error=1; + /* the table is referenced by a foreign key constraint */ + foreign_key_error=1; } if (!error || error == ENOENT) { - /* Delete the table definition file */ - strmov(end,reg_ext); - if (!(error=my_delete(path,MYF(MY_WME)))) - some_tables_deleted=1; + /* Delete the table definition file */ + strmov(end,reg_ext); + if (!(error=my_delete(path,MYF(MY_WME)))) + some_tables_deleted=1; } } if (error) { if (wrong_tables.length()) - wrong_tables.append(','); + wrong_tables.append(','); wrong_tables.append(String(table->real_name,system_charset_info)); } } @@ -262,10 +262,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_update_log.write(thd, thd->query,thd->query_length); if (mysql_bin_log.is_open()) { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, - tmp_table_deleted && !some_tables_deleted); - mysql_bin_log.write(&qinfo); + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, + tmp_table_deleted && !some_tables_deleted); + mysql_bin_log.write(&qinfo); } } } @@ -285,19 +285,16 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, int quick_rm_table(enum db_type base,const char *db, - const char *table_name) + const char *table_name) { 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; } @@ -331,32 +328,32 @@ static int sort_keys(KEY *a, KEY *b) return 1; } else if (b->flags & HA_NOSAME) - return 1; // Prefer b + return 1; // Prefer b if ((a->flags ^ b->flags) & HA_FULLTEXT) { return (a->flags & HA_FULLTEXT) ? 1 : -1; } /* - Prefer original key order. usable_key_parts contains here + Prefer original key order. usable_key_parts contains here the original key position. */ return ((a->usable_key_parts < b->usable_key_parts) ? -1 : - (a->usable_key_parts > b->usable_key_parts) ? 1 : - 0); + (a->usable_key_parts > b->usable_key_parts) ? 1 : + 0); } /* Check TYPELIB (set or enum) for duplicates - + SYNOPSIS check_duplicates_in_interval() set_or_name "SET" or "ENUM" string for warning message - name name of the checked column - typelib list of values for the column + name name of the checked column + typelib list of values for the column DESCRIPTION - This function prints an warning for each value in list + This function prints an warning for each value in list which has some duplicates on its right RETURN VALUES @@ -364,7 +361,7 @@ static int sort_keys(KEY *a, KEY *b) */ void check_duplicates_in_interval(const char *set_or_name, - const char *name, TYPELIB *typelib) + const char *name, TYPELIB *typelib) { unsigned int old_count= typelib->count; const char **old_type_names= typelib->type_names; @@ -379,9 +376,9 @@ void check_duplicates_in_interval(const char *set_or_name, if (find_type((char*)*cur_value,typelib,1)) { push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_DUPLICATED_VALUE_IN_TYPE, - ER(ER_DUPLICATED_VALUE_IN_TYPE), - name,*cur_value,set_or_name); + ER_DUPLICATED_VALUE_IN_TYPE, + ER(ER_DUPLICATED_VALUE_IN_TYPE), + name,*cur_value,set_or_name); } } typelib->count= old_count; @@ -393,34 +390,34 @@ void check_duplicates_in_interval(const char *set_or_name, SYNOPSIS mysql_prepare_table() - thd Thread object - create_info Create information (like MAX_ROWS) - fields List of fields to create - keys List of keys to create + thd Thread object + create_info Create information (like MAX_ROWS) + fields List of fields to create + keys List of keys to create DESCRIPTION Prepares the table and key structures for table creation. RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ 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) + 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) { - const char *key_name; - create_field *sql_field,*dup_field; - uint field,null_fields,blob_columns; - ulong pos; - KEY *key_info; + const char *key_name; + create_field *sql_field,*dup_field; + uint field,null_fields,blob_columns; + ulong pos; + KEY *key_info; KEY_PART_INFO *key_part_info; - int timestamps= 0, timestamps_with_niladic= 0; - int field_no,dup_no; - int select_field_pos,auto_increment=0; + int timestamps= 0, timestamps_with_niladic= 0; + int field_no,dup_no; + int select_field_pos,auto_increment=0; DBUG_ENTER("mysql_prepare_table"); List_iterator<create_field> it(fields),it2(fields); @@ -450,13 +447,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp); DBUG_RETURN(-1); } - + sql_field->create_length_to_internal_length(); /* Don't pack keys in old tables if the user has requested this */ if ((sql_field->flags & BLOB_FLAG) || - sql_field->sql_type == FIELD_TYPE_VAR_STRING && - create_info->row_type != ROW_TYPE_FIXED) + sql_field->sql_type == FIELD_TYPE_VAR_STRING && + create_info->row_type != ROW_TYPE_FIXED) { db_options|=HA_OPTION_PACK_RECORD; } @@ -473,35 +470,35 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) { if (my_strcasecmp(system_charset_info, - sql_field->field_name, - dup_field->field_name) == 0) + sql_field->field_name, + dup_field->field_name) == 0) { - /* - If this was a CREATE ... SELECT statement, accept a field - redefinition if we are changing a field in the SELECT part - */ - if (field_no < select_field_pos || dup_no >= select_field_pos) - { - my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); - DBUG_RETURN(-1); - } - else - { - /* Field redefined */ - sql_field->sql_type= dup_field->sql_type; - sql_field->charset= (dup_field->charset ? - dup_field->charset : - create_info->default_table_charset); - sql_field->length= dup_field->length; - sql_field->pack_length= dup_field->pack_length; - sql_field->create_length_to_internal_length(); - sql_field->decimals= dup_field->decimals; - sql_field->flags= dup_field->flags; - sql_field->unireg_check= dup_field->unireg_check; - it2.remove(); // Remove first (create) definition - select_field_pos--; - break; - } + /* + If this was a CREATE ... SELECT statement, accept a field + redefinition if we are changing a field in the SELECT part + */ + if (field_no < select_field_pos || dup_no >= select_field_pos) + { + my_error(ER_DUP_FIELDNAME,MYF(0),sql_field->field_name); + DBUG_RETURN(-1); + } + else + { + /* Field redefined */ + sql_field->sql_type= dup_field->sql_type; + sql_field->charset= (dup_field->charset ? + dup_field->charset : + create_info->default_table_charset); + sql_field->length= dup_field->length; + sql_field->pack_length= dup_field->pack_length; + sql_field->create_length_to_internal_length(); + sql_field->decimals= dup_field->decimals; + sql_field->flags= dup_field->flags; + sql_field->unireg_check= dup_field->unireg_check; + it2.remove(); // Remove first (create) definition + select_field_pos--; + break; + } } } it2.rewind(); @@ -522,11 +519,11 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, case FIELD_TYPE_TINY_BLOB: case FIELD_TYPE_LONG_BLOB: sql_field->pack_flag=FIELDFLAG_BLOB | - pack_length_to_packflag(sql_field->pack_length - - portable_sizeof_char_ptr); + pack_length_to_packflag(sql_field->pack_length - + portable_sizeof_char_ptr); if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; - sql_field->length=8; // Unireg field length + sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->length=8; // Unireg field length sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; break; @@ -534,49 +531,49 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_SPATIAL if (!(file->table_flags() & HA_HAS_GEOMETRY)) { - my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), - MYF(0), "GEOMETRY"); - DBUG_RETURN(-1); + my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED), + MYF(0), "GEOMETRY"); + DBUG_RETURN(-1); } sql_field->pack_flag=FIELDFLAG_GEOM | - pack_length_to_packflag(sql_field->pack_length - - portable_sizeof_char_ptr); + pack_length_to_packflag(sql_field->pack_length - + portable_sizeof_char_ptr); if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; - sql_field->length=8; // Unireg field length + sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->length=8; // Unireg field length sql_field->unireg_check=Field::BLOB_FIELD; blob_columns++; break; #else my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); + sym_group_geom.name, sym_group_geom.needed_define); DBUG_RETURN(-1); #endif /*HAVE_SPATIAL*/ case FIELD_TYPE_VAR_STRING: case FIELD_TYPE_STRING: sql_field->pack_flag=0; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|=FIELDFLAG_BINARY; break; case FIELD_TYPE_ENUM: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | - FIELDFLAG_INTERVAL; + FIELDFLAG_INTERVAL; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->unireg_check=Field::INTERVAL_FIELD; check_duplicates_in_interval("ENUM",sql_field->field_name, - sql_field->interval); + sql_field->interval); break; case FIELD_TYPE_SET: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | - FIELDFLAG_BITFIELD; + FIELDFLAG_BITFIELD; if (sql_field->charset->state & MY_CS_BINSORT) - sql_field->pack_flag|=FIELDFLAG_BINARY; + sql_field->pack_flag|=FIELDFLAG_BINARY; sql_field->unireg_check=Field::BIT_FIELD; check_duplicates_in_interval("SET",sql_field->field_name, - sql_field->interval); + sql_field->interval); break; - case FIELD_TYPE_DATE: // Rest of string types + case FIELD_TYPE_DATE: // Rest of string types case FIELD_TYPE_NEWDATE: case FIELD_TYPE_TIME: case FIELD_TYPE_DATETIME: @@ -587,27 +584,27 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* We should replace old TIMESTAMP fields with their newer analogs */ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD) { - if (!timestamps) - { - sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD; - timestamps_with_niladic++; - } - else - sql_field->unireg_check= Field::NONE; + if (!timestamps) + { + sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD; + timestamps_with_niladic++; + } + else + sql_field->unireg_check= Field::NONE; } else if (sql_field->unireg_check != Field::NONE) - timestamps_with_niladic++; - + timestamps_with_niladic++; + timestamps++; /* fall-through */ default: sql_field->pack_flag=(FIELDFLAG_NUMBER | - (sql_field->flags & UNSIGNED_FLAG ? 0 : - FIELDFLAG_DECIMAL) | - (sql_field->flags & ZEROFILL_FLAG ? - FIELDFLAG_ZEROFILL : 0) | - f_settype((uint) sql_field->sql_type) | - (sql_field->decimals << FIELDFLAG_DEC_SHIFT)); + (sql_field->flags & UNSIGNED_FLAG ? 0 : + FIELDFLAG_DECIMAL) | + (sql_field->flags & ZEROFILL_FLAG ? + FIELDFLAG_ZEROFILL : 0) | + f_settype((uint) sql_field->sql_type) | + (sql_field->decimals << FIELDFLAG_DEC_SHIFT)); break; } if (!(sql_field->flags & NOT_NULL_FLAG)) @@ -644,13 +641,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, List_iterator<Key> key_iterator(keys); uint key_parts=0, fk_key_count=0; - List<Key> keys_in_order; // Add new keys here + List<Key> keys_in_order; // Add new keys here bool primary_key=0,unique_key=0; Key *key; uint tmp, key_number; /* Calculate number of key segements */ - key_count=0; + *key_count= 0; while ((key=key_iterator++)) { @@ -659,16 +656,16 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, fk_key_count++; foreign_key *fk_key= (foreign_key*) key; if (fk_key->ref_columns.elements && - fk_key->ref_columns.elements != fk_key->columns.elements) + fk_key->ref_columns.elements != fk_key->columns.elements) { - my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : - "foreign key without name", - ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); - DBUG_RETURN(-1); + my_error(ER_WRONG_FK_DEF, MYF(0), fk_key->name ? fk_key->name : + "foreign key without name", + ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF)); + DBUG_RETURN(-1); } continue; } - key_count++; + (*key_count)++; tmp=max(file->max_key_parts(),MAX_REF_PARTS); if (key->columns.elements > tmp) { @@ -682,23 +679,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } key_parts+=key->columns.elements; if (key->name && !tmp_table && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); DBUG_RETURN(-1); } } 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 + DBUG_RETURN(-1); // Out of memory key_iterator.rewind(); key_number=0; @@ -709,25 +706,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, switch(key->type){ case Key::MULTIPLE: - key_info->flags = 0; - break; + key_info->flags = 0; + break; case Key::FULLTEXT: - key_info->flags = HA_FULLTEXT; - break; + key_info->flags = HA_FULLTEXT; + break; case Key::SPATIAL: #ifdef HAVE_SPATIAL - key_info->flags = HA_SPATIAL; - break; + key_info->flags = HA_SPATIAL; + break; #else - my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_geom.name, sym_group_geom.needed_define); - DBUG_RETURN(-1); + my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + DBUG_RETURN(-1); #endif case Key::FOREIGN_KEY: - key_number--; // Skip this key + key_number--; // Skip this key continue; default: - key_info->flags = HA_NOSAME; + key_info->flags = HA_NOSAME; } key_info->key_parts=(uint8) key->columns.elements; @@ -739,8 +736,8 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->table_flags() & HA_CAN_FULLTEXT)) { - my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); - DBUG_RETURN(-1); + my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); + DBUG_RETURN(-1); } } /* @@ -756,9 +753,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, { if (key_info->key_parts != 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); - DBUG_RETURN(-1); + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"SPATIAL INDEX"); + DBUG_RETURN(-1); } } else @@ -767,17 +764,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, #ifdef HAVE_RTREE_KEYS if ((key_info->key_parts & 1) == 1) { - my_printf_error(ER_WRONG_ARGUMENTS, - ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); - DBUG_RETURN(-1); + my_printf_error(ER_WRONG_ARGUMENTS, + ER(ER_WRONG_ARGUMENTS),MYF(0),"RTREE INDEX"); + DBUG_RETURN(-1); } /* TODO: To be deleted */ my_printf_error(ER_NOT_SUPPORTED_YET, ER(ER_NOT_SUPPORTED_YET), - MYF(0), "RTREE INDEX"); + MYF(0), "RTREE INDEX"); DBUG_RETURN(-1); #else my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED),MYF(0), - sym_group_rtree.name, sym_group_rtree.needed_define); + sym_group_rtree.name, sym_group_rtree.needed_define); DBUG_RETURN(-1); #endif } @@ -789,106 +786,106 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, it.rewind(); field=0; while ((sql_field=it++) && - my_strcasecmp(system_charset_info, - column->field_name, - sql_field->field_name)) - field++; + my_strcasecmp(system_charset_info, + column->field_name, + sql_field->field_name)) + field++; if (!sql_field) { - my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, - ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0), - column->field_name); - DBUG_RETURN(-1); + my_printf_error(ER_KEY_COLUMN_DOES_NOT_EXITS, + ER(ER_KEY_COLUMN_DOES_NOT_EXITS),MYF(0), + column->field_name); + DBUG_RETURN(-1); } /* for fulltext keys keyseg length is 1 for blobs (it's ignored in - ft code anyway, and 0 (set to column width later) for char's. - it has to be correct col width for char's, as char data are not - prefixed with length (unlike blobs, where ft code takes data length - from a data prefix, ignoring column->length). + ft code anyway, and 0 (set to column width later) for char's. + it has to be correct col width for char's, as char data are not + prefixed with length (unlike blobs, where ft code takes data length + from a data prefix, ignoring column->length). */ if (key->type == Key::FULLTEXT) { - if ((sql_field->sql_type != FIELD_TYPE_STRING && - sql_field->sql_type != FIELD_TYPE_VAR_STRING && - !f_is_blob(sql_field->pack_flag)) || - sql_field->charset == &my_charset_bin || - sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet - (ft_key_charset && sql_field->charset != ft_key_charset)) - { - my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } - ft_key_charset=sql_field->charset; - /* - for fulltext keys keyseg length is 1 for blobs (it's ignored in ft - code anyway, and 0 (set to column width later) for char's. it has - to be correct col width for char's, as char data are not prefixed - with length (unlike blobs, where ft code takes data length from a - data prefix, ignoring column->length). - */ - column->length=test(f_is_blob(sql_field->pack_flag)); + if ((sql_field->sql_type != FIELD_TYPE_STRING && + sql_field->sql_type != FIELD_TYPE_VAR_STRING && + !f_is_blob(sql_field->pack_flag)) || + sql_field->charset == &my_charset_bin || + sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet + (ft_key_charset && sql_field->charset != ft_key_charset)) + { + my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0), + column->field_name); + DBUG_RETURN(-1); + } + ft_key_charset=sql_field->charset; + /* + for fulltext keys keyseg length is 1 for blobs (it's ignored in ft + code anyway, and 0 (set to column width later) for char's. it has + to be correct col width for char's, as char data are not prefixed + with length (unlike blobs, where ft code takes data length from a + data prefix, ignoring column->length). + */ + column->length=test(f_is_blob(sql_field->pack_flag)); } else { - column->length*= sql_field->charset->mbmaxlen; - - if (f_is_blob(sql_field->pack_flag)) - { - if (!(file->table_flags() & HA_BLOB_KEY)) - { - my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } - if (!column->length) - { - my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, - ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), - column->field_name); - DBUG_RETURN(-1); - } - } + column->length*= sql_field->charset->mbmaxlen; + + if (f_is_blob(sql_field->pack_flag)) + { + if (!(file->table_flags() & HA_BLOB_KEY)) + { + my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0), + column->field_name); + DBUG_RETURN(-1); + } + if (!column->length) + { + my_printf_error(ER_BLOB_KEY_WITHOUT_LENGTH, + ER(ER_BLOB_KEY_WITHOUT_LENGTH),MYF(0), + column->field_name); + DBUG_RETURN(-1); + } + } #ifdef HAVE_SPATIAL - if (key->type == Key::SPATIAL) - { - if (!column->length ) - { - /* - BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case - Lately we'll extend this code to support more dimensions - */ - column->length=4*sizeof(double); - } - } + if (key->type == Key::SPATIAL) + { + if (!column->length ) + { + /* + BAR: 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case + Lately we'll extend this code to support more dimensions + */ + column->length=4*sizeof(double); + } + } #endif - if (!(sql_field->flags & NOT_NULL_FLAG)) - { - if (key->type == Key::PRIMARY) - { - /* Implicitly set primary key fields to NOT NULL for ISO conf. */ - sql_field->flags|= NOT_NULL_FLAG; - sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; - } - else - key_info->flags|= HA_NULL_PART_KEY; - if (!(file->table_flags() & HA_NULL_KEY)) - { - my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), - MYF(0),column->field_name); - DBUG_RETURN(-1); - } - if (key->type == Key::SPATIAL) - { - my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0)); - DBUG_RETURN(-1); - } - } - if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) - { - if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY)) - auto_increment--; // Field is used - } + if (!(sql_field->flags & NOT_NULL_FLAG)) + { + if (key->type == Key::PRIMARY) + { + /* Implicitly set primary key fields to NOT NULL for ISO conf. */ + sql_field->flags|= NOT_NULL_FLAG; + sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; + } + else + key_info->flags|= HA_NULL_PART_KEY; + if (!(file->table_flags() & HA_NULL_KEY)) + { + my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), + MYF(0),column->field_name); + DBUG_RETURN(-1); + } + if (key->type == Key::SPATIAL) + { + my_error(ER_SPATIAL_CANT_HAVE_NULL, MYF(0)); + DBUG_RETURN(-1); + } + } + if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) + { + if (column_nr == 0 || (file->table_flags() & HA_AUTO_PART_KEY)) + auto_increment--; // Field is used + } } key_part_info->fieldnr= field; @@ -897,79 +894,77 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, uint length=sql_field->pack_length; if (column->length) { - if (f_is_blob(sql_field->pack_flag)) - { - if ((length=column->length) > file->max_key_length() || - length > file->max_key_part_length()) - { - length=min(file->max_key_length(), file->max_key_part_length()); - if (key->type == Key::MULTIPLE) - { - /* 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); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_KEY, warn_buff); - } - else - { - my_error(ER_TOO_LONG_KEY,MYF(0),length); - DBUG_RETURN(-1); - } - } - } - else if (!f_is_geom(sql_field->pack_flag) && - (column->length > length || - ((f_is_packed(sql_field->pack_flag) || - ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && - (key_info->flags & HA_NOSAME))) && - column->length != length))) - { - my_error(ER_WRONG_SUB_KEY,MYF(0)); - DBUG_RETURN(-1); - } - else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) - length=column->length; + if (f_is_blob(sql_field->pack_flag)) + { + if ((length=column->length) > file->max_key_length() || + length > file->max_key_part_length()) + { + length=min(file->max_key_length(), file->max_key_part_length()); + if (key->type == Key::MULTIPLE) + { + /* not a critical problem */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + 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); + } + else + { + my_error(ER_TOO_LONG_KEY,MYF(0),length); + DBUG_RETURN(-1); + } + } + } + else if (!f_is_geom(sql_field->pack_flag) && + (column->length > length || + ((f_is_packed(sql_field->pack_flag) || + ((file->table_flags() & HA_NO_PREFIX_CHAR_KEYS) && + (key_info->flags & HA_NOSAME))) && + column->length != length))) + { + my_error(ER_WRONG_SUB_KEY,MYF(0)); + DBUG_RETURN(-1); + } + else if (!(file->table_flags() & HA_NO_PREFIX_CHAR_KEYS)) + length=column->length; } else if (length == 0) { - my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0), - column->field_name); - DBUG_RETURN(-1); + my_printf_error(ER_WRONG_KEY_COLUMN, ER(ER_WRONG_KEY_COLUMN), MYF(0), + column->field_name); + DBUG_RETURN(-1); } if (length > file->max_key_part_length()) { - length=file->max_key_part_length(); - if (key->type == Key::MULTIPLE) - { - /* 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); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TOO_LONG_KEY, warn_buff); - } - else - { - my_error(ER_TOO_LONG_KEY,MYF(0),length); - DBUG_RETURN(-1); - } + length=file->max_key_part_length(); + if (key->type == Key::MULTIPLE) + { + /* not a critical problem */ + char warn_buff[MYSQL_ERRMSG_SIZE]; + 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); + } + else + { + my_error(ER_TOO_LONG_KEY,MYF(0),length); + DBUG_RETURN(-1); + } } key_part_info->length=(uint16) length; /* Use packed keys for long strings on the first column */ if (!(db_options & HA_OPTION_NO_PACK_KEYS) && - (length >= KEY_DEFAULT_PACK_LENGTH && - (sql_field->sql_type == FIELD_TYPE_STRING || - sql_field->sql_type == FIELD_TYPE_VAR_STRING || - sql_field->pack_flag & FIELDFLAG_BLOB))) + (length >= KEY_DEFAULT_PACK_LENGTH && + (sql_field->sql_type == FIELD_TYPE_STRING || + sql_field->sql_type == FIELD_TYPE_VAR_STRING || + sql_field->pack_flag & FIELDFLAG_BLOB))) { - if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) - key_info->flags|= HA_BINARY_PACK_KEY; - else - key_info->flags|= HA_PACK_KEY; + if (column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) + key_info->flags|= HA_BINARY_PACK_KEY; + else + key_info->flags|= HA_PACK_KEY; } key_length+=length; key_part_info++; @@ -977,25 +972,25 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, /* Create the key name based on the first column (if not given) */ if (column_nr == 0) { - if (key->type == Key::PRIMARY) - { - if (primary_key) - { - my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); - DBUG_RETURN(-1); - } - key_name=primary_key_name; - primary_key=1; - } - else if (!(key_name = key->name)) - key_name=make_unique_key_name(sql_field->field_name, - key_info_buffer,key_info); - if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) - { - my_error(ER_DUP_KEYNAME,MYF(0),key_name); - DBUG_RETURN(-1); - } - key_info->name=(char*) key_name; + if (key->type == Key::PRIMARY) + { + if (primary_key) + { + my_error(ER_MULTIPLE_PRI_KEY,MYF(0)); + DBUG_RETURN(-1); + } + key_name=primary_key_name; + primary_key=1; + } + else if (!(key_name = key->name)) + key_name=make_unique_key_name(sql_field->field_name, + key_info_buffer,key_info); + if (check_if_keyname_exists(key_name,key_info_buffer,key_info)) + { + my_error(ER_DUP_KEYNAME,MYF(0),key_name); + DBUG_RETURN(-1); + } + key_info->name=(char*) key_name; } } if (!key_info->name || check_column_name(key_info->name)) @@ -1026,25 +1021,27 @@ 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 SYNOPSIS mysql_create_table() - thd Thread object - db Database - table_name Table name - create_info Create information (like MAX_ROWS) - fields List of fields to create - keys List of keys to create - tmp_table Set to 1 if this is an internal temporary table - (From ALTER TABLE) - no_log Don't log the query to binary log. + thd Thread object + db Database + table_name Table name + create_info Create information (like MAX_ROWS) + fields List of fields to create + keys List of keys to create + tmp_table Set to 1 if this is an internal temporary table + (From ALTER TABLE) + no_log Don't log the query to binary log. DESCRIPTION If one creates a temporary table, this is automaticly opened @@ -1055,23 +1052,23 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, and must be zero for standard create of table. RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_create_table(THD *thd,const char *db, const char *table_name, - HA_CREATE_INFO *create_info, - List<create_field> &fields, - List<Key> &keys,bool tmp_table,bool no_log, - uint select_field_count) + HA_CREATE_INFO *create_info, + List<create_field> &fields, + List<Key> &keys,bool tmp_table,bool no_log, + uint select_field_count) { - char path[FN_REFLEN]; - const char *alias; - int error= -1; - uint db_options, key_count; - KEY *key_info_buffer; - handler *file; - enum db_type new_db_type; + char path[FN_REFLEN]; + const char *alias; + int error= -1; + uint db_options, key_count; + KEY *key_info_buffer; + handler *file; + enum db_type new_db_type; DBUG_ENTER("mysql_create_table"); /* Check for duplicate fields and check type of table to create */ @@ -1085,10 +1082,10 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { create_info->db_type= new_db_type; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_USING_OTHER_HANDLER, - ER(ER_WARN_USING_OTHER_HANDLER), - ha_get_storage_engine(new_db_type), - table_name); + ER_WARN_USING_OTHER_HANDLER, + ER(ER_WARN_USING_OTHER_HANDLER), + ha_get_storage_engine(new_db_type), + table_name); } db_options=create_info->table_options; if (create_info->row_type == ROW_TYPE_DYNAMIC) @@ -1104,24 +1101,22 @@ 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, - select_field_count)) + keys, tmp_table, db_options, file, + 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", - mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id, - thd->tmp_table++, reg_ext)>= (int)sizeof(path)) - DBUG_RETURN(-1); + 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); 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) @@ -1129,7 +1124,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { - create_info->table_existed= 1; // Mark that table existed + create_info->table_existed= 1; // Mark that table existed DBUG_RETURN(0); } my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); @@ -1144,24 +1139,24 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { - create_info->table_existed= 1; // Mark that table existed - error= 0; - } + create_info->table_existed= 1; // Mark that table existed + error= 0; + } else - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); goto end; } } thd->proc_info="creating table"; - create_info->table_existed= 0; // Mark that table is created + create_info->table_existed= 0; // Mark that table is created if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) create_info->data_file_name= create_info->index_file_name= 0; create_info->table_options=db_options; if (rea_create_table(thd, path, create_info, fields, key_count, - key_info_buffer)) + key_info_buffer)) { /* my_error(ER_CANT_CREATE_TABLE,MYF(0),table_name,my_errno); */ goto end; @@ -1184,8 +1179,8 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); + test(create_info->options & + HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } } @@ -1215,37 +1210,39 @@ 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*/ + return (char*) field_name; // Use fieldname + 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 ****************************************************************************/ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, - const char *db, const char *name, - List<create_field> *extra_fields, - List<Key> *keys, - List<Item> *items, - MYSQL_LOCK **lock) + const char *db, const char *name, + List<create_field> *extra_fields, + List<Key> *keys, + List<Item> *items, + MYSQL_LOCK **lock) { - TABLE tmp_table; // Used during 'create_field()' + TABLE tmp_table; // Used during 'create_field()' TABLE *table; tmp_table.table_name=0; uint select_field_count= items->elements; @@ -1259,7 +1256,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, tmp_table.null_row=tmp_table.maybe_null=0; tmp_table.blob_ptr_size=portable_sizeof_char_ptr; tmp_table.db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM || - create_info->db_type == DB_TYPE_HEAP); + create_info->db_type == DB_TYPE_HEAP); while ((item=it++)) { @@ -1269,18 +1266,18 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, field=item->tmp_table_field(&tmp_table); else field=create_tmp_field(thd, &tmp_table, item, item->type(), - (Item ***) 0, &tmp_field,0,0); + (Item ***) 0, &tmp_field,0,0); if (!field || - !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? - ((Item_field *)item)->field : - (Field*) 0)))) + !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ? + ((Item_field *)item)->field : + (Field*) 0)))) DBUG_RETURN(0); extra_fields->push_back(cr_field); } /* create and lock table */ /* QQ: This should be done atomic ! */ if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0,1,select_field_count)) // no logging + *keys,0,1,select_field_count)) // no logging DBUG_RETURN(0); if (!(table=open_table(thd,db,name,name,(bool*) 0))) { @@ -1307,10 +1304,10 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, bool mysql_rename_table(enum db_type base, - const char *old_db, - const char *old_name, - const char *new_db, - const char *new_name) + const char *old_db, + const char *old_name, + const char *new_db, + const char *new_name) { char from[FN_REFLEN], to[FN_REFLEN]; char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1]; @@ -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); @@ -1359,10 +1354,10 @@ mysql_rename_table(enum db_type base, SYNOPSIS wait_while_table_is_used() - thd Thread handler - table Table to remove from cache - function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted - HA_EXTRA_FORCE_REOPEN if table is not be used + thd Thread handler + table Table to remove from cache + function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted + HA_EXTRA_FORCE_REOPEN if table is not be used NOTES When returning, the table will be unusable for other threads until the table is closed. @@ -1373,7 +1368,7 @@ mysql_rename_table(enum db_type base, */ static void wait_while_table_is_used(THD *thd,TABLE *table, - enum ha_extra_function function) + enum ha_extra_function function) { DBUG_PRINT("enter",("table: %s", table->real_name)); DBUG_ENTER("wait_while_table_is_used"); @@ -1381,11 +1376,11 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, VOID(table->file->extra(function)); /* Mark all tables that are in use as 'old' */ - mysql_lock_abort(thd, table); // end threads waiting on lock + mysql_lock_abort(thd, table); // end threads waiting on lock /* Wait until all there are no other threads that has this table open */ while (remove_table_from_cache(thd,table->table_cache_key, - table->real_name)) + table->real_name)) { dropping_tables++; (void) pthread_cond_wait(&COND_refresh,&LOCK_open); @@ -1399,8 +1394,8 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, SYNOPSIS close_cached_table() - thd Thread handler - table Table to remove from cache + thd Thread handler + table Table to remove from cache NOTES Function ends by signaling threads waiting for the table to try to @@ -1410,17 +1405,17 @@ static void wait_while_table_is_used(THD *thd,TABLE *table, Lock on LOCK_open Win32 clients must also have a WRITE LOCK on the table ! */ - + static bool close_cached_table(THD *thd, TABLE *table) { DBUG_ENTER("close_cached_table"); - + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { mysql_unlock_tables(thd, thd->lock); - thd->lock=0; // Start locked threads + thd->lock=0; // Start locked threads } /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ thd->open_tables=unlink_open_table(thd,thd->open_tables,table); @@ -1431,7 +1426,7 @@ static bool close_cached_table(THD *thd, TABLE *table) } static int send_check_errmsg(THD *thd, TABLE_LIST* table, - const char* operator_name, const char* errmsg) + const char* operator_name, const char* errmsg) { Protocol *protocol= thd->protocol; @@ -1448,15 +1443,15 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table, static int prepare_for_restore(THD* thd, TABLE_LIST* table, - HA_CHECK_OPT *check_opt) + HA_CHECK_OPT *check_opt) { DBUG_ENTER("prepare_for_restore"); if (table->table) // do not overwrite existing tables on restore { DBUG_RETURN(send_check_errmsg(thd, table, "restore", - "table exists, will not overwrite on restore" - )); + "table exists, will not overwrite on restore" + )); } else { @@ -1466,25 +1461,24 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, char* db = thd->db ? thd->db : table->db; if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, - reg_ext)) + 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); if (my_copy(src_path, - fn_format(dst_path, dst_path,"", reg_ext, 4), - MYF(MY_WME))) + fn_format(dst_path, dst_path,"", reg_ext, 4), + MYF(MY_WME))) { pthread_mutex_lock(&LOCK_open); unlock_table_name(thd, table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "restore", - "Failed copying .frm file")); + "Failed copying .frm file")); } if (mysql_truncate(thd, table, 1)) { @@ -1492,7 +1486,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, unlock_table_name(thd, table); pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(send_check_errmsg(thd, table, "restore", - "Failed generating table from .frm file")); + "Failed generating table from .frm file")); } } @@ -1511,7 +1505,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, - HA_CHECK_OPT *check_opt) + HA_CHECK_OPT *check_opt) { int error= 0; TABLE tmp_table, *table; @@ -1520,13 +1514,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, if (!(check_opt->sql_flags & TT_USEFRM)) DBUG_RETURN(0); - if (!(table= table_list->table)) /* if open_ltable failed */ + if (!(table= table_list->table)) /* if open_ltable failed */ { char name[FN_REFLEN]; strxmov(name, mysql_data_home, "/", table_list->db, "/", - table_list->real_name, NullS); + table_list->real_name, NullS); if (openfrm(name, "", 0, 0, 0, &tmp_table)) - DBUG_RETURN(0); // Can't open frm file + DBUG_RETURN(0); // Can't open frm file table= &tmp_table; } @@ -1549,18 +1543,14 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, like ISAM or MyISAM */ if (!ext[0] || !ext[1]) - goto end; // No data file + goto end; // No data file - strxmov(from, table->path, ext[1], NullS); // Name of data file + strxmov(from, table->path, ext[1], NullS); // Name of data file 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", - 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) @@ -1580,7 +1570,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", - "Failed renaming data file"); + "Failed renaming data file"); goto end; } if (mysql_truncate(thd, table_list, 1)) @@ -1589,7 +1579,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", - "Failed generating table from .frm file"); + "Failed generating table from .frm file"); goto end; } if (my_rename(tmp, from, MYF(MY_WME))) @@ -1598,7 +1588,7 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, unlock_table_name(thd, table_list); pthread_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", - "Failed restoring .MYD file"); + "Failed restoring .MYD file"); goto end; } @@ -1615,21 +1605,21 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, end: if (table == &tmp_table) - closefrm(table); // Free allocated memory + closefrm(table); // Free allocated memory DBUG_RETURN(error); } static int mysql_admin_table(THD* thd, TABLE_LIST* tables, - HA_CHECK_OPT* check_opt, - const char *operator_name, - thr_lock_type lock_type, - bool open_for_modify, - uint extra_open_options, - int (*prepare_func)(THD *, TABLE_LIST *, - HA_CHECK_OPT *), - int (handler::*operator_func) - (THD *, HA_CHECK_OPT *)) + HA_CHECK_OPT* check_opt, + const char *operator_name, + thr_lock_type lock_type, + bool open_for_modify, + uint extra_open_options, + int (*prepare_func)(THD *, TABLE_LIST *, + HA_CHECK_OPT *), + int (handler::*operator_func) + (THD *, HA_CHECK_OPT *)) { TABLE_LIST *table; List<Item> field_list; @@ -1666,9 +1656,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (prepare_func) { switch ((*prepare_func)(thd, table, check_opt)) { - case 1: continue; // error, message written to net - case -1: goto err; // error, message could be written to net - default: ; // should be 0 otherwise + case 1: continue; // error, message written to net + case -1: goto err; // error, message could be written to net + default: ; // should be 0 otherwise } } @@ -1680,11 +1670,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store(operator_name, system_charset_info); protocol->store("error",5, system_charset_info); if (!(err_msg=thd->net.last_error)) - err_msg=ER(ER_CHECK_NO_SUCH_TABLE); + err_msg=ER(ER_CHECK_NO_SUCH_TABLE); protocol->store(err_msg, system_charset_info); thd->net.last_error[0]=0; if (protocol->write()) - goto err; + goto err; continue; } table->table->pos_in_table_list= table; @@ -1695,14 +1685,12 @@ 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 + table->table=0; // For query cache if (protocol->write()) - goto err; + goto err; continue; } @@ -1711,20 +1699,20 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, { pthread_mutex_lock(&LOCK_open); const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open, - "Waiting to get writelock"); + "Waiting to get writelock"); mysql_lock_abort(thd,table->table); while (remove_table_from_cache(thd, table->table->table_cache_key, - table->table->real_name) && - ! thd->killed) + table->table->real_name) && + ! thd->killed) { - dropping_tables++; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); - dropping_tables--; + dropping_tables++; + (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + dropping_tables--; } thd->exit_cond(old_message); pthread_mutex_unlock(&LOCK_open); if (thd->killed) - goto err; + goto err; open_for_modify=0; } @@ -1739,11 +1727,11 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, switch (result_code) { case HA_ADMIN_NOT_IMPLEMENTED: { - char buf[ERRMSGSIZE+20]; - uint length=my_snprintf(buf, ERRMSGSIZE, - ER(ER_CHECK_NOT_IMPLEMENTED), operator_name); - protocol->store("error", 5, system_charset_info); - protocol->store(buf, length, system_charset_info); + char buf[ERRMSGSIZE+20]; + uint length=my_snprintf(buf, ERRMSGSIZE, + ER(ER_CHECK_NOT_IMPLEMENTED), operator_name); + protocol->store("error", 5, system_charset_info); + protocol->store(buf, length, system_charset_info); } break; @@ -1779,26 +1767,26 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, protocol->store("Invalid argument",16, system_charset_info); break; - default: // Probably HA_ADMIN_INTERNAL_ERROR + default: // Probably HA_ADMIN_INTERNAL_ERROR protocol->store("error", 5, system_charset_info); protocol->store("Unknown - internal error during operation", 41 - , system_charset_info); + , system_charset_info); fatal_error=1; break; } if (fatal_error) - table->table->version=0; // Force close of table + table->table->version=0; // Force close of table else if (open_for_modify) { pthread_mutex_lock(&LOCK_open); remove_table_from_cache(thd, table->table->table_cache_key, - table->table->real_name); + table->table->real_name); pthread_mutex_unlock(&LOCK_open); /* May be something modified consequently we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); } close_thread_tables(thd); - table->table=0; // For query cache + table->table=0; // For query cache if (protocol->write()) goto err; } @@ -1806,7 +1794,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, send_eof(thd); DBUG_RETURN(0); err: - close_thread_tables(thd); // Shouldn't be needed + close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; DBUG_RETURN(-1); @@ -1817,8 +1805,8 @@ int mysql_backup_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_backup_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, - "backup", TL_READ, 0, 0, 0, - &handler::backup)); + "backup", TL_READ, 0, 0, 0, + &handler::backup)); } @@ -1826,9 +1814,9 @@ int mysql_restore_table(THD* thd, TABLE_LIST* table_list) { DBUG_ENTER("mysql_restore_table"); DBUG_RETURN(mysql_admin_table(thd, table_list, 0, - "restore", TL_WRITE, 1, 0, - &prepare_for_restore, - &handler::restore)); + "restore", TL_WRITE, 1, 0, + &prepare_for_restore, + &handler::restore)); } @@ -1836,9 +1824,9 @@ int mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_repair_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, - &prepare_for_repair, - &handler::repair)); + "repair", TL_WRITE, 1, HA_OPEN_FOR_REPAIR, + &prepare_for_repair, + &handler::repair)); } @@ -1846,8 +1834,8 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) { DBUG_ENTER("mysql_optimize_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "optimize", TL_WRITE, 1,0,0, - &handler::optimize)); + "optimize", TL_WRITE, 1,0,0, + &handler::optimize)); } @@ -1856,16 +1844,16 @@ int mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) SYNOPSIS mysql_assign_to_keycache() - thd Thread object - tables Table list (one table only) + thd Thread object + tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, - LEX_STRING *key_cache_name) + LEX_STRING *key_cache_name) { HA_CHECK_OPT check_opt; KEY_CACHE *key_cache; @@ -1882,8 +1870,8 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, pthread_mutex_unlock(&LOCK_global_system_variables); check_opt.key_cache= key_cache; DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt, - "assign_to_keycache", TL_READ_NO_INSERT, 0, - 0, 0, &handler::assign_to_keycache)); + "assign_to_keycache", TL_READ_NO_INSERT, 0, + 0, 0, &handler::assign_to_keycache)); } @@ -1892,9 +1880,9 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, SYNOPSIS reassign_keycache_tables() - thd Thread object - src_cache Reference to the key cache to clean up - dest_cache New key cache + thd Thread object + src_cache Reference to the key cache to clean up + dest_cache New key cache NOTES This is called when one sets a key cache size to zero, in which @@ -1909,20 +1897,20 @@ int mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables, to it for a while after this function returns. RETURN VALUES - 0 ok + 0 ok */ -int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, - KEY_CACHE *dst_cache) +int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, + KEY_CACHE *dst_cache) { DBUG_ENTER("reassign_keycache_tables"); DBUG_ASSERT(src_cache != dst_cache); DBUG_ASSERT(src_cache->in_init); - src_cache->param_buff_size= 0; // Free key cache + src_cache->param_buff_size= 0; // Free key cache ha_resize_key_cache(src_cache); ha_change_key_cache(src_cache, dst_cache); - DBUG_RETURN(0); + DBUG_RETURN(0); } @@ -1931,20 +1919,20 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache, SYNOPSIS mysql_preload_keys() - thd Thread object - tables Table list (one table only) + thd Thread object + tables Table list (one table only) RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ int mysql_preload_keys(THD* thd, TABLE_LIST* tables) { DBUG_ENTER("mysql_preload_keys"); DBUG_RETURN(mysql_admin_table(thd, tables, 0, - "preload_keys", TL_READ, 0, 0, 0, - &handler::preload_keys)); + "preload_keys", TL_READ, 0, 0, 0, + &handler::preload_keys)); } @@ -1953,19 +1941,19 @@ int mysql_preload_keys(THD* thd, TABLE_LIST* tables) SYNOPSIS mysql_create_like_table() - thd Thread object - table Table list (one table only) + thd Thread object + table Table list (one table only) create_info Create info table_ident Src table_ident RETURN VALUES - 0 ok - -1 error + 0 ok + -1 error */ -int mysql_create_like_table(THD* thd, TABLE_LIST* table, - HA_CREATE_INFO *create_info, - Table_ident *table_ident) +int mysql_create_like_table(THD* thd, TABLE_LIST* table, + HA_CREATE_INFO *create_info, + Table_ident *table_ident) { TABLE **tmp_table; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; @@ -1988,11 +1976,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, my_error(ER_WRONG_TABLE_NAME, MYF(0), src_table); DBUG_RETURN(-1); } - + src_tables_list.db= table_ident->db.str ? table_ident->db.str : thd->db; src_tables_list.real_name= table_ident->table.str; src_tables_list.next= 0; - + if (lock_and_wait_for_table_name(thd, &src_tables_list)) goto err; @@ -2000,8 +1988,8 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, strxmov(src_path, (*tmp_table)->path, reg_ext, NullS); else { - strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, - reg_ext, NullS); + strxmov(src_path, mysql_data_home, "/", src_db, "/", src_table, + reg_ext, NullS); if (access(src_path, F_OK)) { my_error(ER_BAD_TABLE_ERROR, MYF(0), src_table); @@ -2012,56 +2000,54 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, /* Validate the destination table - skip the destination table name checking as this is already + skip the destination table name checking as this is already validated. */ if (create_info->options & HA_LEX_CREATE_TMP_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", - mysql_tmpdir, tmp_file_prefix, current_pid, - thd->thread_id, thd->tmp_table++, reg_ext)>= - (int)sizeof(dst_path)) - DBUG_RETURN(-1); + 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); create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE; } else { - strxmov(dst_path, mysql_data_home, "/", db, "/", table_name, - reg_ext, NullS); + strxmov(dst_path, mysql_data_home, "/", db, "/", table_name, + reg_ext, NullS); if (!access(dst_path, F_OK)) goto table_exists; } - /* + /* Create a new table by copying from source table - */ + */ if (my_copy(src_path, dst_path, MYF(MY_WME|MY_DONT_OVERWRITE_FILE))) goto err; /* - As mysql_truncate don't work on a new table at this stage of - creation, instead create the table directly (for both normal + As mysql_truncate don't work on a new table at this stage of + creation, instead create the table directly (for both normal and temporary tables). */ - *fn_ext(dst_path)= 0; + *fn_ext(dst_path)= 0; err= ha_create_table(dst_path, create_info, 1); - + if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { if (err || !open_temporary_table(thd, dst_path, db, table_name, 1)) { - (void) rm_temporary_table(create_info->db_type, - dst_path); /* purecov: inspected */ + (void) rm_temporary_table(create_info->db_type, + dst_path); /* purecov: inspected */ goto err; /* purecov: inspected */ } } else if (err) { - (void) quick_rm_table(create_info->db_type, db, - table_name); /* purecov: inspected */ - goto err; /* purecov: inspected */ + (void) quick_rm_table(create_info->db_type, db, + table_name); /* purecov: inspected */ + goto err; /* purecov: inspected */ } // Must be written before unlock @@ -2070,22 +2056,21 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table, { thd->clear_error(); Query_log_event qinfo(thd, thd->query, thd->query_length, - test(create_info->options & - HA_LEX_CREATE_TMP_TABLE)); + test(create_info->options & + HA_LEX_CREATE_TMP_TABLE)); mysql_bin_log.write(&qinfo); } res= 0; goto err; - + 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); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_TABLE_EXISTS_ERROR,warn_buff); + 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; } else @@ -2109,8 +2094,8 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_analyze_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "analyze", lock_type, 1,0,0, - &handler::analyze)); + "analyze", lock_type, 1,0,0, + &handler::analyze)); } @@ -2124,15 +2109,15 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) DBUG_ENTER("mysql_check_table"); DBUG_RETURN(mysql_admin_table(thd, tables, check_opt, - "check", lock_type, - 0, HA_OPEN_FOR_REPAIR, 0, - &handler::check)); + "check", lock_type, + 0, HA_OPEN_FOR_REPAIR, 0, + &handler::check)); } /* table_list should contain just one table */ int mysql_discard_or_import_tablespace(THD *thd, - TABLE_LIST *table_list, - enum tablespace_op_type tablespace_op) + TABLE_LIST *table_list, + enum tablespace_op_type tablespace_op) { TABLE *table; my_bool discard; @@ -2150,8 +2135,8 @@ int mysql_discard_or_import_tablespace(THD *thd, discard = FALSE; thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open - and ::external_lock() do not complain when we - lock the table */ + and ::external_lock() do not complain when we + lock the table */ mysql_ha_closeall(thd, table_list); if (!(table=open_ltable(thd,table_list,TL_WRITE))) @@ -2159,7 +2144,7 @@ int mysql_discard_or_import_tablespace(THD *thd, thd->tablespace_op=FALSE; DBUG_RETURN(-1); } - + error=table->file->discard_or_import_tablespace(discard); thd->proc_info="end"; @@ -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,38 +2188,38 @@ 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; List<Alter_column> alter; HA_CREATE_INFO create_info; - int rc; - uint idx; - uint db_options; - uint key_count; - TABLE *table; - Field **f_ptr; - KEY *key_info_buffer; - char path[FN_REFLEN]; + int rc; + uint idx; + uint db_options; + uint key_count; + TABLE *table; + Field **f_ptr; + KEY *key_info_buffer; + char path[FN_REFLEN+1]; DBUG_ENTER("mysql_create_index"); /* - Try to use online generation of index. - This requires that all indexes can be created online. - Otherwise, the old alter table procedure is executed. + Try to use online generation of index. + This requires that all indexes can be created online. + Otherwise, the old alter table procedure is executed. - Open the table to have access to the correct table handler. - */ + Open the table to have access to the correct table handler. + */ if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); /* - The add_index method takes an array of KEY structs for the new indexes. - Preparing a new table structure generates this array. - It needs a list with all fields of the table, which does not need to - be correct in every respect. The field names are important. - */ + The add_index method takes an array of KEY structs for the new indexes. + Preparing a new table structure generates this array. + It needs a list with all fields of the table, which does not need to + be correct in every respect. The field names are important. + */ for (f_ptr= table->field; *f_ptr; f_ptr++) { create_field *c_fld= new create_field(*f_ptr, *f_ptr); @@ -2244,20 +2231,20 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) create_info.default_table_charset= thd->variables.collation_database; db_options= 0; if (mysql_prepare_table(thd, &create_info, fields, - keys, /*tmp_table*/ 0, db_options, table->file, - key_info_buffer, key_count, - /*select_field_count*/ 0)) + keys, /*tmp_table*/ 0, db_options, table->file, + key_info_buffer, key_count, + /*select_field_count*/ 0)) DBUG_RETURN(-1); /* - Check if all keys can be generated with the add_index method. - If anyone cannot, then take the old way. - */ + Check if all keys can be generated with the add_index method. + If anyone cannot, then take the old way. + */ for (idx=0; idx< key_count; idx++) { DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name)); if (!(table->file->index_ddl_flags(key_info_buffer+idx)& - (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) + (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) break ; } if ((idx < key_count)|| !key_count) @@ -2269,68 +2256,68 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) /* Cleanup the fields list. We do not want to create existing fields. */ fields.delete_elements(); if (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_INDEX, DUP_ERROR)) - /*don't need to free((gptr) key_info_buffer);*/ + &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);*/ 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)|| - mysql_create_frm(thd, path, &create_info, - fields, key_count, key_info_buffer, table->file)) - /*don't need to free((gptr) key_info_buffer);*/ + (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);*/ 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; + List<Key> keys; List<Alter_column> alter; HA_CREATE_INFO create_info; - uint idx; - uint db_options; - uint key_count; - uint *key_numbers; - TABLE *table; - Field **f_ptr; - KEY *key_info; - KEY *key_info_buffer; - char path[FN_REFLEN]; + uint idx; + uint db_options; + uint key_count; + uint *key_numbers; + TABLE *table; + Field **f_ptr; + KEY *key_info; + KEY *key_info_buffer; + char path[FN_REFLEN]; DBUG_ENTER("mysql_drop_index"); /* - Try to use online generation of index. - This requires that all indexes can be created online. - Otherwise, the old alter table procedure is executed. + Try to use online generation of index. + This requires that all indexes can be created online. + Otherwise, the old alter table procedure is executed. - Open the table to have access to the correct table handler. - */ + Open the table to have access to the correct table handler. + */ if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); /* - The drop_index method takes an array of key numbers. - It cannot get more entries than keys in the table. - */ + The drop_index method takes an array of key numbers. + It cannot get more entries than keys in the table. + */ key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys); key_count= 0; /* - Get the number of each key and check if it can be created online. - */ + Get the number of each key and check if it can be created online. + */ List_iterator<Alter_drop> drop_it(drop); Alter_drop *drop_key; while ((drop_key= drop_it++)) @@ -2340,7 +2327,7 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) for (idx=0; idx< table->keys; idx++, key_info++) { if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name)) - break; + break; } if (idx>= table->keys) { @@ -2349,12 +2336,12 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) DBUG_RETURN(-1); } /* - Check if the key can be generated with the add_index method. - If anyone cannot, then take the old way. - */ + Check if the key can be generated with the add_index method. + If anyone cannot, then take the old way. + */ DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name)); if (!(table->file->index_ddl_flags(table->key_info+idx)& - (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) + (HA_DDL_ONLINE| HA_DDL_WITH_LOCK))) break ; key_numbers[key_count++]= idx; } @@ -2366,9 +2353,9 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) if ((drop_key)|| (drop.elements<= 0)) { if (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_INDEX, DUP_ERROR)) + &create_info, table_list, table, + fields, keys, drop, alter, 0, (ORDER*)0, + ALTER_DROP_INDEX, DUP_ERROR)) /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(-1); } @@ -2376,17 +2363,17 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop) { db_options= 0; if (table->file->drop_index(table, key_numbers, key_count)|| - mysql_prepare_table(thd, &create_info, fields, - keys, /*tmp_table*/ 0, db_options, table->file, - key_info_buffer, key_count, - /*select_field_count*/ 0)|| - (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, - table_list->db, (lower_case_table_names == 2)? - table_list->alias: table_list->real_name, reg_ext)>= - (int)sizeof(path))|| - ! unpack_filename(path, path)|| - mysql_create_frm(thd, path, &create_info, - fields, key_count, key_info_buffer, table->file)) + mysql_prepare_table(thd, &create_info, fields, + keys, /*tmp_table*/ 0, db_options, table->file, + key_info_buffer, key_count, + /*select_field_count*/ 0)|| + (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, + table_list->db, (lower_case_table_names == 2)? + table_list->alias: table_list->real_name, reg_ext)>= + (int)sizeof(path))|| + ! unpack_filename(path, path)|| + mysql_create_frm(thd, path, &create_info, + fields, key_count, key_info_buffer, table->file)) /*don't need to free((gptr) key_numbers);*/ DBUG_RETURN(-1); } @@ -2394,117 +2381,35 @@ 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, - TABLE_LIST *table_list, - 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) + HA_CREATE_INFO *create_info, + TABLE_LIST *table_list, + List<create_field> &fields, + List<Key> &keys,List<Alter_drop> &drop_list, + List<Alter_column> &alter_list, + 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) { @@ -2526,17 +2438,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { if (lower_case_table_names != 2) { - my_casedn_str(system_charset_info, new_name_buff); - new_alias= new_name; // Create lower case table name + my_casedn_str(system_charset_info, new_name_buff); + new_alias= new_name; // Create lower case table name } my_casedn_str(system_charset_info, new_name); } if (new_db == db && - !my_strcasecmp(table_alias_charset, new_name_buff, table_name)) + !my_strcasecmp(table_alias_charset, new_name_buff, table_name)) { /* - Source and destination table names are equal: make later check - easier. + Source and destination table names are equal: make later check + easier. */ new_alias= new_name= table_name; } @@ -2544,21 +2456,21 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { if (table->tmp_table) { - if (find_temporary_table(thd,new_db,new_name_buff)) - { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); - DBUG_RETURN(-1); - } + if (find_temporary_table(thd,new_db,new_name_buff)) + { + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name_buff); + DBUG_RETURN(-1); + } } else { - if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0), - F_OK)) - { - /* Table will be closed in do_command() */ - my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); - DBUG_RETURN(-1); - } + if (!access(fn_format(new_name_buff,new_name_buff,new_db,reg_ext,0), + F_OK)) + { + /* Table will be closed in do_command() */ + my_error(ER_TABLE_EXISTS_ERROR,MYF(0), new_alias); + DBUG_RETURN(-1); + } } } } @@ -2573,10 +2485,10 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { create_info->db_type= new_db_type; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_USING_OTHER_HANDLER, - ER(ER_WARN_USING_OTHER_HANDLER), - ha_get_storage_engine(new_db_type), - new_name); + ER_WARN_USING_OTHER_HANDLER, + ER(ER_WARN_USING_OTHER_HANDLER), + ha_get_storage_engine(new_db_type), + new_name); } if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type=table->row_type; @@ -2593,15 +2505,15 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, error=0; if (!access(new_name_buff,F_OK)) { - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); - error= -1; + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name); + error= -1; } else { - *fn_ext(new_name)=0; - close_cached_table(thd, table); - if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) - error= -1; + *fn_ext(new_name)=0; + close_cached_table(thd, table); + if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias)) + error= -1; } VOID(pthread_mutex_unlock(&LOCK_open)); } @@ -2610,7 +2522,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { switch (keys_onoff) { case LEAVE_AS_IS: - break; + break; case ENABLE: VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); @@ -2627,11 +2539,11 @@ 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), - table->table_name); + ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), + table->table_name); error=0; } if (!error) @@ -2639,18 +2551,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); - mysql_bin_log.write(&qinfo); + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); } send_ok(thd); } else { 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); DBUG_RETURN(error); } @@ -2667,12 +2579,12 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET)) create_info->default_table_charset= table->table_charset; - restore_record(table,default_values); // Empty record for DEFAULT + restore_record(table,default_values); // Empty record for DEFAULT List_iterator<Alter_drop> drop_it(drop_list); List_iterator<create_field> def_it(fields); List_iterator<Alter_column> alter_it(alter_list); - List<create_field> create_list; // Add new fields here - List<Key> key_list; // Add new keys here + List<create_field> create_list; // Add new fields here + List<Key> key_list; // Add new keys here create_field *def; /* @@ -2688,16 +2600,16 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, while ((drop=drop_it++)) { if (drop->type == Alter_drop::COLUMN && - !my_strcasecmp(system_charset_info,field->field_name, drop->name)) + !my_strcasecmp(system_charset_info,field->field_name, drop->name)) { - /* Reset auto_increment value if it was dropped */ - if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && - !(used_fields & HA_CREATE_USED_AUTO)) - { - create_info->auto_increment_value=0; - create_info->used_fields|=HA_CREATE_USED_AUTO; - } - break; + /* Reset auto_increment value if it was dropped */ + if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && + !(used_fields & HA_CREATE_USED_AUTO)) + { + create_info->auto_increment_value=0; + create_info->used_fields|=HA_CREATE_USED_AUTO; + } + break; } } if (drop) @@ -2710,47 +2622,43 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, while ((def=def_it++)) { if (def->change && - !my_strcasecmp(system_charset_info,field->field_name, def->change)) - break; + !my_strcasecmp(system_charset_info,field->field_name, def->change)) + break; } if (def) - { // Field is changed + { // Field is changed def->field=field; - if (def->sql_type == FIELD_TYPE_TIMESTAMP) - use_timestamp=1; if (!def->after) { - create_list.push_back(def); - def_it.remove(); + create_list.push_back(def); + def_it.remove(); } } else - { // Use old field value + { // 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_it.rewind(); // Change default if ALTER Alter_column *alter; while ((alter=alter_it++)) { - if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) - break; + if (!my_strcasecmp(system_charset_info,field->field_name, alter->name)) + break; } if (alter) { - if (def->sql_type == FIELD_TYPE_BLOB) - { - my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); - DBUG_RETURN(-1); - } - def->def=alter->def; // Use new default - alter_it.remove(); + if (def->sql_type == FIELD_TYPE_BLOB) + { + my_error(ER_BLOB_CANT_HAVE_DEFAULT,MYF(0),def->change); + DBUG_RETURN(-1); + } + def->def=alter->def; // Use new default + alter_it.remove(); } } } def_it.rewind(); List_iterator<create_field> find_it(create_list); - while ((def=def_it++)) // Add new columns + while ((def=def_it++)) // Add new columns { if (def->change && ! def->field) { @@ -2765,17 +2673,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { create_field *find; find_it.rewind(); - while ((find=find_it++)) // Add new columns + while ((find=find_it++)) // Add new columns { - if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) - break; + if (!my_strcasecmp(system_charset_info,def->after, find->field_name)) + break; } if (!find) { - my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); - DBUG_RETURN(-1); + my_error(ER_BAD_FIELD_ERROR,MYF(0),def->after,table_name); + DBUG_RETURN(-1); } - find_it.after(def); // Put element after this + find_it.after(def); // Put element after this } } if (alter_list.elements) @@ -2807,8 +2715,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, while ((drop=drop_it++)) { if (drop->type == Alter_drop::KEY && - !my_strcasecmp(system_charset_info,key_name, drop->name)) - break; + !my_strcasecmp(system_charset_info,key_name, drop->name)) + break; } if (drop) { @@ -2821,60 +2729,60 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, for (uint j=0 ; j < key_info->key_parts ; j++,key_part++) { if (!key_part->field) - continue; // Wrong field (from UNIREG) + continue; // Wrong field (from UNIREG) const char *key_part_name=key_part->field->field_name; create_field *cfield; field_it.rewind(); while ((cfield=field_it++)) { - if (cfield->change) - { - if (!my_strcasecmp(system_charset_info, key_part_name, - cfield->change)) - break; - } - else if (!my_strcasecmp(system_charset_info, - key_part_name, cfield->field_name)) - break; + if (cfield->change) + { + if (!my_strcasecmp(system_charset_info, key_part_name, + cfield->change)) + break; + } + else if (!my_strcasecmp(system_charset_info, + key_part_name, cfield->field_name)) + break; } if (!cfield) - continue; // Field is removed + continue; // Field is removed uint key_part_length=key_part->length; - if (cfield->field) // Not new field - { // Check if sub key - if (cfield->field->type() != FIELD_TYPE_BLOB && - (cfield->field->pack_length() == key_part_length || - cfield->length <= key_part_length / - key_part->field->charset()->mbmaxlen)) - key_part_length=0; // Use whole field + if (cfield->field) // Not new field + { // Check if sub key + if (cfield->field->type() != FIELD_TYPE_BLOB && + (cfield->field->pack_length() == key_part_length || + cfield->length <= key_part_length / + key_part->field->charset()->mbmaxlen)) + key_part_length=0; // Use whole field } key_part_length /= key_part->field->charset()->mbmaxlen; key_parts.push_back(new key_part_spec(cfield->field_name, - key_part_length)); + key_part_length)); } if (key_parts.elements) key_list.push_back(new Key(key_info->flags & HA_SPATIAL ? Key::SPATIAL : - (key_info->flags & HA_NOSAME ? - (!my_strcasecmp(system_charset_info, - key_name, primary_key_name) ? - Key::PRIMARY : Key::UNIQUE) : - (key_info->flags & HA_FULLTEXT ? - Key::FULLTEXT : Key::MULTIPLE)), - key_name, - key_info->algorithm, - key_parts)); + (key_info->flags & HA_NOSAME ? + (!my_strcasecmp(system_charset_info, + key_name, primary_key_name) ? + Key::PRIMARY : Key::UNIQUE) : + (key_info->flags & HA_FULLTEXT ? + Key::FULLTEXT : Key::MULTIPLE)), + key_name, + key_info->algorithm, + key_parts)); } { Key *key; - while ((key=key_it++)) // Add new keys + while ((key=key_it++)) // Add new keys { if (key->type != Key::FOREIGN_KEY) - key_list.push_back(key); + key_list.push_back(key); if (key->name && - !my_strcasecmp(system_charset_info,key->name,primary_key_name)) + !my_strcasecmp(system_charset_info,key->name,primary_key_name)) { - my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); - DBUG_RETURN(-1); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name); + DBUG_RETURN(-1); } } } @@ -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; @@ -2909,7 +2816,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->table_options & (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE)) db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE | - HA_OPTION_NO_DELAY_KEY_WRITE); + HA_OPTION_NO_DELAY_KEY_WRITE); create_info->table_options|= db_create_options; if (table->tmp_table) @@ -2940,31 +2847,31 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, Remove old table and symlinks. */ - if (!strcmp(db, new_db)) // Ignore symlink if db changed + if (!strcmp(db, new_db)) // Ignore symlink if db changed { if (create_info->index_file_name) { /* Fix index_file_name to have 'tmp_name' as basename */ strmov(index_file, tmp_name); create_info->index_file_name=fn_same(index_file, - create_info->index_file_name, - 1); + create_info->index_file_name, + 1); } if (create_info->data_file_name) { /* Fix data_file_name to have 'tmp_name' as basename */ strmov(data_file, tmp_name); create_info->data_file_name=fn_same(data_file, - create_info->data_file_name, - 1); + create_info->data_file_name, + 1); } } else create_info->data_file_name=create_info->index_file_name=0; if ((error=mysql_create_table(thd, new_db, tmp_name, - create_info, - create_list,key_list,1,1,0))) // no logging + create_info, + create_list,key_list,1,1,0))) // no logging DBUG_RETURN(error); if (table->tmp_table) @@ -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); } @@ -2984,24 +2890,24 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, goto err; } - - /* - We don't want update TIMESTAMP fields during ALTER TABLE + + /* + We don't want update TIMESTAMP fields during ALTER TABLE and copy_data_between_tables uses only write_row() for new_table so don't need to set up timestamp_on_update_now member. */ new_table->timestamp_default_now= 0; new_table->next_number_field=new_table->found_next_number_field; - thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields + thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields thd->cuted_fields=0L; thd->proc_info="copy to tmp table"; - next_insert_id=thd->next_insert_id; // Remember for loggin + next_insert_id=thd->next_insert_id; // Remember for loggin copied=deleted=0; if (!new_table->is_view) error=copy_data_between_tables(table,new_table,create_list, - handle_duplicates, - order_num, order, &copied, &deleted); - thd->last_insert_id=next_insert_id; // Needed for correct log + handle_duplicates, + order_num, order, &copied, &deleted); + thd->last_insert_id=next_insert_id; // Needed for correct log thd->count_cuted_fields= CHECK_FIELD_IGNORE; if (table->tmp_table) @@ -3010,8 +2916,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, if (error) { /* - The following function call will free the new_table pointer, - in close_temporary_table(), so we can safely directly jump to err + The following function call will free the new_table pointer, + in close_temporary_table(), so we can safely directly jump to err */ close_temporary_table(thd,new_db,tmp_name); goto err; @@ -3025,7 +2931,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, /* Remove link to old table and rename the new one */ close_temporary_table(thd,table->table_cache_key,table_name); if (rename_temporary_table(thd, new_table, new_db, new_alias)) - { // Fatal error + { // Fatal error close_temporary_table(thd,new_db,tmp_name); my_free((gptr) new_table,MYF(0)); goto err; @@ -3040,7 +2946,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, goto end_temporary; } - intern_close_table(new_table); /* close temporary table */ + intern_close_table(new_table); /* close temporary table */ my_free((gptr) new_table,MYF(0)); VOID(pthread_mutex_lock(&LOCK_open)); if (error) @@ -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)) @@ -3080,18 +2985,18 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, Win32 and InnoDB can't drop a table that is in use, so we must close the original table at before doing the rename */ - table_name=thd->strdup(table_name); // must be saved + table_name=thd->strdup(table_name); // must be saved if (close_cached_table(thd, table)) - { // Aborted + { // Aborted VOID(quick_rm_table(new_db_type,new_db,tmp_name)); VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } - table=0; // Marker that table is closed + table=0; // Marker that table is closed } #if (!defined( __WIN__) && !defined( __EMX__) && !defined( OS2)) else - table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore + table->file->extra(HA_EXTRA_FORCE_REOPEN); // Don't use this file anymore #endif @@ -3102,8 +3007,8 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, VOID(quick_rm_table(new_db_type,new_db,tmp_name)); } else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db, - new_alias)) - { // Try to get everything back + new_alias)) + { // Try to get everything back error=1; VOID(quick_rm_table(new_db_type,new_db,new_alias)); VOID(quick_rm_table(new_db_type,new_db,tmp_name)); @@ -3120,7 +3025,7 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } - if (thd->lock || new_name != table_name) // True if WIN32 + if (thd->lock || new_name != table_name) // True if WIN32 { /* Not table locking or alter table with rename @@ -3141,14 +3046,14 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, { VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Use new file remove_table_from_cache(thd,db,table_name); // Mark all in-use copies old - mysql_lock_abort(thd,table); // end threads waiting on lock + mysql_lock_abort(thd,table); // end threads waiting on lock } VOID(quick_rm_table(old_db_type,db,old_name)); if (close_data_tables(thd,db,table_name) || - reopen_tables(thd,1,0)) - { // This shouldn't happen + reopen_tables(thd,1,0)) + { // This shouldn't happen if (table) - close_cached_table(thd,table); // Remove lock for table + close_cached_table(thd,table); // Remove lock for table VOID(pthread_mutex_unlock(&LOCK_open)); goto err; } @@ -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) @@ -3194,18 +3098,17 @@ int real_alter_table(THD *thd,char *new_db, char *new_name, } else sql_print_error("Warning: Could not open BDB table %s.%s after rename\n", - new_db,table_name); + new_db,table_name); (void) berkeley_flush_logs(); } #endif - table_list->table=0; // For query cache + table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); end_temporary: - if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), - (ulong) (copied + deleted), (ulong) deleted, - (ulong) thd->cuted_fields)>= (int)sizeof(tmp_name)) - goto err; + my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO), + (ulong) (copied + deleted), (ulong) deleted, + (ulong) thd->cuted_fields); send_ok(thd,copied+deleted,0L,tmp_name); thd->some_tables_deleted=0; DBUG_RETURN(0); @@ -3217,11 +3120,11 @@ end_temporary: static int copy_data_between_tables(TABLE *from,TABLE *to, - List<create_field> &create, - enum enum_duplicates handle_duplicates, - uint order_num, ORDER *order, - ha_rows *copied, - ha_rows *deleted) + List<create_field> &create, + enum enum_duplicates handle_duplicates, + uint order_num, ORDER *order, + ha_rows *copied, + ha_rows *deleted) { int error; Copy_field *copy,*copy_end; @@ -3238,7 +3141,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, DBUG_ENTER("copy_data_between_tables"); if (!(copy= new Copy_field[to->fields])) - DBUG_RETURN(-1); /* purecov: inspected */ + DBUG_RETURN(-1); /* purecov: inspected */ to->file->external_lock(thd,F_WRLCK); from->file->info(HA_STATUS_VARIABLE); @@ -3259,21 +3162,21 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (order) { from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), - MYF(MY_FAE | MY_ZEROFILL)); + MYF(MY_FAE | MY_ZEROFILL)); bzero((char*) &tables,sizeof(tables)); tables.table = from; tables.alias = tables.real_name= from->real_name; - tables.db = from->table_cache_key; + tables.db = from->table_cache_key; error=1; if (thd->lex->select_lex.setup_ref_array(thd, order_num) || - setup_order(thd, thd->lex->select_lex.ref_pointer_array, - &tables, fields, all_fields, order) || - !(sortorder=make_unireg_sortorder(order, &length)) || - (from->sort.found_records = filesort(thd, from, sortorder, length, - (SQL_SELECT *) 0, HA_POS_ERROR, - &examined_rows)) - == HA_POS_ERROR) + setup_order(thd, thd->lex->select_lex.ref_pointer_array, + &tables, fields, all_fields, order) || + !(sortorder=make_unireg_sortorder(order, &length)) || + (from->sort.found_records = filesort(thd, from, sortorder, length, + (SQL_SELECT *) 0, HA_POS_ERROR, + &examined_rows)) + == HA_POS_ERROR) goto err; }; @@ -3310,12 +3213,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, if ((error=to->file->write_row((byte*) to->record[0]))) { if ((handle_duplicates != DUP_IGNORE && - handle_duplicates != DUP_REPLACE) || - (error != HA_ERR_FOUND_DUPP_KEY && - error != HA_ERR_FOUND_DUPP_UNIQUE)) + handle_duplicates != DUP_REPLACE) || + (error != HA_ERR_FOUND_DUPP_KEY && + error != HA_ERR_FOUND_DUPP_UNIQUE)) { - to->file->print_error(error,MYF(0)); - break; + to->file->print_error(error,MYF(0)); + break; } delete_count++; } @@ -3324,7 +3227,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, } end_read_record(&info); free_io_cache(from); - delete [] copy; // This is never 0 + delete [] copy; // This is never 0 if (to->file->end_bulk_insert() && !error) { @@ -3375,7 +3278,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) strxmov(table_name, table->db ,".", table->real_name, NullS); t= table->table= open_ltable(thd, table, TL_READ_NO_INSERT); - thd->clear_error(); // these errors shouldn't get client + thd->clear_error(); // these errors shouldn't get client protocol->prepare_for_resend(); protocol->store(table_name, system_charset_info); @@ -3391,54 +3294,54 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) t->pos_in_table_list= table; if (t->file->table_flags() & HA_HAS_CHECKSUM && - !(check_opt->flags & T_EXTEND)) - protocol->store((ulonglong)t->file->checksum()); + !(check_opt->flags & T_EXTEND)) + protocol->store((ulonglong)t->file->checksum()); else if (!(t->file->table_flags() & HA_HAS_CHECKSUM) && - (check_opt->flags & T_QUICK)) - protocol->store_null(); + (check_opt->flags & T_QUICK)) + protocol->store_null(); else { - /* calculating table's checksum */ - ha_checksum crc= 0; - - /* InnoDB must be told explicitly to retrieve all columns, because - this function does not set field->query_id in the columns to the - current query id */ - t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - - if (t->file->rnd_init(1)) - protocol->store_null(); - else - { - while (!t->file->rnd_next(t->record[0])) - { - ha_checksum row_crc= 0; - if (t->record[0] != (byte*) t->field[0]->ptr) - row_crc= my_checksum(row_crc, t->record[0], - ((byte*) t->field[0]->ptr) - t->record[0]); - - for (uint i= 0; i < t->fields; i++ ) - { - Field *f= t->field[i]; - if (f->type() == FIELD_TYPE_BLOB) - { - String tmp; - f->val_str(&tmp); - row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length()); - } - else - row_crc= my_checksum(row_crc, (byte*) f->ptr, - f->pack_length()); - } - - crc+= row_crc; - } - protocol->store((ulonglong)crc); - } + /* calculating table's checksum */ + ha_checksum crc= 0; + + /* InnoDB must be told explicitly to retrieve all columns, because + this function does not set field->query_id in the columns to the + current query id */ + t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); + + if (t->file->rnd_init(1)) + protocol->store_null(); + else + { + while (!t->file->rnd_next(t->record[0])) + { + ha_checksum row_crc= 0; + if (t->record[0] != (byte*) t->field[0]->ptr) + row_crc= my_checksum(row_crc, t->record[0], + ((byte*) t->field[0]->ptr) - t->record[0]); + + for (uint i= 0; i < t->fields; i++ ) + { + Field *f= t->field[i]; + if (f->type() == FIELD_TYPE_BLOB) + { + String tmp; + f->val_str(&tmp); + row_crc= my_checksum(row_crc, (byte*) tmp.ptr(), tmp.length()); + } + else + row_crc= my_checksum(row_crc, (byte*) f->ptr, + f->pack_length()); + } + + crc+= row_crc; + } + protocol->store((ulonglong)crc); + } } thd->clear_error(); close_thread_tables(thd); - table->table=0; // For query cache + table->table=0; // For query cache } if (protocol->write()) goto err; @@ -3448,7 +3351,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) DBUG_RETURN(0); err: - close_thread_tables(thd); // Shouldn't be needed + close_thread_tables(thd); // Shouldn't be needed if (table) table->table=0; DBUG_RETURN(-1); diff --git a/sql/unireg.cc b/sql/unireg.cc index 4af1c832b57..8d3e304b5da 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -46,12 +46,29 @@ 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, - HA_CREATE_INFO *create_info, - List<create_field> &create_fields, - uint keys, KEY *key_info, - handler *db_file) +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, + handler *db_file) { uint reclength,info_length,screens,key_info_length,maxlength,null_fields; File file; @@ -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(1); DBUG_RETURN(0); - -err: - my_delete(file_name,MYF(0)); - DBUG_RETURN(1); } /* rea_create_table */ diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 4fd288d257e..d9d80263d31 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -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') + larg = va_arg(ap, int); + else + larg= (long) (uint) va_arg(ap, int); if (*fmt == 'd') - store_end= int10_to_str((long) iarg, store_start, -10); + store_end= int10_to_str(larg, store_start, -10); else - store_end= int10_to_str((long) (uint) iarg, store_start, 10); + 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; |