summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc194
1 files changed, 157 insertions, 37 deletions
diff --git a/sql/handler.cc b/sql/handler.cc
index 5185e7f8921..bb5e980f7bf 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -103,7 +103,7 @@ const char *tx_isolation_names[] =
{ "READ-UNCOMMITTED", "READ-COMMITTED", "REPEATABLE-READ", "SERIALIZABLE",
NullS};
TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"",
- tx_isolation_names};
+ tx_isolation_names, NULL};
enum db_type ha_resolve_by_name(const char *name, uint namelen)
{
@@ -157,12 +157,11 @@ enum db_type ha_checktype(enum db_type database_type)
break;
}
- return
- DB_TYPE_UNKNOWN != (enum db_type) thd->variables.table_type ?
- (enum db_type) 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;
+ return ((enum db_type) thd->variables.table_type != DB_TYPE_UNKNOWN ?
+ (enum db_type) thd->variables.table_type :
+ (enum db_type) global_system_variables.table_type !=
+ DB_TYPE_UNKNOWN ?
+ (enum db_type) global_system_variables.table_type : DB_TYPE_MYISAM);
} /* ha_checktype */
@@ -555,7 +554,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans)
query_cache.invalidate(thd->transaction.changed_tables);
#endif /*HAVE_QUERY_CACHE*/
if (error && trans == &thd->transaction.all && mysql_bin_log.is_open())
- sql_print_error("Error: Got error during commit; Binlog is not up to date!");
+ sql_print_error("Got error during commit; Binlog is not up to date!");
thd->variables.tx_isolation=thd->session_tx_isolation;
if (operation_done)
{
@@ -784,10 +783,14 @@ bool ha_flush_logs()
int ha_delete_table(enum db_type table_type, const char *path)
{
+ handler *file;
char tmp_path[FN_REFLEN];
- handler *file=get_new_handler((TABLE*) 0, table_type);
- if (!file)
+
+ /* DB_TYPE_UNKNOWN is used in ALTER TABLE when renaming only .frm files */
+ if (table_type == DB_TYPE_UNKNOWN ||
+ ! (file=get_new_handler((TABLE*) 0, table_type)))
return ENOENT;
+
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
{
/* Ensure that table handler get path in lower case */
@@ -939,23 +942,6 @@ int handler::read_first_row(byte * buf, uint primary_key)
}
-/* Set a timestamp in record */
-
-void handler::update_timestamp(byte *record)
-{
- long skr= (long) table->in_use->query_start();
-#ifdef WORDS_BIGENDIAN
- if (table->db_low_byte_first)
- {
- int4store(record,skr);
- }
- else
-#endif
- longstore(record,skr);
- return;
-}
-
-
/*
Generate the next auto-increment number based on increment and offset
@@ -1240,6 +1226,21 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_NO_REFERENCED_ROW:
textno=ER_NO_REFERENCED_ROW;
break;
+ case HA_ERR_NO_SUCH_TABLE:
+ {
+ /*
+ We have to use path to find database name instead of using
+ table->table_cache_key because if the table didn't exist, then
+ table_cache_key was not set up
+ */
+ char *db;
+ char buff[FN_REFLEN];
+ 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);
+ break;
+ }
default:
{
/* The error was "unknown" to this function.
@@ -1320,14 +1321,15 @@ int handler::rename_table(const char * from, const char * to)
}
/*
- Tell the handler to turn on or off logging to the handler's recovery log
+ Tell the handler to turn on or off transaction in the handler
*/
-int ha_recovery_logging(THD *thd, bool on)
+int ha_enable_transaction(THD *thd, bool on)
{
int error=0;
- DBUG_ENTER("ha_recovery_logging");
+ DBUG_ENTER("ha_enable_transaction");
+ thd->transaction.on= on;
DBUG_RETURN(error);
}
@@ -1385,6 +1387,71 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
DBUG_RETURN(error != 0);
}
+/*
+ Try to discover table from engine and
+ if found, write the frm file to disk.
+
+ RETURN VALUES:
+ 0 : Table existed in engine and created
+ on disk if so requested
+ 1 : Table does not exist
+ >1 : error
+
+*/
+
+int ha_create_table_from_engine(THD* thd,
+ const char *db,
+ const char *name,
+ bool create_if_found)
+{
+ int error;
+ const void *frmblob;
+ uint frmlen;
+ char path[FN_REFLEN];
+ HA_CREATE_INFO create_info;
+ TABLE table;
+ DBUG_ENTER("ha_create_table_from_engine");
+ DBUG_PRINT("enter", ("name '%s'.'%s' create_if_found: %d",
+ db, name, create_if_found));
+
+ bzero((char*) &create_info,sizeof(create_info));
+
+ if ((error= ha_discover(thd, db, name, &frmblob, &frmlen)))
+ DBUG_RETURN(error);
+ /*
+ Table exists in handler
+ frmblob and frmlen are set
+ */
+
+ if (create_if_found)
+ {
+ (void)strxnmov(path,FN_REFLEN,mysql_data_home,"/",db,"/",name,NullS);
+ // Save the frm file
+ if ((error = writefrm(path, frmblob, frmlen)))
+ goto err_end;
+
+ if (openfrm(thd, path,"",0,(uint) READ_ALL, 0, &table))
+ DBUG_RETURN(1);
+
+ update_create_info_from_table(&create_info, &table);
+ create_info.table_options|= HA_CREATE_FROM_ENGINE;
+
+ if (lower_case_table_names == 2 &&
+ !(table.file->table_flags() & HA_FILE_BASED))
+ {
+ /* Ensure that handler gets name in lower case */
+ my_casedn_str(files_charset_info, path);
+ }
+
+ error=table.file->create(path,&table,&create_info);
+ VOID(closefrm(&table));
+ }
+
+err_end:
+ my_free((char*) frmblob, MYF(MY_ALLOW_ZERO_PTR));
+ DBUG_RETURN(error);
+}
+
static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
{
char buff[FN_REFLEN];
@@ -1490,17 +1557,21 @@ int ha_change_key_cache(KEY_CACHE *old_key_cache,
/*
Try to discover one table from handler(s)
+
+ RETURN
+ 0 ok. In this case *frmblob and *frmlen are set
+ 1 error. frmblob and frmlen may not be set
*/
-int ha_discover(const char* dbname, const char* name,
- const void** frmblob, uint* frmlen)
+int ha_discover(THD *thd, const char *db, const char *name,
+ const void **frmblob, uint *frmlen)
{
int error= 1; // Table does not exist in any handler
DBUG_ENTER("ha_discover");
- DBUG_PRINT("enter", ("db: %s, name: %s", dbname, name));
+ DBUG_PRINT("enter", ("db: %s, name: %s", db, name));
#ifdef HAVE_NDBCLUSTER_DB
if (have_ndbcluster == SHOW_OPTION_YES)
- error= ndbcluster_discover(dbname, name, frmblob, frmlen);
+ error= ndbcluster_discover(thd, db, name, frmblob, frmlen);
#endif
if (!error)
statistic_increment(ha_discover_count,&LOCK_status);
@@ -1509,6 +1580,55 @@ int ha_discover(const char* dbname, const char* name,
/*
+ Call this function in order to give the handler the possiblity
+ to ask engine if there are any new tables that should be written to disk
+ or any dropped tables that need to be removed from disk
+*/
+
+int
+ha_find_files(THD *thd,const char *db,const char *path,
+ const char *wild, bool dir, List<char> *files)
+{
+ int error= 0;
+ DBUG_ENTER("ha_find_files");
+ DBUG_PRINT("enter", ("db: %s, path: %s, wild: %s, dir: %d",
+ db, path, wild, dir));
+#ifdef HAVE_NDBCLUSTER_DB
+ if (have_ndbcluster == SHOW_OPTION_YES)
+ error= ndbcluster_find_files(thd, db, path, wild, dir, files);
+#endif
+ DBUG_RETURN(error);
+
+
+}
+
+#ifdef NOT_YET_USED
+
+/*
+ Ask handler if the table exists in engine
+
+ RETURN
+ 0 Table does not exist
+ 1 Table exists
+ # Error code
+
+ */
+int ha_table_exists(THD* thd, const char* db, const char* name)
+{
+ int error= 2;
+ DBUG_ENTER("ha_table_exists");
+ DBUG_PRINT("enter", ("db: %s, name: %s", db, name));
+#ifdef HAVE_NDBCLUSTER_DB
+ if (have_ndbcluster == SHOW_OPTION_YES)
+ error= ndbcluster_table_exists(thd, db, name);
+#endif
+ DBUG_RETURN(error);
+}
+
+#endif
+
+
+/*
Read first row between two ranges.
Store ranges for future calls to read_range_next
@@ -1554,9 +1674,9 @@ int handler::read_range_first(const key_range *start_key,
start_key->length,
start_key->flag);
if (result)
- DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND ||
- result == HA_ERR_END_OF_FILE) ? HA_ERR_END_OF_FILE :
- result);
+ DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND)
+ ? HA_ERR_END_OF_FILE
+ : result);
DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
}