The world's most popular open source database
#include "mysql_priv.h"#include <hash.h>#include <myisam.h>#include <my_dir.h>#include "sp_head.h"#include "sql_trigger.h"#include "sql_show.h"Include dependency graph for sql_table.cc:

Go to the source code of this file.
Classes | |
| struct | st_global_ddl_log |
Defines | |
| #define | MYSQL50_TABLE_NAME_PREFIX "#mysql50#" |
| #define | MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 |
| #define | ALTER_TABLE_DATA_CHANGED 1 |
| #define | ALTER_TABLE_INDEX_CHANGED 2 |
| #define | DDL_LOG_ENTRY_TYPE_POS 0 |
| #define | DDL_LOG_ACTION_TYPE_POS 1 |
| #define | DDL_LOG_PHASE_POS 2 |
| #define | DDL_LOG_NEXT_ENTRY_POS 4 |
| #define | DDL_LOG_NAME_POS 8 |
| #define | DDL_LOG_NUM_ENTRY_POS 0 |
| #define | DDL_LOG_NAME_LEN_POS 4 |
| #define | DDL_LOG_IO_SIZE_POS 8 |
Typedefs | |
| typedef st_global_ddl_log | GLOBAL_DDL_LOG |
Functions | |
| 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, bool ignore, uint order_num, ORDER *order, ha_rows *copied, ha_rows *deleted) |
| static bool | prepare_blob_field (THD *thd, create_field *sql_field) |
| static bool | check_engine (THD *thd, const char *table_name, HA_CREATE_INFO *create_info) |
| static int | mysql_prepare_table (THD *thd, HA_CREATE_INFO *create_info, List< create_field > *fields, List< Key > *keys, bool tmp_table, uint *db_options, handler *file, KEY **key_info_buffer, uint *key_count, int select_field_count) |
| uint | filename_to_tablename (const char *from, char *to, uint to_length) |
| uint | tablename_to_filename (const char *from, char *to, uint to_length) |
| uint | build_table_filename (char *buff, size_t bufflen, const char *db, const char *table_name, const char *ext, uint flags) |
| uint | build_tmptable_filename (THD *thd, char *buff, size_t bufflen) |
| static int | mysql_copy_create_list (List< create_field > *orig_create_list, List< create_field > *new_create_list) |
| static int | mysql_copy_key_list (List< Key > *orig_key, List< Key > *new_key) |
| static bool | read_ddl_log_file_entry (uint entry_no) |
| static bool | write_ddl_log_file_entry (uint entry_no) |
| static bool | write_ddl_log_header () |
| static void | create_ddl_log_file_name (char *file_name) |
| static uint | read_ddl_log_header () |
| bool | read_ddl_log_entry (uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) |
| static bool | init_ddl_log () |
| static int | execute_ddl_log_action (THD *thd, DDL_LOG_ENTRY *ddl_log_entry) |
| static bool | get_free_ddl_log_entry (DDL_LOG_MEMORY_ENTRY **active_entry, bool *write_header) |
| bool | write_ddl_log_entry (DDL_LOG_ENTRY *ddl_log_entry, DDL_LOG_MEMORY_ENTRY **active_entry) |
| bool | write_execute_ddl_log_entry (uint first_entry, bool complete, DDL_LOG_MEMORY_ENTRY **active_entry) |
| bool | deactivate_ddl_log_entry (uint entry_no) |
| bool | sync_ddl_log () |
| void | release_ddl_log_memory_entry (DDL_LOG_MEMORY_ENTRY *log_entry) |
| bool | execute_ddl_log_entry (THD *thd, uint first_entry) |
| void | execute_ddl_log_recovery () |
| void | release_ddl_log () |
| bool | mysql_write_frm (ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) |
| void | write_bin_log (THD *thd, bool clear_error, char const *query, ulong query_length) |
| bool | mysql_rm_table (THD *thd, TABLE_LIST *tables, my_bool if_exists, my_bool drop_temporary) |
| int | mysql_rm_table_part2_with_lock (THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool dont_log_query) |
| int | mysql_rm_table_part2 (THD *thd, TABLE_LIST *tables, bool if_exists, bool drop_temporary, bool drop_view, bool dont_log_query) |
| bool | quick_rm_table (handlerton *base, const char *db, const char *table_name, uint flags) |
| static int | sort_keys (KEY *a, KEY *b) |
| void | check_duplicates_in_interval (const char *set_or_name, const char *name, TYPELIB *typelib, CHARSET_INFO *cs) |
| void | calculate_interval_lengths (CHARSET_INFO *cs, TYPELIB *interval, uint32 *max_length, uint32 *tot_length) |
| int | prepare_create_field (create_field *sql_field, uint *blob_columns, int *timestamps, int *timestamps_with_niladic, uint table_flags) |
| static void | set_table_default_charset (THD *thd, HA_CREATE_INFO *create_info, char *db) |
| void | sp_prepare_create_field (THD *thd, create_field *sql_field) |
| static HA_CREATE_INFO * | copy_create_info (HA_CREATE_INFO *lex_create_info) |
| bool | mysql_create_table_internal (THD *thd, const char *db, const char *table_name, HA_CREATE_INFO *lex_create_info, List< create_field > &fields, List< Key > &keys, bool internal_tmp_table, uint select_field_count, bool use_copy_create_info) |
| bool | 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 internal_tmp_table, uint select_field_count, bool use_copy_create_info) |
| bool | mysql_rename_table (handlerton *base, const char *old_db, const char *old_name, const char *new_db, const char *new_name, uint flags) |
| static void | wait_while_table_is_used (THD *thd, TABLE *table, enum ha_extra_function function) |
| void | close_cached_table (THD *thd, TABLE *table) |
| static int | send_check_errmsg (THD *thd, TABLE_LIST *table, const char *operator_name, const char *errmsg) |
| static int | prepare_for_restore (THD *thd, TABLE_LIST *table, HA_CHECK_OPT *check_opt) |
| static int | prepare_for_repair (THD *thd, TABLE_LIST *table_list, HA_CHECK_OPT *check_opt) |
| static bool | 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, bool no_warnings_for_error, uint extra_open_options, int(*prepare_func)(THD *, TABLE_LIST *, HA_CHECK_OPT *), int(handler::*operator_func)(THD *, HA_CHECK_OPT *), int(view_operator_func)(THD *, TABLE_LIST *)) |
| bool | mysql_backup_table (THD *thd, TABLE_LIST *table_list) |
| bool | mysql_restore_table (THD *thd, TABLE_LIST *table_list) |
| bool | mysql_repair_table (THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) |
| bool | mysql_optimize_table (THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) |
| bool | mysql_assign_to_keycache (THD *thd, TABLE_LIST *tables, LEX_STRING *key_cache_name) |
| int | reassign_keycache_tables (THD *thd, KEY_CACHE *src_cache, KEY_CACHE *dst_cache) |
| bool | mysql_preload_keys (THD *thd, TABLE_LIST *tables) |
| bool | mysql_create_like_table (THD *thd, TABLE_LIST *table, HA_CREATE_INFO *lex_create_info, Table_ident *table_ident) |
| bool | mysql_analyze_table (THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) |
| bool | mysql_check_table (THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) |
| static int | mysql_discard_or_import_tablespace (THD *thd, TABLE_LIST *table_list, enum tablespace_op_type tablespace_op) |
| static uint | compare_tables (TABLE *table, List< create_field > *create_list, KEY *key_info_buffer, uint key_count, HA_CREATE_INFO *create_info, ALTER_INFO *alter_info, uint order_num, uint *index_drop_buffer, uint *index_drop_count, uint *index_add_buffer, uint *index_add_count, bool varchar) |
| bool | mysql_alter_table (THD *thd, char *new_db, char *new_name, HA_CREATE_INFO *lex_create_info, TABLE_LIST *table_list, List< create_field > &fields, List< Key > &keys, uint order_num, ORDER *order, bool ignore, ALTER_INFO *alter_info, bool do_send_ok) |
| bool | mysql_recreate_table (THD *thd, TABLE_LIST *table_list, bool do_send_ok) |
| bool | mysql_checksum_table (THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) |
Variables | |
| int | creating_table = 0 |
| const char * | primary_key_name = "PRIMARY" |
| GLOBAL_DDL_LOG | global_ddl_log |
| pthread_mutex_t | LOCK_gdl |
| #define ALTER_TABLE_DATA_CHANGED 1 |
| #define ALTER_TABLE_INDEX_CHANGED 2 |
| #define DDL_LOG_ACTION_TYPE_POS 1 |
Definition at line 385 of file sql_table.cc.
Referenced by deactivate_ddl_log_entry(), read_ddl_log_entry(), write_ddl_log_entry(), and write_execute_ddl_log_entry().
| #define DDL_LOG_ENTRY_TYPE_POS 0 |
Definition at line 384 of file sql_table.cc.
Referenced by deactivate_ddl_log_entry(), read_ddl_log_entry(), write_ddl_log_entry(), and write_execute_ddl_log_entry().
| #define DDL_LOG_IO_SIZE_POS 8 |
Definition at line 392 of file sql_table.cc.
Referenced by read_ddl_log_header(), and write_ddl_log_header().
| #define DDL_LOG_NAME_LEN_POS 4 |
Definition at line 391 of file sql_table.cc.
Referenced by read_ddl_log_header(), and write_ddl_log_header().
| #define DDL_LOG_NAME_POS 8 |
Definition at line 388 of file sql_table.cc.
Referenced by read_ddl_log_entry(), write_ddl_log_entry(), and write_execute_ddl_log_entry().
| #define DDL_LOG_NEXT_ENTRY_POS 4 |
Definition at line 387 of file sql_table.cc.
Referenced by read_ddl_log_entry(), write_ddl_log_entry(), and write_execute_ddl_log_entry().
| #define DDL_LOG_NUM_ENTRY_POS 0 |
Definition at line 390 of file sql_table.cc.
Referenced by read_ddl_log_header(), and write_ddl_log_header().
| #define DDL_LOG_PHASE_POS 2 |
Definition at line 386 of file sql_table.cc.
Referenced by deactivate_ddl_log_entry(), read_ddl_log_entry(), write_ddl_log_entry(), and write_execute_ddl_log_entry().
| #define MYSQL50_TABLE_NAME_PREFIX "#mysql50#" |
Definition at line 51 of file sql_table.cc.
Referenced by filename_to_tablename(), and tablename_to_filename().
| #define MYSQL50_TABLE_NAME_PREFIX_LENGTH 9 |
| typedef struct st_global_ddl_log GLOBAL_DDL_LOG |
| uint build_table_filename | ( | char * | buff, | |
| size_t | bufflen, | |||
| const char * | db, | |||
| const char * | table_name, | |||
| const char * | ext, | |||
| uint | flags | |||
| ) |
Definition at line 170 of file sql_table.cc.
References DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, FN_REFLEN, mysql_data_home, NullS, strnmov(), strxnmov(), tablename_to_filename(), and VOID.
Referenced by add_table_for_trigger(), alloc_table_share(), Table_triggers_list::change_table_name_in_trignames(), check_db_dir_existence(), Table_triggers_list::check_n_load(), Table_triggers_list::create_trigger(), get_all_tables(), load_db_opt_by_name(), mysql_alter_db(), mysql_alter_table(), mysql_create_db(), mysql_create_like_table(), mysql_create_table_internal(), mysql_drop_view(), mysql_register_view(), mysql_rename_db(), mysql_rename_table(), mysql_rm_db(), mysql_rm_table_part2(), mysql_table_grant(), mysql_truncate(), mysql_write_frm(), open_table(), prepare_for_restore(), quick_rm_table(), rename_tables(), rm_trigger_file(), rm_trigname_file(), and save_trigger_file().
00172 { 00173 uint length; 00174 char dbbuff[FN_REFLEN]; 00175 char tbbuff[FN_REFLEN]; 00176 DBUG_ENTER("build_table_filename"); 00177 00178 if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP 00179 strnmov(tbbuff, table_name, sizeof(tbbuff)); 00180 else 00181 VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff))); 00182 00183 VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff))); 00184 length= strxnmov(buff, bufflen, mysql_data_home, "/", dbbuff, 00185 "/", tbbuff, ext, NullS) - buff; 00186 DBUG_PRINT("exit", ("buff: '%s'", buff)); 00187 DBUG_RETURN(length); 00188 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 209 of file sql_table.cc.
References current_pid, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, my_snprintf(), NullS, reg_ext, strxnmov(), tmp_file_prefix, tmp_file_prefix_length, and unpack_filename().
Referenced by mysql_create_like_table(), and mysql_create_table_internal().
00210 { 00211 uint length; 00212 char tmp_table_name[tmp_file_prefix_length+22+22+22+3]; 00213 DBUG_ENTER("build_tmptable_filename"); 00214 00215 my_snprintf(tmp_table_name, sizeof(tmp_table_name), 00216 "%s%lx_%lx_%x", 00217 tmp_file_prefix, current_pid, 00218 thd->thread_id, thd->tmp_table++); 00219 00220 strxnmov(buff, bufflen, mysql_tmpdir, "/", tmp_table_name, reg_ext, NullS); 00221 length= unpack_filename(buff, buff); 00222 DBUG_PRINT("exit", ("buff: '%s'", buff)); 00223 DBUG_RETURN(length); 00224 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void calculate_interval_lengths | ( | CHARSET_INFO * | cs, | |
| TYPELIB * | interval, | |||
| uint32 * | max_length, | |||
| uint32 * | tot_length | |||
| ) |
Definition at line 1961 of file sql_table.cc.
References charset_info_st::cset, interval, my_charset_handler_st::numchars, pos(), and set_if_bigger.
Referenced by mysql_prepare_table(), and sp_prepare_create_field().
01963 { 01964 const char **pos; 01965 uint *len; 01966 *max_length= *tot_length= 0; 01967 for (pos= interval->type_names, len= interval->type_lengths; 01968 *pos ; pos++, len++) 01969 { 01970 uint length= cs->cset->numchars(cs, *pos, *pos + *len); 01971 *tot_length+= length; 01972 set_if_bigger(*max_length, (uint32)length); 01973 } 01974 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void check_duplicates_in_interval | ( | const char * | set_or_name, | |
| const char * | name, | |||
| TYPELIB * | typelib, | |||
| CHARSET_INFO * | cs | |||
| ) |
Definition at line 1919 of file sql_table.cc.
References st_typelib::count, current_thd, ER, ER_DUPLICATED_VALUE_IN_TYPE, find_type2(), push_warning_printf(), st_typelib::type_lengths, st_typelib::type_names, typelib(), and MYSQL_ERROR::WARN_LEVEL_NOTE.
Referenced by prepare_create_field().
01922 { 01923 TYPELIB tmp= *typelib; 01924 const char **cur_value= typelib->type_names; 01925 unsigned int *cur_length= typelib->type_lengths; 01926 01927 for ( ; tmp.count > 1; cur_value++, cur_length++) 01928 { 01929 tmp.type_names++; 01930 tmp.type_lengths++; 01931 tmp.count--; 01932 if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs)) 01933 { 01934 push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE, 01935 ER_DUPLICATED_VALUE_IN_TYPE, 01936 ER(ER_DUPLICATED_VALUE_IN_TYPE), 01937 name,*cur_value,set_or_name); 01938 } 01939 } 01940 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool check_engine | ( | THD * | thd, | |
| const char * | table_name, | |||
| HA_CREATE_INFO * | create_info | |||
| ) | [static] |
Definition at line 6748 of file sql_table.cc.
References st_ha_create_information::db_type, ER, ER_ILLEGAL_HA_CREATE_OPTION, ER_WARN_USING_OTHER_HANDLER, FALSE, ha_check_storage_engine_flag(), ha_checktype(), HA_CREATE_USED_ENGINE, ha_legacy_type(), HA_LEX_CREATE_TMP_TABLE, ha_resolve_storage_engine_name(), hton2plugin, HTON_TEMPORARY_NOT_SUPPORTED, MODE_NO_ENGINE_SUBSTITUTION, my_error(), MYF, myisam_hton, st_plugin_int::name, st_ha_create_information::options, push_warning_printf(), LEX_STRING::str, test, TRUE, st_ha_create_information::used_fields, and MYSQL_ERROR::WARN_LEVEL_WARN.
Referenced by mysql_alter_table(), and mysql_create_table_internal().
06750 { 06751 handlerton **new_engine= &create_info->db_type; 06752 handlerton *req_engine= *new_engine; 06753 bool no_substitution= 06754 test(thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION); 06755 if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine), 06756 no_substitution, 1))) 06757 return TRUE; 06758 06759 if (req_engine && req_engine != *new_engine) 06760 { 06761 push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, 06762 ER_WARN_USING_OTHER_HANDLER, 06763 ER(ER_WARN_USING_OTHER_HANDLER), 06764 ha_resolve_storage_engine_name(*new_engine), 06765 table_name); 06766 } 06767 if (create_info->options & HA_LEX_CREATE_TMP_TABLE && 06768 ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED)) 06769 { 06770 if (create_info->used_fields & HA_CREATE_USED_ENGINE) 06771 { 06772 my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0), 06773 hton2plugin[(*new_engine)->slot]->name.str, "TEMPORARY"); 06774 *new_engine= 0; 06775 return TRUE; 06776 } 06777 *new_engine= &myisam_hton; 06778 } 06779 return FALSE; 06780 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3582 of file sql_table.cc.
References key, my_strcasecmp, start(), and system_charset_info.
Referenced by make_unique_key_name().
03583 { 03584 for (KEY *key=start ; key != end ; key++) 03585 if (!my_strcasecmp(system_charset_info,name,key->name)) 03586 return 1; 03587 return 0; 03588 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void close_cached_table | ( | THD * | thd, | |
| TABLE * | table | |||
| ) |
Definition at line 3757 of file sql_table.cc.
References broadcast_refresh(), DBUG_ENTER, DBUG_VOID_RETURN, HA_EXTRA_PREPARE_FOR_DELETE, mysql_unlock_tables(), unlink_open_table(), and wait_while_table_is_used().
Referenced by mysql_alter_table(), and prepare_for_repair().
03758 { 03759 DBUG_ENTER("close_cached_table"); 03760 03761 wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); 03762 /* Close lock if this is not got with LOCK TABLES */ 03763 if (thd->lock) 03764 { 03765 mysql_unlock_tables(thd, thd->lock); 03766 thd->lock=0; // Start locked threads 03767 } 03768 /* Close all copies of 'table'. This also frees all LOCK TABLES lock */ 03769 thd->open_tables=unlink_open_table(thd,thd->open_tables,table); 03770 03771 /* When lock on LOCK_open is freed other threads can continue */ 03772 broadcast_refresh(); 03773 DBUG_VOID_RETURN; 03774 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static uint compare_tables | ( | TABLE * | table, | |
| List< create_field > * | create_list, | |||
| KEY * | key_info_buffer, | |||
| uint | key_count, | |||
| HA_CREATE_INFO * | create_info, | |||
| ALTER_INFO * | alter_info, | |||
| uint | order_num, | |||
| uint * | index_drop_buffer, | |||
| uint * | index_drop_count, | |||
| uint * | index_add_buffer, | |||
| uint * | index_add_count, | |||
| bool | varchar | |||
| ) | [static] |
Definition at line 4902 of file sql_table.cc.
References st_key::algorithm, ALTER_TABLE_DATA_CHANGED, BLOB_FLAG, create_field::charset, st_ha_create_information::db_type, st_table_share::db_type, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_ha_create_information::default_table_charset, base_list::elements, st_table::field, FIELD_IN_ADD_INDEX, FIELD_IS_RENAMED, create_field::field_name, Field::field_name, st_key_part_info::fieldnr, st_table_share::fields, st_key::flags, Field::flags, create_field::flags, FRM_VER_TRUE_VARCHAR, st_table_share::frm_version, HA_CREATE_USED_CHARSET, HA_CREATE_USED_DEFAULT_CHARSET, HA_CREATE_USED_ENGINE, HA_KEYFLAG_MASK, HA_OPTION_PACK_RECORD, Field::is_equal(), st_table::key_info, st_key::key_part, st_key::key_parts, st_table_share::keys, st_key_part_info::length, my_strcasecmp, MYSQL_TYPE_VARCHAR, st_table_share::mysql_version, st_key::name, NOT_NULL_FLAG, st_ha_create_information::row_type, ROW_TYPE_DYNAMIC, ROW_TYPE_FIXED, st_table::s, create_field::sql_type, strcmp(), system_charset_info, st_ha_create_information::table_options, st_table_share::tmp_table, and st_ha_create_information::used_fields.
Referenced by mysql_alter_table().
04909 { 04910 Field **f_ptr, *field; 04911 uint changes= 0, tmp; 04912 List_iterator_fast<create_field> new_field_it(*create_list); 04913 create_field *new_field; 04914 KEY_PART_INFO *key_part; 04915 KEY_PART_INFO *end; 04916 DBUG_ENTER("compare_tables"); 04917 04918 /* 04919 Some very basic checks. If number of fields changes, or the 04920 handler, we need to run full ALTER TABLE. In the future 04921 new fields can be added and old dropped without copy, but 04922 not yet. 04923 04924 Test also that engine was not given during ALTER TABLE, or 04925 we are force to run regular alter table (copy). 04926 E.g. ALTER TABLE tbl_name ENGINE=MyISAM. 04927 04928 For the following ones we also want to run regular alter table: 04929 ALTER TABLE tbl_name ORDER BY .. 04930 ALTER TABLE tbl_name CONVERT TO CHARACTER SET .. 04931 04932 At the moment we can't handle altering temporary tables without a copy. 04933 We also test if OPTIMIZE TABLE was given and was mapped to alter table. 04934 In that case we always do full copy. 04935 04936 There was a bug prior to mysql-4.0.25. Number of null fields was 04937 calculated incorrectly. As a result frm and data files gets out of 04938 sync after fast alter table. There is no way to determine by which 04939 mysql version (in 4.0 and 4.1 branches) table was created, thus we 04940 disable fast alter table for all tables created by mysql versions 04941 prior to 5.0 branch. 04942 See BUG#6236. 04943 */ 04944 if (table->s->fields != create_list->elements || 04945 table->s->db_type != create_info->db_type || 04946 table->s->tmp_table || 04947 create_info->used_fields & HA_CREATE_USED_ENGINE || 04948 create_info->used_fields & HA_CREATE_USED_CHARSET || 04949 create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET || 04950 (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) || 04951 order_num || 04952 !table->s->mysql_version || 04953 (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar)) 04954 DBUG_RETURN(ALTER_TABLE_DATA_CHANGED); 04955 04956 /* 04957 Go through fields and check if the original ones are compatible 04958 with new table. 04959 */ 04960 for (f_ptr= table->field, new_field= new_field_it++; 04961 (field= *f_ptr); f_ptr++, new_field= new_field_it++) 04962 { 04963 /* Make sure we have at least the default charset in use. */ 04964 if (!new_field->charset) 04965 new_field->charset= create_info->default_table_charset; 04966 04967 /* Check that NULL behavior is same for old and new fields */ 04968 if ((new_field->flags & NOT_NULL_FLAG) != 04969 (uint) (field->flags & NOT_NULL_FLAG)) 04970 DBUG_RETURN(ALTER_TABLE_DATA_CHANGED); 04971 04972 /* Don't pack rows in old tables if the user has requested this. */ 04973 if (create_info->

