1 #ifndef HANDLER_INCLUDED
2 #define HANDLER_INCLUDED
3
4 /*
5 Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of
10 the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /* Definitions for parameters to do with handler-routines */
23
24 #ifdef USE_PRAGMA_INTERFACE
25 #pragma interface /* gcc class implementation */
26 #endif
27
28 #include "sql_const.h"
29 #include "mysqld.h" /* server_id */
30 #include "sql_plugin.h" /* plugin_ref, st_plugin_int, plugin */
31 #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA */
32 #include "sql_cache.h"
33 #include "structs.h" /* SHOW_COMP_OPTION */
34
35 #include <my_compare.h>
36 #include <ft_global.h>
37 #include <keycache.h>
38
39 // the following is for checking tables
40
41 #define HA_ADMIN_ALREADY_DONE 1
42 #define HA_ADMIN_OK 0
43 #define HA_ADMIN_NOT_IMPLEMENTED -1
44 #define HA_ADMIN_FAILED -2
45 #define HA_ADMIN_CORRUPT -3
46 #define HA_ADMIN_INTERNAL_ERROR -4
47 #define HA_ADMIN_INVALID -5
48 #define HA_ADMIN_REJECT -6
49 #define HA_ADMIN_TRY_ALTER -7
50 #define HA_ADMIN_WRONG_CHECKSUM -8
51 #define HA_ADMIN_NOT_BASE_TABLE -9
52 #define HA_ADMIN_NEEDS_UPGRADE -10
53 #define HA_ADMIN_NEEDS_ALTER -11
54 #define HA_ADMIN_NEEDS_CHECK -12
55
56 /* Bits in table_flags() to show what database can do */
57
58 #define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */
59 #define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
60 #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
61 /*
62 The following should be set if the following is not true when scanning
63 a table with rnd_next()
64 - We will see all rows (including deleted ones)
65 - Row positions are 'table->s->db_record_offset' apart
66 If this flag is not set, filesort will do a position() call for each matched
67 row to be able to find the row later.
68 */
69 #define HA_REC_NOT_IN_SEQ (1 << 3)
70 #define HA_CAN_GEOMETRY (1 << 4)
71 /*
72 Reading keys in random order is as fast as reading keys in sort order
73 (Used in records.cc to decide if we should use a record cache and by
74 filesort to decide if we should sort key + data or key + pointer-to-row
75 */
76 #define HA_FAST_KEY_READ (1 << 5)
77 /*
78 Set the following flag if we on delete should force all key to be read
79 and on update read all keys that changes
80 */
81 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
82 #define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */
83 #define HA_DUPLICATE_POS (1 << 8) /* ha_position() gives dup row */
84 #define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
85 #define HA_CAN_INDEX_BLOBS (1 << 10)
86 #define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */
87 #define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
88 #define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */
89 /*
90 INSERT_DELAYED only works with handlers that uses MySQL internal table
91 level locks
92 */
93 #define HA_CAN_INSERT_DELAYED (1 << 14)
94 /*
95 If we get the primary key columns for free when we do an index read
96 It also implies that we have to retrive the primary key when using
97 position() and rnd_pos().
98 */
99 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
100 /*
101 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
102 uses a primary key given by the record argument.
103 Without primary key, we can't call position().
104 If not set, the position is returned as the current rows position
105 regardless of what argument is given.
106 */
107 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
108 #define HA_CAN_RTREEKEYS (1 << 17)
109 #define HA_NOT_DELETE_WITH_CACHE (1 << 18)
110 /*
111 The following is we need to a primary key to delete (and update) a row.
112 If there is no primary key, all columns needs to be read on update and delete
113 */
114 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
115 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
116 #define HA_CAN_FULLTEXT (1 << 21)
117 #define HA_CAN_SQL_HANDLER (1 << 22)
118 #define HA_NO_AUTO_INCREMENT (1 << 23)
119 #define HA_HAS_CHECKSUM (1 << 24)
120 /* Table data are stored in separate files (for lower_case_table_names) */
121 #define HA_FILE_BASED (1 << 26)
122 #define HA_NO_VARCHAR (1 << 27)
123 #define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */
124 #define HA_NEED_READ_RANGE_BUFFER (1 << 29) /* for read_multi_range */
125 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
126 #define HA_NO_COPY_ON_ALTER (LL(1) << 31)
127 #define HA_HAS_RECORDS (LL(1) << 32) /* records() gives exact count*/
128 /* Has it's own method of binlog logging */
129 #define HA_HAS_OWN_BINLOGGING (LL(1) << 33)
130 /*
131 Engine is capable of row-format and statement-format logging,
132 respectively
133 */
134 #define HA_BINLOG_ROW_CAPABLE (LL(1) << 34)
135 #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35)
136 /*
137 When a multiple key conflict happens in a REPLACE command mysql
138 expects the conflicts to be reported in the ascending order of
139 key names.
140
141 For e.g.
142
143 CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
144 NULL, INDEX(c));
145
146 REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
147
148 MySQL expects the conflict with 'a' to be reported before the conflict with
149 'b'.
150
151 If the underlying storage engine does not report the conflicting keys in
152 ascending order, it causes unexpected errors when the REPLACE command is
153 executed.
154
155 This flag helps the underlying SE to inform the server that the keys are not
156 ordered.
157 */
158 #define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36)
159 /*
160 Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
161 incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
162 will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
163 */
164 #define HA_CAN_REPAIR (LL(1) << 37)
165
166 /*
167 Set of all binlog flags. Currently only contain the capabilities
168 flags.
169 */
170 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
171
172 /* bits in index_flags(index_number) for what you can do with index */
173 #define HA_READ_NEXT 1 /* TODO really use this flag */
174 #define HA_READ_PREV 2 /* supports ::index_prev */
175 #define HA_READ_ORDER 4 /* index_next/prev follow sort order */
176 #define HA_READ_RANGE 8 /* can find all records in a range */
177 #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
178 #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
179
180 /*
181 bits in alter_table_flags:
182 */
183 /*
184 These bits are set if different kinds of indexes can be created or dropped
185 in-place without re-creating the table using a temporary table.
186 NO_READ_WRITE indicates that the handler needs concurrent reads and writes
187 of table data to be blocked.
188 Partitioning needs both ADD and DROP to be supported by its underlying
189 handlers, due to error handling, see bug#57778.
190 */
191 #define HA_INPLACE_ADD_INDEX_NO_READ_WRITE (1L << 0)
192 #define HA_INPLACE_DROP_INDEX_NO_READ_WRITE (1L << 1)
193 #define HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE (1L << 2)
194 #define HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE (1L << 3)
195 #define HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE (1L << 4)
196 #define HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE (1L << 5)
197 /*
198 These are set if different kinds of indexes can be created or dropped
199 in-place while still allowing concurrent reads (but not writes) of table
200 data. If a handler is capable of one or more of these, it should also set
201 the corresponding *_NO_READ_WRITE bit(s).
202 */
203 #define HA_INPLACE_ADD_INDEX_NO_WRITE (1L << 6)
204 #define HA_INPLACE_DROP_INDEX_NO_WRITE (1L << 7)
205 #define HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE (1L << 8)
206 #define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE (1L << 9)
207 #define HA_INPLACE_ADD_PK_INDEX_NO_WRITE (1L << 10)
208 #define HA_INPLACE_DROP_PK_INDEX_NO_WRITE (1L << 11)
209 /*
210 HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
211 supported at all.
212 HA_FAST_CHANGE_PARTITION means that optimised variants of the changes
213 exists but they are not necessarily done online.
214
215 HA_ONLINE_DOUBLE_WRITE means that the handler supports writing to both
216 the new partition and to the old partitions when updating through the
217 old partitioning schema while performing a change of the partitioning.
218 This means that we can support updating of the table while performing
219 the copy phase of the change. For no lock at all also a double write
220 from new to old must exist and this is not required when this flag is
221 set.
222 This is actually removed even before it was introduced the first time.
223 The new idea is that handlers will handle the lock level already in
224 store_lock for ALTER TABLE partitions.
225
226 HA_PARTITION_ONE_PHASE is a flag that can be set by handlers that take
227 care of changing the partitions online and in one phase. Thus all phases
228 needed to handle the change are implemented inside the storage engine.
229 The storage engine must also support auto-discovery since the frm file
230 is changed as part of the change and this change must be controlled by
231 the storage engine. A typical engine to support this is NDB (through
232 WL #2498).
233 */
234 #define HA_PARTITION_FUNCTION_SUPPORTED (1L << 12)
235 #define HA_FAST_CHANGE_PARTITION (1L << 13)
236 #define HA_PARTITION_ONE_PHASE (1L << 14)
237
238 /*
239 Index scan will not return records in rowid order. Not guaranteed to be
240 set for unordered (e.g. HASH) indexes.
241 */
242 #define HA_KEY_SCAN_NOT_ROR 128
243
244 /* operations for disable/enable indexes */
245 #define HA_KEY_SWITCH_NONUNIQ 0
246 #define HA_KEY_SWITCH_ALL 1
247 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
248 #define HA_KEY_SWITCH_ALL_SAVE 3
249
250 /*
251 Note: the following includes binlog and closing 0.
252 so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
253 example + csv + heap + blackhole + federated + 0
254 (yes, the sum is deliberately inaccurate)
255 TODO remove the limit, use dynarrays
256 */
257 #define MAX_HA 15
258
259 /*
260 Use this instead of 0 as the initial value for the slot number of
261 handlerton, so that we can distinguish uninitialized slot number
262 from slot 0.
263 */
264 #define HA_SLOT_UNDEF ((uint)-1)
265
266 /*
267 Parameters for open() (in register form->filestat)
268 HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
269 */
270
271 #define HA_OPEN_KEYFILE 1
272 #define HA_OPEN_RNDFILE 2
273 #define HA_GET_INDEX 4
274 #define HA_GET_INFO 8 /* do a ha_info() after open */
275 #define HA_READ_ONLY 16 /* File opened as readonly */
276 /* Try readonly if can't open with read and write */
277 #define HA_TRY_READ_ONLY 32
278 #define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */
279 #define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
280 #define HA_BLOCK_LOCK 256 /* unlock when reading some records */
281 #define HA_OPEN_TEMPORARY 512
282
283 /* Some key definitions */
284 #define HA_KEY_NULL_LENGTH 1
285 #define HA_KEY_BLOB_LENGTH 2
286
287 #define HA_LEX_CREATE_TMP_TABLE 1
288 #define HA_LEX_CREATE_IF_NOT_EXISTS 2
289 #define HA_LEX_CREATE_TABLE_LIKE 4
290 #define HA_OPTION_NO_CHECKSUM (1L << 17)
291 #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
292 #define HA_MAX_REC_LENGTH 65535
293
294 /* Table caching type */
295 #define HA_CACHE_TBL_NONTRANSACT 0
296 #define HA_CACHE_TBL_NOCACHE 1
297 #define HA_CACHE_TBL_ASKTRANSACT 2
298 #define HA_CACHE_TBL_TRANSACT 4
299
300 /* Options of START TRANSACTION statement (and later of SET TRANSACTION stmt) */
301 #define MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT 1
302
303 /* Flags for method is_fatal_error */
304 #define HA_CHECK_DUP_KEY 1
305 #define HA_CHECK_DUP_UNIQUE 2
306 #define HA_CHECK_FK_ERROR 4
307 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
308
309 enum legacy_db_type
310 {
311 DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
312 DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
313 DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
314 DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
315 DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
316 DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
317 DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
318 DB_TYPE_FEDERATED_DB,
319 DB_TYPE_BLACKHOLE_DB,
320 DB_TYPE_PARTITION_DB,
321 DB_TYPE_BINLOG,
322 DB_TYPE_SOLID,
323 DB_TYPE_PBXT,
324 DB_TYPE_TABLE_FUNCTION,
325 DB_TYPE_MEMCACHE,
326 DB_TYPE_FALCON,
327 DB_TYPE_MARIA,
328 /** Performance schema engine. */
329 DB_TYPE_PERFORMANCE_SCHEMA,
330 DB_TYPE_FIRST_DYNAMIC=42,
331 DB_TYPE_DEFAULT=127 // Must be last
332 };
333
334 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
335 ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
336 ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
337 /** Unused. Reserved for future versions. */
338 ROW_TYPE_PAGE };
339
340 enum enum_binlog_func {
341 BFN_RESET_LOGS= 1,
342 BFN_RESET_SLAVE= 2,
343 BFN_BINLOG_WAIT= 3,
344 BFN_BINLOG_END= 4,
345 BFN_BINLOG_PURGE_FILE= 5
346 };
347
348 enum enum_binlog_command {
349 LOGCOM_CREATE_TABLE,
350 LOGCOM_ALTER_TABLE,
351 LOGCOM_RENAME_TABLE,
352 LOGCOM_DROP_TABLE,
353 LOGCOM_CREATE_DB,
354 LOGCOM_ALTER_DB,
355 LOGCOM_DROP_DB
356 };
357
358 /* struct to hold information about the table that should be created */
359
360 /* Bits in used_fields */
361 #define HA_CREATE_USED_AUTO (1L << 0)
362 #define HA_CREATE_USED_RAID (1L << 1) //RAID is no longer availble
363 #define HA_CREATE_USED_UNION (1L << 2)
364 #define HA_CREATE_USED_INSERT_METHOD (1L << 3)
365 #define HA_CREATE_USED_MIN_ROWS (1L << 4)
366 #define HA_CREATE_USED_MAX_ROWS (1L << 5)
367 #define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
368 #define HA_CREATE_USED_PACK_KEYS (1L << 7)
369 #define HA_CREATE_USED_CHARSET (1L << 8)
370 #define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
371 #define HA_CREATE_USED_DATADIR (1L << 10)
372 #define HA_CREATE_USED_INDEXDIR (1L << 11)
373 #define HA_CREATE_USED_ENGINE (1L << 12)
374 #define HA_CREATE_USED_CHECKSUM (1L << 13)
375 #define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
376 #define HA_CREATE_USED_ROW_FORMAT (1L << 15)
377 #define HA_CREATE_USED_COMMENT (1L << 16)
378 #define HA_CREATE_USED_PASSWORD (1L << 17)
379 #define HA_CREATE_USED_CONNECTION (1L << 18)
380 #define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
381 /** Unused. Reserved for future versions. */
382 #define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
383 /** Unused. Reserved for future versions. */
384 #define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
385
386
387 /*
388 This is master database for most of system tables. However there
389 can be other databases which can hold system tables. Respective
390 storage engines define their own system database names.
391 */
392 extern const char *mysqld_system_database;
393
394 /*
395 Structure to hold list of system_database.system_table.
396 This is used at both mysqld and storage engine layer.
397 */
398 struct st_system_tablename
399 {
400 const char *db;
401 const char *tablename;
402 };
403
404
405 typedef ulonglong my_xid; // this line is the same as in log_event.h
406 #define MYSQL_XID_PREFIX "MySQLXid"
407 #define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
408 #define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
409 #define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
410
411 #define XIDDATASIZE MYSQL_XIDDATASIZE
412 #define MAXGTRIDSIZE 64
413 #define MAXBQUALSIZE 64
414
415 #define COMPATIBLE_DATA_YES 0
416 #define COMPATIBLE_DATA_NO 1
417
418 /**
419 struct xid_t is binary compatible with the XID structure as
420 in the X/Open CAE Specification, Distributed Transaction Processing:
421 The XA Specification, X/Open Company Ltd., 1991.
422 http://www.opengroup.org/bookstore/catalog/c193.htm
423
424 @see MYSQL_XID in mysql/plugin.h
425 */
426 struct xid_t {
427 long formatID;
428 long gtrid_length;
429 long bqual_length;
430 char data[XIDDATASIZE]; // not \0-terminated !
431
xid_txid_t432 xid_t() {} /* Remove gcc warning */
eqxid_t433 bool eq(struct xid_t *xid)
434 { return eq(xid->gtrid_length, xid->bqual_length, xid->data); }
eqxid_t435 bool eq(long g, long b, const char *d)
436 { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
setxid_t437 void set(struct xid_t *xid)
438 { memcpy(this, xid, xid->length()); }
setxid_t439 void set(long f, const char *g, long gl, const char *b, long bl)
440 {
441 formatID= f;
442 memcpy(data, g, gtrid_length= gl);
443 memcpy(data+gl, b, bqual_length= bl);
444 }
setxid_t445 void set(ulonglong xid)
446 {
447 my_xid tmp;
448 formatID= 1;
449 set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
450 memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
451 tmp= xid;
452 memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
453 gtrid_length=MYSQL_XID_GTRID_LEN;
454 }
setxid_t455 void set(long g, long b, const char *d)
456 {
457 formatID= 1;
458 gtrid_length= g;
459 bqual_length= b;
460 memcpy(data, d, g+b);
461 }
is_nullxid_t462 bool is_null() { return formatID == -1; }
nullxid_t463 void null() { formatID= -1; }
quick_get_my_xidxid_t464 my_xid quick_get_my_xid()
465 {
466 my_xid tmp;
467 memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp));
468 return tmp;
469 }
get_my_xidxid_t470 my_xid get_my_xid()
471 {
472 return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
473 !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
474 quick_get_my_xid() : 0;
475 }
lengthxid_t476 uint length()
477 {
478 return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+
479 gtrid_length+bqual_length;
480 }
keyxid_t481 uchar *key()
482 {
483 return (uchar *)>rid_length;
484 }
key_lengthxid_t485 uint key_length()
486 {
487 return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length;
488 }
489 };
490 typedef struct xid_t XID;
491
492 /* for recover() handlerton call */
493 #define MIN_XID_LIST_SIZE 128
494 #define MAX_XID_LIST_SIZE (1024*128)
495
496 /*
497 These structures are used to pass information from a set of SQL commands
498 on add/drop/change tablespace definitions to the proper hton.
499 */
500 #define UNDEF_NODEGROUP 65535
501 enum ts_command_type
502 {
503 TS_CMD_NOT_DEFINED = -1,
504 CREATE_TABLESPACE = 0,
505 ALTER_TABLESPACE = 1,
506 CREATE_LOGFILE_GROUP = 2,
507 ALTER_LOGFILE_GROUP = 3,
508 DROP_TABLESPACE = 4,
509 DROP_LOGFILE_GROUP = 5,
510 CHANGE_FILE_TABLESPACE = 6,
511 ALTER_ACCESS_MODE_TABLESPACE = 7
512 };
513
514 enum ts_alter_tablespace_type
515 {
516 TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
517 ALTER_TABLESPACE_ADD_FILE = 1,
518 ALTER_TABLESPACE_DROP_FILE = 2
519 };
520
521 enum tablespace_access_mode
522 {
523 TS_NOT_DEFINED= -1,
524 TS_READ_ONLY = 0,
525 TS_READ_WRITE = 1,
526 TS_NOT_ACCESSIBLE = 2
527 };
528
529 struct handlerton;
530 class st_alter_tablespace : public Sql_alloc
531 {
532 public:
533 const char *tablespace_name;
534 const char *logfile_group_name;
535 enum ts_command_type ts_cmd_type;
536 enum ts_alter_tablespace_type ts_alter_tablespace_type;
537 const char *data_file_name;
538 const char *undo_file_name;
539 const char *redo_file_name;
540 ulonglong extent_size;
541 ulonglong undo_buffer_size;
542 ulonglong redo_buffer_size;
543 ulonglong initial_size;
544 ulonglong autoextend_size;
545 ulonglong max_size;
546 uint nodegroup_id;
547 handlerton *storage_engine;
548 bool wait_until_completed;
549 const char *ts_comment;
550 enum tablespace_access_mode ts_access_mode;
st_alter_tablespace()551 st_alter_tablespace()
552 {
553 tablespace_name= NULL;
554 logfile_group_name= "DEFAULT_LG"; //Default log file group
555 ts_cmd_type= TS_CMD_NOT_DEFINED;
556 data_file_name= NULL;
557 undo_file_name= NULL;
558 redo_file_name= NULL;
559 extent_size= 1024*1024; //Default 1 MByte
560 undo_buffer_size= 8*1024*1024; //Default 8 MByte
561 redo_buffer_size= 8*1024*1024; //Default 8 MByte
562 initial_size= 128*1024*1024; //Default 128 MByte
563 autoextend_size= 0; //No autoextension as default
564 max_size= 0; //Max size == initial size => no extension
565 storage_engine= NULL;
566 nodegroup_id= UNDEF_NODEGROUP;
567 wait_until_completed= TRUE;
568 ts_comment= NULL;
569 ts_access_mode= TS_NOT_DEFINED;
570 }
571 };
572
573 /* The handler for a table type. Will be included in the TABLE structure */
574
575 struct TABLE;
576
577 /*
578 Make sure that the order of schema_tables and enum_schema_tables are the same.
579 */
580 enum enum_schema_tables
581 {
582 SCH_CHARSETS= 0,
583 SCH_COLLATIONS,
584 SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
585 SCH_COLUMNS,
586 SCH_COLUMN_PRIVILEGES,
587 SCH_ENGINES,
588 SCH_EVENTS,
589 SCH_FILES,
590 SCH_GLOBAL_STATUS,
591 SCH_GLOBAL_VARIABLES,
592 SCH_KEY_COLUMN_USAGE,
593 SCH_OPEN_TABLES,
594 SCH_PARAMETERS,
595 SCH_PARTITIONS,
596 SCH_PLUGINS,
597 SCH_PROCESSLIST,
598 SCH_PROFILES,
599 SCH_REFERENTIAL_CONSTRAINTS,
600 SCH_PROCEDURES,
601 SCH_SCHEMATA,
602 SCH_SCHEMA_PRIVILEGES,
603 SCH_SESSION_STATUS,
604 SCH_SESSION_VARIABLES,
605 SCH_STATISTICS,
606 SCH_STATUS,
607 SCH_TABLES,
608 SCH_TABLESPACES,
609 SCH_TABLE_CONSTRAINTS,
610 SCH_TABLE_NAMES,
611 SCH_TABLE_PRIVILEGES,
612 SCH_TRIGGERS,
613 SCH_USER_PRIVILEGES,
614 SCH_VARIABLES,
615 SCH_VIEWS
616 };
617
618 struct TABLE_SHARE;
619 struct st_foreign_key_info;
620 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
621 typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len,
622 const char *file, uint file_len,
623 const char *status, uint status_len);
624 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
625 extern st_plugin_int *hton2plugin[MAX_HA];
626
627 /* Transaction log maintains type definitions */
628 enum log_status
629 {
630 HA_LOG_STATUS_FREE= 0, /* log is free and can be deleted */
631 HA_LOG_STATUS_INUSE= 1, /* log can't be deleted because it is in use */
632 HA_LOG_STATUS_NOSUCHLOG= 2 /* no such log (can't be returned by
633 the log iterator status) */
634 };
635 /*
636 Function for signaling that the log file changed its state from
637 LOG_STATUS_INUSE to LOG_STATUS_FREE
638
639 Now it do nothing, will be implemented as part of new transaction
640 log management for engines.
641 TODO: implement the function.
642 */
643 void signal_log_not_needed(struct handlerton, char *log_file);
644 /*
645 Data of transaction log iterator.
646 */
647 struct handler_log_file_data {
648 LEX_STRING filename;
649 enum log_status status;
650 };
651
652
653 enum handler_iterator_type
654 {
655 /* request of transaction log iterator */
656 HA_TRANSACTLOG_ITERATOR= 1
657 };
658 enum handler_create_iterator_result
659 {
660 HA_ITERATOR_OK, /* iterator created */
661 HA_ITERATOR_UNSUPPORTED, /* such type of iterator is not supported */
662 HA_ITERATOR_ERROR /* error during iterator creation */
663 };
664
665 /*
666 Iterator structure. Can be used by handler/handlerton for different purposes.
667
668 Iterator should be created in the way to point "before" the first object
669 it iterate, so next() call move it to the first object or return !=0 if
670 there is nothing to iterate through.
671 */
672 struct handler_iterator {
673 /*
674 Moves iterator to next record and return 0 or return !=0
675 if there is no records.
676 iterator_object will be filled by this function if next() returns 0.
677 Content of the iterator_object depend on iterator type.
678 */
679 int (*next)(struct handler_iterator *, void *iterator_object);
680 /*
681 Free resources allocated by iterator, after this call iterator
682 is not usable.
683 */
684 void (*destroy)(struct handler_iterator *);
685 /*
686 Pointer to buffer for the iterator to use.
687 Should be allocated by function which created the iterator and
688 destroied by freed by above "destroy" call
689 */
690 void *buffer;
691 };
692
693 class handler;
694 /*
695 handlerton is a singleton structure - one instance per storage engine -
696 to provide access to storage engine functionality that works on the
697 "global" level (unlike handler class that works on a per-table basis)
698
699 usually handlerton instance is defined statically in ha_xxx.cc as
700
701 static handlerton { ... } xxx_hton;
702
703 savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
704 */
705 struct handlerton
706 {
707 /*
708 Historical marker for if the engine is available of not
709 */
710 SHOW_COMP_OPTION state;
711
712 /*
713 Historical number used for frm file to determine the correct storage engine.
714 This is going away and new engines will just use "name" for this.
715 */
716 enum legacy_db_type db_type;
717 /*
718 each storage engine has it's own memory area (actually a pointer)
719 in the thd, for storing per-connection information.
720 It is accessed as
721
722 thd->ha_data[xxx_hton.slot]
723
724 slot number is initialized by MySQL after xxx_init() is called.
725 */
726 uint slot;
727 /*
728 to store per-savepoint data storage engine is provided with an area
729 of a requested size (0 is ok here).
730 savepoint_offset must be initialized statically to the size of
731 the needed memory to store per-savepoint information.
732 After xxx_init it is changed to be an offset to savepoint storage
733 area and need not be used by storage engine.
734 see binlog_hton and binlog_savepoint_set/rollback for an example.
735 */
736 uint savepoint_offset;
737 /*
738 handlerton methods:
739
740 close_connection is only called if
741 thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
742 this storage area - set it to something, so that MySQL would know
743 this storage engine was accessed in this connection
744 */
745 int (*close_connection)(handlerton *hton, THD *thd);
746 /*
747 sv points to an uninitialized storage area of requested size
748 (see savepoint_offset description)
749 */
750 int (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
751 /*
752 sv points to a storage area, that was earlier passed
753 to the savepoint_set call
754 */
755 int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
756 int (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
757 /*
758 'all' is true if it's a real commit, that makes persistent changes
759 'all' is false if it's not in fact a commit but an end of the
760 statement that is part of the transaction.
761 NOTE 'all' is also false in auto-commit mode where 'end of statement'
762 and 'real commit' mean the same event.
763 */
764 int (*commit)(handlerton *hton, THD *thd, bool all);
765 int (*rollback)(handlerton *hton, THD *thd, bool all);
766 int (*prepare)(handlerton *hton, THD *thd, bool all);
767 int (*recover)(handlerton *hton, XID *xid_list, uint len);
768 int (*commit_by_xid)(handlerton *hton, XID *xid);
769 int (*rollback_by_xid)(handlerton *hton, XID *xid);
770 void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
771 void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
772 void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
773 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
774 void (*drop_database)(handlerton *hton, char* path);
775 int (*panic)(handlerton *hton, enum ha_panic_function flag);
776 int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
777 bool (*flush_logs)(handlerton *hton);
778 bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
779 uint (*partition_flags)();
780 uint (*alter_table_flags)(uint flags);
781 int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
782 int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
783 class Item *cond,
784 enum enum_schema_tables);
785 uint32 flags; /* global handler flags */
786 /*
787 Those handlerton functions below are properly initialized at handler
788 init.
789 */
790 int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
791 void (*binlog_log_query)(handlerton *hton, THD *thd,
792 enum_binlog_command binlog_command,
793 const char *query, uint query_length,
794 const char *db, const char *table_name);
795 int (*release_temporary_latches)(handlerton *hton, THD *thd);
796
797 /*
798 Get log status.
799 If log_status is null then the handler do not support transaction
800 log information (i.e. log iterator can't be created).
801 (see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE)
802
803 */
804 enum log_status (*get_log_status)(handlerton *hton, char *log);
805
806 /*
807 Iterators creator.
808 Presence of the pointer should be checked before using
809 */
810 enum handler_create_iterator_result
811 (*create_iterator)(handlerton *hton, enum handler_iterator_type type,
812 struct handler_iterator *fill_this_in);
813 int (*discover)(handlerton *hton, THD* thd, const char *db,
814 const char *name,
815 uchar **frmblob,
816 size_t *frmlen);
817 int (*find_files)(handlerton *hton, THD *thd,
818 const char *db,
819 const char *path,
820 const char *wild, bool dir, List<LEX_STRING> *files);
821 int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
822 const char *name);
823
824 /**
825 List of all system tables specific to the SE.
826 Array element would look like below,
827 { "<database_name>", "<system table name>" },
828 The last element MUST be,
829 { (const char*)NULL, (const char*)NULL }
830
831 @see ha_example_system_tables in ha_example.cc
832
833 This interface is optional, so every SE need not implement it.
834 */
835 const char* (*system_database)();
836
837 /**
838 Check if the given db.tablename is a system table for this SE.
839
840 @param db Database name to check.
841 @param table_name table name to check.
842 @param is_sql_layer_system_table if the supplied db.table_name is a SQL
843 layer system table.
844
845 @see example_is_supported_system_table in ha_example.cc
846
847 is_sql_layer_system_table is supplied to make more efficient
848 checks possible for SEs that support all SQL layer tables.
849
850 This interface is optional, so every SE need not implement it.
851 */
852 bool (*is_supported_system_table)(const char *db,
853 const char *table_name,
854 bool is_sql_layer_system_table);
855
856 uint32 license; /* Flag for Engine License */
857 void *data; /* Location for engines to keep personal structures */
858 };
859
860
861 /* Possible flags of a handlerton (there can be 32 of them) */
862 #define HTON_NO_FLAGS 0
863 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
864 #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
865 #define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
866 #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
867 #define HTON_FLUSH_AFTER_RENAME (1 << 4)
868 #define HTON_NOT_USER_SELECTABLE (1 << 5)
869 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
870 #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
871 #define HTON_NO_PARTITION (1 << 8) //You can not partition these tables
872 #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 9) //Foreign key constraint supported.
873
874 class Ha_trx_info;
875
876 struct THD_TRANS
877 {
878 /* true is not all entries in the ht[] support 2pc */
879 bool no_2pc;
880 /* storage engines that registered in this transaction */
881 Ha_trx_info *ha_list;
882 /*
883 The purpose of this flag is to keep track of non-transactional
884 tables that were modified in scope of:
885 - transaction, when the variable is a member of
886 THD::transaction.all
887 - top-level statement or sub-statement, when the variable is a
888 member of THD::transaction.stmt
889 This member has the following life cycle:
890 * stmt.modified_non_trans_table is used to keep track of
891 modified non-transactional tables of top-level statements. At
892 the end of the previous statement and at the beginning of the session,
893 it is reset to FALSE. If such functions
894 as mysql_insert, mysql_update, mysql_delete etc modify a
895 non-transactional table, they set this flag to TRUE. At the
896 end of the statement, the value of stmt.modified_non_trans_table
897 is merged with all.modified_non_trans_table and gets reset.
898 * all.modified_non_trans_table is reset at the end of transaction
899
900 * Since we do not have a dedicated context for execution of a
901 sub-statement, to keep track of non-transactional changes in a
902 sub-statement, we re-use stmt.modified_non_trans_table.
903 At entrance into a sub-statement, a copy of the value of
904 stmt.modified_non_trans_table (containing the changes of the
905 outer statement) is saved on stack. Then
906 stmt.modified_non_trans_table is reset to FALSE and the
907 substatement is executed. Then the new value is merged with the
908 saved value.
909 */
910 bool modified_non_trans_table;
911
resetTHD_TRANS912 void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
is_emptyTHD_TRANS913 bool is_empty() const { return ha_list == NULL; }
914 };
915
916
917 /**
918 Either statement transaction or normal transaction - related
919 thread-specific storage engine data.
920
921 If a storage engine participates in a statement/transaction,
922 an instance of this class is present in
923 thd->transaction.{stmt|all}.ha_list. The addition to
924 {stmt|all}.ha_list is made by trans_register_ha().
925
926 When it's time to commit or rollback, each element of ha_list
927 is used to access storage engine's prepare()/commit()/rollback()
928 methods, and also to evaluate if a full two phase commit is
929 necessary.
930
931 @sa General description of transaction handling in handler.cc.
932 */
933
934 class Ha_trx_info
935 {
936 public:
937 /** Register this storage engine in the given transaction context. */
register_ha(THD_TRANS * trans,handlerton * ht_arg)938 void register_ha(THD_TRANS *trans, handlerton *ht_arg)
939 {
940 DBUG_ASSERT(m_flags == 0);
941 DBUG_ASSERT(m_ht == NULL);
942 DBUG_ASSERT(m_next == NULL);
943
944 m_ht= ht_arg;
945 m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */
946
947 m_next= trans->ha_list;
948 trans->ha_list= this;
949 }
950
951 /** Clear, prepare for reuse. */
reset()952 void reset()
953 {
954 m_next= NULL;
955 m_ht= NULL;
956 m_flags= 0;
957 }
958
Ha_trx_info()959 Ha_trx_info() { reset(); }
960
set_trx_read_write()961 void set_trx_read_write()
962 {
963 DBUG_ASSERT(is_started());
964 m_flags|= (int) TRX_READ_WRITE;
965 }
is_trx_read_write()966 bool is_trx_read_write() const
967 {
968 DBUG_ASSERT(is_started());
969 return m_flags & (int) TRX_READ_WRITE;
970 }
is_started()971 bool is_started() const { return m_ht != NULL; }
972 /** Mark this transaction read-write if the argument is read-write. */
coalesce_trx_with(const Ha_trx_info * stmt_trx)973 void coalesce_trx_with(const Ha_trx_info *stmt_trx)
974 {
975 /*
976 Must be called only after the transaction has been started.
977 Can be called many times, e.g. when we have many
978 read-write statements in a transaction.
979 */
980 DBUG_ASSERT(is_started());
981 if (stmt_trx->is_trx_read_write())
982 set_trx_read_write();
983 }
next()984 Ha_trx_info *next() const
985 {
986 DBUG_ASSERT(is_started());
987 return m_next;
988 }
ht()989 handlerton *ht() const
990 {
991 DBUG_ASSERT(is_started());
992 return m_ht;
993 }
994 private:
995 enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
996 /** Auxiliary, used for ha_list management */
997 Ha_trx_info *m_next;
998 /**
999 Although a given Ha_trx_info instance is currently always used
1000 for the same storage engine, 'ht' is not-NULL only when the
1001 corresponding storage is a part of a transaction.
1002 */
1003 handlerton *m_ht;
1004 /**
1005 Transaction flags related to this engine.
1006 Not-null only if this instance is a part of transaction.
1007 May assume a combination of enum values above.
1008 */
1009 uchar m_flags;
1010 };
1011
1012
1013 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
1014 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
1015
1016
1017 typedef struct {
1018 ulonglong data_file_length;
1019 ulonglong max_data_file_length;
1020 ulonglong index_file_length;
1021 ulonglong delete_length;
1022 ha_rows records;
1023 ulong mean_rec_length;
1024 ulong create_time;
1025 ulong check_time;
1026 ulong update_time;
1027 ulonglong check_sum;
1028 } PARTITION_STATS;
1029
1030 #define UNDEF_NODEGROUP 65535
1031 class Item;
1032 struct st_table_log_memory_entry;
1033
1034 class partition_info;
1035
1036 struct st_partition_iter;
1037 #define NOT_A_PARTITION_ID ((uint32)-1)
1038
1039 enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
1040
1041 typedef struct st_ha_create_information
1042 {
1043 CHARSET_INFO *table_charset, *default_table_charset;
1044 LEX_STRING connect_string;
1045 const char *password, *tablespace;
1046 LEX_STRING comment;
1047 const char *data_file_name, *index_file_name;
1048 const char *alias;
1049 ulonglong max_rows,min_rows;
1050 ulonglong auto_increment_value;
1051 ulong table_options;
1052 ulong avg_row_length;
1053 ulong used_fields;
1054 ulong key_block_size;
1055 SQL_I_List<TABLE_LIST> merge_list;
1056 handlerton *db_type;
1057 /**
1058 Row type of the table definition.
1059
1060 Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
1061 For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
1062
1063 Can be changed either explicitly by the parser.
1064 If nothing speficied inherits the value of the original table (if present).
1065 */
1066 enum row_type row_type;
1067 uint null_bits; /* NULL bits at start of record */
1068 uint options; /* OR of HA_CREATE_ options */
1069 uint merge_insert_method;
1070 uint extra_size; /* length of extra data segment */
1071 enum enum_ha_unused unused1;
1072 bool frm_only; /* 1 if no ha_create_table() */
1073 bool varchar; /* 1 if table has a VARCHAR */
1074 enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
1075 enum enum_ha_unused unused2;
1076 } HA_CREATE_INFO;
1077
1078
1079 typedef struct st_key_create_information
1080 {
1081 enum ha_key_alg algorithm;
1082 ulong block_size;
1083 LEX_STRING parser_name;
1084 LEX_STRING comment;
1085 } KEY_CREATE_INFO;
1086
1087
1088 /*
1089 Class for maintaining hooks used inside operations on tables such
1090 as: create table functions, delete table functions, and alter table
1091 functions.
1092
1093 Class is using the Template Method pattern to separate the public
1094 usage interface from the private inheritance interface. This
1095 imposes no overhead, since the public non-virtual function is small
1096 enough to be inlined.
1097
1098 The hooks are usually used for functions that does several things,
1099 e.g., create_table_from_items(), which both create a table and lock
1100 it.
1101 */
1102 class TABLEOP_HOOKS
1103 {
1104 public:
TABLEOP_HOOKS()1105 TABLEOP_HOOKS() {}
~TABLEOP_HOOKS()1106 virtual ~TABLEOP_HOOKS() {}
1107
prelock(TABLE ** tables,uint count)1108 inline void prelock(TABLE **tables, uint count)
1109 {
1110 do_prelock(tables, count);
1111 }
1112
postlock(TABLE ** tables,uint count)1113 inline int postlock(TABLE **tables, uint count)
1114 {
1115 return do_postlock(tables, count);
1116 }
1117 private:
1118 /* Function primitive that is called prior to locking tables */
do_prelock(TABLE ** tables,uint count)1119 virtual void do_prelock(TABLE **tables, uint count)
1120 {
1121 /* Default is to do nothing */
1122 }
1123
1124 /**
1125 Primitive called after tables are locked.
1126
1127 If an error is returned, the tables will be unlocked and error
1128 handling start.
1129
1130 @return Error code or zero.
1131 */
do_postlock(TABLE ** tables,uint count)1132 virtual int do_postlock(TABLE **tables, uint count)
1133 {
1134 return 0; /* Default is to do nothing */
1135 }
1136 };
1137
1138 typedef struct st_savepoint SAVEPOINT;
1139 extern ulong savepoint_alloc_size;
1140 extern KEY_CREATE_INFO default_key_create_info;
1141
1142 /* Forward declaration for condition pushdown to storage engine */
1143 typedef class Item COND;
1144
1145 typedef struct st_ha_check_opt
1146 {
st_ha_check_optst_ha_check_opt1147 st_ha_check_opt() {} /* Remove gcc warning */
1148 uint flags; /* isam layer flags (e.g. for myisamchk) */
1149 uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
1150 KEY_CACHE *key_cache; /* new key cache when changing key cache */
1151 void init();
1152 } HA_CHECK_OPT;
1153
1154
1155
1156 /*
1157 This is a buffer area that the handler can use to store rows.
1158 'end_of_used_area' should be kept updated after calls to
1159 read-functions so that other parts of the code can use the
1160 remaining area (until next read calls is issued).
1161 */
1162
1163 typedef struct st_handler_buffer
1164 {
1165 const uchar *buffer; /* Buffer one can start using */
1166 const uchar *buffer_end; /* End of buffer */
1167 uchar *end_of_used_area; /* End of area that was used by handler */
1168 } HANDLER_BUFFER;
1169
1170 typedef struct system_status_var SSV;
1171
1172 class ha_statistics
1173 {
1174 public:
1175 ulonglong data_file_length; /* Length off data file */
1176 ulonglong max_data_file_length; /* Length off data file */
1177 ulonglong index_file_length;
1178 ulonglong max_index_file_length;
1179 ulonglong delete_length; /* Free bytes */
1180 ulonglong auto_increment_value;
1181 /*
1182 The number of records in the table.
1183 0 - means the table has exactly 0 rows
1184 other - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
1185 the value is the exact number of records in the table
1186 else
1187 it is an estimate
1188 */
1189 ha_rows records;
1190 ha_rows deleted; /* Deleted records */
1191 ulong mean_rec_length; /* physical reclength */
1192 ulong create_time; /* When table was created */
1193 ulong check_time;
1194 ulong update_time;
1195 uint block_size; /* index block size */
1196
ha_statistics()1197 ha_statistics():
1198 data_file_length(0), max_data_file_length(0),
1199 index_file_length(0), delete_length(0), auto_increment_value(0),
1200 records(0), deleted(0), mean_rec_length(0), create_time(0),
1201 check_time(0), update_time(0), block_size(0)
1202 {}
1203 };
1204
1205 uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
1206 /*
1207 bitmap with first N+1 bits set
1208 (keypart_map for a key prefix of [0..N] keyparts)
1209 */
1210 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
1211 /*
1212 bitmap with first N bits set
1213 (keypart_map for a key prefix of [0..N-1] keyparts)
1214 */
1215 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
1216
1217
1218 /**
1219 Index creation context.
1220 Created by handler::add_index() and destroyed by handler::final_add_index().
1221 And finally freed at the end of the statement.
1222 (Sql_alloc does not free in delete).
1223 */
1224
1225 class handler_add_index : public Sql_alloc
1226 {
1227 public:
1228 /* Table where the indexes are added */
1229 TABLE* const table;
1230 /* Indexes being created */
1231 KEY* const key_info;
1232 /* Size of key_info[] */
1233 const uint num_of_keys;
handler_add_index(TABLE * table_arg,KEY * key_info_arg,uint num_of_keys_arg)1234 handler_add_index(TABLE *table_arg, KEY *key_info_arg, uint num_of_keys_arg)
1235 : table (table_arg), key_info (key_info_arg), num_of_keys (num_of_keys_arg)
1236 {}
~handler_add_index()1237 virtual ~handler_add_index() {}
1238 };
1239
1240 /**
1241 The handler class is the interface for dynamically loadable
1242 storage engines. Do not add ifdefs and take care when adding or
1243 changing virtual functions to avoid vtable confusion
1244 */
1245
1246 class handler :public Sql_alloc
1247 {
1248 public:
1249 typedef ulonglong Table_flags;
1250 protected:
1251 TABLE_SHARE *table_share; /* The table definition */
1252 TABLE *table; /* The current open table */
1253 Table_flags cached_table_flags; /* Set on init() and open() */
1254
1255 ha_rows estimation_rows_to_insert;
1256 public:
1257 handlerton *ht; /* storage engine of this handler */
1258 uchar *ref; /* Pointer to current row */
1259 uchar *dup_ref; /* Pointer to duplicate row */
1260
1261 ha_statistics stats;
1262
1263 /** The following are for read_multi_range */
1264 bool multi_range_sorted;
1265 KEY_MULTI_RANGE *multi_range_curr;
1266 KEY_MULTI_RANGE *multi_range_end;
1267 HANDLER_BUFFER *multi_range_buffer;
1268
1269 /** The following are for read_range() */
1270 key_range save_end_range, *end_range;
1271 KEY_PART_INFO *range_key_part;
1272 int key_compare_result_on_equal;
1273 bool eq_range;
1274
1275 uint errkey; /* Last dup key */
1276 uint key_used_on_scan;
1277 uint active_index;
1278 /** Length of ref (1-8 or the clustered key length) */
1279 uint ref_length;
1280 FT_INFO *ft_handler;
1281 enum {NONE=0, INDEX, RND} inited;
1282 bool locked;
1283 bool implicit_emptied; /* Can be !=0 only if HEAP */
1284 const COND *pushed_cond;
1285 /**
1286 next_insert_id is the next value which should be inserted into the
1287 auto_increment column: in a inserting-multi-row statement (like INSERT
1288 SELECT), for the first row where the autoinc value is not specified by the
1289 statement, get_auto_increment() called and asked to generate a value,
1290 next_insert_id is set to the next value, then for all other rows
1291 next_insert_id is used (and increased each time) without calling
1292 get_auto_increment().
1293 */
1294 ulonglong next_insert_id;
1295 /**
1296 insert id for the current row (*autogenerated*; if not
1297 autogenerated, it's 0).
1298 At first successful insertion, this variable is stored into
1299 THD::first_successful_insert_id_in_cur_stmt.
1300 */
1301 ulonglong insert_id_for_cur_row;
1302 /**
1303 Interval returned by get_auto_increment() and being consumed by the
1304 inserter.
1305 */
1306 Discrete_interval auto_inc_interval_for_cur_row;
1307 /**
1308 Number of reserved auto-increment intervals. Serves as a heuristic
1309 when we have no estimation of how many records the statement will insert:
1310 the more intervals we have reserved, the bigger the next one. Reset in
1311 handler::ha_release_auto_increment().
1312 */
1313 uint auto_inc_intervals_count;
1314
1315 /**
1316 Instrumented table associated with this handler.
1317 This member should be set to NULL when no instrumentation is in place,
1318 so that linking an instrumented/non instrumented server/plugin works.
1319 For example:
1320 - the server is compiled with the instrumentation.
1321 The server expects either NULL or valid pointers in m_psi.
1322 - an engine plugin is compiled without instrumentation.
1323 The plugin can not leave this pointer uninitialized,
1324 or can not leave a trash value on purpose in this pointer,
1325 as this would crash the server.
1326 */
1327 PSI_table *m_psi;
1328
handler(handlerton * ht_arg,TABLE_SHARE * share_arg)1329 handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
1330 :table_share(share_arg), table(0),
1331 estimation_rows_to_insert(0), ht(ht_arg),
1332 ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
1333 ref_length(sizeof(my_off_t)),
1334 ft_handler(0), inited(NONE),
1335 locked(FALSE), implicit_emptied(0),
1336 pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
1337 auto_inc_intervals_count(0),
1338 m_psi(NULL)
1339 {}
~handler(void)1340 virtual ~handler(void)
1341 {
1342 DBUG_ASSERT(locked == FALSE);
1343 DBUG_ASSERT(inited == NONE);
1344 }
1345 virtual handler *clone(const char *name, MEM_ROOT *mem_root);
1346 /** This is called after create to allow us to set up cached variables */
init()1347 void init()
1348 {
1349 cached_table_flags= table_flags();
1350 }
1351 /* ha_ methods: pubilc wrappers for private virtual API */
1352
1353 int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
ha_index_init(uint idx,bool sorted)1354 int ha_index_init(uint idx, bool sorted)
1355 {
1356 DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
1357 int result;
1358 DBUG_ENTER("ha_index_init");
1359 DBUG_ASSERT(inited==NONE);
1360 if (!(result= index_init(idx, sorted)))
1361 inited=INDEX;
1362 DBUG_RETURN(result);
1363 }
ha_index_end()1364 int ha_index_end()
1365 {
1366 DBUG_ENTER("ha_index_end");
1367 DBUG_ASSERT(inited==INDEX);
1368 inited=NONE;
1369 DBUG_RETURN(index_end());
1370 }
ha_rnd_init(bool scan)1371 int ha_rnd_init(bool scan)
1372 {
1373 DBUG_EXECUTE_IF("ha_rnd_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
1374 int result;
1375 DBUG_ENTER("ha_rnd_init");
1376 DBUG_ASSERT(inited==NONE || (inited==RND && scan));
1377 inited= (result= rnd_init(scan)) ? NONE: RND;
1378 DBUG_RETURN(result);
1379 }
ha_rnd_end()1380 int ha_rnd_end()
1381 {
1382 DBUG_ENTER("ha_rnd_end");
1383 DBUG_ASSERT(inited==RND);
1384 inited=NONE;
1385 DBUG_RETURN(rnd_end());
1386 }
1387 int ha_reset();
1388 /* this is necessary in many places, e.g. in HANDLER command */
ha_index_or_rnd_end()1389 int ha_index_or_rnd_end()
1390 {
1391 return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
1392 }
1393 /**
1394 The cached_table_flags is set at ha_open and ha_external_lock
1395 */
ha_table_flags()1396 Table_flags ha_table_flags() const { return cached_table_flags; }
1397 /**
1398 These functions represent the public interface to *users* of the
1399 handler class, hence they are *not* virtual. For the inheritance
1400 interface, see the (private) functions write_row(), update_row(),
1401 and delete_row() below.
1402 */
1403 int ha_external_lock(THD *thd, int lock_type);
1404 int ha_write_row(uchar * buf);
1405 int ha_update_row(const uchar * old_data, uchar * new_data);
1406 int ha_delete_row(const uchar * buf);
1407 void ha_release_auto_increment();
1408
1409 int check_collation_compatibility();
1410 int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
1411 /** to be actually called to get 'check()' functionality*/
1412 int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
1413 int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
ha_start_bulk_insert(ha_rows rows)1414 void ha_start_bulk_insert(ha_rows rows)
1415 {
1416 estimation_rows_to_insert= rows;
1417 start_bulk_insert(rows);
1418 }
ha_end_bulk_insert()1419 int ha_end_bulk_insert()
1420 {
1421 estimation_rows_to_insert= 0;
1422 return end_bulk_insert();
1423 }
1424 int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
1425 uint *dup_key_found);
1426 int ha_delete_all_rows();
1427 int ha_truncate();
1428 int ha_reset_auto_increment(ulonglong value);
1429 int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
1430 int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
1431 bool ha_check_and_repair(THD *thd);
1432 int ha_disable_indexes(uint mode);
1433 int ha_enable_indexes(uint mode);
1434 int ha_discard_or_import_tablespace(my_bool discard);
1435 void ha_prepare_for_alter();
1436 int ha_rename_table(const char *from, const char *to);
1437 int ha_delete_table(const char *name);
1438 void ha_drop_table(const char *name);
1439
1440 int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
1441
1442 int ha_create_handler_files(const char *name, const char *old_name,
1443 int action_flag, HA_CREATE_INFO *info);
1444
1445 int ha_change_partitions(HA_CREATE_INFO *create_info,
1446 const char *path,
1447 ulonglong * const copied,
1448 ulonglong * const deleted,
1449 const uchar *pack_frm_data,
1450 size_t pack_frm_len);
1451 int ha_drop_partitions(const char *path);
1452 int ha_rename_partitions(const char *path);
1453
1454 void adjust_next_insert_id_after_explicit_value(ulonglong nr);
1455 int update_auto_increment();
1456 void print_keydup_error(uint key_nr, const char *msg);
1457 virtual void print_error(int error, myf errflag);
1458 virtual bool get_error_message(int error, String *buf);
1459 uint get_dup_key(int error);
change_table_ptr(TABLE * table_arg,TABLE_SHARE * share)1460 virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
1461 {
1462 table= table_arg;
1463 table_share= share;
1464 }
scan_time()1465 virtual double scan_time()
1466 { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
read_time(uint index,uint ranges,ha_rows rows)1467 virtual double read_time(uint index, uint ranges, ha_rows rows)
1468 { return rows2double(ranges+rows); }
keys_to_use_for_scanning()1469 virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
has_transactions()1470 bool has_transactions()
1471 { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
extra_rec_buf_length()1472 virtual uint extra_rec_buf_length() const { return 0; }
1473
1474 /**
1475 This method is used to analyse the error to see whether the error
1476 is ignorable or not, certain handlers can have more error that are
1477 ignorable than others. E.g. the partition handler can get inserts
1478 into a range where there is no partition and this is an ignorable
1479 error.
1480 HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
1481 same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
1482 a slightly different error message.
1483 */
is_fatal_error(int error,uint flags)1484 virtual bool is_fatal_error(int error, uint flags)
1485 {
1486 if (!error ||
1487 ((flags & HA_CHECK_DUP_KEY) &&
1488 (error == HA_ERR_FOUND_DUPP_KEY ||
1489 error == HA_ERR_FOUND_DUPP_UNIQUE)) ||
1490 ((flags & HA_CHECK_FK_ERROR) &&
1491 (error == HA_ERR_ROW_IS_REFERENCED ||
1492 error == HA_ERR_NO_REFERENCED_ROW)))
1493 return FALSE;
1494 return TRUE;
1495 }
1496
1497 /**
1498 Number of rows in table. It will only be called if
1499 (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
1500 */
records()1501 virtual ha_rows records() { return stats.records; }
1502 /**
1503 Return upper bound of current number of records in the table
1504 (max. of how many records one will retrieve when doing a full table scan)
1505 If upper bound is not known, HA_POS_ERROR should be returned as a max
1506 possible upper bound.
1507 */
estimate_rows_upper_bound()1508 virtual ha_rows estimate_rows_upper_bound()
1509 { return stats.records+EXTRA_RECORDS; }
1510
1511 /**
1512 Get the row type from the storage engine. If this method returns
1513 ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
1514 */
get_row_type()1515 virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
1516
index_type(uint key_number)1517 virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
1518
1519
1520 /**
1521 Signal that the table->read_set and table->write_set table maps changed
1522 The handler is allowed to set additional bits in the above map in this
1523 call. Normally the handler should ignore all calls until we have done
1524 a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
1525 as there may be several calls to this routine.
1526 */
1527 virtual void column_bitmaps_signal();
get_index(void)1528 uint get_index(void) const { return active_index; }
1529 virtual int close(void)=0;
1530
1531 /**
1532 @retval 0 Bulk update used by handler
1533 @retval 1 Bulk update not used, normal operation used
1534 */
start_bulk_update()1535 virtual bool start_bulk_update() { return 1; }
1536 /**
1537 @retval 0 Bulk delete used by handler
1538 @retval 1 Bulk delete not used, normal operation used
1539 */
start_bulk_delete()1540 virtual bool start_bulk_delete() { return 1; }
1541 /**
1542 After this call all outstanding updates must be performed. The number
1543 of duplicate key errors are reported in the duplicate key parameter.
1544 It is allowed to continue to the batched update after this call, the
1545 handler has to wait until end_bulk_update with changing state.
1546
1547 @param dup_key_found Number of duplicate keys found
1548
1549 @retval 0 Success
1550 @retval >0 Error code
1551 */
exec_bulk_update(uint * dup_key_found)1552 virtual int exec_bulk_update(uint *dup_key_found)
1553 {
1554 DBUG_ASSERT(FALSE);
1555 return HA_ERR_WRONG_COMMAND;
1556 }
1557 /**
1558 Perform any needed clean-up, no outstanding updates are there at the
1559 moment.
1560 */
end_bulk_update()1561 virtual void end_bulk_update() { return; }
1562 /**
1563 Execute all outstanding deletes and close down the bulk delete.
1564
1565 @retval 0 Success
1566 @retval >0 Error code
1567 */
end_bulk_delete()1568 virtual int end_bulk_delete()
1569 {
1570 DBUG_ASSERT(FALSE);
1571 return HA_ERR_WRONG_COMMAND;
1572 }
1573 /**
1574 @brief
1575 Positions an index cursor to the index specified in the handle. Fetches the
1576 row if available. If the key value is null, begin at the first key of the
1577 index.
1578 */
index_read_map(uchar * buf,const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag)1579 virtual int index_read_map(uchar * buf, const uchar * key,
1580 key_part_map keypart_map,
1581 enum ha_rkey_function find_flag)
1582 {
1583 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
1584 return index_read(buf, key, key_len, find_flag);
1585 }
1586 /**
1587 @brief
1588 Positions an index cursor to the index specified in the handle. Fetches the
1589 row if available. If the key value is null, begin at the first key of the
1590 index.
1591 */
1592 virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
1593 key_part_map keypart_map,
1594 enum ha_rkey_function find_flag);
index_next(uchar * buf)1595 virtual int index_next(uchar * buf)
1596 { return HA_ERR_WRONG_COMMAND; }
index_prev(uchar * buf)1597 virtual int index_prev(uchar * buf)
1598 { return HA_ERR_WRONG_COMMAND; }
index_first(uchar * buf)1599 virtual int index_first(uchar * buf)
1600 { return HA_ERR_WRONG_COMMAND; }
index_last(uchar * buf)1601 virtual int index_last(uchar * buf)
1602 { return HA_ERR_WRONG_COMMAND; }
1603 virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
1604 /**
1605 @brief
1606 The following functions works like index_read, but it find the last
1607 row with the current key value or prefix.
1608 */
index_read_last_map(uchar * buf,const uchar * key,key_part_map keypart_map)1609 virtual int index_read_last_map(uchar * buf, const uchar * key,
1610 key_part_map keypart_map)
1611 {
1612 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
1613 return index_read_last(buf, key, key_len);
1614 }
1615 virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
1616 KEY_MULTI_RANGE *ranges, uint range_count,
1617 bool sorted, HANDLER_BUFFER *buffer);
1618 virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
1619 virtual int read_range_first(const key_range *start_key,
1620 const key_range *end_key,
1621 bool eq_range, bool sorted);
1622 virtual int read_range_next();
1623 int compare_key(key_range *range);
ft_init()1624 virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
ft_end()1625 void ft_end() { ft_handler=NULL; }
ft_init_ext(uint flags,uint inx,String * key)1626 virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
1627 { return NULL; }
ft_read(uchar * buf)1628 virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
1629 virtual int rnd_next(uchar *buf)=0;
1630 virtual int rnd_pos(uchar * buf, uchar *pos)=0;
1631 /**
1632 This function only works for handlers having
1633 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
1634 It will return the row with the PK given in the record argument.
1635 */
rnd_pos_by_record(uchar * record)1636 virtual int rnd_pos_by_record(uchar *record)
1637 {
1638 position(record);
1639 return rnd_pos(record, ref);
1640 }
1641 virtual int read_first_row(uchar *buf, uint primary_key);
1642 /**
1643 The following function is only needed for tables that may be temporary
1644 tables during joins.
1645 */
restart_rnd_next(uchar * buf,uchar * pos)1646 virtual int restart_rnd_next(uchar *buf, uchar *pos)
1647 { return HA_ERR_WRONG_COMMAND; }
rnd_same(uchar * buf,uint inx)1648 virtual int rnd_same(uchar *buf, uint inx)
1649 { return HA_ERR_WRONG_COMMAND; }
records_in_range(uint inx,key_range * min_key,key_range * max_key)1650 virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
1651 { return (ha_rows) 10; }
1652 /*
1653 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
1654 (reference to the row, aka position, with the primary key given in
1655 the record).
1656 Otherwise it set ref to the current row.
1657 */
1658 virtual void position(const uchar *record)=0;
1659 virtual int info(uint)=0; // see my_base.h for full description
1660 virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
1661 uint part_id);
extra(enum ha_extra_function operation)1662 virtual int extra(enum ha_extra_function operation)
1663 { return 0; }
extra_opt(enum ha_extra_function operation,ulong cache_size)1664 virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
1665 { return extra(operation); }
1666
1667 /**
1668 In an UPDATE or DELETE, if the row under the cursor was locked by another
1669 transaction, and the engine used an optimistic read of the last
1670 committed row value under the cursor, then the engine returns 1 from this
1671 function. MySQL must NOT try to update this optimistic value. If the
1672 optimistic value does not match the WHERE condition, MySQL can decide to
1673 skip over this row. Currently only works for InnoDB. This can be used to
1674 avoid unnecessary lock waits.
1675
1676 If this method returns nonzero, it will also signal the storage
1677 engine that the next read will be a locking re-read of the row.
1678 */
was_semi_consistent_read()1679 virtual bool was_semi_consistent_read() { return 0; }
1680 /**
1681 Tell the engine whether it should avoid unnecessary lock waits.
1682 If yes, in an UPDATE or DELETE, if the row under the cursor was locked
1683 by another transaction, the engine may try an optimistic read of
1684 the last committed row value under the cursor.
1685 */
try_semi_consistent_read(bool)1686 virtual void try_semi_consistent_read(bool) {}
unlock_row()1687 virtual void unlock_row() {}
start_stmt(THD * thd,thr_lock_type lock_type)1688 virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
1689 virtual void get_auto_increment(ulonglong offset, ulonglong increment,
1690 ulonglong nb_desired_values,
1691 ulonglong *first_value,
1692 ulonglong *nb_reserved_values);
set_next_insert_id(ulonglong id)1693 void set_next_insert_id(ulonglong id)
1694 {
1695 DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
1696 next_insert_id= id;
1697 }
restore_auto_increment(ulonglong prev_insert_id)1698 void restore_auto_increment(ulonglong prev_insert_id)
1699 {
1700 /*
1701 Insertion of a row failed, re-use the lastly generated auto_increment
1702 id, for the next row. This is achieved by resetting next_insert_id to
1703 what it was before the failed insertion (that old value is provided by
1704 the caller). If that value was 0, it was the first row of the INSERT;
1705 then if insert_id_for_cur_row contains 0 it means no id was generated
1706 for this first row, so no id was generated since the INSERT started, so
1707 we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
1708 is the generated id of the first and failed row, so we use it.
1709 */
1710 next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
1711 insert_id_for_cur_row;
1712 }
1713
update_create_info(HA_CREATE_INFO * create_info)1714 virtual void update_create_info(HA_CREATE_INFO *create_info) {}
1715 int check_old_types();
assign_to_keycache(THD * thd,HA_CHECK_OPT * check_opt)1716 virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
1717 { return HA_ADMIN_NOT_IMPLEMENTED; }
preload_keys(THD * thd,HA_CHECK_OPT * check_opt)1718 virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
1719 { return HA_ADMIN_NOT_IMPLEMENTED; }
1720 /* end of the list of admin commands */
1721
indexes_are_disabled(void)1722 virtual int indexes_are_disabled(void) {return 0;}
update_table_comment(const char * comment)1723 virtual char *update_table_comment(const char * comment)
1724 { return (char*) comment;}
append_create_info(String * packet)1725 virtual void append_create_info(String *packet) {}
1726 /**
1727 If index == MAX_KEY then a check for table is made and if index <
1728 MAX_KEY then a check is made if the table has foreign keys and if
1729 a foreign key uses this index (and thus the index cannot be dropped).
1730
1731 @param index Index to check if foreign key uses it
1732
1733 @retval TRUE Foreign key defined on table or index
1734 @retval FALSE No foreign key defined
1735 */
is_fk_defined_on_table_or_index(uint index)1736 virtual bool is_fk_defined_on_table_or_index(uint index)
1737 { return FALSE; }
get_foreign_key_create_info()1738 virtual char* get_foreign_key_create_info()
1739 { return(NULL);} /* gets foreign key create string from InnoDB */
get_tablespace_name(THD * thd,char * name,uint name_len)1740 virtual char* get_tablespace_name(THD *thd, char *name, uint name_len)
1741 { return(NULL);} /* gets tablespace name from handler */
1742 /** used in ALTER TABLE; 1 if changing storage engine is allowed */
can_switch_engines()1743 virtual bool can_switch_engines() { return 1; }
1744 /**
1745 Get the list of foreign keys in this table.
1746
1747 @remark Returns the set of foreign keys where this table is the
1748 dependent or child table.
1749
1750 @param thd The thread handle.
1751 @param f_key_list[out] The list of foreign keys.
1752
1753 @return The handler error code or zero for success.
1754 */
1755 virtual int
get_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)1756 get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
1757 { return 0; }
1758 /**
1759 Get the list of foreign keys referencing this table.
1760
1761 @remark Returns the set of foreign keys where this table is the
1762 referenced or parent table.
1763
1764 @param thd The thread handle.
1765 @param f_key_list[out] The list of foreign keys.
1766
1767 @return The handler error code or zero for success.
1768 */
1769 virtual int
get_parent_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)1770 get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
1771 { return 0; }
referenced_by_foreign_key()1772 virtual uint referenced_by_foreign_key() { return 0;}
init_table_handle_for_HANDLER()1773 virtual void init_table_handle_for_HANDLER()
1774 { return; } /* prepare InnoDB for HANDLER */
free_foreign_key_create_info(char * str)1775 virtual void free_foreign_key_create_info(char* str) {}
1776 /** The following can be called without an open handler */
1777 virtual const char *table_type() const =0;
1778 /**
1779 If frm_error() is called then we will use this to find out what file
1780 extentions exist for the storage engine. This is also used by the default
1781 rename_table and delete_table method in handler.cc.
1782
1783 For engines that have two file name extentions (separate meta/index file
1784 and data file), the order of elements is relevant. First element of engine
1785 file name extentions array should be meta/index file extention. Second
1786 element - data file extention. This order is assumed by
1787 prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
1788 */
1789 virtual const char **bas_ext() const =0;
1790
get_default_no_partitions(HA_CREATE_INFO * info)1791 virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;}
set_auto_partitions(partition_info * part_info)1792 virtual void set_auto_partitions(partition_info *part_info) { return; }
get_no_parts(const char * name,uint * no_parts)1793 virtual bool get_no_parts(const char *name,
1794 uint *no_parts)
1795 {
1796 *no_parts= 0;
1797 return 0;
1798 }
set_part_info(partition_info * part_info)1799 virtual void set_part_info(partition_info *part_info) {return;}
1800
1801 virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
1802
1803 /**
1804 First phase of in-place add index.
1805 Handlers are supposed to create new indexes here but not make them
1806 visible.
1807
1808 @param table_arg Table to add index to
1809 @param key_info Information about new indexes
1810 @param num_of_key Number of new indexes
1811 @param add[out] Context of handler specific information needed
1812 for final_add_index().
1813
1814 @note This function can be called with less than exclusive metadata
1815 lock depending on which flags are listed in alter_table_flags.
1816 */
add_index(TABLE * table_arg,KEY * key_info,uint num_of_keys,handler_add_index ** add)1817 virtual int add_index(TABLE *table_arg, KEY *key_info, uint num_of_keys,
1818 handler_add_index **add)
1819 { return (HA_ERR_WRONG_COMMAND); }
1820
1821 /**
1822 Second and last phase of in-place add index.
1823 Commit or rollback pending new indexes.
1824
1825 @param add Context of handler specific information from add_index().
1826 @param commit If true, commit. If false, rollback index changes.
1827
1828 @note This function is called with exclusive metadata lock.
1829 */
final_add_index(handler_add_index * add,bool commit)1830 virtual int final_add_index(handler_add_index *add, bool commit)
1831 { return (HA_ERR_WRONG_COMMAND); }
1832
prepare_drop_index(TABLE * table_arg,uint * key_num,uint num_of_keys)1833 virtual int prepare_drop_index(TABLE *table_arg, uint *key_num,
1834 uint num_of_keys)
1835 { return (HA_ERR_WRONG_COMMAND); }
final_drop_index(TABLE * table_arg)1836 virtual int final_drop_index(TABLE *table_arg)
1837 { return (HA_ERR_WRONG_COMMAND); }
1838
max_record_length()1839 uint max_record_length() const
1840 { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
max_keys()1841 uint max_keys() const
1842 { return min(MAX_KEY, max_supported_keys()); }
max_key_parts()1843 uint max_key_parts() const
1844 { return min(MAX_REF_PARTS, max_supported_key_parts()); }
max_key_length()1845 uint max_key_length() const
1846 { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
max_key_part_length()1847 uint max_key_part_length() const
1848 { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
1849
max_supported_record_length()1850 virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
max_supported_keys()1851 virtual uint max_supported_keys() const { return 0; }
max_supported_key_parts()1852 virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
max_supported_key_length()1853 virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
max_supported_key_part_length()1854 virtual uint max_supported_key_part_length() const { return 255; }
min_record_length(uint options)1855 virtual uint min_record_length(uint options) const { return 1; }
1856
low_byte_first()1857 virtual bool low_byte_first() const { return 1; }
checksum()1858 virtual uint checksum() const { return 0; }
is_crashed()1859 virtual bool is_crashed() const { return 0; }
auto_repair()1860 virtual bool auto_repair() const { return 0; }
1861
1862
1863 #define CHF_CREATE_FLAG 0
1864 #define CHF_DELETE_FLAG 1
1865 #define CHF_RENAME_FLAG 2
1866 #define CHF_INDEX_FLAG 3
1867
1868
1869 /**
1870 @note lock_count() can return > 1 if the table is MERGE or partitioned.
1871 */
lock_count(void)1872 virtual uint lock_count(void) const { return 1; }
1873 /**
1874 Is not invoked for non-transactional temporary tables.
1875
1876 @note store_lock() can return more than one lock if the table is MERGE
1877 or partitioned.
1878
1879 @note that one can NOT rely on table->in_use in store_lock(). It may
1880 refer to a different thread if called from mysql_lock_abort_for_thread().
1881
1882 @note If the table is MERGE, store_lock() can return less locks
1883 than lock_count() claimed. This can happen when the MERGE children
1884 are not attached when this is called from another thread.
1885 */
1886 virtual THR_LOCK_DATA **store_lock(THD *thd,
1887 THR_LOCK_DATA **to,
1888 enum thr_lock_type lock_type)=0;
1889
1890 /** Type of table for caching query */
table_cache_type()1891 virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
1892
1893
1894 /**
1895 @brief Register a named table with a call back function to the query cache.
1896
1897 @param thd The thread handle
1898 @param table_key A pointer to the table name in the table cache
1899 @param key_length The length of the table name
1900 @param[out] engine_callback The pointer to the storage engine call back
1901 function
1902 @param[out] engine_data Storage engine specific data which could be
1903 anything
1904
1905 This method offers the storage engine, the possibility to store a reference
1906 to a table name which is going to be used with query cache.
1907 The method is called each time a statement is written to the cache and can
1908 be used to verify if a specific statement is cachable. It also offers
1909 the possibility to register a generic (but static) call back function which
1910 is called each time a statement is matched against the query cache.
1911
1912 @note If engine_data supplied with this function is different from
1913 engine_data supplied with the callback function, and the callback returns
1914 FALSE, a table invalidation on the current table will occur.
1915
1916 @return Upon success the engine_callback will point to the storage engine
1917 call back function, if any, and engine_data will point to any storage
1918 engine data used in the specific implementation.
1919 @retval TRUE Success
1920 @retval FALSE The specified table or current statement should not be
1921 cached
1922 */
1923
register_query_cache_table(THD * thd,char * table_key,uint key_length,qc_engine_callback * engine_callback,ulonglong * engine_data)1924 virtual my_bool register_query_cache_table(THD *thd, char *table_key,
1925 uint key_length,
1926 qc_engine_callback
1927 *engine_callback,
1928 ulonglong *engine_data)
1929 {
1930 *engine_callback= 0;
1931 return TRUE;
1932 }
1933
1934
1935 /*
1936 @retval TRUE Primary key (if there is one) is clustered
1937 key covering all fields
1938 @retval FALSE otherwise
1939 */
primary_key_is_clustered()1940 virtual bool primary_key_is_clustered() { return FALSE; }
cmp_ref(const uchar * ref1,const uchar * ref2)1941 virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
1942 {
1943 return memcmp(ref1, ref2, ref_length);
1944 }
1945
1946 /*
1947 Condition pushdown to storage engines
1948 */
1949
1950 /**
1951 Push condition down to the table handler.
1952
1953 @param cond Condition to be pushed. The condition tree must not be
1954 modified by the by the caller.
1955
1956 @return
1957 The 'remainder' condition that caller must use to filter out records.
1958 NULL means the handler will not return rows that do not match the
1959 passed condition.
1960
1961 @note
1962 The pushed conditions form a stack (from which one can remove the
1963 last pushed condition using cond_pop).
1964 The table handler filters out rows using (pushed_cond1 AND pushed_cond2
1965 AND ... AND pushed_condN)
1966 or less restrictive condition, depending on handler's capabilities.
1967
1968 handler->ha_reset() call empties the condition stack.
1969 Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
1970 condition stack.
1971 */
cond_push(const COND * cond)1972 virtual const COND *cond_push(const COND *cond) { return cond; };
1973 /**
1974 Pop the top condition from the condition stack of the handler instance.
1975
1976 Pops the top if condition stack, if stack is not empty.
1977 */
cond_pop()1978 virtual void cond_pop() { return; };
check_if_incompatible_data(HA_CREATE_INFO * create_info,uint table_changes)1979 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
1980 uint table_changes)
1981 { return COMPATIBLE_DATA_NO; }
1982
1983 /**
1984 use_hidden_primary_key() is called in case of an update/delete when
1985 (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
1986 but we don't have a primary key
1987 */
1988 virtual void use_hidden_primary_key();
alter_table_flags(uint flags)1989 virtual uint alter_table_flags(uint flags)
1990 {
1991 if (ht->alter_table_flags)
1992 return ht->alter_table_flags(flags);
1993 return 0;
1994 }
1995
1996 protected:
1997 /* Service methods for use by storage engines. */
1998 void ha_statistic_increment(ulong SSV::*offset) const;
1999 void **ha_data(THD *) const;
2000 THD *ha_thd(void) const;
2001
2002 /**
2003 Acquire the instrumented table information from a table share.
2004 @param share a table share
2005 @return an instrumented table share, or NULL.
2006 */
2007 PSI_table_share *ha_table_share_psi(const TABLE_SHARE *share) const;
2008
psi_open()2009 inline void psi_open()
2010 {
2011 DBUG_ASSERT(m_psi == NULL);
2012 DBUG_ASSERT(table_share != NULL);
2013 #ifdef HAVE_PSI_INTERFACE
2014 if (PSI_server)
2015 {
2016 PSI_table_share *share_psi= ha_table_share_psi(table_share);
2017 if (share_psi)
2018 m_psi= PSI_server->open_table(share_psi, this);
2019 }
2020 #endif
2021 }
2022
psi_close()2023 inline void psi_close()
2024 {
2025 #ifdef HAVE_PSI_INTERFACE
2026 if (PSI_server && m_psi)
2027 {
2028 PSI_server->close_table(m_psi);
2029 m_psi= NULL; /* instrumentation handle, invalid after close_table() */
2030 }
2031 #endif
2032 DBUG_ASSERT(m_psi == NULL);
2033 }
2034
2035 /**
2036 Default rename_table() and delete_table() rename/delete files with a
2037 given name and extensions from bas_ext().
2038
2039 These methods can be overridden, but their default implementation
2040 provide useful functionality.
2041 */
2042 virtual int rename_table(const char *from, const char *to);
2043 /**
2044 Delete a table in the engine. Called for base as well as temporary
2045 tables.
2046 */
2047 virtual int delete_table(const char *name);
2048 private:
2049 /* Private helpers */
2050 inline void mark_trx_read_write();
2051 private:
2052 /*
2053 Low-level primitives for storage engines. These should be
2054 overridden by the storage engine class. To call these methods, use
2055 the corresponding 'ha_*' method above.
2056 */
2057
2058 virtual int open(const char *name, int mode, uint test_if_locked)=0;
index_init(uint idx,bool sorted)2059 virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
index_end()2060 virtual int index_end() { active_index= MAX_KEY; return 0; }
2061 /**
2062 rnd_init() can be called two times without rnd_end() in between
2063 (it only makes sense if scan=1).
2064 then the second call should prepare for the new table scan (e.g
2065 if rnd_init allocates the cursor, second call should position it
2066 to the start of the table, no need to deallocate and allocate it again
2067 */
2068 virtual int rnd_init(bool scan)= 0;
rnd_end()2069 virtual int rnd_end() { return 0; }
write_row(uchar * buf)2070 virtual int write_row(uchar *buf __attribute__((unused)))
2071 {
2072 return HA_ERR_WRONG_COMMAND;
2073 }
2074
update_row(const uchar * old_data,uchar * new_data)2075 virtual int update_row(const uchar *old_data __attribute__((unused)),
2076 uchar *new_data __attribute__((unused)))
2077 {
2078 return HA_ERR_WRONG_COMMAND;
2079 }
2080
delete_row(const uchar * buf)2081 virtual int delete_row(const uchar *buf __attribute__((unused)))
2082 {
2083 return HA_ERR_WRONG_COMMAND;
2084 }
2085 /**
2086 Reset state of file to after 'open'.
2087 This function is called after every statement for all tables used
2088 by that statement.
2089 */
reset()2090 virtual int reset() { return 0; }
2091 virtual Table_flags table_flags(void) const= 0;
2092 /**
2093 Is not invoked for non-transactional temporary tables.
2094
2095 Tells the storage engine that we intend to read or write data
2096 from the table. This call is prefixed with a call to handler::store_lock()
2097 and is invoked only for those handler instances that stored the lock.
2098
2099 Calls to rnd_init/index_init are prefixed with this call. When table
2100 IO is complete, we call external_lock(F_UNLCK).
2101 A storage engine writer should expect that each call to
2102 ::external_lock(F_[RD|WR]LOCK is followed by a call to
2103 ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
2104
2105 The name and signature originate from the first implementation
2106 in MyISAM, which would call fcntl to set/clear an advisory
2107 lock on the data file in this method.
2108
2109 @param lock_type F_RDLCK, F_WRLCK, F_UNLCK
2110
2111 @return non-0 in case of failure, 0 in case of success.
2112 When lock_type is F_UNLCK, the return value is ignored.
2113 */
external_lock(THD * thd,int lock_type)2114 virtual int external_lock(THD *thd __attribute__((unused)),
2115 int lock_type __attribute__((unused)))
2116 {
2117 return 0;
2118 }
release_auto_increment()2119 virtual void release_auto_increment() { return; };
2120 /** admin commands - called from mysql_admin_table */
check_for_upgrade(HA_CHECK_OPT * check_opt)2121 virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
2122 { return 0; }
check(THD * thd,HA_CHECK_OPT * check_opt)2123 virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
2124 { return HA_ADMIN_NOT_IMPLEMENTED; }
2125
2126 /**
2127 In this method check_opt can be modified
2128 to specify CHECK option to use to call check()
2129 upon the table.
2130 */
repair(THD * thd,HA_CHECK_OPT * check_opt)2131 virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
2132 {
2133 DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR));
2134 return HA_ADMIN_NOT_IMPLEMENTED;
2135 }
start_bulk_insert(ha_rows rows)2136 virtual void start_bulk_insert(ha_rows rows) {}
end_bulk_insert()2137 virtual int end_bulk_insert() { return 0; }
index_read(uchar * buf,const uchar * key,uint key_len,enum ha_rkey_function find_flag)2138 virtual int index_read(uchar * buf, const uchar * key, uint key_len,
2139 enum ha_rkey_function find_flag)
2140 { return HA_ERR_WRONG_COMMAND; }
index_read_last(uchar * buf,const uchar * key,uint key_len)2141 virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
2142 { return (my_errno= HA_ERR_WRONG_COMMAND); }
2143 /**
2144 This method is similar to update_row, however the handler doesn't need
2145 to execute the updates at this point in time. The handler can be certain
2146 that another call to bulk_update_row will occur OR a call to
2147 exec_bulk_update before the set of updates in this query is concluded.
2148
2149 @param old_data Old record
2150 @param new_data New record
2151 @param dup_key_found Number of duplicate keys found
2152
2153 @retval 0 Bulk delete used by handler
2154 @retval 1 Bulk delete not used, normal operation used
2155 */
bulk_update_row(const uchar * old_data,uchar * new_data,uint * dup_key_found)2156 virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
2157 uint *dup_key_found)
2158 {
2159 DBUG_ASSERT(FALSE);
2160 return HA_ERR_WRONG_COMMAND;
2161 }
2162 /**
2163 This is called to delete all rows in a table
2164 If the handler don't support this, then this function will
2165 return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
2166 by one.
2167 */
delete_all_rows()2168 virtual int delete_all_rows()
2169 { return (my_errno=HA_ERR_WRONG_COMMAND); }
2170 /**
2171 Quickly remove all rows from a table.
2172
2173 @remark This method is responsible for implementing MySQL's TRUNCATE
2174 TABLE statement, which is a DDL operation. As such, a engine
2175 can bypass certain integrity checks and in some cases avoid
2176 fine-grained locking (e.g. row locks) which would normally be
2177 required for a DELETE statement.
2178
2179 @remark Typically, truncate is not used if it can result in integrity
2180 violation. For example, truncate is not used when a foreign
2181 key references the table, but it might be used if foreign key
2182 checks are disabled.
2183
2184 @remark Engine is responsible for resetting the auto-increment counter.
2185
2186 @remark The table is locked in exclusive mode.
2187 */
truncate()2188 virtual int truncate()
2189 { return HA_ERR_WRONG_COMMAND; }
2190 /**
2191 Reset the auto-increment counter to the given value, i.e. the next row
2192 inserted will get the given value. HA_ERR_WRONG_COMMAND is returned by
2193 storage engines that don't support this operation.
2194 */
reset_auto_increment(ulonglong value)2195 virtual int reset_auto_increment(ulonglong value)
2196 { return HA_ERR_WRONG_COMMAND; }
optimize(THD * thd,HA_CHECK_OPT * check_opt)2197 virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
2198 { return HA_ADMIN_NOT_IMPLEMENTED; }
analyze(THD * thd,HA_CHECK_OPT * check_opt)2199 virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
2200 { return HA_ADMIN_NOT_IMPLEMENTED; }
check_and_repair(THD * thd)2201 virtual bool check_and_repair(THD *thd) { return TRUE; }
disable_indexes(uint mode)2202 virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
enable_indexes(uint mode)2203 virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
discard_or_import_tablespace(my_bool discard)2204 virtual int discard_or_import_tablespace(my_bool discard)
2205 { return (my_errno=HA_ERR_WRONG_COMMAND); }
prepare_for_alter()2206 virtual void prepare_for_alter() { return; }
2207 virtual void drop_table(const char *name);
2208 virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
2209
create_handler_files(const char * name,const char * old_name,int action_flag,HA_CREATE_INFO * info)2210 virtual int create_handler_files(const char *name, const char *old_name,
2211 int action_flag, HA_CREATE_INFO *info)
2212 { return FALSE; }
2213
change_partitions(HA_CREATE_INFO * create_info,const char * path,ulonglong * const copied,ulonglong * const deleted,const uchar * pack_frm_data,size_t pack_frm_len)2214 virtual int change_partitions(HA_CREATE_INFO *create_info,
2215 const char *path,
2216 ulonglong * const copied,
2217 ulonglong * const deleted,
2218 const uchar *pack_frm_data,
2219 size_t pack_frm_len)
2220 { return HA_ERR_WRONG_COMMAND; }
drop_partitions(const char * path)2221 virtual int drop_partitions(const char *path)
2222 { return HA_ERR_WRONG_COMMAND; }
rename_partitions(const char * path)2223 virtual int rename_partitions(const char *path)
2224 { return HA_ERR_WRONG_COMMAND; }
2225 };
2226
2227
2228 /* Some extern variables used with handlers */
2229
2230 extern const char *ha_row_type[];
2231 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
2232 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
2233 extern TYPELIB tx_isolation_typelib;
2234 extern const char *myisam_stats_method_names[];
2235 extern ulong total_ha, total_ha_2pc;
2236
2237 /* lookups */
2238 handlerton *ha_default_handlerton(THD *thd);
2239 plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name);
2240 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
2241 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
2242 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
2243 handlerton *db_type);
2244 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
2245 bool no_substitute, bool report_error);
2246
2247
ha_legacy_type(const handlerton * db_type)2248 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
2249 {
2250 return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
2251 }
2252
ha_resolve_storage_engine_name(const handlerton * db_type)2253 static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
2254 {
2255 return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
2256 }
2257
ha_check_storage_engine_flag(const handlerton * db_type,uint32 flag)2258 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
2259 {
2260 return db_type == NULL ? FALSE : test(db_type->flags & flag);
2261 }
2262
ha_storage_engine_is_enabled(const handlerton * db_type)2263 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
2264 {
2265 return (db_type && db_type->create) ?
2266 (db_type->state == SHOW_OPTION_YES) : FALSE;
2267 }
2268
2269 /* basic stuff */
2270 int ha_init_errors(void);
2271 int ha_init(void);
2272 int ha_end(void);
2273 int ha_initialize_handlerton(st_plugin_int *plugin);
2274 int ha_finalize_handlerton(st_plugin_int *plugin);
2275
2276 TYPELIB *ha_known_exts(void);
2277 int ha_panic(enum ha_panic_function flag);
2278 void ha_close_connection(THD* thd);
2279 bool ha_flush_logs(handlerton *db_type);
2280 void ha_drop_database(char* path);
2281 int ha_create_table(THD *thd, const char *path,
2282 const char *db, const char *table_name,
2283 HA_CREATE_INFO *create_info,
2284 bool update_create_info);
2285 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
2286 const char *db, const char *alias, bool generate_warning);
2287
2288 /* statistics and info */
2289 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
2290
2291 /* discovery */
2292 int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
2293 bool ha_check_if_table_exists(THD* thd, const char *db, const char *name,
2294 bool *exists);
2295 int ha_discover(THD* thd, const char* dbname, const char* name,
2296 uchar** frmblob, size_t* frmlen);
2297 int ha_find_files(THD *thd,const char *db,const char *path,
2298 const char *wild, bool dir, List<LEX_STRING>* files);
2299 int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
2300 bool ha_check_if_supported_system_table(handlerton *hton, const char* db,
2301 const char* table_name);
2302
2303 /* key cache */
2304 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
2305 int ha_resize_key_cache(KEY_CACHE *key_cache);
2306 int ha_change_key_cache_param(KEY_CACHE *key_cache);
2307 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
2308
2309 /* report to InnoDB that control passes to the client */
2310 int ha_release_temporary_latches(THD *thd);
2311
2312 /* transactions: interface to handlerton functions */
2313 int ha_start_consistent_snapshot(THD *thd);
2314 int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
2315 int ha_commit_one_phase(THD *thd, bool all);
2316 int ha_commit_trans(THD *thd, bool all);
2317 int ha_rollback_trans(THD *thd, bool all);
2318 int ha_prepare(THD *thd);
2319 int ha_recover(HASH *commit_list);
2320
2321 /* transactions: these functions never call handlerton functions directly */
2322 int ha_enable_transaction(THD *thd, bool on);
2323
2324 /* savepoints */
2325 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
2326 int ha_savepoint(THD *thd, SAVEPOINT *sv);
2327 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
2328
2329 /* these are called by storage engines */
2330 void trans_register_ha(THD *thd, bool all, handlerton *ht);
2331
2332 /*
2333 Storage engine has to assume the transaction will end up with 2pc if
2334 - there is more than one 2pc-capable storage engine available
2335 - in the current transaction 2pc was not disabled yet
2336 */
2337 #define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \
2338 !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
2339
2340 #ifdef HAVE_NDB_BINLOG
2341 int ha_reset_logs(THD *thd);
2342 int ha_binlog_index_purge_file(THD *thd, const char *file);
2343 void ha_reset_slave(THD *thd);
2344 void ha_binlog_log_query(THD *thd, handlerton *db_type,
2345 enum_binlog_command binlog_command,
2346 const char *query, uint query_length,
2347 const char *db, const char *table_name);
2348 void ha_binlog_wait(THD *thd);
2349 int ha_binlog_end(THD *thd);
2350 #else
2351 #define ha_reset_logs(a) do {} while (0)
2352 #define ha_binlog_index_purge_file(a,b) do {} while (0)
2353 #define ha_reset_slave(a) do {} while (0)
2354 #define ha_binlog_log_query(a,b,c,d,e,f,g) do {} while (0)
2355 #define ha_binlog_wait(a) do {} while (0)
2356 #define ha_binlog_end(a) do {} while (0)
2357 #endif
2358
2359 const char *get_canonical_filename(handler *file, const char *path,
2360 char *tmp_path);
2361 bool mysql_xa_recover(THD *thd);
2362
2363
table_case_name(HA_CREATE_INFO * info,const char * name)2364 inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
2365 {
2366 return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
2367 }
2368
2369 void warn_fk_constraint_violation(THD *thd, TABLE *table, int error);
2370
2371 #endif /* HANDLER_INCLUDED */
2372