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 *)&gtrid_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