summaryrefslogtreecommitdiff
path: root/sql/handler.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.h')
-rw-r--r--sql/handler.h478
1 files changed, 406 insertions, 72 deletions
diff --git a/sql/handler.h b/sql/handler.h
index d4bb19dd7b2..b61683c59b9 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -44,16 +44,25 @@
#define HA_ADMIN_INVALID -5
#define HA_ADMIN_REJECT -6
#define HA_ADMIN_TRY_ALTER -7
+#define HA_ADMIN_WRONG_CHECKSUM -8
/* Bits in table_flags() to show what database can do */
-#define HA_READ_RND_SAME (1 << 0) /* can switch index during the scan
- with ::rnd_same() - not used yet.
- see mi_rsame/heap_rsame/myrg_rsame */
+
+/*
+ Can switch index during the scan with ::rnd_same() - not used yet.
+ see mi_rsame/heap_rsame/myrg_rsame
+*/
+#define HA_READ_RND_SAME (1 << 0)
#define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
#define HA_REC_NOT_IN_SEQ (1 << 3) /* ha_info don't return recnumber;
It returns a position to ha_r_rnd */
#define HA_CAN_GEOMETRY (1 << 4)
-#define HA_FAST_KEY_READ (1 << 5) /* no need for a record cache in filesort */
+/*
+ Reading keys in random order is as fast as reading keys in sort order
+ (Used in records.cc to decide if we should use a record cache and by
+ filesort to decide if we should sort key + data or key + pointer-to-row
+*/
+#define HA_FAST_KEY_READ (1 << 5)
#define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */
#define HA_DUPP_POS (1 << 8) /* ha_position() gives dup row */
#define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
@@ -61,9 +70,11 @@
#define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */
#define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
#define HA_NOT_EXACT_COUNT (1 << 13)
-#define HA_CAN_INSERT_DELAYED (1 << 14) /* only handlers with table-level locks
- need no special code to support
- INSERT DELAYED */
+/*
+ INSERT_DELAYED only works with handlers that uses MySQL internal table
+ level locks
+*/
+#define HA_CAN_INSERT_DELAYED (1 << 14)
#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
#define HA_NOT_DELETE_WITH_CACHE (1 << 18)
#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
@@ -73,6 +84,9 @@
#define HA_HAS_CHECKSUM (1 << 24)
/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1 << 26)
+#define HA_NO_VARCHAR (1 << 27)
+#define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */
+#define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
#define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
@@ -90,6 +104,13 @@
#define HA_KEY_SWITCH_NONUNIQ_SAVE 2
#define HA_KEY_SWITCH_ALL_SAVE 3
+/*
+ Note: the following includes binlog and closing 0.
+ so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
+ example + csv + heap + blackhole + federated + 0
+ (yes, the sum is deliberately inaccurate)
+*/
+#define MAX_HA 14
/*
Bits in index_ddl_flags(KEY *wanted_index)
@@ -142,13 +163,13 @@
/* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
#define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
-enum db_type
-{
+enum db_type
+{
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
- DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
+ DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
DB_TYPE_FEDERATED_DB,
@@ -164,27 +185,196 @@ struct show_table_type_st {
};
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
- ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED};
+ ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
+ ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT };
/* struct to hold information about the table that should be created */
/* Bits in used_fields */
-#define HA_CREATE_USED_AUTO 1
-#define HA_CREATE_USED_RAID 2
-#define HA_CREATE_USED_UNION 4
-#define HA_CREATE_USED_INSERT_METHOD 8
-#define HA_CREATE_USED_MIN_ROWS 16
-#define HA_CREATE_USED_MAX_ROWS 32
-#define HA_CREATE_USED_AVG_ROW_LENGTH 64
-#define HA_CREATE_USED_PACK_KEYS 128
-#define HA_CREATE_USED_CHARSET 256
-#define HA_CREATE_USED_DEFAULT_CHARSET 512
-
-typedef struct st_thd_trans {
- void *bdb_tid;
- void *innobase_tid;
- bool innodb_active_trans;
- void *ndb_tid;
+#define HA_CREATE_USED_AUTO (1L << 0)
+#define HA_CREATE_USED_RAID (1L << 1)
+#define HA_CREATE_USED_UNION (1L << 2)
+#define HA_CREATE_USED_INSERT_METHOD (1L << 3)
+#define HA_CREATE_USED_MIN_ROWS (1L << 4)
+#define HA_CREATE_USED_MAX_ROWS (1L << 5)
+#define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
+#define HA_CREATE_USED_PACK_KEYS (1L << 7)
+#define HA_CREATE_USED_CHARSET (1L << 8)
+#define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
+#define HA_CREATE_USED_DATADIR (1L << 10)
+#define HA_CREATE_USED_INDEXDIR (1L << 11)
+#define HA_CREATE_USED_ENGINE (1L << 12)
+#define HA_CREATE_USED_CHECKSUM (1L << 13)
+#define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
+#define HA_CREATE_USED_ROW_FORMAT (1L << 15)
+#define HA_CREATE_USED_COMMENT (1L << 16)
+#define HA_CREATE_USED_PASSWORD (1L << 17)
+#define HA_CREATE_USED_CONNECTION (1L << 18)
+
+typedef ulonglong my_xid; // this line is the same as in log_event.h
+#define MYSQL_XID_PREFIX "MySQLXid"
+#define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
+#define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
+#define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
+
+#define XIDDATASIZE 128
+#define MAXGTRIDSIZE 64
+#define MAXBQUALSIZE 64
+
+struct xid_t {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[XIDDATASIZE]; // not \0-terminated !
+
+ bool eq(struct xid_t *xid)
+ { return !memcmp(this, xid, length()); }
+ bool eq(long g, long b, const char *d)
+ { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
+ void set(struct xid_t *xid)
+ { memcpy(this, xid, xid->length()); }
+ void set(long f, const char *g, long gl, const char *b, long bl)
+ {
+ formatID= f;
+ memcpy(data, g, gtrid_length= gl);
+ memcpy(data+gl, b, bqual_length= bl);
+ }
+ void set(ulonglong xid)
+ {
+ my_xid tmp;
+ formatID= 1;
+ set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
+ memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
+ tmp= xid;
+ memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
+ gtrid_length=MYSQL_XID_GTRID_LEN;
+ }
+ void set(long g, long b, const char *d)
+ {
+ formatID= 1;
+ gtrid_length= g;
+ bqual_length= b;
+ memcpy(data, d, g+b);
+ }
+ bool is_null() { return formatID == -1; }
+ void null() { formatID= -1; }
+ my_xid quick_get_my_xid()
+ {
+ my_xid tmp;
+ memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp));
+ return tmp;
+ }
+ my_xid get_my_xid()
+ {
+ return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
+ !memcmp(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)) &&
+ !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
+ quick_get_my_xid() : 0;
+ }
+ uint length()
+ {
+ return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
+ gtrid_length+bqual_length;
+ }
+};
+typedef struct xid_t XID;
+
+/* for recover() handlerton call */
+#define MIN_XID_LIST_SIZE 128
+#ifdef SAFEMALLOC
+#define MAX_XID_LIST_SIZE 256
+#else
+#define MAX_XID_LIST_SIZE (1024*128)
+#endif
+
+/*
+ handlerton is a singleton structure - one instance per storage engine -
+ to provide access to storage engine functionality that works on the
+ "global" level (unlike handler class that works on a per-table basis)
+
+ usually handlerton instance is defined statically in ha_xxx.cc as
+
+ static handlerton { ... } xxx_hton;
+
+ savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
+*/
+typedef struct
+{
+ /*
+ storage engine name as it should be printed to a user
+ */
+ const char *name;
+ /*
+ each storage engine has it's own memory area (actually a pointer)
+ in the thd, for storing per-connection information.
+ It is accessed as
+
+ thd->ha_data[xxx_hton.slot]
+
+ slot number is initialized by MySQL after xxx_init() is called.
+ */
+ uint slot;
+ /*
+ to store per-savepoint data storage engine is provided with an area
+ of a requested size (0 is ok here).
+ savepoint_offset must be initialized statically to the size of
+ the needed memory to store per-savepoint information.
+ After xxx_init it is changed to be an offset to savepoint storage
+ area and need not be used by storage engine.
+ see binlog_hton and binlog_savepoint_set/rollback for an example.
+ */
+ uint savepoint_offset;
+ /*
+ handlerton methods:
+
+ close_connection is only called if
+ thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
+ this storage area - set it to something, so that MySQL would know
+ this storage engine was accessed in this connection
+ */
+ int (*close_connection)(THD *thd);
+ /*
+ sv points to an uninitialized storage area of requested size
+ (see savepoint_offset description)
+ */
+ int (*savepoint_set)(THD *thd, void *sv);
+ /*
+ sv points to a storage area, that was earlier passed
+ to the savepoint_set call
+ */
+ int (*savepoint_rollback)(THD *thd, void *sv);
+ int (*savepoint_release)(THD *thd, void *sv);
+ /*
+ 'all' is true if it's a real commit, that makes persistent changes
+ 'all' is false if it's not in fact a commit but an end of the
+ statement that is part of the transaction.
+ NOTE 'all' is also false in auto-commit mode where 'end of statement'
+ and 'real commit' mean the same event.
+ */
+ int (*commit)(THD *thd, bool all);
+ int (*rollback)(THD *thd, bool all);
+ int (*prepare)(THD *thd, bool all);
+ int (*recover)(XID *xid_list, uint len);
+ int (*commit_by_xid)(XID *xid);
+ int (*rollback_by_xid)(XID *xid);
+ void *(*create_cursor_read_view)();
+ void (*set_cursor_read_view)(void *);
+ void (*close_cursor_read_view)(void *);
+ uint32 flags; /* global handler flags */
+} handlerton;
+
+/* Possible flags of a handlerton */
+#define HTON_NO_FLAGS 0
+#define HTON_CLOSE_CURSORS_AT_COMMIT 1
+
+typedef struct st_thd_trans
+{
+ /* number of entries in the ht[] */
+ uint nht;
+ /* true is not all entries in the ht[] support 2pc */
+ bool no_2pc;
+ /* storage engines that registered themselves for this transaction */
+ handlerton *ht[MAX_HA];
} THD_TRANS;
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
@@ -193,6 +383,7 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
typedef struct st_ha_create_information
{
CHARSET_INFO *table_charset, *default_table_charset;
+ LEX_STRING connect_string;
const char *comment,*password;
const char *data_file_name, *index_file_name;
const char *alias;
@@ -210,6 +401,8 @@ typedef struct st_ha_create_information
uint raid_type,raid_chunks;
uint merge_insert_method;
bool table_existed; /* 1 in create if table existed */
+ bool frm_only; /* 1 if no ha_create_table() */
+ bool varchar; /* 1 if table has a VARCHAR */
} HA_CREATE_INFO;
@@ -217,6 +410,14 @@ typedef struct st_ha_create_information
struct st_table;
typedef struct st_table TABLE;
+struct st_foreign_key_info;
+typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
+
+typedef struct st_savepoint SAVEPOINT;
+extern ulong savepoint_alloc_size;
+
+/* Forward declaration for condition pushdown to storage engine */
+typedef class Item COND;
typedef struct st_ha_check_opt
{
@@ -228,6 +429,21 @@ typedef struct st_ha_check_opt
} HA_CHECK_OPT;
+/*
+ This is a buffer area that the handler can use to store rows.
+ 'end_of_used_area' should be kept updated after calls to
+ read-functions so that other parts of the code can use the
+ remaining area (until next read calls is issued).
+*/
+
+typedef struct st_handler_buffer
+{
+ const byte *buffer; /* Buffer one can start using */
+ const byte *buffer_end; /* End of buffer */
+ byte *end_of_used_area; /* End of area that was used by handler */
+} HANDLER_BUFFER;
+
+
class handler :public Sql_alloc
{
protected:
@@ -246,6 +462,7 @@ class handler :public Sql_alloc
virtual int rnd_end() { return 0; }
public:
+ const handlerton *ht; /* storage engine of this handler */
byte *ref; /* Pointer to current row */
byte *dupp_ref; /* Pointer to dupp row */
ulonglong data_file_length; /* Length off data file */
@@ -262,6 +479,12 @@ public:
time_t check_time;
time_t update_time;
+ /* The following are for read_multi_range */
+ bool multi_range_sorted;
+ KEY_MULTI_RANGE *multi_range_curr;
+ KEY_MULTI_RANGE *multi_range_end;
+ HANDLER_BUFFER *multi_range_buffer;
+
/* The following are for read_range() */
key_range save_end_range, *end_range;
KEY_PART_INFO *range_key_part;
@@ -279,20 +502,22 @@ public:
enum {NONE=0, INDEX, RND} inited;
bool auto_increment_column_changed;
bool implicit_emptied; /* Can be !=0 only if HEAP */
+ const COND *pushed_cond;
-
- handler(TABLE *table_arg) :table(table_arg),
+ handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg),
+ ht(ht_arg),
ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0),
delete_length(0), auto_increment_value(0),
records(0), deleted(0), mean_rec_length(0),
create_time(0), check_time(0), update_time(0),
key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
ref_length(sizeof(my_off_t)), block_size(0),
- raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0)
+ raid_type(0), ft_handler(0), inited(NONE), implicit_emptied(0),
+ pushed_cond(NULL)
{}
virtual ~handler(void) { /* TODO: DBUG_ASSERT(inited == NONE); */ }
int ha_open(const char *name, int mode, int test_if_locked);
- void update_auto_increment();
+ bool update_auto_increment();
virtual void print_error(int error, myf errflag);
virtual bool get_error_message(int error, String *buf);
uint get_dup_key(int error);
@@ -314,33 +539,43 @@ public:
virtual ha_rows estimate_rows_upper_bound()
{ return records+EXTRA_RECORDS; }
+ /*
+ Get the row type from the storage engine. If this method returns
+ ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
+ */
+ virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
+
virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
int ha_index_init(uint idx)
{
+ DBUG_ENTER("ha_index_init");
DBUG_ASSERT(inited==NONE);
inited=INDEX;
- return index_init(idx);
+ DBUG_RETURN(index_init(idx));
}
int ha_index_end()
{
+ DBUG_ENTER("ha_index_end");
DBUG_ASSERT(inited==INDEX);
inited=NONE;
- return index_end();
+ DBUG_RETURN(index_end());
}
int ha_rnd_init(bool scan)
{
+ DBUG_ENTER("ha_rnd_init");
DBUG_ASSERT(inited==NONE || (inited==RND && scan));
inited=RND;
- return rnd_init(scan);
+ DBUG_RETURN(rnd_init(scan));
}
int ha_rnd_end()
{
+ DBUG_ENTER("ha_rnd_end");
DBUG_ASSERT(inited==RND);
inited=NONE;
- return rnd_end();
+ DBUG_RETURN(rnd_end());
}
- /* this is neseccary in many places, e.g. in HANDLER command */
+ /* this is necessary in many places, e.g. in HANDLER command */
int ha_index_or_rnd_end()
{
return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
@@ -369,6 +604,10 @@ public:
virtual int index_next_same(byte *buf, const byte *key, uint keylen);
virtual int index_read_last(byte * buf, const byte * key, uint key_len)
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
+ virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
+ KEY_MULTI_RANGE *ranges, uint range_count,
+ bool sorted, HANDLER_BUFFER *buffer);
+ virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
virtual int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
@@ -400,7 +639,7 @@ public:
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
{ return extra(operation); }
virtual int reset() { return extra(HA_EXTRA_RESET); }
- virtual int external_lock(THD *thd, int lock_type)=0;
+ virtual int external_lock(THD *thd, int lock_type) { return 0; }
virtual void unlock_row() {}
virtual int start_stmt(THD *thd) {return 0;}
/*
@@ -411,7 +650,18 @@ public:
*/
virtual int delete_all_rows()
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
- virtual longlong get_auto_increment();
+ virtual ulonglong get_auto_increment();
+ virtual void restore_auto_increment();
+
+ /*
+ Reset the auto-increment counter to the given value, i.e. the next row
+ inserted will get the given value. This is called e.g. after TRUNCATE
+ is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
+ returned by storage engines that don't support this operation.
+ */
+ virtual int reset_auto_increment(ulonglong value)
+ { return HA_ERR_WRONG_COMMAND; }
+
virtual void update_create_info(HA_CREATE_INFO *create_info) {}
/* admin commands - called from mysql_admin_table */
@@ -455,6 +705,8 @@ public:
/* used in ALTER TABLE; 1 if changing storage engine is allowed */
virtual bool can_switch_engines() { return 1; }
/* used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
+ virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
+ { return 0; }
virtual uint referenced_by_foreign_key() { return 0;}
virtual void init_table_handle_for_HANDLER()
{ return; } /* prepare InnoDB for HANDLER */
@@ -511,10 +763,61 @@ public:
/* Type of table for caching query */
virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
- /*
- Is query with this table cachable (have sense only for ASKTRANSACT
- tables)
- */
+ /* ask handler about permission to cache table when query is to be cached */
+ virtual my_bool register_query_cache_table(THD *thd, char *table_key,
+ uint key_length,
+ qc_engine_callback
+ *engine_callback,
+ ulonglong *engine_data)
+ {
+ *engine_callback= 0;
+ return 1;
+ }
+ /*
+ RETURN
+ true Primary key (if there is one) is clustered key covering all fields
+ false otherwise
+ */
+ virtual bool primary_key_is_clustered() { return FALSE; }
+
+ virtual int cmp_ref(const byte *ref1, const byte *ref2)
+ {
+ return memcmp(ref1, ref2, ref_length);
+ }
+
+ /*
+ Condition pushdown to storage engines
+ */
+
+ /*
+ Push condition down to the table handler.
+ SYNOPSIS
+ cond_push()
+ cond Condition to be pushed. The condition tree must not be
+ modified by the by the caller.
+ RETURN
+ The 'remainder' condition that caller must use to filter out records.
+ NULL means the handler will not return rows that do not match the
+ passed condition.
+ NOTES
+ The pushed conditions form a stack (from which one can remove the
+ last pushed condition using cond_pop).
+ The table handler filters out rows using (pushed_cond1 AND pushed_cond2
+ AND ... AND pushed_condN)
+ or less restrictive condition, depending on handler's capabilities.
+
+ handler->extra(HA_EXTRA_RESET) call empties the condition stack.
+ Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
+ condition stack.
+ */
+ virtual const COND *cond_push(const COND *cond) { return cond; };
+ /*
+ Pop the top condition from the condition stack of the handler instance.
+ SYNOPSIS
+ cond_pop()
+ Pops the top if condition stack, if stack is not empty
+ */
+ virtual void cond_pop() { return; };
};
/* Some extern variables used with handlers */
@@ -523,12 +826,14 @@ extern struct show_table_type_st sys_table_types[];
extern const char *ha_row_type[];
extern TYPELIB tx_isolation_typelib;
extern TYPELIB myisam_stats_method_typelib;
+extern handlerton *handlertons[MAX_HA];
+extern ulong total_ha, total_ha_2pc;
/* Wrapper functions */
-#define ha_commit_stmt(thd) (ha_commit_trans((thd), &((thd)->transaction.stmt)))
-#define ha_rollback_stmt(thd) (ha_rollback_trans((thd), &((thd)->transaction.stmt)))
-#define ha_commit(thd) (ha_commit_trans((thd), &((thd)->transaction.all)))
-#define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all)))
+#define ha_commit_stmt(thd) (ha_commit_trans((thd), FALSE))
+#define ha_rollback_stmt(thd) (ha_rollback_trans((thd), FALSE))
+#define ha_commit(thd) (ha_commit_trans((thd), TRUE))
+#define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
#define ha_supports_generate(T) (T != DB_TYPE_INNODB && \
T != DB_TYPE_BERKELEY_DB && \
@@ -536,46 +841,75 @@ extern TYPELIB myisam_stats_method_typelib;
T != DB_TYPE_FEDERATED_DB && \
T != DB_TYPE_NDBCLUSTER)
-bool ha_caching_allowed(THD* thd, char* table_key,
- uint key_length, uint8 cache_type);
+/* lookups */
enum db_type ha_resolve_by_name(const char *name, uint namelen);
const char *ha_get_storage_engine(enum db_type db_type);
handler *get_new_handler(TABLE *table, enum db_type db_type);
-my_off_t ha_get_ptr(byte *ptr, uint pack_length);
-void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos);
+enum db_type ha_checktype(THD *thd, enum db_type database_type,
+ bool no_substitute, bool report_error);
+
+/* basic stuff */
int ha_init(void);
+TYPELIB *ha_known_exts(void);
int ha_panic(enum ha_panic_function flag);
+int ha_update_statistics();
void ha_close_connection(THD* thd);
-enum db_type ha_checktype(enum db_type database_type);
my_bool ha_storage_engine_is_enabled(enum db_type database_type);
+bool ha_flush_logs(void);
+void ha_drop_database(char* path);
int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
bool update_create_info);
+int ha_delete_table(THD *thd, enum db_type db_type, const char *path,
+ const char *alias, bool generate_warning);
+
+/* discovery */
int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
-int ha_delete_table(enum db_type db_type, const char *path);
-void ha_drop_database(char* path);
+int ha_discover(THD* thd, const char* dbname, const char* name,
+ const void** frmblob, uint* frmlen);
+int ha_find_files(THD *thd,const char *db,const char *path,
+ const char *wild, bool dir,List<char>* files);
+int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
+
+/* key cache */
int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
int ha_resize_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache_param(KEY_CACHE *key_cache);
+int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
int ha_end_key_cache(KEY_CACHE *key_cache);
-int ha_start_stmt(THD *thd);
-int ha_report_binlog_offset_and_commit(THD *thd, char *log_file_name,
- my_off_t end_offset);
-int ha_commit_complete(THD *thd);
+
+/* report to InnoDB that control passes to the client */
int ha_release_temporary_latches(THD *thd);
-int ha_commit_trans(THD *thd, THD_TRANS *trans);
-int ha_rollback_trans(THD *thd, THD_TRANS *trans);
-int ha_rollback_to_savepoint(THD *thd, char *savepoint_name);
-int ha_savepoint(THD *thd, char *savepoint_name);
+
+/* transactions: interface to handlerton functions */
+int ha_start_consistent_snapshot(THD *thd);
+int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
+int ha_commit_one_phase(THD *thd, bool all);
+int ha_rollback_trans(THD *thd, bool all);
+int ha_prepare(THD *thd);
+int ha_recover(HASH *commit_list);
+
+/* transactions: these functions never call handlerton functions directly */
+int ha_commit_trans(THD *thd, bool all);
int ha_autocommit_or_rollback(THD *thd, int error);
-void ha_set_spin_retries(uint retries);
-bool ha_flush_logs(void);
int ha_enable_transaction(THD *thd, bool on);
-int ha_change_key_cache(KEY_CACHE *old_key_cache,
- KEY_CACHE *new_key_cache);
-int ha_discover(THD* thd, const char* dbname, const char* name,
- const void** frmblob, uint* frmlen);
-int ha_find_files(THD *thd,const char *db,const char *path,
- const char *wild, bool dir,List<char>* files);
-int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
-TYPELIB *ha_known_exts(void);
-int ha_start_consistent_snapshot(THD *thd);
+
+/* savepoints */
+int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
+int ha_savepoint(THD *thd, SAVEPOINT *sv);
+int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
+
+/* these are called by storage engines */
+void trans_register_ha(THD *thd, bool all, handlerton *ht);
+
+/*
+ Storage engine has to assume the transaction will end up with 2pc if
+ - there is more than one 2pc-capable storage engine available
+ - in the current transaction 2pc was not disabled yet
+*/
+#define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \
+ !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
+
+/* semi-synchronous replication */
+int ha_repl_report_sent_binlog(THD *thd, char *log_file_name,
+ my_off_t end_offset);
+int ha_repl_report_replication_stop(THD *thd);