summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc111
1 files changed, 102 insertions, 9 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index bb5e980f7bf..12820a66cb9 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -105,6 +105,9 @@ const char *tx_isolation_names[] =
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
tx_isolation_names, NULL};
+static TYPELIB known_extensions= {0,"known_exts", NULL, NULL};
+uint known_extensions_id= 0;
+
enum db_type ha_resolve_by_name(const char *name, uint namelen)
{
THD *thd= current_thd;
@@ -514,7 +517,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
if ((error=ndbcluster_commit(thd,trans->ndb_tid)))
{
if (error == -1)
- my_error(ER_ERROR_DURING_COMMIT, MYF(0));
+ my_message(ER_ERROR_DURING_COMMIT, ER(ER_ERROR_DURING_COMMIT),
+ MYF(0));
error=1;
}
if (trans == &thd->transaction.all)
@@ -577,13 +581,20 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
if (opt_using_transactions)
{
bool operation_done=0;
+ /*
+ As rollback can be 30 times slower than insert in InnoDB, and user may
+ not know there's rollback (if it's because of a dupl row), better warn.
+ */
+ const char *save_proc_info= thd->proc_info;
+ thd->proc_info= "Rolling back";
#ifdef HAVE_NDBCLUSTER_DB
if (trans->ndb_tid)
{
if ((error=ndbcluster_rollback(thd, trans->ndb_tid)))
{
if (error == -1)
- my_error(ER_ERROR_DURING_ROLLBACK, MYF(0));
+ my_message(ER_ERROR_DURING_ROLLBACK, ER(ER_ERROR_DURING_ROLLBACK),
+ MYF(0));
error=1;
}
trans->ndb_tid = 0;
@@ -648,6 +659,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans)
thd->variables.tx_isolation=thd->session_tx_isolation;
if (operation_done)
statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status);
+ thd->proc_info= save_proc_info;
}
#endif /* USING_TRANSACTIONS */
DBUG_RETURN(error);
@@ -760,6 +772,25 @@ int ha_savepoint(THD *thd, char *savepoint_name)
DBUG_RETURN(error);
}
+
+int ha_start_consistent_snapshot(THD *thd)
+{
+#ifdef HAVE_INNOBASE_DB
+ if ((have_innodb == SHOW_OPTION_YES) &&
+ !innobase_start_trx_and_assign_read_view(thd))
+ return 0;
+#endif
+ /*
+ Same idea as when one wants to CREATE TABLE in one engine which does not
+ exist:
+ */
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "This MySQL server does not support any "
+ "consistent-read capable storage engine");
+ return 0;
+}
+
+
bool ha_flush_logs()
{
bool result=0;
@@ -1169,7 +1200,7 @@ void handler::print_error(int error, myf errflag)
str.length(max_length-4);
str.append("...");
}
- my_error(ER_DUP_ENTRY,MYF(0),str.c_ptr(),key_nr+1);
+ my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1);
DBUG_VOID_RETURN;
}
textno=ER_DUP_KEY;
@@ -1191,7 +1222,7 @@ void handler::print_error(int error, myf errflag)
textno=ER_CRASHED_ON_REPAIR;
break;
case HA_ERR_OUT_OF_MEM:
- my_error(ER_OUT_OF_RESOURCES,errflag);
+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), errflag);
DBUG_VOID_RETURN;
case HA_ERR_WRONG_COMMAND:
textno=ER_ILLEGAL_HA;
@@ -1238,7 +1269,7 @@ void handler::print_error(int error, myf errflag)
uint length=dirname_part(buff,table->path);
buff[length-1]=0;
db=buff+dirname_length(buff);
- my_error(ER_NO_SUCH_TABLE,MYF(0),db,table->table_name);
+ my_error(ER_NO_SUCH_TABLE, MYF(0), db, table->table_name);
break;
}
default:
@@ -1252,16 +1283,16 @@ void handler::print_error(int error, myf errflag)
{
const char* engine= table_type();
if (temporary)
- my_error(ER_GET_TEMPORARY_ERRMSG,MYF(0),error,str.ptr(),engine);
+ my_error(ER_GET_TEMPORARY_ERRMSG, MYF(0), error, str.ptr(), engine);
else
- my_error(ER_GET_ERRMSG,MYF(0),error,str.ptr(),engine);
+ my_error(ER_GET_ERRMSG, MYF(0), error, str.ptr(), engine);
}
else
my_error(ER_GET_ERRNO,errflag,error);
DBUG_VOID_RETURN;
}
}
- my_error(textno,errflag,table->table_name,error);
+ my_error(textno, errflag, table->table_name, error);
DBUG_VOID_RETURN;
}
@@ -1383,7 +1414,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
error=table.file->create(name,&table,create_info);
VOID(closefrm(&table));
if (error)
- my_error(ER_CANT_CREATE_TABLE,MYF(ME_BELL+ME_WAITTANG),name,error);
+ my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name,error);
DBUG_RETURN(error != 0);
}
@@ -1755,3 +1786,65 @@ int handler::index_read_idx(byte * buf, uint index, const byte * key,
error= ha_index_end();
return error;
}
+
+
+/*
+ Returns a list of all known extensions.
+
+ SYNOPSIS
+ ha_known_exts()
+
+ NOTES
+ No mutexes, worst case race is a minor surplus memory allocation
+ We have to recreate the extension map if mysqld is restarted (for example
+ within libmysqld)
+
+ RETURN VALUE
+ pointer pointer to TYPELIB structure
+*/
+
+TYPELIB *ha_known_exts(void)
+{
+ if (!known_extensions.type_names || mysys_usage_id != known_extensions_id)
+ {
+ show_table_type_st *types;
+ List<char> found_exts;
+ List_iterator_fast<char> it(found_exts);
+ const char **ext, *old_ext;
+
+ known_extensions_id= mysys_usage_id;
+ found_exts.push_back((char*) ".db");
+ for (types= sys_table_types; types->type; types++)
+ {
+ if (*types->value == SHOW_OPTION_YES)
+ {
+ handler *file= get_new_handler(0,(enum db_type) types->db_type);
+ for (ext= file->bas_ext(); *ext; ext++)
+ {
+ while ((old_ext= it++))
+ {
+ if (!strcmp(old_ext, *ext))
+ break;
+ }
+ if (!old_ext)
+ found_exts.push_back((char *) *ext);
+
+ it.rewind();
+ }
+ delete file;
+ }
+ }
+ ext= (const char **) my_once_alloc(sizeof(char *)*
+ (found_exts.elements+1),
+ MYF(MY_WME | MY_FAE));
+
+ DBUG_ASSERT(ext);
+ known_extensions.count= found_exts.elements;
+ known_extensions.type_names= ext;
+
+ while ((old_ext= it++))
+ *ext++= old_ext;
+ *ext= 0;
+ }
+ return &known_extensions;
+}