diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 228 |
1 files changed, 191 insertions, 37 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index f0756aceadb..afeec26f034 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -34,6 +34,8 @@ #endif #ifdef HAVE_INNOBASE_DB #include "ha_innodb.h" +#else +#define innobase_query_caching_of_table_permitted(X,Y,Z) 1 #endif #include <myisampack.h> #include <errno.h> @@ -48,14 +50,33 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, ha_commit_count, ha_rollback_count, ha_read_rnd_count, ha_read_rnd_next_count; -const char *ha_table_type[] = { - "", "DIAB_ISAM","HASH","MISAM","PISAM","RMS_ISAM","HEAP", "ISAM", - "MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNODB", "GEMINI", "?", "?",NullS -}; +static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES; -TYPELIB ha_table_typelib= +struct show_table_type_st sys_table_types[]= { - array_elements(ha_table_type)-3, "", ha_table_type + {"MyISAM", &have_yes, + "Default type from 3.23 with great performance", DB_TYPE_MYISAM}, + {"HEAP", &have_yes, + "Hash based, stored in memory, useful for temporary tables", DB_TYPE_HEAP}, + {"MEMORY", &have_yes, + "Alias for HEAP", DB_TYPE_HEAP}, + {"MERGE", &have_yes, + "Collection of identical MyISAM tables", DB_TYPE_MRG_MYISAM}, + {"MRG_MYISAM",&have_yes, + "Alias for MERGE", DB_TYPE_MRG_MYISAM}, + {"ISAM", &have_isam, + "Obsolete table type; Is replaced by MyISAM", DB_TYPE_ISAM}, + {"MRG_ISAM", &have_isam, + "Obsolete table type; Is replaced by MRG_MYISAM", DB_TYPE_MRG_ISAM}, + {"InnoDB", &have_innodb, + "Supports transactions, row-level locking and foreign keys", DB_TYPE_INNODB}, + {"INNOBASE", &have_innodb, + "Alias for INNODB", DB_TYPE_INNODB}, + {"BDB", &have_berkeley_db, + "Supports transactions and page-level locking", DB_TYPE_BERKELEY_DB}, + {"BERKELEYDB",&have_berkeley_db, + "Alias for BDB", DB_TYPE_BERKELEY_DB}, + {NullS, NULL, NullS, DB_TYPE_UNKNOWN} }; const char *ha_row_type[] = { @@ -68,6 +89,33 @@ const char *tx_isolation_names[] = TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", tx_isolation_names}; +enum db_type ha_resolve_by_name(const char *name, uint namelen) +{ + if (!my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { + return(enum db_type) current_thd->variables.table_type; + } + + show_table_type_st *types; + for (types= sys_table_types; types->type; types++) + { + if (!my_strcasecmp(&my_charset_latin1, name, types->type)) + return(enum db_type)types->db_type; + } + return DB_TYPE_UNKNOWN; +} + +const char *ha_get_storage_engine(enum db_type db_type) +{ + show_table_type_st *types; + for (types= sys_table_types; types->type; types++) + { + if (db_type == types->db_type) + return types->type; + } + + return "none"; +} + /* Use other database handler if databasehandler is not incompiled */ enum db_type ha_checktype(enum db_type database_type) @@ -75,18 +123,26 @@ enum db_type ha_checktype(enum db_type database_type) switch (database_type) { #ifdef HAVE_BERKELEY_DB case DB_TYPE_BERKELEY_DB: - return(berkeley_skip ? DB_TYPE_MYISAM : database_type); + if (berkeley_skip) break; + return (database_type); #endif #ifdef HAVE_INNOBASE_DB case DB_TYPE_INNODB: - return(innodb_skip ? DB_TYPE_MYISAM : database_type); + if (innodb_skip) break; + return (database_type); #endif #ifndef NO_HASH case DB_TYPE_HASH: #endif #ifdef HAVE_ISAM case DB_TYPE_ISAM: + if (isam_skip) break; + return (database_type); + case DB_TYPE_MRG_ISAM: + return (isam_skip ? DB_TYPE_MRG_MYISAM : database_type); +#else case DB_TYPE_MRG_ISAM: + return (DB_TYPE_MRG_MYISAM); #endif case DB_TYPE_HEAP: case DB_TYPE_MYISAM: @@ -95,7 +151,13 @@ enum db_type ha_checktype(enum db_type database_type) default: break; } - return(DB_TYPE_MYISAM); /* Use this as default */ + + return + DB_TYPE_UNKNOWN != (enum db_type) current_thd->variables.table_type ? + (enum db_type) current_thd->variables.table_type : + DB_TYPE_UNKNOWN != (enum db_type) global_system_variables.table_type ? + (enum db_type) global_system_variables.table_type : + DB_TYPE_MYISAM; } /* ha_checktype */ @@ -110,6 +172,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type) return new ha_isammrg(table); case DB_TYPE_ISAM: return new ha_isam(table); +#else + case DB_TYPE_MRG_ISAM: + return new ha_myisammrg(table); #endif #ifdef HAVE_BERKELEY_DB case DB_TYPE_BERKELEY_DB: @@ -735,6 +800,16 @@ int handler::analyze(THD* thd, HA_CHECK_OPT* check_opt) return HA_ADMIN_NOT_IMPLEMENTED; } +int handler::assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) +{ + return HA_ADMIN_NOT_IMPLEMENTED; +} + +int handler::preload_keys(THD* thd, HA_CHECK_OPT* check_opt) +{ + return HA_ADMIN_NOT_IMPLEMENTED; +} + /* Read first row (only) from a table This is never called for InnoDB or BDB tables, as these table types @@ -807,18 +882,24 @@ void handler::update_auto_increment() longlong nr; THD *thd; DBUG_ENTER("update_auto_increment"); - if (table->next_number_field->val_int() != 0) + if (table->next_number_field->val_int() != 0 || + table->auto_increment_field_not_null && + current_thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) { + table->auto_increment_field_not_null= false; auto_increment_column_changed=0; DBUG_VOID_RETURN; } + table->auto_increment_field_not_null= false; thd=current_thd; if ((nr=thd->next_insert_id)) thd->next_insert_id=0; // Clear after use else nr=get_auto_increment(); - thd->insert_id((ulonglong) nr); - table->next_number_field->store(nr); + if (!table->next_number_field->store(nr)) + thd->insert_id((ulonglong) nr); + else + thd->insert_id(table->next_number_field->val_int()); auto_increment_column_changed=1; DBUG_VOID_RETURN; } @@ -887,7 +968,7 @@ void handler::print_error(int error, myf errflag) { /* Write the dupplicated key in the error message */ char key[MAX_KEY_LENGTH]; - String str(key,sizeof(key)); + String str(key,sizeof(key),system_charset_info); key_unpack(&str,table,(uint) key_nr); uint max_length=MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_DUP_ENTRY)); if (str.length() >= max_length) @@ -1040,6 +1121,16 @@ int handler::delete_all_rows() return (my_errno=HA_ERR_WRONG_COMMAND); } +bool handler::caching_allowed(THD* thd, char* table_key, + uint key_length, uint8 cache_type) +{ + if (cache_type == HA_CACHE_TBL_ASKTRANSACT) + return innobase_query_caching_of_table_permitted(thd, table_key, + key_length); + else + return 1; +} + /**************************************************************************** ** Some general functions that isn't in the handler class ****************************************************************************/ @@ -1079,41 +1170,104 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, DBUG_RETURN(error != 0); } - /* Use key cacheing on all databases */ +static int NEAR_F delete_file(const char *name,const char *ext,int extflag) +{ + char buff[FN_REFLEN]; + VOID(fn_format(buff,name,"",ext,extflag | 4)); + return(my_delete_with_symlink(buff,MYF(MY_WME))); +} -void ha_key_cache(void) +void st_ha_check_opt::init() { - /* - The following mutex is not really needed as long as keybuff_size is - treated as a long value, but we use the mutex here to guard for future - changes. - */ - pthread_mutex_lock(&LOCK_global_system_variables); - long tmp= (long) keybuff_size; - pthread_mutex_unlock(&LOCK_global_system_variables); - if (tmp) - (void) init_key_cache(tmp); + flags= sql_flags= 0; + sort_buffer_size = current_thd->variables.myisam_sort_buff_size; } -void ha_resize_key_cache(void) +/***************************************************************************** + Key cache handling. + + This code is only relevant for ISAM/MyISAM tables + + key_cache->cache may be 0 only in the case where a key cache is not + initialized or when we where not able to init the key cache in a previous + call to ha_init_key_cache() (probably out of memory) +*****************************************************************************/ + +/* Init a key cache if it has not been initied before */ + + +int ha_init_key_cache(const char *name, KEY_CACHE *key_cache) { - pthread_mutex_lock(&LOCK_global_system_variables); - long tmp= (long) keybuff_size; - pthread_mutex_unlock(&LOCK_global_system_variables); - (void) resize_key_cache(tmp); + DBUG_ENTER("ha_init_key_cache"); + + if (!key_cache->key_cache_inited) + { + pthread_mutex_lock(&LOCK_global_system_variables); + long tmp_buff_size= (long) key_cache->param_buff_size; + long tmp_block_size= (long) key_cache->param_block_size; + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; + pthread_mutex_unlock(&LOCK_global_system_variables); + DBUG_RETURN(!init_key_cache(key_cache, + tmp_block_size, + tmp_buff_size, + division_limit, age_threshold)); + } + DBUG_RETURN(0); } -static int NEAR_F delete_file(const char *name,const char *ext,int extflag) +/* Resize key cache */ + +int ha_resize_key_cache(KEY_CACHE *key_cache) { - char buff[FN_REFLEN]; - VOID(fn_format(buff,name,"",ext,extflag | 4)); - return(my_delete_with_symlink(buff,MYF(MY_WME))); + DBUG_ENTER("ha_resize_key_cache"); + + if (key_cache->key_cache_inited) + { + pthread_mutex_lock(&LOCK_global_system_variables); + long tmp_buff_size= (long) key_cache->param_buff_size; + long tmp_block_size= (long) key_cache->param_block_size; + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; + pthread_mutex_unlock(&LOCK_global_system_variables); + DBUG_RETURN(!resize_key_cache(key_cache, tmp_block_size, + tmp_buff_size, + division_limit, age_threshold)); + } + DBUG_RETURN(0); } -void st_ha_check_opt::init() + +/* Change parameters for key cache (like size) */ + +int ha_change_key_cache_param(KEY_CACHE *key_cache) { - flags= sql_flags= 0; - sort_buffer_size = current_thd->variables.myisam_sort_buff_size; + if (key_cache->key_cache_inited) + { + pthread_mutex_lock(&LOCK_global_system_variables); + uint division_limit= key_cache->param_division_limit; + uint age_threshold= key_cache->param_age_threshold; + pthread_mutex_unlock(&LOCK_global_system_variables); + change_key_cache_param(key_cache, division_limit, age_threshold); + } + return 0; +} + +/* Free memory allocated by a key cache */ + +int ha_end_key_cache(KEY_CACHE *key_cache) +{ + end_key_cache(key_cache, 1); // Can never fail + return 0; +} + +/* Move all tables from one key cache to another one */ + +int ha_change_key_cache(KEY_CACHE *old_key_cache, + KEY_CACHE *new_key_cache) +{ + mi_change_key_cache(old_key_cache, new_key_cache); + return 0; } |