handler

handler.h

  1 /*
2 Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; version 2 of
7 the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 /* Definitions for parameters to do with handler-routines */
20
21 #ifdef USE_PRAGMA_INTERFACE
22 #pragma interface /* gcc class implementation */
23 #endif
24
25 #include <ft_global.h>
26 #include <keycache.h>
27
28 #ifndef NO_HASH
29 #define NO_HASH /* Not yet implemented */
30 #endif
31
32 #define USING_TRANSACTIONS
33
34 // the following is for checking tables
35
36 #define HA_ADMIN_ALREADY_DONE 1
37 #define HA_ADMIN_OK 0
38 #define HA_ADMIN_NOT_IMPLEMENTED -1
39 #define HA_ADMIN_FAILED -2
40 #define HA_ADMIN_CORRUPT -3
41 #define HA_ADMIN_INTERNAL_ERROR -4
42 #define HA_ADMIN_INVALID -5
43 #define HA_ADMIN_REJECT -6
44 #define HA_ADMIN_TRY_ALTER -7
45 #define HA_ADMIN_WRONG_CHECKSUM -8
46 #define HA_ADMIN_NOT_BASE_TABLE -9
47 #define HA_ADMIN_NEEDS_UPGRADE -10
48 #define HA_ADMIN_NEEDS_ALTER -11
49 #define HA_ADMIN_NEEDS_CHECK -12
50
51 /* Bits in table_flags() to show what database can do */
52
53 #define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */
54 #define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
55 #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
56 /*
57 The following should be set if the following is not true when scanning
58 a table with rnd_next()
59 - We will see all rows (including deleted ones)
60 - Row positions are 'table->s->db_record_offset' apart
61 If this flag is not set, filesort will do a position() call for each matched
62 row to be able to find the row later.
63 */
64 #define HA_REC_NOT_IN_SEQ (1 << 3)
65 #define HA_CAN_GEOMETRY (1 << 4)
66 /*
67 Reading keys in random order is as fast as reading keys in sort order
68 (Used in records.cc to decide if we should use a record cache and by
69 filesort to decide if we should sort key + data or key + pointer-to-row
70 */
71 #define HA_FAST_KEY_READ (1 << 5)
72 /*
73 Set the following flag if we on delete should force all key to be read
74 and on update read all keys that changes
75 */
76 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
77 #define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */
78 #define HA_DUPLICATE_POS (1 << 8) /* ha_position() gives dup row */
79 #define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
80 #define HA_CAN_INDEX_BLOBS (1 << 10)
81 #define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */
82 #define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
83 #define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */
84 /*
85 INSERT_DELAYED only works with handlers that uses MySQL internal table
86 level locks
87 */
88 #define HA_CAN_INSERT_DELAYED (1 << 14)
89 /*
90 If we get the primary key columns for free when we do an index read
91 It also implies that we have to retrive the primary key when using
92 position() and rnd_pos().
93 */
94 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
95 /*
96 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
97 uses a primary key given by the record argument.
98 Without primary key, we can't call position().
99 If not set, the position is returned as the current rows position
100 regardless of what argument is given.
101 */
102 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
103 #define HA_CAN_RTREEKEYS (1 << 17)
104 #define HA_NOT_DELETE_WITH_CACHE (1 << 18)
105 /*
106 The following is we need to a primary key to delete (and update) a row.
107 If there is no primary key, all columns needs to be read on update and delete
108 */
109 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
110 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
111 #define HA_CAN_FULLTEXT (1 << 21)
112 #define HA_CAN_SQL_HANDLER (1 << 22)
113 #define HA_NO_AUTO_INCREMENT (1 << 23)
114 #define HA_HAS_CHECKSUM (1 << 24)
115 /* Table data are stored in separate files (for lower_case_table_names) */
116 #define HA_FILE_BASED (1 << 26)
117 #define HA_NO_VARCHAR (1 << 27)
118 #define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */
119 #define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
120 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
121 #define HA_NO_COPY_ON_ALTER (LL(1) << 31)
122 #define HA_HAS_RECORDS (LL(1) << 32) /* records() gives exact count*/
123 /* Has it's own method of binlog logging */
124 #define HA_HAS_OWN_BINLOGGING (LL(1) << 33)
125 /*
126 Engine is capable of row-format and statement-format logging,
127 respectively
128 */
129 #define HA_BINLOG_ROW_CAPABLE (LL(1) << 34)
130 #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
131
132 /*
133 Set of all binlog flags. Currently only contain the capabilities
134 flags.
135 */
136 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
137
138 /* bits in index_flags(index_number) for what you can do with index */
139 #define HA_READ_NEXT 1 /* TODO really use this flag */
140 #define HA_READ_PREV 2 /* supports ::index_prev */
141 #define HA_READ_ORDER 4 /* index_next/prev follow sort order */
142 #define HA_READ_RANGE 8 /* can find all records in a range */
143 #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
144 #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
145
146 /*
147 bits in alter_table_flags:
148 */
149 /*
150 These bits are set if different kinds of indexes can be created
151 off-line without re-create of the table (but with a table lock).
152 */
153 #define HA_ONLINE_ADD_INDEX_NO_WRITES (1L << 0) /*add index w/lock*/
154 #define HA_ONLINE_DROP_INDEX_NO_WRITES (1L << 1) /*drop index w/lock*/
155 #define HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES (1L << 2) /*add unique w/lock*/
156 #define HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES (1L << 3) /*drop uniq. w/lock*/
157 #define HA_ONLINE_ADD_PK_INDEX_NO_WRITES (1L << 4) /*add prim. w/lock*/
158 #define HA_ONLINE_DROP_PK_INDEX_NO_WRITES (1L << 5) /*drop prim. w/lock*/
159 /*
160 These are set if different kinds of indexes can be created on-line
161 (without a table lock). If a handler is capable of one or more of
162 these, it should also set the corresponding *_NO_WRITES bit(s).
163 */
164 #define HA_ONLINE_ADD_INDEX (1L << 6) /*add index online*/
165 #define HA_ONLINE_DROP_INDEX (1L << 7) /*drop index online*/
166 #define HA_ONLINE_ADD_UNIQUE_INDEX (1L << 8) /*add unique online*/
167 #define HA_ONLINE_DROP_UNIQUE_INDEX (1L << 9) /*drop uniq. online*/
168 #define HA_ONLINE_ADD_PK_INDEX (1L << 10)/*add prim. online*/
169 #define HA_ONLINE_DROP_PK_INDEX (1L << 11)/*drop prim. online*/
170 /*
171 HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
172 supported at all.
173 HA_FAST_CHANGE_PARTITION means that optimised variants of the changes
174 exists but they are not necessarily done online.
175
176 HA_ONLINE_DOUBLE_WRITE means that the handler supports writing to both
177 the new partition and to the old partitions when updating through the
178 old partitioning schema while performing a change of the partitioning.
179 This means that we can support updating of the table while performing
180 the copy phase of the change. For no lock at all also a double write
181 from new to old must exist and this is not required when this flag is
182 set.
183 This is actually removed even before it was introduced the first time.
184 The new idea is that handlers will handle the lock level already in
185 store_lock for ALTER TABLE partitions.
186
187 HA_PARTITION_ONE_PHASE is a flag that can be set by handlers that take
188 care of changing the partitions online and in one phase. Thus all phases
189 needed to handle the change are implemented inside the storage engine.
190 The storage engine must also support auto-discovery since the frm file
191 is changed as part of the change and this change must be controlled by
192 the storage engine. A typical engine to support this is NDB (through
193 WL #2498).
194 */
195 #define HA_PARTITION_FUNCTION_SUPPORTED (1L << 12)
196 #define HA_FAST_CHANGE_PARTITION (1L << 13)
197 #define HA_PARTITION_ONE_PHASE (1L << 14)
198
199 /*
200 Index scan will not return records in rowid order. Not guaranteed to be
201 set for unordered (e.g. HASH) indexes.
202 */
203 #define HA_KEY_SCAN_NOT_ROR 128
204
205 /* operations for disable/enable indexes */
206 #define HA_KEY_SWITCH_NONUNIQ 0
207 #define HA_KEY_SWITCH_ALL 1
208 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
209 #define HA_KEY_SWITCH_ALL_SAVE 3
210
211 /*
212 Note: the following includes binlog and closing 0.
213 so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
214 example + csv + heap + blackhole + federated + 0
215 (yes, the sum is deliberately inaccurate)
216 TODO remove the limit, use dynarrays
217 */
218 #define MAX_HA 15
219
220 /*
221 Parameters for open() (in register form->filestat)
222 HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
223 */
224
225 #define HA_OPEN_KEYFILE 1
226 #define HA_OPEN_RNDFILE 2
227 #define HA_GET_INDEX 4
228 #define HA_GET_INFO 8 /* do a ha_info() after open */
229 #define HA_READ_ONLY 16 /* File opened as readonly */
230 /* Try readonly if can't open with read and write */
231 #define HA_TRY_READ_ONLY 32
232 #define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */
233 #define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
234 #define HA_BLOCK_LOCK 256 /* unlock when reading some records */
235 #define HA_OPEN_TEMPORARY 512
236
237 /* Some key definitions */
238 #define HA_KEY_NULL_LENGTH 1
239 #define HA_KEY_BLOB_LENGTH 2
240
241 #define HA_LEX_CREATE_TMP_TABLE 1
242 #define HA_LEX_CREATE_IF_NOT_EXISTS 2
243 #define HA_LEX_CREATE_TABLE_LIKE 4
244 #define HA_OPTION_NO_CHECKSUM (1L << 17)
245 #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
246 #define HA_MAX_REC_LENGTH 65535
247
248 /* Table caching type */
249 #define HA_CACHE_TBL_NONTRANSACT 0
250 #define HA_CACHE_TBL_NOCACHE 1
251 #define HA_CACHE_TBL_ASKTRANSACT 2
252 #define HA_CACHE_TBL_TRANSACT 4
253
254 /* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
255 #define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
256
257 /* Flags for method is_fatal_error */
258 #define HA_CHECK_DUP_KEY 1
259 #define HA_CHECK_DUP_UNIQUE 2
260 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
261
262 enum legacy_db_type
263 {
264 DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
265 DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
266 DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
267 DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
268 DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
269 DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
270 DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
271 DB_TYPE_FEDERATED_DB,
272 DB_TYPE_BLACKHOLE_DB,
273 DB_TYPE_PARTITION_DB,
274 DB_TYPE_BINLOG,
275 DB_TYPE_SOLID,
276 DB_TYPE_PBXT,
277 DB_TYPE_TABLE_FUNCTION,
278 DB_TYPE_MEMCACHE,
279 DB_TYPE_FALCON,
280 DB_TYPE_MARIA,
281 DB_TYPE_LILLIAN,
282 DB_TYPE_SPARTAN,
283 DB_TYPE_FIRST_DYNAMIC=42,
284 DB_TYPE_DEFAULT=127 // Must be last
285 };
286
287 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
288 ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
289 ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
290 /** Unused. Reserved for future versions. */
291 ROW_TYPE_PAGE };
292
293 enum enum_binlog_func {
294 BFN_RESET_LOGS= 1,
295 BFN_RESET_SLAVE= 2,
296 BFN_BINLOG_WAIT= 3,
297 BFN_BINLOG_END= 4,
298 BFN_BINLOG_PURGE_FILE= 5
299 };
300
301 enum enum_binlog_command {
302 LOGCOM_CREATE_TABLE,
303 LOGCOM_ALTER_TABLE,
304 LOGCOM_RENAME_TABLE,
305 LOGCOM_DROP_TABLE,
306 LOGCOM_CREATE_DB,
307 LOGCOM_ALTER_DB,
308 LOGCOM_DROP_DB
309 };
310
311 /* struct to hold information about the table that should be created */
312
313 /* Bits in used_fields */
314 #define HA_CREATE_USED_AUTO (1L << 0)
315 #define HA_CREATE_USED_RAID (1L << 1) //RAID is no longer availble
316 #define HA_CREATE_USED_UNION (1L << 2)
317 #define HA_CREATE_USED_INSERT_METHOD (1L << 3)
318 #define HA_CREATE_USED_MIN_ROWS (1L << 4)
319 #define HA_CREATE_USED_MAX_ROWS (1L << 5)
320 #define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
321 #define HA_CREATE_USED_PACK_KEYS (1L << 7)
322 #define HA_CREATE_USED_CHARSET (1L << 8)
323 #define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
324 #define HA_CREATE_USED_DATADIR (1L << 10)
325 #define HA_CREATE_USED_INDEXDIR (1L << 11)
326 #define HA_CREATE_USED_ENGINE (1L << 12)
327 #define HA_CREATE_USED_CHECKSUM (1L << 13)
328 #define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
329 #define HA_CREATE_USED_ROW_FORMAT (1L << 15)
330 #define HA_CREATE_USED_COMMENT (1L << 16)
331 #define HA_CREATE_USED_PASSWORD (1L << 17)
332 #define HA_CREATE_USED_CONNECTION (1L << 18)
333 #define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
334 /** Unused. Reserved for future versions. */
335 #define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
336 /** Unused. Reserved for future versions. */
337 #define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
338
339 typedef ulonglong my_xid; // this line is the same as in log_event.h
340 #define MYSQL_XID_PREFIX "MySQLXid"
341 #define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
342 #define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
343 #define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
344
345 #define XIDDATASIZE MYSQL_XIDDATASIZE
346 #define MAXGTRIDSIZE 64
347 #define MAXBQUALSIZE 64
348
349 #define COMPATIBLE_DATA_YES 0
350 #define COMPATIBLE_DATA_NO 1

  1 /**
2 struct xid_t is binary compatible with the XID structure as
3 in the X/Open CAE Specification, Distributed Transaction Processing:
4 The XA Specification, X/Open Company Ltd., 1991.
5 http://www.opengroup.org/bookstore/catalog/c193.htm
6
7 @see MYSQL_XID in mysql/plugin.h
8 */
9 struct xid_t {
10 long formatID;
11 long gtrid_length;
12 long bqual_length;
13 char data[XIDDATASIZE]; // not \0-terminated !
14
15 xid_t() {} /* Remove gcc warning */
16 bool eq(struct xid_t *xid)
17 { return eq(xid->gtrid_length, xid->bqual_length, xid->data); }
18 bool eq(long g, long b, const char *d)
19 { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
20 void set(struct xid_t *xid)
21 { memcpy(this, xid, xid->length()); }
22 void set(long f, const char *g, long gl, const char *b, long bl)
23 {
24 formatID= f;
25 memcpy(data, g, gtrid_length= gl);
26 memcpy(data+gl, b, bqual_length= bl);
27 }
28 void set(ulonglong xid)
29 {
30 my_xid tmp;
31 formatID= 1;
32 set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
33 memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
34 tmp= xid;
35 memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
36 gtrid_length=MYSQL_XID_GTRID_LEN;
37 }
38 void set(long g, long b, const char *d)
39 {
40 formatID= 1;
41 gtrid_length= g;
42 bqual_length= b;
43 memcpy(data, d, g+b);
44 }
45 bool is_null() { return formatID == -1; }
46 void null() { formatID= -1; }
47 my_xid quick_get_my_xid()
48 {
49 my_xid tmp;
50 memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp));
51 return tmp;
52 }
53 my_xid get_my_xid()
54 {
55 return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
56 !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
57 quick_get_my_xid() : 0;
58 }
59 uint length()
60 {
61 return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
62 gtrid_length+bqual_length;
63 }
64 uchar *key()
65 {
66 return (uchar *)&gtrid_length;
67 }
68 uint key_length()
69 {
70 return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length;
71 }
72 };
73 typedef struct xid_t XID;
74
75 /* for recover() handlerton call */
76 #define MIN_XID_LIST_SIZE 128
77 #ifdef SAFEMALLOC
78 #define MAX_XID_LIST_SIZE 256
79 #else
80 #define MAX_XID_LIST_SIZE (1024*128)
81 #endif
82
83 /*
84 These structures are used to pass information from a set of SQL commands
85 on add/drop/change tablespace definitions to the proper hton.
86 */
87 #define UNDEF_NODEGROUP 65535
88 enum ts_command_type
89 {
90 TS_CMD_NOT_DEFINED = -1,
91 CREATE_TABLESPACE = 0,
92 ALTER_TABLESPACE = 1,
93 CREATE_LOGFILE_GROUP = 2,
94 ALTER_LOGFILE_GROUP = 3,
95 DROP_TABLESPACE = 4,
96 DROP_LOGFILE_GROUP = 5,
97 CHANGE_FILE_TABLESPACE = 6,
98 ALTER_ACCESS_MODE_TABLESPACE = 7
99 };
100
101 enum ts_alter_tablespace_type
102 {
103 TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
104 ALTER_TABLESPACE_ADD_FILE = 1,
105 ALTER_TABLESPACE_DROP_FILE = 2
106 };
107
108 enum tablespace_access_mode
109 {
110 TS_NOT_DEFINED= -1,
111 TS_READ_ONLY = 0,
112 TS_READ_WRITE = 1,
113 TS_NOT_ACCESSIBLE = 2
114 };
115
116 struct handlerton;
117 class st_alter_tablespace : public Sql_alloc
118 {
119 public:
120 const char *tablespace_name;
121 const char *logfile_group_name;
122 enum ts_command_type ts_cmd_type;
123 enum ts_alter_tablespace_type ts_alter_tablespace_type;
124 const char *data_file_name;
125 const char *undo_file_name;
126 const char *redo_file_name;
127 ulonglong extent_size;
128 ulonglong undo_buffer_size;
129 ulonglong redo_buffer_size;
130 ulonglong initial_size;
131 ulonglong autoextend_size;
132 ulonglong max_size;
133 uint nodegroup_id;
134 handlerton *storage_engine;
135 bool wait_until_completed;
136 const char *ts_comment;
137 enum tablespace_access_mode ts_access_mode;
138 st_alter_tablespace()
139 {
140 tablespace_name= NULL;
141 logfile_group_name= "DEFAULT_LG"; //Default log file group
142 ts_cmd_type= TS_CMD_NOT_DEFINED;
143 data_file_name= NULL;
144 undo_file_name= NULL;
145 redo_file_name= NULL;
146 extent_size= 1024*1024; //Default 1 MByte
147 undo_buffer_size= 8*1024*1024; //Default 8 MByte
148 redo_buffer_size= 8*1024*1024; //Default 8 MByte
149 initial_size= 128*1024*1024; //Default 128 MByte
150 autoextend_size= 0; //No autoextension as default
151 max_size= 0; //Max size == initial size => no extension
152 storage_engine= NULL;
153 nodegroup_id= UNDEF_NODEGROUP;
154 wait_until_completed= TRUE;
155 ts_comment= NULL;
156 ts_access_mode= TS_NOT_DEFINED;
157 }
158 };
159
160 /* The handler for a table type. Will be included in the TABLE structure */
161
162 struct st_table;
163 typedef struct st_table TABLE;
164 typedef struct st_table_share TABLE_SHARE;
165 struct st_foreign_key_info;
166 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
167 typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
168 const char *file, uint file_len,
169 const char *status, uint status_len);
170 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
171 extern st_plugin_int *hton2plugin[MAX_HA];
172
173 /* Transaction log maintains type definitions */
174 enum log_status
175 {
176 HA_LOG_STATUS_FREE= 0, /* log is free and can be deleted */
177 HA_LOG_STATUS_INUSE= 1, /* log can't be deleted because it is in use */
178 HA_LOG_STATUS_NOSUCHLOG= 2 /* no such log (can't be returned by
179 the log iterator status) */
180 };
181 /*
182 Function for signaling that the log file changed its state from
183 LOG_STATUS_INUSE to LOG_STATUS_FREE
184
185 Now it do nothing, will be implemented as part of new transaction
186 log management for engines.
187 TODO: implement the function.
188 */
189 void signal_log_not_needed(struct handlerton, char *log_file);
190 /*
191 Data of transaction log iterator.
192 */
193 struct handler_log_file_data {
194 LEX_STRING filename;
195 enum log_status status;
196 };
197
198
199 enum handler_iterator_type
200 {
201 /* request of transaction log iterator */
202 HA_TRANSACTLOG_ITERATOR= 1
203 };
204 enum handler_create_iterator_result
205 {
206 HA_ITERATOR_OK, /* iterator created */
207 HA_ITERATOR_UNSUPPORTED, /* such type of iterator is not supported */
208 HA_ITERATOR_ERROR /* error during iterator creation */
209 };

  1 /*
2 Iterator structure. Can be used by handler/handlerton for different purposes.
3
4 Iterator should be created in the way to point "before" the first object
5 it iterate, so next() call move it to the first object or return !=0 if
6 there is nothing to iterate through.
7 */
8 struct handler_iterator {
9 /*
10 Moves iterator to next record and return 0 or return !=0
11 if there is no records.
12 iterator_object will be filled by this function if next() returns 0.
13 Content of the iterator_object depend on iterator type.
14 */
15 int (*next)(struct handler_iterator *, void *iterator_object);
16 /*
17 Free resources allocated by iterator, after this call iterator
18 is not usable.
19 */
20 void (*destroy)(struct handler_iterator *);
21 /*
22 Pointer to buffer for the iterator to use.
23 Should be allocated by function which created the iterator and
24 destroied by freed by above "destroy" call
25 */
26 void *buffer;
27 };
28
29 /*
30 handlerton is a singleton structure - one instance per storage engine -
31 to provide access to storage engine functionality that works on the
32 "global" level (unlike handler class that works on a per-table basis)
33
34 usually handlerton instance is defined statically in ha_xxx.cc as
35
36 static handlerton { ... } xxx_hton;
37
38 savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
39 */
40 struct handlerton
41 {
42 /*
43 Historical marker for if the engine is available of not
44 */
45 SHOW_COMP_OPTION state;
46
47 /*
48 Historical number used for frm file to determine the correct storage engine.
49 This is going away and new engines will just use "name" for this.
50 */
51 enum legacy_db_type db_type;
52 /*
53 each storage engine has it's own memory area (actually a pointer)
54 in the thd, for storing per-connection information.
55 It is accessed as
56
57 thd->ha_data[xxx_hton.slot]
58
59 slot number is initialized by MySQL after xxx_init() is called.
60 */
61 uint slot;
62 /*
63 to store per-savepoint data storage engine is provided with an area
64 of a requested size (0 is ok here).
65 savepoint_offset must be initialized statically to the size of
66 the needed memory to store per-savepoint information.
67 After xxx_init it is changed to be an offset to savepoint storage
68 area and need not be used by storage engine.
69 see binlog_hton and binlog_savepoint_set/rollback for an example.
70 */
71 uint savepoint_offset;
72 /*
73 handlerton methods:
74
75 close_connection is only called if
76 thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
77 this storage area - set it to something, so that MySQL would know
78 this storage engine was accessed in this connection
79 */
80 int (*close_connection)(handlerton *hton, THD *thd);
81 /*
82 sv points to an uninitialized storage area of requested size
83 (see savepoint_offset description)
84 */
85 int (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
86 /*
87 sv points to a storage area, that was earlier passed
88 to the savepoint_set call
89 */
90 int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
91 int (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
92 /*
93 'all' is true if it's a real commit, that makes persistent changes
94 'all' is false if it's not in fact a commit but an end of the
95 statement that is part of the transaction.
96 NOTE 'all' is also false in auto-commit mode where 'end of statement'
97 and 'real commit' mean the same event.
98 */
99 int (*commit)(handlerton *hton, THD *thd, bool all);
100 int (*rollback)(handlerton *hton, THD *thd, bool all);
101 int (*prepare)(handlerton *hton, THD *thd, bool all);
102 int (*recover)(handlerton *hton, XID *xid_list, uint len);
103 int (*commit_by_xid)(handlerton *hton, XID *xid);
104 int (*rollback_by_xid)(handlerton *hton, XID *xid);
105 void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
106 void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
107 void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
108 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
109 void (*drop_database)(handlerton *hton, char* path);
110 int (*panic)(handlerton *hton, enum ha_panic_function flag);
111 int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
112 bool (*flush_logs)(handlerton *hton);
113 bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
114 uint (*partition_flags)();
115 uint (*alter_table_flags)(uint flags);
116 int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
117 int (*fill_files_table)(handlerton *hton, THD *thd,
118 TABLE_LIST *tables,
119 class Item *cond);
120 uint32 flags; /* global handler flags */
121 /*
122 Those handlerton functions below are properly initialized at handler
123 init.
124 */
125 int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
126 void (*binlog_log_query)(handlerton *hton, THD *thd,
127 enum_binlog_command binlog_command,
128 const char *query, uint query_length,
129 const char *db, const char *table_name);
130 int (*release_temporary_latches)(handlerton *hton, THD *thd);
131
132 /*
133 Get log status.
134 If log_status is null then the handler do not support transaction
135 log information (i.e. log iterator can't be created).
136 (see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE)
137
138 */
139 enum log_status (*get_log_status)(handlerton *hton, char *log);
140
141 /*
142 Iterators creator.
143 Presence of the pointer should be checked before using
144 */
145 enum handler_create_iterator_result
146 (*create_iterator)(handlerton *hton, enum handler_iterator_type type,
147 struct handler_iterator *fill_this_in);
148 int (*discover)(handlerton *hton, THD* thd, const char *db,
149 const char *name,
150 uchar **frmblob,
151 size_t *frmlen);
152 int (*find_files)(handlerton *hton, THD *thd,
153 const char *db,
154 const char *path,
155 const char *wild, bool dir, List<LEX_STRING> *files);
156 int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
157 const char *name);
158 uint32 license; /* Flag for Engine License */
159 void *data; /* Location for engines to keep personal structures */
160 };
161
162
163 /* Possible flags of a handlerton (there can be 32 of them) */
164 #define HTON_NO_FLAGS 0
165 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
166 #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
167 #define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
168 #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
169 #define HTON_FLUSH_AFTER_RENAME (1 << 4)
170 #define HTON_NOT_USER_SELECTABLE (1 << 5)
171 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
172 #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
173 #define HTON_NO_PARTITION (1 << 8) //You can not partition these tables
174
175 class Ha_trx_info;
176
177 struct THD_TRANS
178 {
179 /* true is not all entries in the ht[] support 2pc */
180 bool no_2pc;
181 /* storage engines that registered in this transaction */
182 Ha_trx_info *ha_list;
183 /*
184 The purpose of this flag is to keep track of non-transactional
185 tables that were modified in scope of:
186 - transaction, when the variable is a member of
187 THD::transaction.all
188 - top-level statement or sub-statement, when the variable is a
189 member of THD::transaction.stmt
190 This member has the following life cycle:
191 * stmt.modified_non_trans_table is used to keep track of
192 modified non-transactional tables of top-level statements. At
193 the end of the previous statement and at the beginning of the session,
194 it is reset to FALSE. If such functions
195 as mysql_insert, mysql_update, mysql_delete etc modify a
196 non-transactional table, they set this flag to TRUE. At the
197 end of the statement, the value of stmt.modified_non_trans_table
198 is merged with all.modified_non_trans_table and gets reset.
199 * all.modified_non_trans_table is reset at the end of transaction
200
201 * Since we do not have a dedicated context for execution of a
202 sub-statement, to keep track of non-transactional changes in a
203 sub-statement, we re-use stmt.modified_non_trans_table.
204 At entrance into a sub-statement, a copy of the value of
205 stmt.modified_non_trans_table (containing the changes of the
206 outer statement) is saved on stack. Then
207 stmt.modified_non_trans_table is reset to FALSE and the
208 substatement is executed. Then the new value is merged with the
209 saved value.
210 */
211 bool modified_non_trans_table;
212
213 void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
214 };
215
216
217 /**
218 Either statement transaction or normal transaction - related
219 thread-specific storage engine data.
220
221 If a storage engine participates in a statement/transaction,
222 an instance of this class is present in
223 thd->transaction.{stmt|all}.ha_list. The addition to
224 {stmt|all}.ha_list is made by trans_register_ha().
225
226 When it's time to commit or rollback, each element of ha_list
227 is used to access storage engine's prepare()/commit()/rollback()
228 methods, and also to evaluate if a full two phase commit is
229 necessary.
230
231 @sa General description of transaction handling in handler.cc.
232 */
233
234 class Ha_trx_info
235 {
236 public:
237 /** Register this storage engine in the given transaction context. */
238 void register_ha(THD_TRANS *trans, handlerton *ht_arg)
239 {
240 DBUG_ASSERT(m_flags == 0);
241 DBUG_ASSERT(m_ht == NULL);
242 DBUG_ASSERT(m_next == NULL);
243
244 m_ht= ht_arg;
245 m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */
246
247 m_next= trans->ha_list;
248 trans->ha_list= this;
249 }

  1 /** Clear, prepare for reuse. */
2 void reset()
3 {
4 m_next= NULL;
5 m_ht= NULL;
6 m_flags= 0;
7 }
8
9 Ha_trx_info() { reset(); }
10
11 void set_trx_read_write()
12 {
13 DBUG_ASSERT(is_started());
14 m_flags|= (int) TRX_READ_WRITE;
15 }
16 bool is_trx_read_write() const
17 {
18 DBUG_ASSERT(is_started());
19 return m_flags & (int) TRX_READ_WRITE;
20 }
21 bool is_started() const { return m_ht != NULL; }
22 /** Mark this transaction read-write if the argument is read-write. */
23 void coalesce_trx_with(const Ha_trx_info *stmt_trx)
24 {
25 /*
26 Must be called only after the transaction has been started.
27 Can be called many times, e.g. when we have many
28 read-write statements in a transaction.
29 */
30 DBUG_ASSERT(is_started());
31 if (stmt_trx->is_trx_read_write())
32 set_trx_read_write();
33 }
34 Ha_trx_info *next() const
35 {
36 DBUG_ASSERT(is_started());
37 return m_next;
38 }
39 handlerton *ht() const
40 {
41 DBUG_ASSERT(is_started());
42 return m_ht;
43 }
44 private:
45 enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
46 /** Auxiliary, used for ha_list management */
47 Ha_trx_info *m_next;
48 /**
49 Although a given Ha_trx_info instance is currently always used
50 for the same storage engine, 'ht' is not-NULL only when the
51 corresponding storage is a part of a transaction.
52 */
53 handlerton *m_ht;
54 /**
55 Transaction flags related to this engine.
56 Not-null only if this instance is a part of transaction.
57 May assume a combination of enum values above.
58 */
59 uchar m_flags;
60 };
61
62
63 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
64 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
65
66
67 enum ndb_distribution { ND_KEYHASH= 0, ND_LINHASH= 1 };
68
69
70 typedef struct {
71 ulonglong data_file_length;
72 ulonglong max_data_file_length;
73 ulonglong index_file_length;
74 ulonglong delete_length;
75 ha_rows records;
76 ulong mean_rec_length;
77 ulong create_time;
78 ulong check_time;
79 ulong update_time;
80 ulonglong check_sum;
81 } PARTITION_INFO;
82
83 #define UNDEF_NODEGROUP 65535
84 class Item;
85 struct st_table_log_memory_entry;
86
87 class partition_info;
88
89 struct st_partition_iter;
90 #define NOT_A_PARTITION_ID ((uint32)-1)
91
92 enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
93
94 typedef struct st_ha_create_information
95 {
96 CHARSET_INFO *table_charset, *default_table_charset;
97 LEX_STRING connect_string;
98 const char *password, *tablespace;
99 LEX_STRING comment;
100 const char *data_file_name, *index_file_name;
101 const char *alias;
102 ulonglong max_rows,min_rows;
103 ulonglong auto_increment_value;
104 ulong table_options;
105 ulong avg_row_length;
106 ulong used_fields;
107 ulong key_block_size;
108 SQL_I_List<TABLE_LIST> merge_list;
109 handlerton *db_type;
110 /**
111 Row type of the table definition.
112
113 Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
114 For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
115
116 Can be changed either explicitly by the parser.
117 If nothing speficied inherits the value of the original table (if present).
118 */
119 enum row_type row_type;
120 uint null_bits; /* NULL bits at start of record */
121 uint options; /* OR of HA_CREATE_ options */
122 uint merge_insert_method;
123 uint extra_size; /* length of extra data segment */
124 enum enum_ha_unused unused1;
125 bool table_existed; /* 1 in create if table existed */
126 bool frm_only; /* 1 if no ha_create_table() */
127 bool varchar; /* 1 if table has a VARCHAR */
128 enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
129 enum enum_ha_unused unused2;
130 } HA_CREATE_INFO;
131
132
133 typedef struct st_key_create_information
134 {
135 enum ha_key_alg algorithm;
136 ulong block_size;
137 LEX_STRING parser_name;
138 } KEY_CREATE_INFO;
139
140
141 /*
142 Class for maintaining hooks used inside operations on tables such
143 as: create table functions, delete table functions, and alter table
144 functions.
145
146 Class is using the Template Method pattern to separate the public
147 usage interface from the private inheritance interface. This
148 imposes no overhead, since the public non-virtual function is small
149 enough to be inlined.
150
151 The hooks are usually used for functions that does several things,
152 e.g., create_table_from_items(), which both create a table and lock
153 it.
154 */
155 class TABLEOP_HOOKS
156 {
157 public:
158 TABLEOP_HOOKS() {}
159 virtual ~TABLEOP_HOOKS() {}
160
161 inline void prelock(TABLE **tables, uint count)
162 {
163 do_prelock(tables, count);
164 }
165
166 inline int postlock(TABLE **tables, uint count)
167 {
168 return do_postlock(tables, count);
169 }
170 private:
171 /* Function primitive that is called prior to locking tables */
172 virtual void do_prelock(TABLE **tables, uint count)
173 {
174 /* Default is to do nothing */
175 }
176
177 /**
178 Primitive called after tables are locked.
179
180 If an error is returned, the tables will be unlocked and error
181 handling start.
182
183 @return Error code or zero.
184 */
185 virtual int do_postlock(TABLE **tables, uint count)
186 {
187 return 0; /* Default is to do nothing */
188 }
189 };
190
191 typedef struct st_savepoint SAVEPOINT;
192 extern ulong savepoint_alloc_size;
193 extern KEY_CREATE_INFO default_key_create_info;
194
195 /* Forward declaration for condition pushdown to storage engine */
196 typedef class Item COND;
197
198 typedef struct st_ha_check_opt
199 {
200 st_ha_check_opt() {} /* Remove gcc warning */
201 ulong sort_buffer_size;
202 uint flags; /* isam layer flags (e.g. for myisamchk) */
203 uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
204 KEY_CACHE *key_cache; /* new key cache when changing key cache */
205 void init();
206 } HA_CHECK_OPT;

  1 /*
2 This is a buffer area that the handler can use to store rows.
3 'end_of_used_area' should be kept updated after calls to
4 read-functions so that other parts of the code can use the
5 remaining area (until next read calls is issued).
6 */
7
8 typedef struct st_handler_buffer
9 {
10 const uchar *buffer; /* Buffer one can start using */
11 const uchar *buffer_end; /* End of buffer */
12 uchar *end_of_used_area; /* End of area that was used by handler */
13 } HANDLER_BUFFER;
14
15 typedef struct system_status_var SSV;
16
17 class ha_statistics
18 {
19 public:
20 ulonglong data_file_length; /* Length off data file */
21 ulonglong max_data_file_length; /* Length off data file */
22 ulonglong index_file_length;
23 ulonglong max_index_file_length;
24 ulonglong delete_length; /* Free bytes */
25 ulonglong auto_increment_value;
26 /*
27 The number of records in the table.
28 0 - means the table has exactly 0 rows
29 other - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
30 the value is the exact number of records in the table
31 else
32 it is an estimate
33 */
34 ha_rows records;
35 ha_rows deleted; /* Deleted records */
36 ulong mean_rec_length; /* physical reclength */
37 ulong create_time; /* When table was created */
38 ulong check_time;
39 ulong update_time;
40 uint block_size; /* index block size */
41
42 ha_statistics():
43 data_file_length(0), max_data_file_length(0),
44 index_file_length(0), delete_length(0), auto_increment_value(0),
45 records(0), deleted(0), mean_rec_length(0), create_time(0),
46 check_time(0), update_time(0), block_size(0)
47 {}
48 };
49
50 uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
51 /*
52 bitmap with first N+1 bits set
53 (keypart_map for a key prefix of [0..N] keyparts)
54 */
55 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
56 /*
57 bitmap with first N bits set
58 (keypart_map for a key prefix of [0..N-1] keyparts)
59 */
60 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
61
62 /**
63 The handler class is the interface for dynamically loadable
64 storage engines. Do not add ifdefs and take care when adding or
65 changing virtual functions to avoid vtable confusion
66 */
67
68 class handler :public Sql_alloc
69 {
70 public:
71 typedef ulonglong Table_flags;
72 protected:
73 struct st_table_share *table_share; /* The table definition */
74 struct st_table *table; /* The current open table */
75 Table_flags cached_table_flags; /* Set on init() and open() */
76
77 ha_rows estimation_rows_to_insert;
78 public:
79 handlerton *ht; /* storage engine of this handler */
80 uchar *ref; /* Pointer to current row */
81 uchar *dup_ref; /* Pointer to duplicate row */
82
83 ha_statistics stats;
84
85 /** The following are for read_multi_range */
86 bool multi_range_sorted;
87 KEY_MULTI_RANGE *multi_range_curr;
88 KEY_MULTI_RANGE *multi_range_end;
89 HANDLER_BUFFER *multi_range_buffer;
90
91 /** The following are for read_range() */
92 key_range save_end_range, *end_range;
93 KEY_PART_INFO *range_key_part;
94 int key_compare_result_on_equal;
95 bool eq_range;
96
97 uint errkey; /* Last dup key */
98 uint key_used_on_scan;
99 uint active_index;
100 /** Length of ref (1-8 or the clustered key length) */
101 uint ref_length;
102 FT_INFO *ft_handler;
103 enum {NONE=0, INDEX, RND} inited;
104 bool locked;
105 bool implicit_emptied; /* Can be !=0 only if HEAP */
106 const COND *pushed_cond;
107 /**
108 next_insert_id is the next value which should be inserted into the
109 auto_increment column: in a inserting-multi-row statement (like INSERT
110 SELECT), for the first row where the autoinc value is not specified by the
111 statement, get_auto_increment() called and asked to generate a value,
112 next_insert_id is set to the next value, then for all other rows
113 next_insert_id is used (and increased each time) without calling
114 get_auto_increment().
115 */
116 ulonglong next_insert_id;
117 /**
118 insert id for the current row (*autogenerated*; if not
119 autogenerated, it's 0).
120 At first successful insertion, this variable is stored into
121 THD::first_successful_insert_id_in_cur_stmt.
122 */
123 ulonglong insert_id_for_cur_row;
124 /**
125 Interval returned by get_auto_increment() and being consumed by the
126 inserter.
127 */
128 Discrete_interval auto_inc_interval_for_cur_row;
129 /**
130 Number of reserved auto-increment intervals. Serves as a heuristic
131 when we have no estimation of how many records the statement will insert:
132 the more intervals we have reserved, the bigger the next one. Reset in
133 handler::ha_release_auto_increment().
134 */
135 uint auto_inc_intervals_count;
136
137 handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
138 :table_share(share_arg), table(0),
139 estimation_rows_to_insert(0), ht(ht_arg),
140 ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
141 ref_length(sizeof(my_off_t)),
142 ft_handler(0), inited(NONE),
143 locked(FALSE), implicit_emptied(0),
144 pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
145 auto_inc_intervals_count(0)
146 {}
147 virtual ~handler(void)
148 {
149 DBUG_ASSERT(locked == FALSE);
150 /* TODO: DBUG_ASSERT(inited == NONE); */
151 }
152 virtual handler *clone(const char *name, MEM_ROOT *mem_root);
153 /** This is called after create to allow us to set up cached variables */
154 void init()
155 {
156 cached_table_flags= table_flags();
157 }
158 /* ha_ methods: pubilc wrappers for private virtual API */
159
160 int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
161 int ha_index_init(uint idx, bool sorted)
162 {
163 int result;
164 DBUG_ENTER("ha_index_init");
165 DBUG_ASSERT(inited==NONE);
166 if (!(result= index_init(idx, sorted)))
167 inited=INDEX;
168 DBUG_RETURN(result);
169 }
170 int ha_index_end()
171 {
172 DBUG_ENTER("ha_index_end");
173 DBUG_ASSERT(inited==INDEX);
174 inited=NONE;
175 DBUG_RETURN(index_end());
176 }
177 int ha_rnd_init(bool scan)
178 {
179 int result;
180 DBUG_ENTER("ha_rnd_init");
181 DBUG_ASSERT(inited==NONE || (inited==RND && scan));
182 inited= (result= rnd_init(scan)) ? NONE: RND;
183 DBUG_RETURN(result);
184 }
185 int ha_rnd_end()
186 {
187 DBUG_ENTER("ha_rnd_end");
188 DBUG_ASSERT(inited==RND);
189 inited=NONE;
190 DBUG_RETURN(rnd_end());
191 }
192 int ha_reset();
193 /* this is necessary in many places, e.g. in HANDLER command */
194 int ha_index_or_rnd_end()
195 {
196 return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
197 }
198 /**
199 The cached_table_flags is set at ha_open and ha_external_lock
200 */
201 Table_flags ha_table_flags() const { return cached_table_flags; }
202 /**
203 These functions represent the public interface to *users* of the
204 handler class, hence they are *not* virtual. For the inheritance
205 interface, see the (private) functions write_row(), update_row(),
206 and delete_row() below.
207 */
208 int ha_external_lock(THD *thd, int lock_type);
209 int ha_write_row(uchar * buf);
210 int ha_update_row(const uchar * old_data, uchar * new_data);
211 int ha_delete_row(const uchar * buf);
212 void ha_release_auto_increment();
213
214 int check_collation_compatibility();
215 int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
216 /** to be actually called to get 'check()' functionality*/
217 int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
218 int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
219 void ha_start_bulk_insert(ha_rows rows)
220 {
221 estimation_rows_to_insert= rows;
222 start_bulk_insert(rows);
223 }
224 int ha_end_bulk_insert()
225 {
226 estimation_rows_to_insert= 0;
227 return end_bulk_insert();
228 }
229 int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
230 uint *dup_key_found);
231 int ha_delete_all_rows();
232 int ha_reset_auto_increment(ulonglong value);
233 int ha_backup(THD* thd, HA_CHECK_OPT* check_opt);
234 int ha_restore(THD* thd, HA_CHECK_OPT* check_opt);
235 int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
236 int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
237 bool ha_check_and_repair(THD *thd);
238 int ha_disable_indexes(uint mode);
239 int ha_enable_indexes(uint mode);
240 int ha_discard_or_import_tablespace(my_bool discard);
241 void ha_prepare_for_alter();
242 int ha_rename_table(const char *from, const char *to);
243 int ha_delete_table(const char *name);
244 void ha_drop_table(const char *name);
245
246 int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
247
248 int ha_create_handler_files(const char *name, const char *old_name,
249 int action_flag, HA_CREATE_INFO *info);
250
251 int ha_change_partitions(HA_CREATE_INFO *create_info,
252 const char *path,
253 ulonglong * const copied,
254 ulonglong * const deleted,
255 const uchar *pack_frm_data,
256 size_t pack_frm_len);
257 int ha_drop_partitions(const char *path);
258 int ha_rename_partitions(const char *path);
259
260 void adjust_next_insert_id_after_explicit_value(ulonglong nr);
261 int update_auto_increment();
262 void print_keydup_error(uint key_nr, const char *msg);
263 virtual void print_error(int error, myf errflag);
264 virtual bool get_error_message(int error, String *buf);
265 uint get_dup_key(int error);
266 virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
267 {
268 table= table_arg;
269 table_share= share;
270 }
271 virtual double scan_time()
272 { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
273 virtual double read_time(uint index, uint ranges, ha_rows rows)
274 { return rows2double(ranges+rows); }
275 virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
276 bool has_transactions()
277 { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
278 virtual uint extra_rec_buf_length() const { return 0; }
279
280 /**
281 This method is used to analyse the error to see whether the error
282 is ignorable or not, certain handlers can have more error that are
283 ignorable than others. E.g. the partition handler can get inserts
284 into a range where there is no partition and this is an ignorable
285 error.
286 HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
287 same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
288 a slightly different error message.
289 */
290 virtual bool is_fatal_error(int error, uint flags)
291 {
292 if (!error ||
293 ((flags & HA_CHECK_DUP_KEY) &&
294 (error == HA_ERR_FOUND_DUPP_KEY ||
295 error == HA_ERR_FOUND_DUPP_UNIQUE)))
296 return FALSE;
297 return TRUE;
298 }
299
300 /**
301 Number of rows in table. It will only be called if
302 (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
303 */
304 virtual ha_rows records() { return stats.records; }
305 /**
306 Return upper bound of current number of records in the table
307 (max. of how many records one will retrieve when doing a full table scan)
308 If upper bound is not known, HA_POS_ERROR should be returned as a max
309 possible upper bound.
310 */
311 virtual ha_rows estimate_rows_upper_bound()
312 { return stats.records+EXTRA_RECORDS; }
313
314 /**
315 Get the row type from the storage engine. If this method returns
316 ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
317 */
318 virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
319
320 virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
321
322
323 /**
324 Signal that the table->read_set and table->write_set table maps changed
325 The handler is allowed to set additional bits in the above map in this
326 call. Normally the handler should ignore all calls until we have done
327 a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
328 as there may be several calls to this routine.
329 */
330 virtual void column_bitmaps_signal();
331 uint get_index(void) const { return active_index; }
332 virtual int close(void)=0;
333
334 /**
335 @retval 0 Bulk update used by handler
336 @retval 1 Bulk update not used, normal operation used
337 */
338 virtual bool start_bulk_update() { return 1; }
339 /**
340 @retval 0 Bulk delete used by handler
341 @retval 1 Bulk delete not used, normal operation used
342 */
343 virtual bool start_bulk_delete() { return 1; }
344 /**
345 After this call all outstanding updates must be performed. The number
346 of duplicate key errors are reported in the duplicate key parameter.
347 It is allowed to continue to the batched update after this call, the
348 handler has to wait until end_bulk_update with changing state.
349
350 @param dup_key_found Number of duplicate keys found
351
352 @retval 0 Success
353 @retval >0 Error code
354 */
355 virtual int exec_bulk_update(uint *dup_key_found)
356 {
357 DBUG_ASSERT(FALSE);
358 return HA_ERR_WRONG_COMMAND;
359 }
360 /**
361 Perform any needed clean-up, no outstanding updates are there at the
362 moment.
363 */
364 virtual void end_bulk_update() { return; }
365 /**
366 Execute all outstanding deletes and close down the bulk delete.
367
368 @retval 0 Success
369 @retval >0 Error code
370 */
371 virtual int end_bulk_delete()
372 {
373 DBUG_ASSERT(FALSE);
374 return HA_ERR_WRONG_COMMAND;
375 }
376 /**
377 @brief
378 Positions an index cursor to the index specified in the handle. Fetches the
379 row if available. If the key value is null, begin at the first key of the
380 index.
381 */
382 virtual int index_read_map(uchar * buf, const uchar * key,
383 key_part_map keypart_map,
384 enum ha_rkey_function find_flag)
385 {
386 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
387 return index_read(buf, key, key_len, find_flag);
388 }
389 /**
390 @brief
391 Positions an index cursor to the index specified in the handle. Fetches the
392 row if available. If the key value is null, begin at the first key of the
393 index.
394 */
395 virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
396 key_part_map keypart_map,
397 enum ha_rkey_function find_flag);
398 virtual int index_next(uchar * buf)
399 { return HA_ERR_WRONG_COMMAND; }
400 virtual int index_prev(uchar * buf)
401 { return HA_ERR_WRONG_COMMAND; }
402 virtual int index_first(uchar * buf)
403 { return HA_ERR_WRONG_COMMAND; }
404 virtual int index_last(uchar * buf)
405 { return HA_ERR_WRONG_COMMAND; }
406 virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);

  1 /**
2 @brief
3 The following functions works like index_read, but it find the last
4 row with the current key value or prefix.
5 */
6 virtual int index_read_last_map(uchar * buf, const uchar * key,
7 key_part_map keypart_map)
8 {
9 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
10 return index_read_last(buf, key, key_len);
11 }
12 virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
13 KEY_MULTI_RANGE *ranges, uint range_count,
14 bool sorted, HANDLER_BUFFER *buffer);
15 virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
16 virtual int read_range_first(const key_range *start_key,
17 const key_range *end_key,
18 bool eq_range, bool sorted);
19 virtual int read_range_next();
20 int compare_key(key_range *range);
21 virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
22 void ft_end() { ft_handler=NULL; }
23 virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
24 { return NULL; }
25 virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
26 virtual int rnd_next(uchar *buf)=0;
27 virtual int rnd_pos(uchar * buf, uchar *pos)=0;
28 /**
29 This function only works for handlers having
30 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
31 It will return the row with the PK given in the record argument.
32 */
33 virtual int rnd_pos_by_record(uchar *record)
34 {
35 position(record);
36 return rnd_pos(record, ref);
37 }
38 virtual int read_first_row(uchar *buf, uint primary_key);
39 /**
40 The following function is only needed for tables that may be temporary
41 tables during joins.
42 */
43 virtual int restart_rnd_next(uchar *buf, uchar *pos)
44 { return HA_ERR_WRONG_COMMAND; }
45 virtual int rnd_same(uchar *buf, uint inx)
46 { return HA_ERR_WRONG_COMMAND; }
47 virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
48 { return (ha_rows) 10; }
49 /*
50 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
51 (reference to the row, aka position, with the primary key given in
52 the record).
53 Otherwise it set ref to the current row.
54 */
55 virtual void position(const uchar *record)=0;
56 virtual int info(uint)=0; // see my_base.h for full description
57 virtual void get_dynamic_partition_info(PARTITION_INFO *stat_info,
58 uint part_id);
59 virtual int extra(enum ha_extra_function operation)
60 { return 0; }
61 virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
62 { return extra(operation); }
63
64 /**
65 In an UPDATE or DELETE, if the row under the cursor was locked by another
66 transaction, and the engine used an optimistic read of the last
67 committed row value under the cursor, then the engine returns 1 from this
68 function. MySQL must NOT try to update this optimistic value. If the
69 optimistic value does not match the WHERE condition, MySQL can decide to
70 skip over this row. Currently only works for InnoDB. This can be used to
71 avoid unnecessary lock waits.
72
73 If this method returns nonzero, it will also signal the storage
74 engine that the next read will be a locking re-read of the row.
75 */
76 virtual bool was_semi_consistent_read() { return 0; }
77 /**
78 Tell the engine whether it should avoid unnecessary lock waits.
79 If yes, in an UPDATE or DELETE, if the row under the cursor was locked
80 by another transaction, the engine may try an optimistic read of
81 the last committed row value under the cursor.
82 */
83 virtual void try_semi_consistent_read(bool) {}
84 virtual void unlock_row() {}
85 virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
86 virtual void get_auto_increment(ulonglong offset, ulonglong increment,
87 ulonglong nb_desired_values,
88 ulonglong *first_value,
89 ulonglong *nb_reserved_values);
90 void set_next_insert_id(ulonglong id)
91 {
92 DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
93 next_insert_id= id;
94 }
95 void restore_auto_increment(ulonglong prev_insert_id)
96 {
97 /*
98 Insertion of a row failed, re-use the lastly generated auto_increment
99 id, for the next row. This is achieved by resetting next_insert_id to
100 what it was before the failed insertion (that old value is provided by
101 the caller). If that value was 0, it was the first row of the INSERT;
102 then if insert_id_for_cur_row contains 0 it means no id was generated
103 for this first row, so no id was generated since the INSERT started, so
104 we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
105 is the generated id of the first and failed row, so we use it.
106 */
107 next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
108 insert_id_for_cur_row;
109 }
110
111 virtual void update_create_info(HA_CREATE_INFO *create_info) {}
112 int check_old_types();
113 virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
114 { return HA_ADMIN_NOT_IMPLEMENTED; }
115 virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
116 { return HA_ADMIN_NOT_IMPLEMENTED; }
117 /* end of the list of admin commands */
118
119 virtual int dump(THD* thd, int fd = -1) { return HA_ERR_WRONG_COMMAND; }
120 virtual int indexes_are_disabled(void) {return 0;}
121 virtual int net_read_dump(NET* net) { return HA_ERR_WRONG_COMMAND; }
122 virtual char *update_table_comment(const char * comment)
123 { return (char*) comment;}
124 virtual void append_create_info(String *packet) {}
125 /**
126 If index == MAX_KEY then a check for table is made and if index <
127 MAX_KEY then a check is made if the table has foreign keys and if
128 a foreign key uses this index (and thus the index cannot be dropped).
129
130 @param index Index to check if foreign key uses it
131
132 @retval TRUE Foreign key defined on table or index
133 @retval FALSE No foreign key defined
134 */
135 virtual bool is_fk_defined_on_table_or_index(uint index)
136 { return FALSE; }
137 virtual char* get_foreign_key_create_info()
138 { return(NULL);} /* gets foreign key create string from InnoDB */
139 virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
140 { return(NULL);} /* gets tablespace name from handler */
141 /** used in ALTER TABLE; 1 if changing storage engine is allowed */
142 virtual bool can_switch_engines() { return 1; }
143 /** used in REPLACE; is > 0 if table is referred by a FOREIGN KEY */
144 virtual int get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
145 { return 0; }
146 virtual uint referenced_by_foreign_key() { return 0;}
147 virtual void init_table_handle_for_HANDLER()
148 { return; } /* prepare InnoDB for HANDLER */
149 virtual void free_foreign_key_create_info(char* str) {}
150 /** The following can be called without an open handler */
151 virtual const char *table_type() const =0;

  1 /**
2 If frm_error() is called then we will use this to find out what file
3 extentions exist for the storage engine. This is also used by the default
4 rename_table and delete_table method in handler.cc.
5
6 For engines that have two file name extentions (separate meta/index file
7 and data file), the order of elements is relevant. First element of engine
8 file name extentions array should be meta/index file extention. Second
9 element - data file extention. This order is assumed by
10 prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
11 */
12 virtual const char **bas_ext() const =0;
13
14 virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;}
15 virtual void set_auto_partitions(partition_info *part_info) { return; }
16 virtual bool get_no_parts(const char *name,
17 uint *no_parts)
18 {
19 *no_parts= 0;
20 return 0;
21 }
22 virtual void set_part_info(partition_info *part_info) {return;}
23
24 virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
25
26 virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys)
27 { return (HA_ERR_WRONG_COMMAND); }
28 virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
29 uint num_of_keys)
30 { return (HA_ERR_WRONG_COMMAND); }
31 virtual int final_drop_index(TABLE *table_arg)
32 { return (HA_ERR_WRONG_COMMAND); }
33
34 uint max_record_length() const
35 { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
36 uint max_keys() const
37 { return min(MAX_KEY, max_supported_keys()); }
38 uint max_key_parts() const
39 { return min(MAX_REF_PARTS, max_supported_key_parts()); }
40 uint max_key_length() const
41 { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
42 uint max_key_part_length() const
43 { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
44
45 virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
46 virtual uint max_supported_keys() const { return 0; }
47 virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
48 virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
49 virtual uint max_supported_key_part_length() const { return 255; }
50 virtual uint min_record_length(uint options) const { return 1; }
51
52 virtual bool low_byte_first() const { return 1; }
53 virtual uint checksum() const { return 0; }
54 virtual bool is_crashed() const { return 0; }
55 virtual bool auto_repair() const { return 0; }
56
57
58 #define CHF_CREATE_FLAG 0
59 #define CHF_DELETE_FLAG 1
60 #define CHF_RENAME_FLAG 2
61 #define CHF_INDEX_FLAG 3
62
63
64 /**
65 @note lock_count() can return > 1 if the table is MERGE or partitioned.
66 */
67 virtual uint lock_count(void) const { return 1; }
68 /**
69 Is not invoked for non-transactional temporary tables.
70
71 @note store_lock() can return more than one lock if the table is MERGE
72 or partitioned.
73
74 @note that one can NOT rely on table->in_use in store_lock(). It may
75 refer to a different thread if called from mysql_lock_abort_for_thread().
76
77 @note If the table is MERGE, store_lock() can return less locks
78 than lock_count() claimed. This can happen when the MERGE children
79 are not attached when this is called from another thread.
80 */
81 virtual THR_LOCK_DATA **store_lock(THD *thd,
82 THR_LOCK_DATA **to,
83 enum thr_lock_type lock_type)=0;
84
85 /** Type of table for caching query */
86 virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
87
88
89 /**
90 @brief Register a named table with a call back function to the query cache.
91
92 @param thd The thread handle
93 @param table_key A pointer to the table name in the table cache
94 @param key_length The length of the table name
95 @param[out] engine_callback The pointer to the storage engine call back
96 function
97 @param[out] engine_data Storage engine specific data which could be
98 anything
99
100 This method offers the storage engine, the possibility to store a reference
101 to a table name which is going to be used with query cache.
102 The method is called each time a statement is written to the cache and can
103 be used to verify if a specific statement is cachable. It also offers
104 the possibility to register a generic (but static) call back function which
105 is called each time a statement is matched against the query cache.
106
107 @note If engine_data supplied with this function is different from
108 engine_data supplied with the callback function, and the callback returns
109 FALSE, a table invalidation on the current table will occur.
110
111 @return Upon success the engine_callback will point to the storage engine
112 call back function, if any, and engine_data will point to any storage
113 engine data used in the specific implementation.
114 @retval TRUE Success
115 @retval FALSE The specified table or current statement should not be
116 cached
117 */
118
119 virtual my_bool register_query_cache_table(THD *thd, char *table_key,
120 uint key_length,
121 qc_engine_callback
122 *engine_callback,
123 ulonglong *engine_data)
124 {
125 *engine_callback= 0;
126 return TRUE;
127 }
128
129
130 /*
131 @retval TRUE Primary key (if there is one) is clustered
132 key covering all fields
133 @retval FALSE otherwise
134 */
135 virtual bool primary_key_is_clustered() { return FALSE; }
136 virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
137 {
138 return memcmp(ref1, ref2, ref_length);
139 }

  1 /*
2 Condition pushdown to storage engines
3 */
4
5 /**
6 Push condition down to the table handler.
7
8 @param cond Condition to be pushed. The condition tree must not be
9 modified by the by the caller.
10
11 @return
12 The 'remainder' condition that caller must use to filter out records.
13 NULL means the handler will not return rows that do not match the
14 passed condition.
15
16 @note
17 The pushed conditions form a stack (from which one can remove the
18 last pushed condition using cond_pop).
19 The table handler filters out rows using (pushed_cond1 AND pushed_cond2
20 AND ... AND pushed_condN)
21 or less restrictive condition, depending on handler's capabilities.
22
23 handler->ha_reset() call empties the condition stack.
24 Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
25 condition stack.
26 */
27 virtual const COND *cond_push(const COND *cond) { return cond; };
28 /**
29 Pop the top condition from the condition stack of the handler instance.
30
31 Pops the top if condition stack, if stack is not empty.
32 */
33 virtual void cond_pop() { return; };
34 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
35 uint table_changes)
36 { return COMPATIBLE_DATA_NO; }
37
38 /**
39 use_hidden_primary_key() is called in case of an update/delete when
40 (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
41 but we don't have a primary key
42 */
43 virtual void use_hidden_primary_key();
44 virtual uint alter_table_flags(uint flags)
45 {
46 if (ht->alter_table_flags)
47 return ht->alter_table_flags(flags);
48 return 0;
49 }
50
51 protected:
52 /* Service methods for use by storage engines. */
53 void ha_statistic_increment(ulong SSV::*offset) const;
54 void **ha_data(THD *) const;
55 THD *ha_thd(void) const;
56
57 /**
58 Default rename_table() and delete_table() rename/delete files with a
59 given name and extensions from bas_ext().
60
61 These methods can be overridden, but their default implementation
62 provide useful functionality.
63 */
64 virtual int rename_table(const char *from, const char *to);
65 /**
66 Delete a table in the engine. Called for base as well as temporary
67 tables.
68 */
69 virtual int delete_table(const char *name);
70 private:
71 /* Private helpers */
72 inline void mark_trx_read_write();
73 private:
74 /*
75 Low-level primitives for storage engines. These should be
76 overridden by the storage engine class. To call these methods, use
77 the corresponding 'ha_*' method above.
78 */
79
80 virtual int open(const char *name, int mode, uint test_if_locked)=0;
81 virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
82 virtual int index_end() { active_index= MAX_KEY; return 0; }
83 /**
84 rnd_init() can be called two times without rnd_end() in between
85 (it only makes sense if scan=1).
86 then the second call should prepare for the new table scan (e.g
87 if rnd_init allocates the cursor, second call should position it
88 to the start of the table, no need to deallocate and allocate it again
89 */
90 virtual int rnd_init(bool scan)= 0;
91 virtual int rnd_end() { return 0; }
92 virtual int write_row(uchar *buf __attribute__((unused)))
93 {
94 return HA_ERR_WRONG_COMMAND;
95 }
96
97 virtual int update_row(const uchar *old_data __attribute__((unused)),
98 uchar *new_data __attribute__((unused)))
99 {
100 return HA_ERR_WRONG_COMMAND;
101 }
102
103 virtual int delete_row(const uchar *buf __attribute__((unused)))
104 {
105 return HA_ERR_WRONG_COMMAND;
106 }
107 /**
108 Reset state of file to after 'open'.
109 This function is called after every statement for all tables used
110 by that statement.
111 */
112 virtual int reset() { return 0; }
113 virtual Table_flags table_flags(void) const= 0;
114 /**
115 Is not invoked for non-transactional temporary tables.
116
117 Tells the storage engine that we intend to read or write data
118 from the table. This call is prefixed with a call to handler::store_lock()
119 and is invoked only for those handler instances that stored the lock.
120
121 Calls to rnd_init/index_init are prefixed with this call. When table
122 IO is complete, we call external_lock(F_UNLCK).
123 A storage engine writer should expect that each call to
124 ::external_lock(F_[RD|WR]LOCK is followed by a call to
125 ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
126
127 The name and signature originate from the first implementation
128 in MyISAM, which would call fcntl to set/clear an advisory
129 lock on the data file in this method.
130
131 @param lock_type F_RDLCK, F_WRLCK, F_UNLCK
132
133 @return non-0 in case of failure, 0 in case of success.
134 When lock_type is F_UNLCK, the return value is ignored.
135 */
136 virtual int external_lock(THD *thd __attribute__((unused)),
137 int lock_type __attribute__((unused)))
138 {
139 return 0;
140 }
141 virtual void release_auto_increment() { return; };
142 /** admin commands - called from mysql_admin_table */
143 virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
144 { return 0; }
145 virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
146 { return HA_ADMIN_NOT_IMPLEMENTED; }
147
148 /**
149 In this method check_opt can be modified
150 to specify CHECK option to use to call check()
151 upon the table.
152 */
153 virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
154 { return HA_ADMIN_NOT_IMPLEMENTED; }
155 virtual void start_bulk_insert(ha_rows rows) {}
156 virtual int end_bulk_insert() { return 0; }
157 virtual int index_read(uchar * buf, const uchar * key, uint key_len,
158 enum ha_rkey_function find_flag)
159 { return HA_ERR_WRONG_COMMAND; }
160 virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
161 { return (my_errno= HA_ERR_WRONG_COMMAND); }

  1 /**
2 This method is similar to update_row, however the handler doesn't need
3 to execute the updates at this point in time. The handler can be certain
4 that another call to bulk_update_row will occur OR a call to
5 exec_bulk_update before the set of updates in this query is concluded.
6
7 @param old_data Old record
8 @param new_data New record
9 @param dup_key_found Number of duplicate keys found
10
11 @retval 0 Bulk delete used by handler
12 @retval 1 Bulk delete not used, normal operation used
13 */
14 virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
15 uint *dup_key_found)
16 {
17 DBUG_ASSERT(FALSE);
18 return HA_ERR_WRONG_COMMAND;
19 }
20 /**
21 This is called to delete all rows in a table
22 If the handler don't support this, then this function will
23 return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
24 by one. It should reset auto_increment if
25 thd->lex->sql_command == SQLCOM_TRUNCATE.
26 */
27 virtual int delete_all_rows()
28 { return (my_errno=HA_ERR_WRONG_COMMAND); }
29 /**
30 Reset the auto-increment counter to the given value, i.e. the next row
31 inserted will get the given value. This is called e.g. after TRUNCATE
32 is emulated by doing a 'DELETE FROM t'. HA_ERR_WRONG_COMMAND is
33 returned by storage engines that don't support this operation.
34 */
35 virtual int reset_auto_increment(ulonglong value)
36 { return HA_ERR_WRONG_COMMAND; }
37 virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
38 { return HA_ADMIN_NOT_IMPLEMENTED; }
39 /**
40 Restore assumes .frm file must exist, and that generate_table() has been
41 called; It will just copy the data file and run repair.
42 */
43 virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
44 { return HA_ADMIN_NOT_IMPLEMENTED; }
45 virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
46 { return HA_ADMIN_NOT_IMPLEMENTED; }
47 virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
48 { return HA_ADMIN_NOT_IMPLEMENTED; }
49 virtual bool check_and_repair(THD *thd) { return TRUE; }
50 virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
51 virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
52 virtual int discard_or_import_tablespace(my_bool discard)
53 { return (my_errno=HA_ERR_WRONG_COMMAND); }
54 virtual void prepare_for_alter() { return; }
55 virtual void drop_table(const char *name);
56 virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
57
58 virtual int create_handler_files(const char *name, const char *old_name,
59 int action_flag, HA_CREATE_INFO *info)
60 { return FALSE; }
61
62 virtual int change_partitions(HA_CREATE_INFO *create_info,
63 const char *path,
64 ulonglong * const copied,
65 ulonglong * const deleted,
66 const uchar *pack_frm_data,
67 size_t pack_frm_len)
68 { return HA_ERR_WRONG_COMMAND; }
69 virtual int drop_partitions(const char *path)
70 { return HA_ERR_WRONG_COMMAND; }
71 virtual int rename_partitions(const char *path)
72 { return HA_ERR_WRONG_COMMAND; }
73 };
74
75
76 /* Some extern variables used with handlers */
77
78 extern const char *ha_row_type[];
79 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
80 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
81 extern TYPELIB tx_isolation_typelib;
82 extern TYPELIB myisam_stats_method_typelib;
83 extern ulong total_ha, total_ha_2pc;
84
85 /* Wrapper functions */
86 #define ha_commit(thd) (ha_commit_trans((thd), TRUE))
87 #define ha_rollback(thd) (ha_rollback_trans((thd), TRUE))
88
89 /* lookups */
90 handlerton *ha_default_handlerton(THD *thd);
91 plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
92 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
93 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
94 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
95 handlerton *db_type);
96 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
97 bool no_substitute, bool report_error);
98
99
100 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
101 {
102 return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
103 }
104
105 static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
106 {
107 return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
108 }
109
110 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
111 {
112 return db_type == NULL ? FALSE : test(db_type->flags & flag);
113 }
114
115 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
116 {
117 return (db_type && db_type->create) ?
118 (db_type->state == SHOW_OPTION_YES) : FALSE;
119 }
120
121 /* basic stuff */
122 int ha_init_errors(void);
123 int ha_init(void);
124 int ha_end(void);
125 int ha_initialize_handlerton(st_plugin_int *plugin);
126 int ha_finalize_handlerton(st_plugin_int *plugin);
127
128 TYPELIB *ha_known_exts(void);
129 int ha_panic(enum ha_panic_function flag);
130 void ha_close_connection(THD* thd);
131 bool ha_flush_logs(handlerton *db_type);
132 void ha_drop_database(char* path);
133 int ha_create_table(THD *thd, const char *path,
134 const char *db, const char *table_name,
135 HA_CREATE_INFO *create_info,
136 bool update_create_info);
137 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
138 const char *db, const char *alias, bool generate_warning);
139
140 /* statistics and info */
141 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
142
143 /* discovery */
144 int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
145 int ha_discover(THD* thd, const char* dbname, const char* name,
146 uchar** frmblob, size_t* frmlen);
147 int ha_find_files(THD *thd,const char *db,const char *path,
148 const char *wild, bool dir, List<LEX_STRING>* files);
149 int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
150
151 /* key cache */
152 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
153 int ha_resize_key_cache(KEY_CACHE *key_cache);
154 int ha_change_key_cache_param(KEY_CACHE *key_cache);
155 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
156 int ha_end_key_cache(KEY_CACHE *key_cache);
157
158 /* report to InnoDB that control passes to the client */
159 int ha_release_temporary_latches(THD *thd);
160
161 /* transactions: interface to handlerton functions */
162 int ha_start_consistent_snapshot(THD *thd);
163 int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
164 int ha_commit_one_phase(THD *thd, bool all);
165 int ha_rollback_trans(THD *thd, bool all);
166 int ha_prepare(THD *thd);
167 int ha_recover(HASH *commit_list);
168
169 /* transactions: these functions never call handlerton functions directly */
170 int ha_commit_trans(THD *thd, bool all);
171 int ha_autocommit_or_rollback(THD *thd, int error);
172 int ha_enable_transaction(THD *thd, bool on);
173
174 /* savepoints */
175 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
176 int ha_savepoint(THD *thd, SAVEPOINT *sv);
177 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
178
179 /* these are called by storage engines */
180 void trans_register_ha(THD *thd, bool all, handlerton *ht);
181
182 /*
183 Storage engine has to assume the transaction will end up with 2pc if
184 - there is more than one 2pc-capable storage engine available
185 - in the current transaction 2pc was not disabled yet
186 */
187 #define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \
188 !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
189
190 #ifdef HAVE_NDB_BINLOG
191 int ha_reset_logs(THD *thd);
192 int ha_binlog_index_purge_file(THD *thd, const char *file);
193 void ha_reset_slave(THD *thd);
194 void ha_binlog_log_query(THD *thd, handlerton *db_type,
195 enum_binlog_command binlog_command,
196 const char *query, uint query_length,
197 const char *db, const char *table_name);
198 void ha_binlog_wait(THD *thd);
199 int ha_binlog_end(THD *thd);
200 #else
201 #define ha_reset_logs(a) do {} while (0)
202 #define ha_binlog_index_purge_file(a,b) do {} while (0)
203 #define ha_reset_slave(a) do {} while (0)
204 #define ha_binlog_log_query(a,b,c,d,e,f,g) do {} while (0)
205 #define ha_binlog_wait(a) do {} while (0)
206 #define ha_binlog_end(a) do {} while (0)
207 #endif













posted on 2012-03-28 10:09  bigshuai  阅读(490)  评论(0编辑  收藏  举报