summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc160
1 files changed, 93 insertions, 67 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 0191a7139cd..f9be90c9379 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -120,34 +120,21 @@ const char *ha_get_storage_engine(enum db_type db_type)
enum db_type ha_checktype(enum db_type database_type)
{
+ show_table_type_st *types;
+ for (types= sys_table_types; types->type; types++)
+ {
+ if ((database_type == types->db_type) &&
+ (*types->value == SHOW_OPTION_YES))
+ return database_type;
+ }
+
switch (database_type) {
-#ifdef HAVE_BERKELEY_DB
- case DB_TYPE_BERKELEY_DB:
- if (berkeley_skip) break;
- return (database_type);
-#endif
-#ifdef HAVE_INNOBASE_DB
- case DB_TYPE_INNODB:
- 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
+#endif
case DB_TYPE_MRG_ISAM:
return (DB_TYPE_MRG_MYISAM);
-#endif
- case DB_TYPE_HEAP:
- case DB_TYPE_MYISAM:
- case DB_TYPE_MRG_MYISAM:
- return (database_type); /* Database exists on system */
default:
break;
}
@@ -165,7 +152,8 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
{
switch (db_type) {
#ifndef NO_HASH
- return new ha_hash(table);
+ case DB_TYPE_HASH:
+ return new ha_hash(table);
#endif
#ifdef HAVE_ISAM
case DB_TYPE_MRG_ISAM:
@@ -203,30 +191,32 @@ handler *get_new_handler(TABLE *table, enum db_type db_type)
int ha_init()
{
+ int error= 0;
#ifdef HAVE_BERKELEY_DB
- if (!berkeley_skip)
+ if (have_berkeley_db == SHOW_OPTION_YES)
{
- int error;
- if ((error=berkeley_init()))
- return error;
- if (!berkeley_skip) // If we couldn't use handler
- opt_using_transactions=1;
+ if (berkeley_init())
+ {
+ have_berkeley_db= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ error= 1;
+ }
else
- have_berkeley_db=SHOW_OPTION_DISABLED;
+ opt_using_transactions=1;
}
#endif
#ifdef HAVE_INNOBASE_DB
- if (!innodb_skip)
+ if (have_innodb == SHOW_OPTION_YES)
{
if (innobase_init())
- return -1;
- if (!innodb_skip) // If we couldn't use handler
- opt_using_transactions=1;
+ {
+ have_innodb= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ error= 1;
+ }
else
- have_innodb=SHOW_OPTION_DISABLED;
+ opt_using_transactions=1;
}
#endif
- return 0;
+ return error;
}
/* close, flush or restart databases */
@@ -246,11 +236,11 @@ int ha_panic(enum ha_panic_function flag)
error|=mi_panic(flag);
error|=myrg_panic(flag);
#ifdef HAVE_BERKELEY_DB
- if (!berkeley_skip)
+ if (have_berkeley_db == SHOW_OPTION_YES)
error|=berkeley_end();
#endif
#ifdef HAVE_INNOBASE_DB
- if (!innodb_skip)
+ if (have_innodb == SHOW_OPTION_YES)
error|=innobase_end();
#endif
return error;
@@ -259,7 +249,7 @@ int ha_panic(enum ha_panic_function flag)
void ha_drop_database(char* path)
{
#ifdef HAVE_INNOBASE_DB
- if (!innodb_skip)
+ if (have_innodb == SHOW_OPTION_YES)
innobase_drop_database(path);
#endif
}
@@ -267,7 +257,7 @@ void ha_drop_database(char* path)
void ha_close_connection(THD* thd)
{
#ifdef HAVE_INNOBASE_DB
- if (!innodb_skip)
+ if (have_innodb == SHOW_OPTION_YES)
innobase_close_connection(thd);
#endif
}
@@ -415,6 +405,16 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
my_b_tell(&thd->transaction.trans_log))
{
mysql_bin_log.write(thd, &thd->transaction.trans_log, 1);
+ statistic_increment(binlog_cache_use, &LOCK_status);
+ if (thd->transaction.trans_log.disk_writes != 0)
+ {
+ /*
+ We have to do this after addition of trans_log to main binlog since
+ this operation can cause flushing of end of trans_log to disk.
+ */
+ statistic_increment(binlog_cache_disk_use, &LOCK_status);
+ thd->transaction.trans_log.disk_writes= 0;
+ }
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
thd->transaction.trans_log.end_of_file= max_binlog_cache_size;
@@ -496,17 +496,29 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
operation_done=1;
}
#endif
- if (trans == &thd->transaction.all)
+ if ((trans == &thd->transaction.all) && mysql_bin_log.is_open())
{
/*
Update the binary log with a BEGIN/ROLLBACK block if we have cached some
queries and we updated some non-transactional table. Such cases should
be rare (updating a non-transactional table inside a transaction...).
+ Count disk writes to trans_log in any case.
*/
- if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
- mysql_bin_log.is_open() &&
- my_b_tell(&thd->transaction.trans_log)))
- mysql_bin_log.write(thd, &thd->transaction.trans_log, 0);
+ if (my_b_tell(&thd->transaction.trans_log))
+ {
+ if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
+ mysql_bin_log.write(thd, &thd->transaction.trans_log, 0);
+ statistic_increment(binlog_cache_use, &LOCK_status);
+ if (thd->transaction.trans_log.disk_writes != 0)
+ {
+ /*
+ We have to do this after addition of trans_log to main binlog since
+ this operation can cause flushing of end of trans_log to disk.
+ */
+ statistic_increment(binlog_cache_disk_use, &LOCK_status);
+ thd->transaction.trans_log.disk_writes= 0;
+ }
+ }
/* Flushed or not, empty the binlog cache */
reinit_io_cache(&thd->transaction.trans_log,
WRITE_CACHE, (my_off_t) 0, 0, 1);
@@ -569,7 +581,7 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name)
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error);
error=1;
}
- else
+ else if (mysql_bin_log.is_open())
{
/*
Write ROLLBACK TO SAVEPOINT to the binlog cache if we have updated some
@@ -577,7 +589,6 @@ int ha_rollback_to_savepoint(THD *thd, char *savepoint_name)
from the SAVEPOINT command.
*/
if (unlikely((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) &&
- mysql_bin_log.is_open() &&
my_b_tell(&thd->transaction.trans_log)))
{
Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE);
@@ -606,23 +617,26 @@ Return value: always 0, that is, succeeds always
int ha_savepoint(THD *thd, char *savepoint_name)
{
- my_off_t binlog_cache_pos=0;
int error=0;
DBUG_ENTER("ha_savepoint");
#ifdef USING_TRANSACTIONS
if (opt_using_transactions)
{
- binlog_cache_pos=my_b_tell(&thd->transaction.trans_log);
-#ifdef HAVE_INNOBASE_DB
- innobase_savepoint(thd,savepoint_name, binlog_cache_pos);
-#endif
- /* Write it to the binary log (see comments of ha_rollback_to_savepoint). */
+ /* Write it to the binary log (see comments of ha_rollback_to_savepoint) */
if (mysql_bin_log.is_open())
{
+#ifdef HAVE_INNOBASE_DB
+ innobase_savepoint(thd,savepoint_name,
+ my_b_tell(&thd->transaction.trans_log));
+#endif
Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE);
if (mysql_bin_log.write(&qinfo))
error= 1;
}
+#ifdef HAVE_INNOBASE_DB
+ else
+ innobase_savepoint(thd,savepoint_name,0);
+#endif
}
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error);
@@ -632,11 +646,13 @@ bool ha_flush_logs()
{
bool result=0;
#ifdef HAVE_BERKELEY_DB
- if (!berkeley_skip && berkeley_flush_logs())
+ if ((have_berkeley_db == SHOW_OPTION_YES) &&
+ berkeley_flush_logs())
result=1;
#endif
#ifdef HAVE_INNOBASE_DB
- if (!innodb_skip && innobase_flush_logs())
+ if ((have_innodb == SHOW_OPTION_YES) &&
+ innobase_flush_logs())
result=1;
#endif
return result;
@@ -649,14 +665,23 @@ bool ha_flush_logs()
int ha_delete_table(enum db_type table_type, const char *path)
{
+ char tmp_path[FN_REFLEN];
handler *file=get_new_handler((TABLE*) 0, table_type);
if (!file)
return ENOENT;
+ if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
+ {
+ /* Ensure that table handler get path in lower case */
+ strmov(tmp_path, path);
+ my_casedn_str(system_charset_info, tmp_path);
+ path= tmp_path;
+ }
int error=file->delete_table(path);
delete file;
return error;
}
+
void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos)
{
switch (pack_length) {
@@ -877,11 +902,11 @@ void handler::update_auto_increment()
table->auto_increment_field_not_null &&
current_thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO)
{
- table->auto_increment_field_not_null= false;
+ table->auto_increment_field_not_null= FALSE;
auto_increment_column_changed=0;
DBUG_VOID_RETURN;
}
- table->auto_increment_field_not_null= false;
+ table->auto_increment_field_not_null= FALSE;
thd=current_thd;
if ((nr=thd->next_insert_id))
thd->next_insert_id=0; // Clear after use
@@ -1136,6 +1161,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
{
int error;
TABLE table;
+ char name_buff[FN_REFLEN];
DBUG_ENTER("ha_create_table");
if (openfrm(name,"",0,(uint) READ_ALL, 0, &table))
@@ -1146,19 +1172,19 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
if (table.file->table_flags() & HA_DROP_BEFORE_CREATE)
table.file->delete_table(name); // Needed for BDB tables
}
+ if (lower_case_table_names == 2 &&
+ !(table.file->table_flags() & HA_FILE_BASED))
+ {
+ /* Ensure that handler gets name in lower case */
+ strmov(name_buff, name);
+ my_casedn_str(system_charset_info, name_buff);
+ name= name_buff;
+ }
+
error=table.file->create(name,&table,create_info);
VOID(closefrm(&table));
if (error)
- {
- if (table.db_type == DB_TYPE_INNODB)
- {
- /* Creation of InnoDB table cannot fail because of an OS error:
- put error as the number */
- my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error);
- }
- else
- my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,my_errno);
- }
+ my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error);
DBUG_RETURN(error != 0);
}