summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc228
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;
}