1 #ifndef HANDLER_INCLUDED
2 #define HANDLER_INCLUDED
3 
4 /*
5    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License, version 2.0,
9    as published by the Free Software Foundation.
10 
11    This program is also distributed with certain software (including
12    but not limited to OpenSSL) that is licensed under separate terms,
13    as designated in a particular file or component or in included license
14    documentation.  The authors of MySQL hereby grant you an additional
15    permission to link the program and your derivative works with the
16    separately licensed software that they have included with MySQL.
17 
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21    GNU General Public License, version 2.0, for more details.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
26 */
27 
28 /* Definitions for parameters to do with handler-routines */
29 
30 #include "my_global.h"
31 #include "ft_global.h"         // ft_hints
32 #include "my_thread_local.h"   // my_errno
33 #include "thr_lock.h"          // thr_lock_type
34 #include "discrete_interval.h" // Discrete_interval
35 #include "key.h"               // KEY
36 #include "mysqld.h"            // lower_case_table_names
37 #include "sql_const.h"         // SHOW_COMP_OPTION
38 #include "sql_list.h"          // SQL_I_List
39 #include "sql_plugin_ref.h"    // plugin_ref
40 
41 #include "mysql/psi/psi.h"
42 
43 #include <algorithm>
44 #include <string>
45 
46 class Alter_info;
47 class SE_cost_constants;     // see opt_costconstants.h
48 class String;
49 struct TABLE_LIST;
50 typedef struct st_bitmap MY_BITMAP;
51 typedef struct st_hash HASH;
52 typedef struct st_key_cache KEY_CACHE;
53 typedef struct xid_t XID;
54 class partition_info;
55 class Partition_handler;
56 typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
57                                       uint key_length,
58                                       ulonglong *engine_data);
59 
60 
61 // the following is for checking tables
62 
63 #define HA_ADMIN_ALREADY_DONE	  1
64 #define HA_ADMIN_OK               0
65 #define HA_ADMIN_NOT_IMPLEMENTED -1
66 #define HA_ADMIN_FAILED		 -2
67 #define HA_ADMIN_CORRUPT         -3
68 #define HA_ADMIN_INTERNAL_ERROR  -4
69 #define HA_ADMIN_INVALID         -5
70 #define HA_ADMIN_REJECT          -6
71 #define HA_ADMIN_TRY_ALTER       -7
72 #define HA_ADMIN_WRONG_CHECKSUM  -8
73 #define HA_ADMIN_NOT_BASE_TABLE  -9
74 #define HA_ADMIN_NEEDS_UPGRADE  -10
75 #define HA_ADMIN_NEEDS_ALTER    -11
76 #define HA_ADMIN_NEEDS_CHECK    -12
77 /** Needs ALTER TABLE t UPGRADE PARTITIONING. */
78 #define HA_ADMIN_NEEDS_UPG_PART -13
79 /** Needs to dump and re-create to fix pre 5.0 decimal types */
80 #define HA_ADMIN_NEEDS_DUMP_UPGRADE -14
81 
82 /**
83    Return values for check_if_supported_inplace_alter().
84 
85    @see check_if_supported_inplace_alter() for description of
86    the individual values.
87 */
88 enum enum_alter_inplace_result {
89   HA_ALTER_ERROR,
90   HA_ALTER_INPLACE_NOT_SUPPORTED,
91   HA_ALTER_INPLACE_EXCLUSIVE_LOCK,
92   HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE,
93   HA_ALTER_INPLACE_SHARED_LOCK,
94   HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE,
95   HA_ALTER_INPLACE_NO_LOCK
96 };
97 
98 /* Bits in table_flags() to show what database can do */
99 
100 #define HA_NO_TRANSACTIONS     (1 << 0) /* Doesn't support transactions */
101 #define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
102 #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
103 /*
104   The following should be set if the following is not true when scanning
105   a table with rnd_next()
106   - We will see all rows (including deleted ones)
107   - Row positions are 'table->s->db_record_offset' apart
108   If this flag is not set, filesort will do a position() call for each matched
109   row to be able to find the row later.
110 */
111 #define HA_REC_NOT_IN_SEQ      (1 << 3)
112 #define HA_CAN_GEOMETRY        (1 << 4)
113 /*
114   Reading keys in random order is as fast as reading keys in sort order
115   (Used in records.cc to decide if we should use a record cache and by
116   filesort to decide if we should sort key + data or key + pointer-to-row
117 */
118 #define HA_FAST_KEY_READ       (1 << 5)
119 /*
120   Set the following flag if we on delete should force all key to be read
121   and on update read all keys that changes
122 */
123 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
124 #define HA_NULL_IN_KEY         (1 << 7) /* One can have keys with NULL */
125 #define HA_DUPLICATE_POS       (1 << 8)    /* position() gives dup row */
126 #define HA_NO_BLOBS            (1 << 9) /* Doesn't support blobs */
127 #define HA_CAN_INDEX_BLOBS     (1 << 10)
128 #define HA_AUTO_PART_KEY       (1 << 11) /* auto-increment in multi-part key */
129 #define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
130 #define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */
131 /// Not in use.
132 #define HA_UNUSED  (1 << 14)
133 /*
134   If we get the primary key columns for free when we do an index read
135   (usually, it also implies that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
136   flag is set).
137 */
138 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
139 /*
140   If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
141   uses a primary key given by the record argument.
142   Without primary key, we can't call position().
143   If not set, the position is returned as the current rows position
144   regardless of what argument is given.
145 */
146 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
147 #define HA_CAN_RTREEKEYS       (1 << 17)
148 #define HA_NOT_DELETE_WITH_CACHE (1 << 18)
149 /*
150   The following is we need to a primary key to delete (and update) a row.
151   If there is no primary key, all columns needs to be read on update and delete
152 */
153 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
154 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
155 #define HA_CAN_FULLTEXT        (1 << 21)
156 #define HA_CAN_SQL_HANDLER     (1 << 22)
157 #define HA_NO_AUTO_INCREMENT   (1 << 23)
158 #define HA_HAS_CHECKSUM        (1 << 24)
159 /* Table data are stored in separate files (for lower_case_table_names) */
160 #define HA_FILE_BASED	       (1 << 26)
161 #define HA_NO_VARCHAR	       (1 << 27)
162 #define HA_CAN_BIT_FIELD       (1 << 28) /* supports bit fields */
163 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
164 #define HA_NO_COPY_ON_ALTER    (1LL << 31)
165 #define HA_HAS_RECORDS	       (1LL << 32) /* records() gives exact count*/
166 /* Has it's own method of binlog logging */
167 #define HA_HAS_OWN_BINLOGGING  (1LL << 33)
168 /*
169   Engine is capable of row-format and statement-format logging,
170   respectively
171 */
172 #define HA_BINLOG_ROW_CAPABLE  (1LL << 34)
173 #define HA_BINLOG_STMT_CAPABLE (1LL << 35)
174 /*
175     When a multiple key conflict happens in a REPLACE command mysql
176     expects the conflicts to be reported in the ascending order of
177     key names.
178 
179     For e.g.
180 
181     CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
182                      NULL, INDEX(c));
183 
184     REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
185 
186     MySQL expects the conflict with 'a' to be reported before the conflict with
187     'b'.
188 
189     If the underlying storage engine does not report the conflicting keys in
190     ascending order, it causes unexpected errors when the REPLACE command is
191     executed.
192 
193     This flag helps the underlying SE to inform the server that the keys are not
194     ordered.
195 */
196 #define HA_DUPLICATE_KEY_NOT_IN_ORDER    (1LL << 36)
197 /*
198   Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
199   incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
200   will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
201 */
202 #define HA_CAN_REPAIR                    (1LL << 37)
203 
204 /*
205   Set of all binlog flags. Currently only contain the capabilities
206   flags.
207  */
208 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
209 
210 /**
211   The handler supports read before write removal optimization
212 
213   Read before write removal may be used for storage engines which support
214   write without previous read of the row to be updated. Handler returning
215   this flag must implement start_read_removal() and end_read_removal().
216   The handler may return "fake" rows constructed from the key of the row
217   asked for. This is used to optimize UPDATE and DELETE by reducing the
218   numer of roundtrips between handler and storage engine.
219 
220   Example:
221   UPDATE a=1 WHERE pk IN (<keys>)
222 
223   mysql_update()
224   {
225     if (<conditions for starting read removal>)
226       start_read_removal()
227       -> handler returns true if read removal supported for this table/query
228 
229     while(read_record("pk=<key>"))
230       -> handler returns fake row with column "pk" set to <key>
231 
232       ha_update_row()
233       -> handler sends write "a=1" for row with "pk=<key>"
234 
235     end_read_removal()
236     -> handler returns the number of rows actually written
237   }
238 
239   @note This optimization in combination with batching may be used to
240         remove even more roundtrips.
241 */
242 #define HA_READ_BEFORE_WRITE_REMOVAL  (1LL << 38)
243 
244 /*
245   Engine supports extended fulltext API
246  */
247 #define HA_CAN_FULLTEXT_EXT              (1LL << 39)
248 
249 /*
250   Storage engine doesn't synchronize result set with expected table contents.
251   Used by replication slave to check if it is possible to retrieve rows from
252   the table when deciding whether to do a full table scan, index scan or hash
253   scan while applying a row event.
254  */
255 #define HA_READ_OUT_OF_SYNC              (1LL << 40)
256 
257 /*
258   Storage engine supports table export using the
259   FLUSH TABLE <table_list> FOR EXPORT statement.
260  */
261 #define HA_CAN_EXPORT                 (1LL << 41)
262 
263 /*
264   The handler don't want accesses to this table to
265   be const-table optimized
266 */
267 #define HA_BLOCK_CONST_TABLE          (1LL << 42)
268 
269 /*
270   Handler supports FULLTEXT hints
271 */
272 #define HA_CAN_FULLTEXT_HINTS         (1LL << 43)
273 
274 /**
275   Storage engine doesn't support LOCK TABLE ... READ LOCAL locks
276   but doesn't want to use handler::store_lock() API for upgrading
277   them to LOCK TABLE ... READ locks, for example, because it doesn't
278   use THR_LOCK locks at all.
279 */
280 #define HA_NO_READ_LOCAL_LOCK         (1LL << 44)
281 
282 /**
283   A storage engine is compatible with the attachable transaction requirements
284   means that
285 
286     - either SE detects the fact that THD::ha_data was reset and starts a new
287       attachable transaction, closes attachable transaction on close_connection
288       and resumes regular (outer) transaction when THD::ha_data is restored;
289 
290     - or SE completely ignores THD::ha_data and close_connection like MyISAM
291       does.
292 */
293 #define HA_ATTACHABLE_TRX_COMPATIBLE  (1LL << 45)
294 
295 /**
296   Handler supports Generated Columns
297 */
298 #define HA_GENERATED_COLUMNS            (1LL << 46)
299 
300 /**
301   Supports index on virtual generated column
302 */
303 #define HA_CAN_INDEX_VIRTUAL_GENERATED_COLUMN (1LL << 47)
304 
305 /**
306   There is no need to evict the table from the table definition cache having
307   run ANALYZE TABLE on it
308  */
309 #define HA_ONLINE_ANALYZE             (1LL << 48)
310 
311 /* bits in index_flags(index_number) for what you can do with index */
312 #define HA_READ_NEXT            1       /* TODO really use this flag */
313 #define HA_READ_PREV            2       /* supports ::index_prev */
314 #define HA_READ_ORDER           4       /* index_next/prev follow sort order */
315 #define HA_READ_RANGE           8       /* can find all records in a range */
316 #define HA_ONLY_WHOLE_INDEX	16	/* Can't use part key searches */
317 #define HA_KEYREAD_ONLY         64	/* Support HA_EXTRA_KEYREAD */
318 /*
319   Index scan will not return records in rowid order. Not guaranteed to be
320   set for unordered (e.g. HASH) indexes.
321 */
322 #define HA_KEY_SCAN_NOT_ROR     128
323 #define HA_DO_INDEX_COND_PUSHDOWN  256 /* Supports Index Condition Pushdown */
324 #define HA_CLUSTERED_INDEX      512     /* Data is clustered on this key */
325 
326 /* operations for disable/enable indexes */
327 #define HA_KEY_SWITCH_NONUNIQ      0
328 #define HA_KEY_SWITCH_ALL          1
329 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
330 #define HA_KEY_SWITCH_ALL_SAVE     3
331 
332 /*
333   Note: the following includes binlog and closing 0.
334   so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
335       example + csv + heap + blackhole + federated + 0
336   (yes, the sum is deliberately inaccurate)
337   TODO remove the limit, use dynarrays
338 */
339 #define MAX_HA 15
340 
341 /*
342   Use this instead of 0 as the initial value for the slot number of
343   handlerton, so that we can distinguish uninitialized slot number
344   from slot 0.
345 */
346 #define HA_SLOT_UNDEF ((uint)-1)
347 
348 /*
349   Parameters for open() (in register form->filestat)
350   HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
351 */
352 
353 #define HA_OPEN_KEYFILE		1
354 #define HA_OPEN_RNDFILE		2
355 #define HA_GET_INDEX		4
356 #define HA_GET_INFO		8	/* do a handler::info() after open */
357 #define HA_READ_ONLY		16	/* File opened as readonly */
358 /* Try readonly if can't open with read and write */
359 #define HA_TRY_READ_ONLY	32
360 #define HA_WAIT_IF_LOCKED	64	/* Wait if locked on open */
361 #define HA_ABORT_IF_LOCKED	128	/* skip if locked on open.*/
362 #define HA_BLOCK_LOCK		256	/* unlock when reading some records */
363 #define HA_OPEN_TEMPORARY	512
364 
365 	/* Some key definitions */
366 #define HA_KEY_NULL_LENGTH	1
367 #define HA_KEY_BLOB_LENGTH	2
368 
369 #define HA_LEX_CREATE_TMP_TABLE	1
370 #define HA_LEX_CREATE_IF_NOT_EXISTS 2
371 #define HA_LEX_CREATE_TABLE_LIKE 4
372 #define HA_LEX_CREATE_INTERNAL_TMP_TABLE 8
373 #define HA_OPTION_NO_CHECKSUM	(1L << 17)
374 #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
375 #define HA_MAX_REC_LENGTH	65535U
376 
377 /* Table caching type */
378 #define HA_CACHE_TBL_NONTRANSACT 0
379 #define HA_CACHE_TBL_NOCACHE     1
380 #define HA_CACHE_TBL_ASKTRANSACT 2
381 #define HA_CACHE_TBL_TRANSACT    4
382 
383 /**
384   Options for the START TRANSACTION statement.
385 
386   Note that READ ONLY and READ WRITE are logically mutually exclusive.
387   This is enforced by the parser and depended upon by trans_begin().
388 
389   We need two flags instead of one in order to differentiate between
390   situation when no READ WRITE/ONLY clause were given and thus transaction
391   is implicitly READ WRITE and the case when READ WRITE clause was used
392   explicitly.
393 */
394 
395 // WITH CONSISTENT SNAPSHOT option
396 static const uint MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT = 1;
397 // READ ONLY option
398 static const uint MYSQL_START_TRANS_OPT_READ_ONLY          = 2;
399 // READ WRITE option
400 static const uint MYSQL_START_TRANS_OPT_READ_WRITE         = 4;
401 // HIGH PRIORITY option
402 static const uint MYSQL_START_TRANS_OPT_HIGH_PRIORITY      = 8;
403 
404 enum legacy_db_type
405 {
406   DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
407   DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
408   DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
409   DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
410   DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
411   DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
412   DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
413   DB_TYPE_FEDERATED_DB,
414   DB_TYPE_BLACKHOLE_DB,
415   DB_TYPE_PARTITION_DB,
416   DB_TYPE_BINLOG,
417   DB_TYPE_SOLID,
418   DB_TYPE_PBXT,
419   DB_TYPE_TABLE_FUNCTION,
420   DB_TYPE_MEMCACHE,
421   DB_TYPE_FALCON,
422   DB_TYPE_MARIA,
423   /** Performance schema engine. */
424   DB_TYPE_PERFORMANCE_SCHEMA,
425   DB_TYPE_TOKUDB=41,
426   DB_TYPE_ROCKSDB=42,
427   DB_TYPE_FIRST_DYNAMIC=43,
428   DB_TYPE_DEFAULT=127 // Must be last
429 };
430 
431 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
432 		ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
433 		ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
434                 /** Unused. Reserved for future versions. */
435                 ROW_TYPE_PAGE,
436                 ROW_TYPE_TOKU_UNCOMPRESSED, ROW_TYPE_TOKU_ZLIB,
437                 ROW_TYPE_TOKU_SNAPPY, ROW_TYPE_TOKU_QUICKLZ,
438                 ROW_TYPE_TOKU_LZMA, ROW_TYPE_TOKU_FAST, ROW_TYPE_TOKU_SMALL,
439                 ROW_TYPE_TOKU_DEFAULT };
440 
441 /* Specifies data storage format for individual columns */
442 enum column_format_type {
443   COLUMN_FORMAT_TYPE_DEFAULT=   0, /* Not specified (use engine default) */
444   COLUMN_FORMAT_TYPE_FIXED=     1, /* FIXED format */
445   COLUMN_FORMAT_TYPE_DYNAMIC=   2, /* DYNAMIC format */
446   COLUMN_FORMAT_TYPE_COMPRESSED= 3  /* COMPRESSED format*/
447 };
448 
449 enum enum_binlog_func {
450   BFN_RESET_LOGS=        1,
451   BFN_RESET_SLAVE=       2,
452   BFN_BINLOG_WAIT=       3,
453   BFN_BINLOG_END=        4,
454   BFN_BINLOG_PURGE_FILE= 5
455 };
456 
457 enum enum_binlog_command {
458   LOGCOM_CREATE_TABLE,
459   LOGCOM_ALTER_TABLE,
460   LOGCOM_RENAME_TABLE,
461   LOGCOM_DROP_TABLE,
462   LOGCOM_CREATE_DB,
463   LOGCOM_ALTER_DB,
464   LOGCOM_DROP_DB,
465   LOGCOM_ACL_NOTIFY
466 };
467 
468 /* struct to hold information about the table that should be created */
469 
470 /* Bits in used_fields */
471 #define HA_CREATE_USED_AUTO             (1L << 0)
472 #define HA_CREATE_USED_RAID             (1L << 1) //RAID is no longer availble
473 #define HA_CREATE_USED_UNION            (1L << 2)
474 #define HA_CREATE_USED_INSERT_METHOD    (1L << 3)
475 #define HA_CREATE_USED_MIN_ROWS         (1L << 4)
476 #define HA_CREATE_USED_MAX_ROWS         (1L << 5)
477 #define HA_CREATE_USED_AVG_ROW_LENGTH   (1L << 6)
478 #define HA_CREATE_USED_PACK_KEYS        (1L << 7)
479 #define HA_CREATE_USED_CHARSET          (1L << 8)
480 #define HA_CREATE_USED_DEFAULT_CHARSET  (1L << 9)
481 #define HA_CREATE_USED_DATADIR          (1L << 10)
482 #define HA_CREATE_USED_INDEXDIR         (1L << 11)
483 #define HA_CREATE_USED_ENGINE           (1L << 12)
484 #define HA_CREATE_USED_CHECKSUM         (1L << 13)
485 #define HA_CREATE_USED_DELAY_KEY_WRITE  (1L << 14)
486 #define HA_CREATE_USED_ROW_FORMAT       (1L << 15)
487 #define HA_CREATE_USED_COMMENT          (1L << 16)
488 #define HA_CREATE_USED_PASSWORD         (1L << 17)
489 #define HA_CREATE_USED_CONNECTION       (1L << 18)
490 #define HA_CREATE_USED_KEY_BLOCK_SIZE   (1L << 19)
491 /** Unused. Reserved for future versions. */
492 #define HA_CREATE_USED_TRANSACTIONAL    (1L << 20)
493 /** Unused. Reserved for future versions. */
494 #define HA_CREATE_USED_PAGE_CHECKSUM    (1L << 21)
495 /** This is set whenever STATS_PERSISTENT=0|1|default has been
496 specified in CREATE/ALTER TABLE. See also HA_OPTION_STATS_PERSISTENT in
497 include/my_base.h. It is possible to distinguish whether
498 STATS_PERSISTENT=default has been specified or no STATS_PERSISTENT= is
499 given at all. */
500 #define HA_CREATE_USED_STATS_PERSISTENT (1L << 22)
501 /**
502    This is set whenever STATS_AUTO_RECALC=0|1|default has been
503    specified in CREATE/ALTER TABLE. See enum_stats_auto_recalc.
504    It is possible to distinguish whether STATS_AUTO_RECALC=default
505    has been specified or no STATS_AUTO_RECALC= is given at all.
506 */
507 #define HA_CREATE_USED_STATS_AUTO_RECALC (1L << 23)
508 /**
509    This is set whenever STATS_SAMPLE_PAGES=N|default has been
510    specified in CREATE/ALTER TABLE. It is possible to distinguish whether
511    STATS_SAMPLE_PAGES=default has been specified or no STATS_SAMPLE_PAGES= is
512    given at all.
513 */
514 #define HA_CREATE_USED_STATS_SAMPLE_PAGES (1L << 24)
515 
516 /**
517    This is set whenever a 'TABLESPACE=...' phrase is used on CREATE TABLE
518 */
519 #define HA_CREATE_USED_TABLESPACE       (1L << 25)
520 
521 /** COMPRESSION="zlib|lz4|none" used during table create. */
522 #define HA_CREATE_USED_COMPRESS         (1L << 26)
523 
524 /*
525   This is master database for most of system tables. However there
526   can be other databases which can hold system tables. Respective
527   storage engines define their own system database names.
528 */
529 extern const char *mysqld_system_database;
530 
531 /*
532   Structure to hold list of database_name.table_name.
533   This is used at both mysqld and storage engine layer.
534 */
535 struct st_handler_tablename
536 {
537   const char *db;
538   const char *tablename;
539 };
540 
541 #define MAXGTRIDSIZE 64
542 #define MAXBQUALSIZE 64
543 
544 #define COMPATIBLE_DATA_YES 0
545 #define COMPATIBLE_DATA_NO  1
546 
547 namespace AQP {
548   class Join_plan;
549 };
550 
551 /** ENCRYPTION="Y" used during table create. */
552 #define HA_CREATE_USED_ENCRYPT          (1L << 27)
553 
554 #define HA_CREATE_USED_ENCRYPTION_KEY_ID (1L << 28)
555 
556 /*
557   These structures are used to pass information from a set of SQL commands
558   on add/drop/change tablespace definitions to the proper hton.
559 */
560 #define UNDEF_NODEGROUP 65535
561 enum ts_command_type
562 {
563   TS_CMD_NOT_DEFINED = -1,
564   CREATE_TABLESPACE = 0,
565   ALTER_TABLESPACE = 1,
566   CREATE_LOGFILE_GROUP = 2,
567   ALTER_LOGFILE_GROUP = 3,
568   DROP_TABLESPACE = 4,
569   DROP_LOGFILE_GROUP = 5,
570   CHANGE_FILE_TABLESPACE = 6,
571   ALTER_ACCESS_MODE_TABLESPACE = 7
572 };
573 
574 enum ts_alter_tablespace_type
575 {
576   TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
577   ALTER_TABLESPACE_ADD_FILE = 1,
578   ALTER_TABLESPACE_DROP_FILE = 2
579 };
580 
581 enum tablespace_access_mode
582 {
583   TS_NOT_DEFINED= -1,
584   TS_READ_ONLY = 0,
585   TS_READ_WRITE = 1,
586   TS_NOT_ACCESSIBLE = 2
587 };
588 
589 struct handlerton;
590 class st_alter_tablespace : public Sql_alloc
591 {
592   public:
593   const char *tablespace_name;
594   const char *logfile_group_name;
595   enum ts_command_type ts_cmd_type;
596   enum ts_alter_tablespace_type ts_alter_tablespace_type;
597   const char *data_file_name;
598   const char *undo_file_name;
599   const char *redo_file_name;
600   ulonglong extent_size;
601   ulonglong undo_buffer_size;
602   ulonglong redo_buffer_size;
603   ulonglong initial_size;
604   ulonglong autoextend_size;
605   ulonglong max_size;
606   ulonglong file_block_size;
607   uint nodegroup_id;
608   handlerton *storage_engine;
609   bool wait_until_completed;
610   const char *ts_comment;
611   enum tablespace_access_mode ts_access_mode;
612   bool encrypt;
613   LEX_STRING encrypt_type;
is_tablespace_command()614   bool is_tablespace_command()
615   {
616     return ts_cmd_type == CREATE_TABLESPACE      ||
617             ts_cmd_type == ALTER_TABLESPACE       ||
618             ts_cmd_type == DROP_TABLESPACE        ||
619             ts_cmd_type == CHANGE_FILE_TABLESPACE ||
620             ts_cmd_type == ALTER_ACCESS_MODE_TABLESPACE;
621   }
622 
623   /** Default constructor */
st_alter_tablespace()624   st_alter_tablespace()
625   {
626     tablespace_name= NULL;
627     logfile_group_name= "DEFAULT_LG"; //Default log file group
628     ts_cmd_type= TS_CMD_NOT_DEFINED;
629     data_file_name= NULL;
630     undo_file_name= NULL;
631     redo_file_name= NULL;
632     extent_size= 1024*1024;        // Default 1 MByte
633     undo_buffer_size= 8*1024*1024; // Default 8 MByte
634     redo_buffer_size= 8*1024*1024; // Default 8 MByte
635     initial_size= 128*1024*1024;   // Default 128 MByte
636     autoextend_size= 0;            // No autoextension as default
637     max_size= 0;                   // Max size == initial size => no extension
638     storage_engine= NULL;
639     file_block_size= 0;            // 0=default or must be a valid Page Size
640     nodegroup_id= UNDEF_NODEGROUP;
641     wait_until_completed= TRUE;
642     ts_comment= NULL;
643     ts_access_mode= TS_NOT_DEFINED;
644     encrypt= false;
645     encrypt_type = LEX_STRING();
646   }
647 };
648 
649 /* The handler for a table type.  Will be included in the TABLE structure */
650 
651 struct TABLE;
652 
653 /*
654   Make sure that the order of schema_tables and enum_schema_tables are the same.
655 */
656 enum enum_schema_tables
657 {
658   SCH_CHARSETS= 0,
659   SCH_CLIENT_STATS,
660   SCH_COLLATIONS,
661   SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
662   SCH_COLUMNS,
663   SCH_COLUMN_PRIVILEGES,
664   SCH_INDEX_STATS,
665   SCH_ENGINES,
666   SCH_EVENTS,
667   SCH_FILES,
668   SCH_GLOBAL_STATUS,
669   SCH_GLOBAL_TEMPORARY_TABLES,
670   SCH_GLOBAL_VARIABLES,
671   SCH_KEY_COLUMN_USAGE,
672   SCH_OPEN_TABLES,
673   SCH_OPTIMIZER_TRACE,
674   SCH_PARAMETERS,
675   SCH_PARTITIONS,
676   SCH_PLUGINS,
677   SCH_PROCESSLIST,
678   SCH_PROFILES,
679   SCH_REFERENTIAL_CONSTRAINTS,
680   SCH_PROCEDURES,
681   SCH_SCHEMATA,
682   SCH_SCHEMA_PRIVILEGES,
683   SCH_SESSION_STATUS,
684   SCH_SESSION_VARIABLES,
685   SCH_STATISTICS,
686   SCH_STATUS,
687   SCH_TABLES,
688   SCH_TABLESPACES,
689   SCH_TABLE_CONSTRAINTS,
690   SCH_TABLE_NAMES,
691   SCH_TABLE_PRIVILEGES,
692   SCH_TABLE_STATS,
693   SCH_TEMPORARY_TABLES,
694   SCH_THREAD_STATS,
695   SCH_TRIGGERS,
696   SCH_USER_PRIVILEGES,
697   SCH_USER_STATS,
698   SCH_VARIABLES,
699   SCH_VIEWS
700 };
701 
702 struct TABLE_SHARE;
703 struct st_foreign_key_info;
704 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
705 typedef bool (stat_print_fn)(THD *thd, const char *type, size_t type_len,
706                              const char *file, size_t file_len,
707                              const char *status, size_t status_len);
708 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
709 enum ha_notification_type { HA_NOTIFY_PRE_EVENT, HA_NOTIFY_POST_EVENT };
710 
711 extern st_plugin_int *hton2plugin[MAX_HA];
712 
713 /** Create compression dictionary result type. */
714 enum handler_create_zip_dict_result
715 {
716   HA_CREATE_ZIP_DICT_OK,             /*!< zip_dict successfully created */
717   HA_CREATE_ZIP_DICT_ALREADY_EXISTS, /*!< zip dict with such name already
718                                           exists */
719   HA_CREATE_ZIP_DICT_NAME_TOO_LONG,  /*!< zip dict name is too long */
720   HA_CREATE_ZIP_DICT_DATA_TOO_LONG,  /*!< zip dict data is too long */
721   HA_CREATE_ZIP_DICT_READ_ONLY,      /*!< cannot create in read-only mode */
722   HA_CREATE_ZIP_DICT_OUT_OF_MEMORY,  /*!< out of memory */
723   HA_CREATE_ZIP_DICT_OUT_OF_FILE_SPACE,
724                                      /*!< out of disk space */
725   HA_CREATE_ZIP_DICT_TOO_MANY_CONCURRENT_TRXS,
726                                      /*!< too many concurrent transactions */
727   HA_CREATE_ZIP_DICT_UNKNOWN_ERROR   /*!< unknown error during zip_dict
728                                           creation */
729 };
730 
731 /** Drop compression dictionary result type. */
732 enum handler_drop_zip_dict_result
733 {
734   HA_DROP_ZIP_DICT_OK,             /*!< zip_dict successfully dropped */
735   HA_DROP_ZIP_DICT_DOES_NOT_EXIST, /*!< zip dict with such name does not
736                                         exist */
737   HA_DROP_ZIP_DICT_IS_REFERENCED,  /*!< zip dict is in use */
738   HA_DROP_ZIP_DICT_READ_ONLY,      /*!< cannot drop in read-only mode */
739   HA_DROP_ZIP_DICT_OUT_OF_MEMORY,  /*!< out of memory */
740   HA_DROP_ZIP_DICT_OUT_OF_FILE_SPACE,
741                                    /*!< out of disk space */
742   HA_DROP_ZIP_DICT_TOO_MANY_CONCURRENT_TRXS,
743                                    /*!< too many concurrent transactions */
744   HA_DROP_ZIP_DICT_UNKNOWN_ERROR   /*!< unknown error during zip_dict
745                                         removal */
746 };
747 
748 class handler;
749 /*
750   handlerton is a singleton structure - one instance per storage engine -
751   to provide access to storage engine functionality that works on the
752   "global" level (unlike handler class that works on a per-table basis)
753 
754   usually handlerton instance is defined statically in ha_xxx.cc as
755 
756   static handlerton { ... } xxx_hton;
757 
758   savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
759 */
760 struct handlerton
761 {
762   /*
763     Historical marker for if the engine is available of not
764   */
765   SHOW_COMP_OPTION state;
766 
767   /*
768     Historical number used for frm file to determine the correct storage engine.
769     This is going away and new engines will just use "name" for this.
770   */
771   enum legacy_db_type db_type;
772   /*
773     each storage engine has it's own memory area (actually a pointer)
774     in the thd, for storing per-connection information.
775     It is accessed as
776 
777       thd->ha_data[xxx_hton.slot]
778 
779    slot number is initialized by MySQL after xxx_init() is called.
780    */
781    uint slot;
782    /*
783      to store per-savepoint data storage engine is provided with an area
784      of a requested size (0 is ok here).
785      savepoint_offset must be initialized statically to the size of
786      the needed memory to store per-savepoint information.
787      After xxx_init it is changed to be an offset to savepoint storage
788      area and need not be used by storage engine.
789      see binlog_hton and binlog_savepoint_set/rollback for an example.
790    */
791    uint savepoint_offset;
792    /*
793      handlerton methods:
794 
795      close_connection is only called if
796      thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
797      this storage area - set it to something, so that MySQL would know
798      this storage engine was accessed in this connection
799    */
800    int  (*close_connection)(handlerton *hton, THD *thd);
801    /* Terminate connection/statement notification. */
802    void (*kill_connection)(handlerton *hton, THD *thd);
803    /*
804      sv points to an uninitialized storage area of requested size
805      (see savepoint_offset description)
806    */
807    int  (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
808    /*
809      sv points to a storage area, that was earlier passed
810      to the savepoint_set call
811    */
812    int  (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
813    /**
814      Check if storage engine allows to release metadata locks which were
815      acquired after the savepoint if rollback to savepoint is done.
816      @return true  - If it is safe to release MDL locks.
817              false - If it is not.
818    */
819    bool (*savepoint_rollback_can_release_mdl)(handlerton *hton, THD *thd);
820    int  (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
821    /*
822      'all' is true if it's a real commit, that makes persistent changes
823      'all' is false if it's not in fact a commit but an end of the
824      statement that is part of the transaction.
825      NOTE 'all' is also false in auto-commit mode where 'end of statement'
826      and 'real commit' mean the same event.
827    */
828    int  (*commit)(handlerton *hton, THD *thd, bool all);
829    int  (*rollback)(handlerton *hton, THD *thd, bool all);
830    int  (*prepare)(handlerton *hton, THD *thd, bool all);
831    int  (*recover)(handlerton *hton, XID *xid_list, uint len);
832    int  (*commit_by_xid)(handlerton *hton, XID *xid);
833    int  (*rollback_by_xid)(handlerton *hton, XID *xid);
834    handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
835    void (*drop_database)(handlerton *hton, char* path);
836    int (*panic)(handlerton *hton, enum ha_panic_function flag);
837    int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
838    int (*clone_consistent_snapshot)(handlerton *hton, THD *thd, THD *from_thd);
839    /**
840      Flush the log(s) of storage engine(s).
841 
842      @param hton Handlerton of storage engine.
843      @param binlog_group_flush true if we got invoked by binlog group
844      commit during flush stage, false in other cases.
845      @retval false Succeed
846      @retval true Error
847    */
848    bool (*flush_logs)(handlerton *hton, bool binlog_group_flush);
849    int (*store_binlog_info)(handlerton *hton, THD *thd);
850    bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
851    /*
852      The flag values are defined in sql_partition.h.
853      If this function is set, then it implies that the handler supports
854      partitioned tables.
855      If this function exists, then handler::get_partition_handler must also be
856      implemented.
857    */
858    uint (*partition_flags)();
859 
860 
861   /**
862     Get the tablespace name from the SE for the given schema and table.
863 
864     @param       thd              Thread context.
865     @param       db_name          Name of the relevant schema.
866     @param       table_name       Name of the relevant table.
867     @param [out] tablespace_name  Name of the tablespace containing the table.
868 
869     @return Operation status.
870       @retval == 0  Success.
871       @retval != 0  Error (handler error code returned).
872    */
873 
874   int (*get_tablespace)(THD* thd, LEX_CSTRING db_name, LEX_CSTRING table_name,
875                         LEX_CSTRING *tablespace_name);
876 
877    int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
878    int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
879                         class Item *cond,
880                         enum enum_schema_tables);
881    my_bool (*flush_changed_page_bitmaps)(void);
882    my_bool (*purge_changed_page_bitmaps)(ulonglong lsn);
883 
884    /**
885       Get the list of foreign keys referencing a specified table
886 
887       @param thd        The thread handle
888       @param path       Path to the table
889       @param f_key_list[out]    The list of foreign keys
890 
891       @return error code or zero for success
892     */
893    int (*get_parent_fk_list)(THD *thd, const char *path,
894                              List<FOREIGN_KEY_INFO>* f_key_list);
895    uint32 flags;                                /* global handler flags */
896    /*
897       Those handlerton functions below are properly initialized at handler
898       init.
899    */
900    int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
901    void (*binlog_log_query)(handlerton *hton, THD *thd,
902                             enum_binlog_command binlog_command,
903                             const char *query, uint query_length,
904                             const char *db, const char *table_name);
905    int (*release_temporary_latches)(handlerton *hton, THD *thd);
906 
907    int (*discover)(handlerton *hton, THD* thd, const char *db,
908                    const char *name,
909                    uchar **frmblob,
910                    size_t *frmlen);
911    int (*find_files)(handlerton *hton, THD *thd,
912                      const char *db,
913                      const char *path,
914                      const char *wild, bool dir, List<LEX_STRING> *files);
915    int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
916                                  const char *name);
917    int (*make_pushed_join)(handlerton *hton, THD* thd,
918                            const AQP::Join_plan* plan);
919 
920   /**
921     List of all system tables specific to the SE.
922     Array element would look like below,
923      { "<database_name>", "<system table name>" },
924     The last element MUST be,
925      { (const char*)NULL, (const char*)NULL }
926 
927     @see ha_example_system_tables in ha_example.cc
928 
929     This interface is optional, so every SE need not implement it.
930   */
931   const char* (*system_database)();
932 
933   /**
934     Check if the given db.tablename is a system table for this SE.
935 
936     @param db                         Database name to check.
937     @param table_name                 table name to check.
938     @param is_sql_layer_system_table  if the supplied db.table_name is a SQL
939                                       layer system table.
940 
941     @see example_is_supported_system_table in ha_example.cc
942 
943     is_sql_layer_system_table is supplied to make more efficient
944     checks possible for SEs that support all SQL layer tables.
945 
946     This interface is optional, so every SE need not implement it.
947   */
948   bool (*is_supported_system_table)(const char *db,
949                                     const char *table_name,
950                                     bool is_sql_layer_system_table);
951 
952   /**
953     Retrieve cost constants to be used for this storage engine.
954 
955     A storage engine that wants to provide its own cost constants to
956     be used in the optimizer cost model, should implement this function.
957     The server will call this function to get a cost constant object
958     that will be used for tables stored in this storage engine instead
959     of using the default cost constants.
960 
961     Life cycle for the cost constant object: The storage engine must
962     allocate the cost constant object on the heap. After the function
963     returns, the server takes over the ownership of this object.
964     The server will eventually delete the object by calling delete.
965 
966     @note In the initial version the storage_category parameter will
967     not be used. The only valid value this will have is DEFAULT_STORAGE_CLASS
968     (see declartion in opt_costconstants.h).
969 
970     @param storage_category the storage type that the cost constants will
971                             be used for
972 
973     @return a pointer to the cost constant object, if NULL is returned
974             the default cost constants will be used
975   */
976 
977   SE_cost_constants *(*get_cost_constants)(uint storage_category);
978 
979   /**
980     @param[in,out]  thd          pointer to THD
981     @param[in]      new_trx_arg  pointer to replacement transaction
982     @param[out]     ptr_trx_arg  double pointer to being replaced transaction
983 
984     Associated with THD engine's native transaction is replaced
985     with @c new_trx_arg. The old value is returned through a buffer if non-null
986     pointer is provided with @c ptr_trx_arg.
987     The method is adapted by XA start and XA prepare handlers to
988     handle XA transaction that is logged as two parts by slave applier.
989 
990     This interface concerns engines that are aware of XA transaction.
991   */
992   void (*replace_native_transaction_in_thd)(THD *thd, void *new_trx_arg,
993                                             void **ptr_trx_arg);
994 
995 
996   /**
997     Notify/get permission from storage engine before acquisition or after
998     release of exclusive metadata lock on object represented by key.
999 
1000     @param thd                Thread context.
1001     @param mdl_key            MDL key identifying object on which exclusive
1002                               lock is to be acquired/was released.
1003     @param notification_type  Indicates whether this is pre-acquire or
1004                               post-release notification.
1005     @param victimized        'true' if locking failed as we were selected
1006                               as a victim in order to avoid possible deadlocks.
1007 
1008     @note Notification is done only for objects from TABLESPACE, SCHEMA,
1009           TABLE, FUNCTION, PROCEDURE, TRIGGER and EVENT namespaces.
1010 
1011     @note Problems during notification are to be reported as warnings, MDL
1012           subsystem will report generic error if pre-acquire notification
1013           fails/SE refuses lock acquisition.
1014     @note Return value is ignored/error is not reported in case of
1015           post-release notification.
1016 
1017     @note In some cases post-release notification might happen even if
1018           there were no prior pre-acquire notification. For example,
1019           when SE was loaded after exclusive lock acquisition, or when
1020           we need notify SEs which permitted lock acquisition that it
1021           didn't happen because one of SEs didn't allow it (in such case
1022           we will do post-release notification for all SEs for simplicity).
1023 
1024     @return False - if notification was successful/lock can be acquired,
1025             True - if it has failed/lock should not be acquired.
1026   */
1027   bool (*notify_exclusive_mdl)(THD *thd, const MDL_key *mdl_key,
1028                                ha_notification_type notification_type,
1029                                bool *victimized);
1030 
1031   /**
1032     Notify/get permission from storage engine before or after execution of
1033     ALTER TABLE operation on the table identified by the MDL key.
1034 
1035     @param thd                Thread context.
1036     @param mdl_key            MDL key identifying table which is going to be
1037                               or was ALTERed.
1038     @param notification_type  Indicates whether this is pre-ALTER TABLE or
1039                               post-ALTER TABLE notification.
1040 
1041     @note This hook is necessary because for ALTER TABLE upgrade to X
1042           metadata lock happens fairly late during the execution process,
1043           so it can be expensive to abort ALTER TABLE operation at this
1044           stage by returning failure from notify_exclusive_mdl() hook.
1045 
1046     @note This hook follows the same error reporting convention as
1047           @see notify_exclusive_mdl().
1048 
1049     @note Similarly to notify_exclusive_mdl() in some cases post-ALTER
1050           notification might happen even if there were no prior pre-ALTER
1051           notification.
1052 
1053     @note Post-ALTER notification can happen before post-release notification
1054           for exclusive metadata lock acquired by this ALTER TABLE.
1055 
1056     @return False - if notification was successful/ALTER TABLE can proceed.
1057             True - if it has failed/ALTER TABLE should be aborted.
1058   */
1059   bool (*notify_alter_table)(THD *thd, const MDL_key *mdl_key,
1060                              ha_notification_type notification_type);
1061 
1062 
1063   /**
1064     @brief
1065     Initiate master key rotation
1066 
1067     @returns false on success,
1068              true on failure
1069   */
1070   bool (*rotate_encryption_master_key)(void);
1071   /**
1072     Check if the given database name is reserved.
1073 
1074     @param  hton          Handlerton for SE.
1075     @param  name          Database name.
1076 
1077     @retval true          Database name is reserved by SE.
1078     @retval false         Database name is not reserved.
1079   */
1080   bool (*is_reserved_db_name)(handlerton *hton, const char *name);
1081 
1082  /**
1083     @brief
1084     Fix empty UUID of tablespaces of an engine. This is used when engine encrypts
1085     tablespaces as part of initialization. These tablespaces will have empty UUID
1086     because UUID is generated after all plugins are initialized. This API will be
1087     called by server only after UUID is available.
1088     @returns false on success,
1089              true on failure
1090   */
1091   bool (*fix_tablespaces_empty_uuid)(void);
1092 
1093   /**
1094     Creates a new compression dictionary with the specified data for this SE.
1095 
1096     @param hton                       handletron object.
1097     @param thd                        thread descriptor.
1098     @param name                       compression dictionary name
1099     @param name_len                   compression dictionary name length
1100     @param data                       compression dictionary data
1101     @param data_len                   compression dictionary data length
1102 
1103     @return a valid #handler_create_zip_dict_result value.
1104 
1105     This interface is optional, so not every SE needs to implement it.
1106   */
1107   handler_create_zip_dict_result (*create_zip_dict)(handlerton *hton,
1108     THD* thd, const char* name, ulong* name_len, const char* data,
1109     ulong* data_len);
1110   /**
1111     Deletes a compression dictionary for this SE.
1112 
1113     @param hton                       handletron object.
1114     @param thd                        thread descriptor.
1115     @param name                       compression dictionary name
1116     @param name_len                   compression dictionary name length
1117 
1118     @return a valid #handler_drop_zip_dict_result value.
1119 
1120     This interface is optional, so not every SE needs to implement it.
1121   */
1122   handler_drop_zip_dict_result (*drop_zip_dict)(handlerton *hton, THD* thd,
1123     const char* name, ulong* name_len);
1124 
1125    uint32 license; /* Flag for Engine License */
1126    void *data; /* Location for engines to keep personal structures */
1127 };
1128 
1129 
1130 /* Possible flags of a handlerton (there can be 32 of them) */
1131 #define HTON_NO_FLAGS                 0
1132 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
1133 #define HTON_ALTER_NOT_SUPPORTED     (1 << 1) //Engine does not support alter
1134 #define HTON_CAN_RECREATE            (1 << 2) //Delete all is used fro truncate
1135 #define HTON_HIDDEN                  (1 << 3) //Engine does not appear in lists
1136 #define HTON_FLUSH_AFTER_RENAME      (1 << 4)
1137 #define HTON_NOT_USER_SELECTABLE     (1 << 5)
1138 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
1139 #define HTON_SUPPORT_LOG_TABLES      (1 << 7) //Engine supports log tables
1140 #define HTON_NO_PARTITION            (1 << 8) //You can not partition these tables
1141 
1142 /*
1143   This flag should be set when deciding that the engine does not allow row based
1144   binary logging (RBL) optimizations.
1145 
1146   Currently, setting this flag, means that table's read/write_set will be left
1147   untouched when logging changes to tables in this engine. In practice this
1148   means that the server will not mess around with table->write_set and/or
1149   table->read_set when using RBL and deciding whether to log full or minimal rows.
1150 
1151   It's valuable for instance for virtual tables, eg: Performance Schema which have
1152   no meaning for replication.
1153 */
1154 #define HTON_NO_BINLOG_ROW_OPT       (1 << 9)
1155 
1156 /**
1157   Engine supports extended keys. The flag allows to
1158   use 'extended key' feature if the engine is able to
1159   do it (has primary key values in the secondary key).
1160   Note that handler flag HA_PRIMARY_KEY_IN_READ_INDEX is
1161   actually partial case of HTON_SUPPORTS_EXTENDED_KEYS.
1162 */
1163 
1164 #define HTON_SUPPORTS_EXTENDED_KEYS  (1 << 10)
1165 
1166 /**
1167    Set if the storage engine supports 'online' backups. This means that there
1168    exists a way to create a consistent copy of its tables without blocking
1169    updates to them. If so, statements that update such tables will not be
1170    affected by an active LOCK TABLES FOR BACKUP.
1171 */
1172 #define HTON_SUPPORTS_ONLINE_BACKUPS (1 << 11)
1173 
1174 /**
1175   Engine supports secondary clustered keys.
1176 */
1177 #define HTON_SUPPORTS_CLUSTERED_KEYS (1 << 12)
1178 // Engine support foreign key constraint.
1179 
1180 #define HTON_SUPPORTS_FOREIGN_KEYS   (1 << 13)
1181 
1182 /**
1183   Engine supports compressed columns.
1184 */
1185 #define HTON_SUPPORTS_COMPRESSED_COLUMNS (1 << 14)
1186 
1187 // Engine supports packed keys.
1188 #define HTON_SUPPORTS_PACKED_KEYS    (1 << 12)
1189 
1190 // Engine supports table or tablespace encryption.
1191 #define HTON_SUPPORTS_TABLE_ENCRYPTION (1 << 13)
1192 
1193 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
1194 			 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
1195 
1196 typedef struct {
1197   ulonglong data_file_length;
1198   ulonglong max_data_file_length;
1199   ulonglong index_file_length;
1200   ulonglong delete_length;
1201   ha_rows records;
1202   ulong mean_rec_length;
1203   ulong create_time;
1204   ulong check_time;
1205   ulong update_time;
1206   ulonglong check_sum;
1207 } PARTITION_STATS;
1208 
1209 typedef struct st_table_stats {
1210   char table[NAME_LEN * 2 + 2];  // [db] + '.' + [table] + '\0'
1211   size_t table_len;
1212   ulonglong rows_read, rows_changed;
1213   ulonglong rows_changed_x_indexes;
1214   /* Stores enum db_type, but forward declarations cannot be done */
1215   int engine_type;
1216 } TABLE_STATS;
1217 
1218 typedef struct st_index_stats {
1219   char index[NAME_LEN * 3 + 3];  // [db] + '.' + [table] + '.' + [index] + '\0'
1220   size_t index_len;
1221   ulonglong rows_read;
1222 } INDEX_STATS;
1223 
1224 #define UNDEF_NODEGROUP 65535
1225 class Item;
1226 struct st_table_log_memory_entry;
1227 
1228 enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
1229 
1230 enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0,
1231                               HA_STATS_AUTO_RECALC_ON,
1232                               HA_STATS_AUTO_RECALC_OFF };
1233 
1234 typedef struct st_ha_create_information
1235 {
st_ha_create_informationst_ha_create_information1236   st_ha_create_information() { memset(this, 0, sizeof(*this)); }
1237 
1238   const CHARSET_INFO *table_charset, *default_table_charset;
1239   LEX_STRING connect_string;
1240   const char *password, *tablespace;
1241   LEX_STRING comment;
1242 
1243   /**
1244   Algorithm (and possible options) to be used for InnoDB's transparent
1245   page compression. If this attribute is set then it is hint to the
1246   storage engine to try and compress the data using the specified algorithm
1247   where possible. Note: this value is interpreted by the storage engine only.
1248   and ignored by the Server layer. */
1249 
1250   LEX_STRING compress;
1251 
1252   /**
1253   This attibute is used for InnoDB's transparent page encryption.
1254   If this attribute is set then it is hint to the storage engine to encrypt
1255   the data. Note: this value is interpreted by the storage engine only.
1256   and ignored by the Server layer. */
1257 
1258   LEX_STRING encrypt_type;
1259   uint32_t encryption_key_id;
1260   bool was_encryption_key_id_set;
1261 
1262   const char *data_file_name, *index_file_name;
1263   const char *alias;
1264   ulonglong max_rows,min_rows;
1265   ulonglong auto_increment_value;
1266   ulong table_options;
1267   ulong avg_row_length;
1268   ulong used_fields;
1269   ulong key_block_size;
1270   uint stats_sample_pages;		/* number of pages to sample during
1271 					stats estimation, if used, otherwise 0. */
1272   enum_stats_auto_recalc stats_auto_recalc;
1273   SQL_I_List<TABLE_LIST> merge_list;
1274   handlerton *db_type;
1275   /**
1276     Row type of the table definition.
1277 
1278     Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
1279     For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
1280 
1281     Can be changed either explicitly by the parser.
1282     If nothing specified inherits the value of the original table (if present).
1283   */
1284   enum row_type row_type;
1285   uint null_bits;                       /* NULL bits at start of record */
1286   uint options;				/* OR of HA_CREATE_ options */
1287   uint merge_insert_method;
1288   uint extra_size;                      /* length of extra data segment */
1289   bool varchar;                         /* 1 if table has a VARCHAR */
1290   enum ha_storage_media storage_media;  /* DEFAULT, DISK or MEMORY */
1291 } HA_CREATE_INFO;
1292 
1293 
1294 /**
1295   Structure describing changes to an index to be caused by ALTER TABLE.
1296 */
1297 
1298 struct KEY_PAIR
1299 {
1300   /**
1301     Pointer to KEY object describing old version of index in
1302     TABLE::key_info array for TABLE instance representing old
1303     version of table.
1304   */
1305   KEY *old_key;
1306   /**
1307     Pointer to KEY object describing new version of index in
1308     Alter_inplace_info::key_info_buffer array.
1309   */
1310   KEY *new_key;
1311 };
1312 
1313 
1314 /**
1315   In-place alter handler context.
1316 
1317   This is a superclass intended to be subclassed by individual handlers
1318   in order to store handler unique context between in-place alter API calls.
1319 
1320   The handler is responsible for creating the object. This can be done
1321   as early as during check_if_supported_inplace_alter().
1322 
1323   The SQL layer is responsible for destroying the object.
1324   The class extends Sql_alloc so the memory will be mem root allocated.
1325 
1326   @see Alter_inplace_info
1327 */
1328 
1329 class inplace_alter_handler_ctx : public Sql_alloc
1330 {
1331 public:
inplace_alter_handler_ctx()1332   inplace_alter_handler_ctx() {}
1333 
~inplace_alter_handler_ctx()1334   virtual ~inplace_alter_handler_ctx() {}
set_shared_data(const inplace_alter_handler_ctx * ctx)1335   virtual void set_shared_data(const inplace_alter_handler_ctx *ctx) {};
1336 };
1337 
1338 
1339 /**
1340   Class describing changes to be done by ALTER TABLE.
1341   Instance of this class is passed to storage engine in order
1342   to determine if this ALTER TABLE can be done using in-place
1343   algorithm. It is also used for executing the ALTER TABLE
1344   using in-place algorithm.
1345 */
1346 
1347 class Alter_inplace_info
1348 {
1349 public:
1350   /**
1351      Bits to show in detail what operations the storage engine is
1352      to execute.
1353 
1354      All these operations are supported as in-place operations by the
1355      SQL layer. This means that operations that by their nature must
1356      be performed by copying the table to a temporary table, will not
1357      have their own flags here (e.g. ALTER TABLE FORCE, ALTER TABLE
1358      ENGINE).
1359 
1360      We generally try to specify handler flags only if there are real
1361      changes. But in cases when it is cumbersome to determine if some
1362      attribute has really changed we might choose to set flag
1363      pessimistically, for example, relying on parser output only.
1364   */
1365   typedef ulonglong HA_ALTER_FLAGS;
1366 
1367   // Add non-unique, non-primary index
1368   static const HA_ALTER_FLAGS ADD_INDEX                  = 1ULL << 0;
1369 
1370   // Drop non-unique, non-primary index
1371   static const HA_ALTER_FLAGS DROP_INDEX                 = 1ULL << 1;
1372 
1373   // Add unique, non-primary index
1374   static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX           = 1ULL << 2;
1375 
1376   // Drop unique, non-primary index
1377   static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX          = 1ULL << 3;
1378 
1379   // Add primary index
1380   static const HA_ALTER_FLAGS ADD_PK_INDEX               = 1ULL << 4;
1381 
1382   // Drop primary index
1383   static const HA_ALTER_FLAGS DROP_PK_INDEX              = 1ULL << 5;
1384 
1385   // Add column
1386 
1387   // Virtual generated column
1388   static const HA_ALTER_FLAGS ADD_VIRTUAL_COLUMN         = 1ULL << 6;
1389   // Stored base (non-generated) column
1390   static const HA_ALTER_FLAGS ADD_STORED_BASE_COLUMN     = 1ULL << 7;
1391   // Stored generated column
1392   static const HA_ALTER_FLAGS ADD_STORED_GENERATED_COLUMN= 1ULL << 8;
1393   // Add generic column (convience constant).
1394   static const HA_ALTER_FLAGS ADD_COLUMN= ADD_VIRTUAL_COLUMN |
1395                                           ADD_STORED_BASE_COLUMN |
1396                                           ADD_STORED_GENERATED_COLUMN;
1397 
1398   // Drop column
1399   static const HA_ALTER_FLAGS DROP_VIRTUAL_COLUMN        = 1ULL << 9;
1400   static const HA_ALTER_FLAGS DROP_STORED_COLUMN         = 1ULL << 10;
1401   static const HA_ALTER_FLAGS DROP_COLUMN= DROP_VIRTUAL_COLUMN |
1402                                            DROP_STORED_COLUMN;
1403 
1404   // Rename column
1405   static const HA_ALTER_FLAGS ALTER_COLUMN_NAME          = 1ULL << 11;
1406 
1407   // Change column datatype
1408   static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_TYPE         = 1ULL << 12;
1409   static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_TYPE          = 1ULL << 13;
1410 
1411   /**
1412     Change column datatype in such way that new type has compatible
1413     packed representation with old type, so it is theoretically
1414     possible to perform change by only updating data dictionary
1415     without changing table rows.
1416   */
1417   static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1ULL << 14;
1418 
1419   /// A virtual column has changed its position
1420   static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_ORDER     = 1ULL << 15;
1421 
1422   /// A stored column has changed its position (disregarding virtual columns)
1423   static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_ORDER      = 1ULL << 16;
1424 
1425   // Change column from NOT NULL to NULL
1426   static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE      = 1ULL << 17;
1427 
1428   // Change column from NULL to NOT NULL
1429   static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE  = 1ULL << 18;
1430 
1431   // Set or remove default column value
1432   static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT       = 1ULL << 19;
1433 
1434   // Change column generation expression
1435   static const HA_ALTER_FLAGS ALTER_VIRTUAL_GCOL_EXPR    = 1ULL << 20;
1436   static const HA_ALTER_FLAGS ALTER_STORED_GCOL_EXPR     = 1ULL << 21;
1437 
1438   // Add foreign key
1439   static const HA_ALTER_FLAGS ADD_FOREIGN_KEY            = 1ULL << 22;
1440 
1441   // Drop foreign key
1442   static const HA_ALTER_FLAGS DROP_FOREIGN_KEY           = 1ULL << 23;
1443 
1444   // table_options changed, see HA_CREATE_INFO::used_fields for details.
1445   static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION       = 1ULL << 24;
1446 
1447   // Table is renamed
1448   static const HA_ALTER_FLAGS ALTER_RENAME               = 1ULL << 25;
1449 
1450   // Change the storage type of column
1451   static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1ULL << 26;
1452 
1453   // Change the column format of column
1454   static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1ULL << 27;
1455 
1456   // Add partition
1457   static const HA_ALTER_FLAGS ADD_PARTITION              = 1ULL << 28;
1458 
1459   // Drop partition
1460   static const HA_ALTER_FLAGS DROP_PARTITION             = 1ULL << 29;
1461 
1462   // Changing partition options
1463   static const HA_ALTER_FLAGS ALTER_PARTITION            = 1ULL << 30;
1464 
1465   // Coalesce partition
1466   static const HA_ALTER_FLAGS COALESCE_PARTITION         = 1ULL << 31;
1467 
1468   // Reorganize partition ... into
1469   static const HA_ALTER_FLAGS REORGANIZE_PARTITION       = 1ULL << 32;
1470 
1471   // Reorganize partition
1472   static const HA_ALTER_FLAGS ALTER_TABLE_REORG          = 1ULL << 33;
1473 
1474   // Remove partitioning
1475   static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING  = 1ULL << 34;
1476 
1477   // Partition operation with ALL keyword
1478   static const HA_ALTER_FLAGS ALTER_ALL_PARTITION        = 1ULL << 35;
1479 
1480   /**
1481     Rename index. Note that we set this flag only if there are no other
1482     changes to the index being renamed. Also for simplicity we don't
1483     detect renaming of indexes which is done by dropping index and then
1484     re-creating index with identical definition under different name.
1485   */
1486   static const HA_ALTER_FLAGS RENAME_INDEX               = 1ULL << 36;
1487 
1488   /**
1489     Recreate the table for ALTER TABLE FORCE, ALTER TABLE ENGINE
1490     and OPTIMIZE TABLE operations.
1491   */
1492   static const HA_ALTER_FLAGS RECREATE_TABLE             = 1ULL << 37;
1493 
1494   // Add spatial index
1495   static const HA_ALTER_FLAGS ADD_SPATIAL_INDEX          = 1ULL << 38;
1496 
1497   // Alter index comment
1498   static const HA_ALTER_FLAGS ALTER_INDEX_COMMENT        = 1ULL << 39;
1499 
1500   // Upgrade partitioning
1501   static const HA_ALTER_FLAGS ALTER_UPGRADE_PARTITIONING  = 1ULL << 40;
1502 
1503   // New/changed virtual generated column require validation
1504   static const HA_ALTER_FLAGS VALIDATE_VIRTUAL_COLUMN    = 1ULL << 41;
1505 
1506   /**
1507     Change in index length such that it does not require index rebuild.
1508     For example, change in index length due to column expansion like
1509     varchar(X) changed to varchar(X + N).
1510   */
1511   static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH = 1ULL << 42;
1512 
1513 
1514   /**
1515     Create options (like MAX_ROWS) for the new version of table.
1516 
1517     @note The referenced instance of HA_CREATE_INFO object was already
1518           used to create new .FRM file for table being altered. So it
1519           has been processed by mysql_prepare_create_table() already.
1520           For example, this means that it has HA_OPTION_PACK_RECORD
1521           flag in HA_CREATE_INFO::table_options member correctly set.
1522   */
1523   HA_CREATE_INFO *create_info;
1524 
1525   /**
1526     Alter options, fields and keys for the new version of table.
1527 
1528     @note The referenced instance of Alter_info object was already
1529           used to create new .FRM file for table being altered. So it
1530           has been processed by mysql_prepare_create_table() already.
1531           In particular, this means that in Create_field objects for
1532           fields which were present in some form in the old version
1533           of table, Create_field::field member points to corresponding
1534           Field instance for old version of table.
1535   */
1536   Alter_info *alter_info;
1537 
1538   /**
1539     Array of KEYs for new version of table - including KEYs to be added.
1540 
1541     @note Currently this array is produced as result of
1542           mysql_prepare_create_table() call.
1543           This means that it follows different convention for
1544           KEY_PART_INFO::fieldnr values than objects in TABLE::key_info
1545           array.
1546 
1547     @todo This is mainly due to the fact that we need to keep compatibility
1548           with removed handler::add_index() call. We plan to switch to
1549           TABLE::key_info numbering later.
1550 
1551     KEYs are sorted - see sort_keys().
1552   */
1553   KEY  *key_info_buffer;
1554 
1555   /** Size of key_info_buffer array. */
1556   uint key_count;
1557 
1558   /** Size of index_drop_buffer array. */
1559   uint index_drop_count;
1560 
1561   /**
1562      Array of pointers to KEYs to be dropped belonging to the TABLE instance
1563      for the old version of the table.
1564   */
1565   KEY  **index_drop_buffer;
1566 
1567   /** Size of index_add_buffer array. */
1568   uint index_add_count;
1569 
1570   /**
1571      Array of indexes into key_info_buffer for KEYs to be added,
1572      sorted in increasing order.
1573   */
1574   uint *index_add_buffer;
1575 
1576   /** Size of index_rename_buffer array. */
1577   uint index_rename_count;
1578 
1579   /**
1580     Array of KEY_PAIR objects describing indexes being renamed.
1581     For each index renamed it contains object with KEY_PAIR::old_key
1582     pointing to KEY object belonging to the TABLE instance for old
1583     version of table representing old version of index and with
1584     KEY_PAIR::new_key pointing to KEY object for new version of
1585     index in key_info_buffer member.
1586   */
1587   KEY_PAIR  *index_rename_buffer;
1588 
1589   /**
1590      Context information to allow handlers to keep context between in-place
1591      alter API calls.
1592 
1593      @see inplace_alter_handler_ctx for information about object lifecycle.
1594   */
1595   inplace_alter_handler_ctx *handler_ctx;
1596 
1597   /**
1598     If the table uses several handlers, like ha_partition uses one handler
1599     per partition, this contains a Null terminated array of ctx pointers
1600     that should all be committed together.
1601     Or NULL if only handler_ctx should be committed.
1602     Set to NULL if the low level handler::commit_inplace_alter_table uses it,
1603     to signal to the main handler that everything was committed as atomically.
1604 
1605     @see inplace_alter_handler_ctx for information about object lifecycle.
1606   */
1607   inplace_alter_handler_ctx **group_commit_ctx;
1608 
1609   /**
1610      Flags describing in detail which operations the storage engine is to execute.
1611   */
1612   HA_ALTER_FLAGS handler_flags;
1613 
1614   /**
1615      Partition_info taking into account the partition changes to be performed.
1616      Contains all partitions which are present in the old version of the table
1617      with partitions to be dropped or changed marked as such + all partitions
1618      to be added in the new version of table marked as such.
1619   */
1620   partition_info *modified_part_info;
1621 
1622   /** true for online operation (LOCK=NONE) */
1623   bool online;
1624 
1625   /**
1626      Can be set by handler to describe why a given operation cannot be done
1627      in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
1628      online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE)
1629      If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
1630      results from handler::check_if_supported_inplace_alter() doesn't match
1631      requirements set by user. If not set, the more generic
1632      ER_ALTER_OPERATION_NOT_SUPPORTED will be used.
1633 
1634      Please set to a properly localized string, for example using
1635      my_get_err_msg(), so that the error message as a whole is localized.
1636   */
1637   const char *unsupported_reason;
1638 
Alter_inplace_info(HA_CREATE_INFO * create_info_arg,Alter_info * alter_info_arg,KEY * key_info_arg,uint key_count_arg,partition_info * modified_part_info_arg)1639   Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
1640                      Alter_info *alter_info_arg,
1641                      KEY *key_info_arg, uint key_count_arg,
1642                      partition_info *modified_part_info_arg)
1643     : create_info(create_info_arg),
1644     alter_info(alter_info_arg),
1645     key_info_buffer(key_info_arg),
1646     key_count(key_count_arg),
1647     index_drop_count(0),
1648     index_drop_buffer(NULL),
1649     index_add_count(0),
1650     index_add_buffer(NULL),
1651     index_rename_count(0),
1652     index_rename_buffer(NULL),
1653     handler_ctx(NULL),
1654     group_commit_ctx(NULL),
1655     handler_flags(0),
1656     modified_part_info(modified_part_info_arg),
1657     online(false),
1658     unsupported_reason(NULL)
1659   {}
1660 
~Alter_inplace_info()1661   ~Alter_inplace_info()
1662   {
1663     delete handler_ctx;
1664   }
1665 
1666   /**
1667     Used after check_if_supported_inplace_alter() to report
1668     error if the result does not match the LOCK/ALGORITHM
1669     requirements set by the user.
1670 
1671     @param not_supported  Part of statement that was not supported.
1672     @param try_instead    Suggestion as to what the user should
1673                           replace not_supported with.
1674   */
1675   void report_unsupported_error(const char *not_supported,
1676                                 const char *try_instead);
1677 
1678   /** Add old and new version of key to array of indexes to be renamed. */
add_renamed_key(KEY * old_key,KEY * new_key)1679   void add_renamed_key(KEY *old_key, KEY *new_key)
1680   {
1681     KEY_PAIR *key_pair= index_rename_buffer + index_rename_count++;
1682     key_pair->old_key= old_key;
1683     key_pair->new_key= new_key;
1684     DBUG_PRINT("info", ("index renamed: '%s' to '%s'",
1685                         old_key->name, new_key->name));
1686   }
1687 
1688   /**
1689     Add old and new version of modified key to arrays of indexes to
1690     be dropped and added (correspondingly).
1691   */
add_modified_key(KEY * old_key,KEY * new_key)1692   void add_modified_key(KEY *old_key, KEY *new_key)
1693   {
1694     index_drop_buffer[index_drop_count++]= old_key;
1695     index_add_buffer[index_add_count++]= (uint) (new_key - key_info_buffer);
1696     DBUG_PRINT("info", ("index changed: '%s'", old_key->name));
1697   }
1698 
1699   /** Drop key to array of indexes to be dropped. */
add_dropped_key(KEY * old_key)1700   void add_dropped_key(KEY *old_key)
1701   {
1702     index_drop_buffer[index_drop_count++]= old_key;
1703     DBUG_PRINT("info", ("index dropped: '%s'", old_key->name));
1704   }
1705 
1706   /** Add key to array of indexes to be added. */
add_added_key(KEY * new_key)1707   void add_added_key(KEY *new_key)
1708   {
1709     index_add_buffer[index_add_count++]= (uint) (new_key - key_info_buffer);
1710     DBUG_PRINT("info", ("index added: '%s'", new_key->name));
1711   }
1712 };
1713 
1714 
1715 typedef struct st_key_create_information
1716 {
1717   enum ha_key_alg algorithm;
1718   ulong block_size;
1719   LEX_STRING parser_name;
1720   LEX_STRING comment;
1721   /**
1722     A flag to determine if we will check for duplicate indexes.
1723     This typically means that the key information was specified
1724     directly by the user (set by the parser) or a column
1725     associated with it was dropped.
1726   */
1727   bool check_for_duplicate_indexes;
1728 } KEY_CREATE_INFO;
1729 
1730 
1731 /*
1732   Class for maintaining hooks used inside operations on tables such
1733   as: create table functions, delete table functions, and alter table
1734   functions.
1735 
1736   Class is using the Template Method pattern to separate the public
1737   usage interface from the private inheritance interface.  This
1738   imposes no overhead, since the public non-virtual function is small
1739   enough to be inlined.
1740 
1741   The hooks are usually used for functions that does several things,
1742   e.g., create_table_from_items(), which both create a table and lock
1743   it.
1744  */
1745 class TABLEOP_HOOKS
1746 {
1747 public:
TABLEOP_HOOKS()1748   TABLEOP_HOOKS() {}
~TABLEOP_HOOKS()1749   virtual ~TABLEOP_HOOKS() {}
1750 
prelock(TABLE ** tables,uint count)1751   inline void prelock(TABLE **tables, uint count)
1752   {
1753     do_prelock(tables, count);
1754   }
1755 
postlock(TABLE ** tables,uint count)1756   inline int postlock(TABLE **tables, uint count)
1757   {
1758     return do_postlock(tables, count);
1759   }
1760 private:
1761   /* Function primitive that is called prior to locking tables */
do_prelock(TABLE ** tables,uint count)1762   virtual void do_prelock(TABLE **tables, uint count)
1763   {
1764     /* Default is to do nothing */
1765   }
1766 
1767   /**
1768      Primitive called after tables are locked.
1769 
1770      If an error is returned, the tables will be unlocked and error
1771      handling start.
1772 
1773      @return Error code or zero.
1774    */
do_postlock(TABLE ** tables,uint count)1775   virtual int do_postlock(TABLE **tables, uint count)
1776   {
1777     return 0;                           /* Default is to do nothing */
1778   }
1779 };
1780 
1781 typedef struct st_savepoint SAVEPOINT;
1782 extern ulong savepoint_alloc_size;
1783 extern KEY_CREATE_INFO default_key_create_info;
1784 
1785 typedef struct st_ha_check_opt
1786 {
st_ha_check_optst_ha_check_opt1787   st_ha_check_opt() {}                        /* Remove gcc warning */
1788   uint flags;       /* isam layer flags (e.g. for myisamchk) */
1789   uint sql_flags;   /* sql layer flags - for something myisamchk cannot do */
1790   KEY_CACHE *key_cache;	/* new key cache when changing key cache */
1791   void init();
1792 } HA_CHECK_OPT;
1793 
1794 
1795 
1796 /*
1797   This is a buffer area that the handler can use to store rows.
1798   'end_of_used_area' should be kept updated after calls to
1799   read-functions so that other parts of the code can use the
1800   remaining area (until next read calls is issued).
1801 */
1802 
1803 typedef struct st_handler_buffer
1804 {
1805   uchar *buffer;         /* Buffer one can start using */
1806   uchar *buffer_end;     /* End of buffer */
1807   uchar *end_of_used_area;     /* End of area that was used by handler */
1808 } HANDLER_BUFFER;
1809 
1810 typedef struct system_status_var SSV;
1811 
1812 
1813 typedef void *range_seq_t;
1814 
1815 typedef struct st_range_seq_if
1816 {
1817   /*
1818     Initialize the traversal of range sequence
1819 
1820     SYNOPSIS
1821       init()
1822         init_params  The seq_init_param parameter
1823         n_ranges     The number of ranges obtained
1824         flags        A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
1825 
1826     RETURN
1827       An opaque value to be used as RANGE_SEQ_IF::next() parameter
1828   */
1829   range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
1830 
1831 
1832   /*
1833     Get the next range in the range sequence
1834 
1835     SYNOPSIS
1836       next()
1837         seq    The value returned by RANGE_SEQ_IF::init()
1838         range  OUT Information about the next range
1839 
1840     RETURN
1841       0 - Ok, the range structure filled with info about the next range
1842       1 - No more ranges
1843   */
1844   uint (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
1845 
1846   /*
1847     Check whether range_info orders to skip the next record
1848 
1849     SYNOPSIS
1850       skip_record()
1851         seq         The value returned by RANGE_SEQ_IF::init()
1852         range_info  Information about the next range
1853                     (Ignored if MRR_NO_ASSOCIATION is set)
1854         rowid       Rowid of the record to be checked (ignored if set to 0)
1855 
1856     RETURN
1857       1 - Record with this range_info and/or this rowid shall be filtered
1858           out from the stream of records returned by multi_range_read_next()
1859       0 - The record shall be left in the stream
1860   */
1861   bool (*skip_record) (range_seq_t seq, char *range_info, uchar *rowid);
1862 
1863   /*
1864     Check if the record combination matches the index condition
1865     SYNOPSIS
1866       skip_index_tuple()
1867         seq         The value returned by RANGE_SEQ_IF::init()
1868         range_info  Information about the next range
1869 
1870     RETURN
1871       0 - The record combination satisfies the index condition
1872       1 - Otherwise
1873   */
1874   bool (*skip_index_tuple) (range_seq_t seq, char *range_info);
1875 } RANGE_SEQ_IF;
1876 
1877 uint16 &mrr_persistent_flag_storage(range_seq_t seq, uint idx);
1878 char* &mrr_get_ptr_by_idx(range_seq_t seq, uint idx);
1879 
1880 /**
1881   Used to store optimizer cost estimates.
1882 
1883   The class consists of PODs only: default operator=, copy constructor
1884   and destructor are used.
1885  */
1886 class Cost_estimate
1887 {
1888 private:
1889   double io_cost;                               ///< cost of I/O operations
1890   double cpu_cost;                              ///< cost of CPU operations
1891   double import_cost;                           ///< cost of remote operations
1892   double mem_cost;                              ///< memory used (bytes)
1893 
1894 public:
Cost_estimate()1895   Cost_estimate() :
1896     io_cost(0),
1897     cpu_cost(0),
1898     import_cost(0),
1899     mem_cost(0)
1900   {}
1901 
1902   /// Returns sum of time-consuming costs, i.e., not counting memory cost
total_cost()1903   double total_cost() const  { return io_cost + cpu_cost + import_cost; }
get_io_cost()1904   double get_io_cost()     const { return io_cost; }
get_cpu_cost()1905   double get_cpu_cost()    const { return cpu_cost; }
get_import_cost()1906   double get_import_cost() const { return import_cost; }
get_mem_cost()1907   double get_mem_cost()    const { return mem_cost; }
1908 
1909   /**
1910     Whether or not all costs in the object are zero
1911 
1912     @return true if all costs are zero, false otherwise
1913   */
is_zero()1914   bool is_zero() const
1915   {
1916     return !(io_cost || cpu_cost || import_cost || mem_cost);
1917   }
1918   /**
1919     Whether or not the total cost is the maximal double
1920 
1921     @return true if total cost is the maximal double, false otherwise
1922   */
is_max_cost()1923   bool is_max_cost()  const { return io_cost == DBL_MAX; }
1924   /// Reset all costs to zero
reset()1925   void reset()
1926   {
1927     io_cost= cpu_cost= import_cost= mem_cost= 0;
1928   }
1929   /// Set current cost to the maximal double
set_max_cost()1930   void set_max_cost()
1931   {
1932     reset();
1933     io_cost= DBL_MAX;
1934   }
1935 
1936   /// Multiply io, cpu and import costs by parameter
multiply(double m)1937   void multiply(double m)
1938   {
1939     assert(!is_max_cost());
1940 
1941     io_cost *= m;
1942     cpu_cost *= m;
1943     import_cost *= m;
1944     /* Don't multiply mem_cost */
1945   }
1946 
1947   Cost_estimate& operator+= (const Cost_estimate &other)
1948   {
1949     assert(!is_max_cost() && !other.is_max_cost());
1950 
1951     io_cost+= other.io_cost;
1952     cpu_cost+= other.cpu_cost;
1953     import_cost+= other.import_cost;
1954     mem_cost+= other.mem_cost;
1955 
1956     return *this;
1957   }
1958 
1959   Cost_estimate operator+ (const Cost_estimate &other)
1960   {
1961     Cost_estimate result= *this;
1962     result+= other;
1963 
1964     return result;
1965   }
1966 
1967   Cost_estimate operator- (const Cost_estimate &other)
1968   {
1969     Cost_estimate result;
1970 
1971     assert(!other.is_max_cost());
1972 
1973     result.io_cost= io_cost - other.io_cost;
1974     result.cpu_cost= cpu_cost - other.cpu_cost;
1975     result.import_cost= import_cost - other.import_cost;
1976     result.mem_cost= mem_cost - other.mem_cost;
1977     return result;
1978   }
1979 
1980   bool operator> (const Cost_estimate &other) const
1981   {
1982     return total_cost() > other.total_cost() ? true : false;
1983   }
1984 
1985   bool operator< (const Cost_estimate &other) const
1986   {
1987     return other > *this ? true : false;
1988   }
1989 
1990   /// Add to IO cost
add_io(double add_io_cost)1991   void add_io(double add_io_cost)
1992   {
1993     assert(!is_max_cost());
1994     io_cost+= add_io_cost;
1995   }
1996 
1997   /// Add to CPU cost
add_cpu(double add_cpu_cost)1998   void add_cpu(double add_cpu_cost)
1999   {
2000     assert(!is_max_cost());
2001     cpu_cost+= add_cpu_cost;
2002   }
2003 
2004   /// Add to import cost
add_import(double add_import_cost)2005   void add_import(double add_import_cost)
2006   {
2007     assert(!is_max_cost());
2008     import_cost+= add_import_cost;
2009   }
2010 
2011   /// Add to memory cost
add_mem(double add_mem_cost)2012   void add_mem(double add_mem_cost)
2013   {
2014     assert(!is_max_cost());
2015     mem_cost+= add_mem_cost;
2016   }
2017 };
2018 
2019 void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
2020                          Cost_estimate *cost);
2021 
2022 /*
2023   The below two are not used (and not handled) in this milestone of this WL
2024   entry because there seems to be no use for them at this stage of
2025   implementation.
2026 */
2027 #define HA_MRR_SINGLE_POINT 1
2028 #define HA_MRR_FIXED_KEY  2
2029 
2030 /*
2031   Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
2032   'range' parameter.
2033 */
2034 #define HA_MRR_NO_ASSOCIATION 4
2035 
2036 /*
2037   The MRR user will provide ranges in key order, and MRR implementation
2038   must return rows in key order.
2039   Passing this flag to multi_read_range_init() may cause the
2040   default MRR handler to be used even if HA_MRR_USE_DEFAULT_IMPL
2041   was not specified.
2042   (If the native MRR impl. can not provide SORTED result)
2043 */
2044 #define HA_MRR_SORTED 8
2045 
2046 /* MRR implementation doesn't have to retrieve full records */
2047 #define HA_MRR_INDEX_ONLY 16
2048 
2049 /*
2050   The passed memory buffer is of maximum possible size, the caller can't
2051   assume larger buffer.
2052 */
2053 #define HA_MRR_LIMITS 32
2054 
2055 
2056 /*
2057   Flag set <=> default MRR implementation is used
2058   (The choice is made by **_info[_const]() function which may set this
2059    flag. SQL layer remembers the flag value and then passes it to
2060    multi_read_range_init().
2061 */
2062 #define HA_MRR_USE_DEFAULT_IMPL 64
2063 
2064 /*
2065   Used only as parameter to multi_range_read_info():
2066   Flag set <=> the caller guarantees that the bounds of the scanned ranges
2067   will not have NULL values.
2068 */
2069 #define HA_MRR_NO_NULL_ENDPOINTS 128
2070 
2071 /*
2072   Set by the MRR implementation to signal that it will natively
2073   produced sorted result if multi_range_read_init() is called with
2074   the HA_MRR_SORTED flag - Else multi_range_read_init(HA_MRR_SORTED)
2075   will revert to use the default MRR implementation.
2076 */
2077 #define HA_MRR_SUPPORT_SORTED 256
2078 
2079 
2080 class ha_statistics
2081 {
2082 public:
2083   ulonglong data_file_length;		/* Length off data file */
2084   ulonglong max_data_file_length;	/* Length off data file */
2085   ulonglong index_file_length;
2086   ulonglong max_index_file_length;
2087   ulonglong delete_length;		/* Free bytes */
2088   ulonglong auto_increment_value;
2089   /*
2090     The number of records in the table.
2091       0    - means the table has exactly 0 rows
2092     other  - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
2093                the value is the exact number of records in the table
2094              else
2095                it is an estimate
2096   */
2097   ha_rows records;
2098   ha_rows deleted;			/* Deleted records */
2099   ulong mean_rec_length;		/* physical reclength */
2100   time_t create_time;			/* When table was created */
2101   ulong check_time;
2102   ulong update_time;
2103   uint block_size;			/* index block size */
2104 
2105   /*
2106     number of buffer bytes that native mrr implementation needs,
2107   */
2108   uint mrr_length_per_rec;
2109 
2110   /**
2111     Estimate for how much of the table that is availabe in a memory
2112     buffer. Valid range is [0..1]. If it has the special value
2113     IN_MEMORY_ESTIMATE_UNKNOWN (defined in structs.h), it means that
2114     the storage engine has not supplied any value for it.
2115   */
2116   double table_in_mem_estimate;
2117 
ha_statistics()2118   ha_statistics():
2119     data_file_length(0), max_data_file_length(0),
2120     index_file_length(0), delete_length(0), auto_increment_value(0),
2121     records(0), deleted(0), mean_rec_length(0), create_time(0),
2122     check_time(0), update_time(0), block_size(0),
2123     table_in_mem_estimate(IN_MEMORY_ESTIMATE_UNKNOWN)
2124   {}
2125 };
2126 
2127 /**
2128   Calculates length of key.
2129 
2130   Given a key index and a map of key parts return length of buffer used by key
2131   parts.
2132 
2133   @param  table        Table containing the key
2134   @param  key          Key index
2135   @param  keypart_map  which key parts that is used
2136 
2137   @return Length of used key parts.
2138 */
2139 uint calculate_key_len(TABLE *table, uint key,
2140                        key_part_map keypart_map);
2141 /*
2142   bitmap with first N+1 bits set
2143   (keypart_map for a key prefix of [0..N] keyparts)
2144 */
2145 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
2146 /*
2147   bitmap with first N bits set
2148   (keypart_map for a key prefix of [0..N-1] keyparts)
2149 */
2150 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
2151 
2152 
2153 /** Base class to be used by handlers different shares */
2154 class Handler_share
2155 {
2156 public:
Handler_share()2157   Handler_share() {}
~Handler_share()2158   virtual ~Handler_share() {}
2159 };
2160 
2161 
2162 /**
2163   Wrapper for struct ft_hints.
2164 */
2165 
2166 class Ft_hints: public Sql_alloc
2167 {
2168 private:
2169   struct ft_hints hints;
2170 
2171 public:
Ft_hints(uint ft_flags)2172   Ft_hints(uint ft_flags)
2173   {
2174     hints.flags= ft_flags;
2175     hints.op_type= FT_OP_UNDEFINED;
2176     hints.op_value= 0.0;
2177     hints.limit= HA_POS_ERROR;
2178   }
2179 
2180   /**
2181     Set comparison operation type and and value for master MATCH function.
2182 
2183      @param type   comparison operation type
2184      @param value  comparison operation value
2185   */
set_hint_op(enum ft_operation type,double value)2186   void set_hint_op(enum ft_operation type, double value)
2187   {
2188     hints.op_type= type;
2189     hints.op_value= value;
2190   }
2191 
2192   /**
2193     Set Ft_hints flag.
2194 
2195     @param ft_flag Ft_hints flag
2196   */
set_hint_flag(uint ft_flag)2197   void set_hint_flag(uint ft_flag)
2198   {
2199     hints.flags|= ft_flag;
2200   }
2201 
2202   /**
2203     Set Ft_hints limit.
2204 
2205     @param Ft_hints limit
2206   */
set_hint_limit(ha_rows ft_limit)2207   void set_hint_limit(ha_rows ft_limit)
2208   {
2209     hints.limit= ft_limit;
2210   }
2211 
2212   /**
2213     Get Ft_hints limit.
2214 
2215     @return Ft_hints limit
2216   */
get_limit()2217   ha_rows get_limit()
2218   {
2219     return hints.limit;
2220   }
2221 
2222   /**
2223     Get Ft_hints operation value.
2224 
2225     @return operation value
2226   */
get_op_value()2227   double get_op_value()
2228   {
2229     return hints.op_value;
2230   }
2231 
2232   /**
2233     Get Ft_hints operation type.
2234 
2235     @return operation type
2236   */
get_op_type()2237   enum ft_operation get_op_type()
2238   {
2239     return hints.op_type;
2240   }
2241 
2242   /**
2243     Get Ft_hints flags.
2244 
2245     @return Ft_hints flags
2246   */
get_flags()2247   uint get_flags()
2248   {
2249     return hints.flags;
2250   }
2251 
2252  /**
2253     Get ft_hints struct.
2254 
2255     @return pointer to ft_hints struct
2256   */
get_hints()2257   struct ft_hints* get_hints()
2258   {
2259     return &hints;
2260   }
2261 };
2262 
2263 
2264 /**
2265   The handler class is the interface for dynamically loadable
2266   storage engines. Do not add ifdefs and take care when adding or
2267   changing virtual functions to avoid vtable confusion
2268 
2269   Functions in this class accept and return table columns data. Two data
2270   representation formats are used:
2271   1. TableRecordFormat - Used to pass [partial] table records to/from
2272      storage engine
2273 
2274   2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
2275      storage engine. See opt_range.cc for description of this format.
2276 
2277   TableRecordFormat
2278   =================
2279   [Warning: this description is work in progress and may be incomplete]
2280   The table record is stored in a fixed-size buffer:
2281 
2282     record: null_bytes, column1_data, column2_data, ...
2283 
2284   The offsets of the parts of the buffer are also fixed: every column has
2285   an offset to its column{i}_data, and if it is nullable it also has its own
2286   bit in null_bytes.
2287 
2288   The record buffer only includes data about columns that are marked in the
2289   relevant column set (table->read_set and/or table->write_set, depending on
2290   the situation).
2291   <not-sure>It could be that it is required that null bits of non-present
2292   columns are set to 1</not-sure>
2293 
2294   VARIOUS EXCEPTIONS AND SPECIAL CASES
2295 
2296   f the table has no nullable columns, then null_bytes is still
2297   present, its length is one byte <not-sure> which must be set to 0xFF
2298   at all times. </not-sure>
2299 
2300   If the table has columns of type BIT, then certain bits from those columns
2301   may be stored in null_bytes as well. Grep around for Field_bit for
2302   details.
2303 
2304   For blob columns (see Field_blob), the record buffer stores length of the
2305   data, following by memory pointer to the blob data. The pointer is owned
2306   by the storage engine and is valid until the next operation.
2307 
2308   If a blob column has NULL value, then its length and blob data pointer
2309   must be set to 0.
2310 */
2311 
2312 class handler :public Sql_alloc
2313 {
2314   friend class Partition_handler;
2315 public:
2316   typedef ulonglong Table_flags;
2317 protected:
2318   TABLE_SHARE *table_share;             /* The table definition */
2319   TABLE *table;                         /* The current open table */
2320   mutable Table_flags cached_table_flags;  /* Set on init() and open() */
2321 
2322   ha_rows estimation_rows_to_insert;
2323 public:
2324   handlerton *ht;                 /* storage engine of this handler */
2325   uchar *ref;				/* Pointer to current row */
2326   uchar *dup_ref;			/* Pointer to duplicate row */
2327 
2328   ha_statistics stats;
2329 
2330   /* MultiRangeRead-related members: */
2331   range_seq_t mrr_iter;    /* Interator to traverse the range sequence */
2332   RANGE_SEQ_IF mrr_funcs;  /* Range sequence traversal functions */
2333   HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
2334   uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
2335   /* TRUE <=> source MRR ranges and the output are ordered */
2336   bool mrr_is_output_sorted;
2337 
2338   /* TRUE <=> we're currently traversing a range in mrr_cur_range. */
2339   bool mrr_have_range;
2340   /* Current range (the one we're now returning rows from) */
2341   KEY_MULTI_RANGE mrr_cur_range;
2342 
2343   /*
2344     The direction of the current range or index scan. This is used by
2345     the ICP implementation to determine if it has reached the end
2346     of the current range.
2347   */
2348   enum enum_range_scan_direction {
2349     RANGE_SCAN_ASC,
2350     RANGE_SCAN_DESC
2351   };
2352 private:
2353   /*
2354     Storage space for the end range value. Should only be accessed using
2355     the end_range pointer. The content is invalid when end_range is NULL.
2356   */
2357   key_range save_end_range;
2358   enum_range_scan_direction range_scan_direction;
2359   int key_compare_result_on_equal;
2360 
2361 protected:
2362   KEY_PART_INFO *range_key_part;
2363   bool eq_range;
2364   /*
2365     TRUE <=> the engine guarantees that returned records are within the range
2366     being scanned.
2367   */
2368   bool in_range_check_pushed_down;
2369 
2370 public:
2371   /*
2372     End value for a range scan. If this is NULL the range scan has no
2373     end value. Should also be NULL when there is no ongoing range scan.
2374     Used by the read_range() functions and also evaluated by pushed
2375     index conditions.
2376   */
2377   key_range *end_range;
2378   /**
2379     Flag which tells if #end_range contains a virtual generated column.
2380     The content is invalid when #end_range is NULL.
2381   */
2382   bool m_virt_gcol_in_end_range;
2383   uint errkey;				/* Last dup key */
2384   uint key_used_on_scan;
2385   uint active_index;
2386   /** Length of ref (1-8 or the clustered key length) */
2387   uint ref_length;
2388   FT_INFO *ft_handler;
2389   enum {NONE=0, INDEX, RND} inited;
2390   bool implicit_emptied;                /* Can be !=0 only if HEAP */
2391   const Item *pushed_cond;
2392 
2393   Item *pushed_idx_cond;
2394   uint pushed_idx_cond_keyno;  /* The index which the above condition is for */
2395 
2396   ulonglong rows_read;
2397   ulonglong rows_changed;
2398   ulonglong index_rows_read[MAX_KEY];
2399   /**
2400     next_insert_id is the next value which should be inserted into the
2401     auto_increment column: in a inserting-multi-row statement (like INSERT
2402     SELECT), for the first row where the autoinc value is not specified by the
2403     statement, get_auto_increment() called and asked to generate a value,
2404     next_insert_id is set to the next value, then for all other rows
2405     next_insert_id is used (and increased each time) without calling
2406     get_auto_increment().
2407   */
2408   ulonglong next_insert_id;
2409   /**
2410     insert id for the current row (*autogenerated*; if not
2411     autogenerated, it's 0).
2412     At first successful insertion, this variable is stored into
2413     THD::first_successful_insert_id_in_cur_stmt.
2414   */
2415   ulonglong insert_id_for_cur_row;
2416   /**
2417     Interval returned by get_auto_increment() and being consumed by the
2418     inserter.
2419   */
2420   Discrete_interval auto_inc_interval_for_cur_row;
2421   /**
2422      Number of reserved auto-increment intervals. Serves as a heuristic
2423      when we have no estimation of how many records the statement will insert:
2424      the more intervals we have reserved, the bigger the next one. Reset in
2425      handler::ha_release_auto_increment().
2426   */
2427   uint auto_inc_intervals_count;
2428 
2429   /**
2430     Instrumented table associated with this handler.
2431   */
2432   PSI_table *m_psi;
2433 
2434 private:
2435   /** Internal state of the batch instrumentation. */
2436   enum batch_mode_t
2437   {
2438     /** Batch mode not used. */
2439     PSI_BATCH_MODE_NONE,
2440     /** Batch mode used, before first table io. */
2441     PSI_BATCH_MODE_STARTING,
2442     /** Batch mode used, after first table io. */
2443     PSI_BATCH_MODE_STARTED
2444   };
2445   /**
2446     Batch mode state.
2447     @sa start_psi_batch_mode.
2448     @sa end_psi_batch_mode.
2449   */
2450   batch_mode_t m_psi_batch_mode;
2451   /**
2452     The number of rows in the batch.
2453     @sa start_psi_batch_mode.
2454     @sa end_psi_batch_mode.
2455   */
2456   ulonglong m_psi_numrows;
2457   /**
2458     The current event in a batch.
2459     @sa start_psi_batch_mode.
2460     @sa end_psi_batch_mode.
2461   */
2462   PSI_table_locker *m_psi_locker;
2463   /**
2464     Storage for the event in a batch.
2465     @sa start_psi_batch_mode.
2466     @sa end_psi_batch_mode.
2467   */
2468   PSI_table_locker_state m_psi_locker_state;
2469 
2470 public:
2471   virtual void unbind_psi();
2472   virtual void rebind_psi();
2473   /**
2474     Put the handler in 'batch' mode when collecting
2475     table io instrumented events.
2476     When operating in batch mode:
2477     - a single start event is generated in the performance schema.
2478     - all table io performed between @c start_psi_batch_mode
2479       and @c end_psi_batch_mode is not instrumented:
2480       the number of rows affected is counted instead in @c m_psi_numrows.
2481     - a single end event is generated in the performance schema
2482       when the batch mode ends with @c end_psi_batch_mode.
2483   */
2484   void start_psi_batch_mode();
2485   /** End a batch started with @c start_psi_batch_mode. */
2486   void end_psi_batch_mode();
2487 
2488 private:
2489   friend class DsMrr_impl;
2490   /**
2491     The lock type set by when calling::ha_external_lock(). This is
2492     propagated down to the storage engine. The reason for also storing
2493     it here, is that when doing MRR we need to create/clone a second handler
2494     object. This cloned handler object needs to know about the lock_type used.
2495   */
2496   int m_lock_type;
2497   /**
2498     Pointer where to store/retrieve the Handler_share pointer.
2499     For non partitioned handlers this is &TABLE_SHARE::ha_share.
2500   */
2501   Handler_share **ha_share;
2502 
2503   /**
2504     Some non-virtual ha_* functions, responsible for reading rows,
2505     like ha_rnd_pos(), must ensure that virtual generated columns are
2506     calculated before they return. For that, they should set this
2507     member to true at their start, and check it before they return: if
2508     the member is still true, it means they should calculate; if it's
2509     false, it means the calculation has been done by some called
2510     lower-level function and does not need to be re-done (which is why
2511     we need this status flag: to avoid redundant calculations, for
2512     performance).
2513   */
2514   bool m_update_generated_read_fields;
2515 
2516 public:
handler(handlerton * ht_arg,TABLE_SHARE * share_arg)2517   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
2518     :table_share(share_arg), table(0),
2519     estimation_rows_to_insert(0), ht(ht_arg),
2520     ref(0), range_scan_direction(RANGE_SCAN_ASC),
2521     in_range_check_pushed_down(false), end_range(NULL),
2522     m_virt_gcol_in_end_range(false),
2523     key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
2524     ref_length(sizeof(my_off_t)),
2525     ft_handler(0), inited(NONE),
2526     implicit_emptied(0),
2527     pushed_cond(0), pushed_idx_cond(NULL),
2528     pushed_idx_cond_keyno(MAX_KEY), rows_read(0), rows_changed(0),
2529     next_insert_id(0), insert_id_for_cur_row(0),
2530     auto_inc_intervals_count(0),
2531     m_psi(NULL),
2532     m_psi_batch_mode(PSI_BATCH_MODE_NONE),
2533     m_psi_numrows(0),
2534     m_psi_locker(NULL),
2535     m_lock_type(F_UNLCK), ha_share(NULL),
2536     m_update_generated_read_fields(false), cloned(false)
2537     {
2538       DBUG_PRINT("info",
2539                  ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
2540                   F_UNLCK, F_RDLCK, F_WRLCK));
2541       memset(index_rows_read, 0, sizeof(index_rows_read));
2542     }
~handler(void)2543   virtual ~handler(void)
2544   {
2545     assert(m_psi == NULL);
2546     assert(m_psi_batch_mode == PSI_BATCH_MODE_NONE);
2547     assert(m_psi_locker == NULL);
2548     assert(m_lock_type == F_UNLCK);
2549     assert(inited == NONE);
2550   }
2551   /* TODO: reorganize the methods and have proper public/protected/private qualifiers!!! */
2552   virtual handler *clone(const char *name, MEM_ROOT *mem_root);
2553   /** This is called after create to allow us to set up cached variables */
init()2554   void init()
2555   {
2556     cached_table_flags= table_flags();
2557   }
2558   /**
2559     For MyRocks, secondary initialization that happens after frm is parsed into
2560     field information from within open_binary_frm. MyRocks uses this secondary
2561     init phase to analyze the key and field definitions to determine if
2562     HA_PRIMARY_KEY_IN_READ_INDEX flag is available for the table as it only
2563     supports that behavior for certain types of key combinations. The
2564     HA_PRIMARY_KEY_IN_READ_INDEX flag is enabled by default till this method
2565     invocation and can be disabled here in case it isn't supported.
2566     Return values: false success, true failure.
2567   */
init_with_fields()2568   virtual bool init_with_fields() { return false; }
2569   /* ha_ methods: public wrappers for private virtual API */
2570 
2571   int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
2572   int ha_close(void);
2573   int ha_index_init(uint idx, bool sorted);
2574   int ha_index_end();
2575   int ha_rnd_init(bool scan);
2576   int ha_rnd_end();
2577   int ha_rnd_next(uchar *buf);
2578   int ha_rnd_pos(uchar * buf, uchar *pos);
2579   int ha_index_read_map(uchar *buf, const uchar *key,
2580                         key_part_map keypart_map,
2581                         enum ha_rkey_function find_flag);
2582   int ha_index_read_last_map(uchar * buf, const uchar * key,
2583                              key_part_map keypart_map);
2584   int ha_index_read_idx_map(uchar *buf, uint index, const uchar *key,
2585                            key_part_map keypart_map,
2586                            enum ha_rkey_function find_flag);
2587   int ha_index_next(uchar * buf);
2588   int ha_index_prev(uchar * buf);
2589   int ha_index_first(uchar * buf);
2590   int ha_index_last(uchar * buf);
2591   int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
2592   int ha_reset();
2593   /* this is necessary in many places, e.g. in HANDLER command */
ha_index_or_rnd_end()2594   int ha_index_or_rnd_end()
2595   {
2596     return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
2597   }
2598   /**
2599     The cached_table_flags is set at ha_open and ha_external_lock
2600 
2601     @param recalculate[in]  Force flags recalculation instead of using cached
2602     value.
2603 
2604     @retval                 table flags
2605   */
2606   Table_flags ha_table_flags(bool recalculate = false) const
2607   {
2608     if (recalculate)
2609       cached_table_flags= table_flags();
2610     return cached_table_flags;
2611   }
2612 
2613   /**
2614     These functions represent the public interface to *users* of the
2615     handler class, hence they are *not* virtual. For the inheritance
2616     interface, see the (private) functions write_row(), update_row(),
2617     and delete_row() below.
2618   */
2619   int ha_external_lock(THD *thd, int lock_type);
2620   int ha_write_row(uchar * buf);
2621   int ha_update_row(const uchar * old_data, uchar * new_data);
2622   int ha_delete_row(const uchar * buf);
2623   void ha_release_auto_increment();
2624 
2625   int check_collation_compatibility();
2626   int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
2627   /** to be actually called to get 'check()' functionality*/
2628   int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
2629   int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
2630   void ha_start_bulk_insert(ha_rows rows);
2631   int ha_end_bulk_insert();
2632   int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
2633                          uint *dup_key_found);
2634   int ha_delete_all_rows();
2635   int ha_truncate();
2636   int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
2637   int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
2638   bool ha_check_and_repair(THD *thd);
2639   int ha_disable_indexes(uint mode);
2640   int ha_enable_indexes(uint mode);
2641   int ha_discard_or_import_tablespace(my_bool discard);
2642   int ha_rename_table(const char *from, const char *to);
2643   int ha_delete_table(const char *name);
2644   void ha_drop_table(const char *name);
2645 
2646   int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
2647 
2648   int ha_create_handler_files(const char *name, const char *old_name,
2649                               int action_flag, HA_CREATE_INFO *info);
2650 
2651   void adjust_next_insert_id_after_explicit_value(ulonglong nr);
2652   int update_auto_increment();
2653   virtual void print_error(int error, myf errflag);
2654   virtual bool get_error_message(int error, String *buf);
2655   uint get_dup_key(int error);
2656   /**
2657     Retrieves the names of the table and the key for which there was a
2658     duplicate entry in the case of HA_ERR_FOREIGN_DUPLICATE_KEY.
2659 
2660     If any of the table or key name is not available this method will return
2661     false and will not change any of child_table_name or child_key_name.
2662 
2663     @param child_table_name[out]    Table name
2664     @param child_table_name_len[in] Table name buffer size
2665     @param child_key_name[out]      Key name
2666     @param child_key_name_len[in]   Key name buffer size
2667 
2668     @retval  true                  table and key names were available
2669                                    and were written into the corresponding
2670                                    out parameters.
2671     @retval  false                 table and key names were not available,
2672                                    the out parameters were not touched.
2673   */
get_foreign_dup_key(char * child_table_name,uint child_table_name_len,char * child_key_name,uint child_key_name_len)2674   virtual bool get_foreign_dup_key(char *child_table_name,
2675                                    uint child_table_name_len,
2676                                    char *child_key_name,
2677                                    uint child_key_name_len)
2678   { assert(false); return(false); }
change_table_ptr(TABLE * table_arg,TABLE_SHARE * share)2679   virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
2680   {
2681     table= table_arg;
2682     table_share= share;
2683     rows_read= rows_changed= 0;
2684     memset(index_rows_read, 0, sizeof(index_rows_read));
2685   }
2686   /* Estimates calculation */
2687 
2688   /**
2689     @deprecated This function is deprecated and will be removed in a future
2690                 version. Use table_scan_cost() instead.
2691   */
2692 
scan_time()2693   virtual double scan_time()
2694   { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
2695 
2696   /**
2697     The cost of reading a set of ranges from the table using an index
2698     to access it.
2699 
2700     @deprecated This function is deprecated and will be removed in a future
2701                 version. Use read_cost() instead.
2702 
2703     @param index  The index number.
2704     @param ranges The number of ranges to be read.
2705     @param rows   Total number of rows to be read.
2706 
2707     This method can be used to calculate the total cost of scanning a table
2708     using an index by calling it using read_time(index, 1, table_size).
2709   */
2710 
read_time(uint index,uint ranges,ha_rows rows)2711   virtual double read_time(uint index, uint ranges, ha_rows rows)
2712   { return rows2double(ranges+rows); }
2713 
2714   /**
2715     @deprecated This function is deprecated and will be removed in a future
2716                 version. Use index_scan_cost() instead.
2717   */
2718 
2719   virtual double index_only_read_time(uint keynr, double records);
2720 
2721   /**
2722     Cost estimate for doing a complete table scan.
2723 
2724     @note For this version it is recommended that storage engines continue
2725     to override scan_time() instead of this function.
2726 
2727     @returns the estimated cost
2728   */
2729 
2730   virtual Cost_estimate table_scan_cost();
2731 
2732   /**
2733     Cost estimate for reading a number of ranges from an index.
2734 
2735     The cost estimate will only include the cost of reading data that
2736     is contained in the index. If the records need to be read, use
2737     read_cost() instead.
2738 
2739     @note The ranges parameter is currently ignored and is not taken
2740     into account in the cost estimate.
2741 
2742     @note For this version it is recommended that storage engines continue
2743     to override index_only_read_time() instead of this function.
2744 
2745     @param index  the index number
2746     @param ranges the number of ranges to be read
2747     @param rows   total number of rows to be read
2748 
2749     @returns the estimated cost
2750   */
2751 
2752   virtual Cost_estimate index_scan_cost(uint index, double ranges, double rows);
2753 
2754   /**
2755     Cost estimate for reading a set of ranges from the table using an index
2756     to access it.
2757 
2758     @note For this version it is recommended that storage engines continue
2759     to override read_time() instead of this function.
2760 
2761     @param index  the index number
2762     @param ranges the number of ranges to be read
2763     @param rows   total number of rows to be read
2764 
2765     @returns the estimated cost
2766   */
2767 
2768   virtual Cost_estimate read_cost(uint index, double ranges, double rows);
2769 
2770   /**
2771     Return an estimate on the amount of memory the storage engine will
2772     use for caching data in memory. If this is unknown or the storage
2773     engine does not cache data in memory -1 is returned.
2774   */
get_memory_buffer_size()2775   virtual longlong get_memory_buffer_size() const { return -1; }
2776 
2777   /**
2778     Return an estimate of how much of the table that is currently stored
2779     in main memory.
2780 
2781     This estimate should be the fraction of the table that currently
2782     is available in a main memory buffer. The estimate should be in the
2783     range from 0.0 (nothing in memory) to 1.0 (entire table in memory).
2784 
2785     @return The fraction of the table in main memory buffer
2786   */
2787 
2788   double table_in_memory_estimate() const;
2789 
2790   /**
2791     Return an estimate of how much of the index that is currently stored
2792     in main memory.
2793 
2794     This estimate should be the fraction of the index that currently
2795     is available in a main memory buffer. The estimate should be in the
2796     range from 0.0 (nothing in memory) to 1.0 (entire index in memory).
2797 
2798     @param keyno the index to get an estimate for
2799 
2800     @return The fraction of the index in main memory buffer
2801   */
2802 
2803   double index_in_memory_estimate(uint keyno) const;
2804 
2805 private:
2806   /**
2807     Make a guestimate for how much of a table or index is in a memory
2808     buffer in the case where the storage engine has not provided any
2809     estimate for this.
2810 
2811     @param table_index_size size of the table or index
2812 
2813     @return The fraction of the table or index in main memory buffer
2814   */
2815 
2816   double estimate_in_memory_buffer(ulonglong table_index_size) const;
2817 
2818 public:
2819   virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
2820                                               void *seq_init_param,
2821                                               uint n_ranges, uint *bufsz,
2822                                               uint *flags,
2823                                               Cost_estimate *cost);
2824   virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
2825                                         uint *bufsz, uint *flags,
2826                                         Cost_estimate *cost);
2827   virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
2828                                     uint n_ranges, uint mode,
2829                                     HANDLER_BUFFER *buf);
2830   virtual int multi_range_read_next(char **range_info);
2831 
2832 
keys_to_use_for_scanning()2833   virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
has_transactions()2834   bool has_transactions() const
2835   { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
extra_rec_buf_length()2836   virtual uint extra_rec_buf_length() const { return 0; }
2837 
2838   /**
2839     @brief Determine whether an error can be ignored or not.
2840 
2841     @details This method is used to analyze the error to see whether the
2842     error is ignorable or not. Such errors will be reported as warnings
2843     instead of errors for IGNORE statements. This means that the statement
2844     will not abort, but instead continue to the next row.
2845 
2846     HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
2847     same thing as HA_ERR_FOUND_DUP_KEY, but can in some cases lead to
2848     a slightly different error message.
2849 
2850     @param error  error code received from the handler interface (HA_ERR_...)
2851 
2852     @return   whether the error is ignorablel or not
2853       @retval true  the error is ignorable
2854       @retval false the error is not ignorable
2855   */
2856 
2857   virtual bool is_ignorable_error(int error);
2858 
2859   /**
2860     @brief Determine whether an error is fatal or not.
2861 
2862     @details This method is used to analyze the error to see whether the
2863     error is fatal or not. A fatal error is an error that will not be
2864     possible to handle with SP handlers and will not be subject to
2865     retry attempts on the slave.
2866 
2867     @param error  error code received from the handler interface (HA_ERR_...)
2868 
2869     @return   whether the error is fatal or not
2870       @retval true  the error is fatal
2871       @retval false the error is not fatal
2872   */
2873 
2874   virtual bool is_fatal_error(int error);
2875 
2876 protected:
2877   /**
2878     Number of rows in table. It will only be called if
2879     (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
2880     @param[out]  num_rows number of rows in table.
2881     @retval 0 for OK, one of the HA_xxx values in case of error.
2882   */
records(ha_rows * num_rows)2883   virtual int records(ha_rows *num_rows)
2884   {
2885     *num_rows= stats.records;
2886     return 0;
2887   }
2888 
2889 public:
2890  /**
2891    Public function wrapping the actual handler call, and doing error checking.
2892     @param[out]  num_rows number of rows in table.
2893     @retval 0 for OK, one of the HA_xxx values in case of error.
2894  */
ha_records(ha_rows * num_rows)2895   int ha_records(ha_rows *num_rows)
2896   {
2897     int error= records(num_rows);
2898     // A return value of HA_POS_ERROR was previously used to indicate error.
2899     if (error != 0)
2900       assert(*num_rows == HA_POS_ERROR);
2901     if (*num_rows == HA_POS_ERROR)
2902       assert(error != 0);
2903     if (error != 0)
2904     {
2905       /*
2906         ha_innobase::records may have rolled back internally.
2907         In this case, thd_mark_transaction_to_rollback() will have been called.
2908         For the errors below, we need to abort right away.
2909       */
2910       switch (error) {
2911       case HA_ERR_LOCK_DEADLOCK:
2912       case HA_ERR_LOCK_TABLE_FULL:
2913       case HA_ERR_LOCK_WAIT_TIMEOUT:
2914       case HA_ERR_QUERY_INTERRUPTED:
2915         print_error(error, MYF(0));
2916         return error;
2917       default:
2918         return error;
2919       }
2920     }
2921     return 0;
2922   }
2923 
2924   /**
2925     Return upper bound of current number of records in the table
2926     (max. of how many records one will retrieve when doing a full table scan)
2927     If upper bound is not known, HA_POS_ERROR should be returned as a max
2928     possible upper bound.
2929   */
estimate_rows_upper_bound()2930   virtual ha_rows estimate_rows_upper_bound()
2931   { return stats.records+EXTRA_RECORDS; }
2932 
2933   /**
2934     Get the row type from the storage engine.  If this method returns
2935     ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
2936   */
get_row_type()2937   virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
2938 
index_type(uint key_number)2939   virtual const char *index_type(uint key_number) { assert(0); return "";}
2940 
2941 
2942   /**
2943     Signal that the table->read_set and table->write_set table maps changed
2944     The handler is allowed to set additional bits in the above map in this
2945     call. Normally the handler should ignore all calls until we have done
2946     a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
2947     as there may be several calls to this routine.
2948   */
2949   virtual void column_bitmaps_signal();
get_index(void)2950   uint get_index(void) const { return active_index; }
2951 
2952   /**
2953     @retval  0   Bulk update used by handler
2954     @retval  1   Bulk update not used, normal operation used
2955   */
start_bulk_update()2956   virtual bool start_bulk_update() { return 1; }
2957   /**
2958     @retval  0   Bulk delete used by handler
2959     @retval  1   Bulk delete not used, normal operation used
2960   */
start_bulk_delete()2961   virtual bool start_bulk_delete() { return 1; }
2962   /**
2963     After this call all outstanding updates must be performed. The number
2964     of duplicate key errors are reported in the duplicate key parameter.
2965     It is allowed to continue to the batched update after this call, the
2966     handler has to wait until end_bulk_update with changing state.
2967 
2968     @param    dup_key_found       Number of duplicate keys found
2969 
2970     @retval  0           Success
2971     @retval  >0          Error code
2972   */
exec_bulk_update(uint * dup_key_found)2973   virtual int exec_bulk_update(uint *dup_key_found)
2974   {
2975     assert(FALSE);
2976     return HA_ERR_WRONG_COMMAND;
2977   }
2978   /**
2979     Perform any needed clean-up, no outstanding updates are there at the
2980     moment.
2981   */
end_bulk_update()2982   virtual void end_bulk_update() { return; }
2983   /**
2984     Execute all outstanding deletes and close down the bulk delete.
2985 
2986     @retval 0             Success
2987     @retval >0            Error code
2988   */
end_bulk_delete()2989   virtual int end_bulk_delete()
2990   {
2991     assert(FALSE);
2992     return HA_ERR_WRONG_COMMAND;
2993   }
2994 protected:
2995   /**
2996      @brief
2997      Positions an index cursor to the index specified in the handle
2998      ('active_index'). Fetches the row if available. If the key value is null,
2999      begin at the first key of the index.
3000      @returns 0 if success (found a record, and function has set table->status
3001      to 0); non-zero if no record (function has set table->status to
3002      STATUS_NOT_FOUND).
3003   */
index_read_map(uchar * buf,const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag)3004   virtual int index_read_map(uchar * buf, const uchar * key,
3005                              key_part_map keypart_map,
3006                              enum ha_rkey_function find_flag)
3007   {
3008     uint key_len= calculate_key_len(table, active_index, keypart_map);
3009     return  index_read(buf, key, key_len, find_flag);
3010   }
3011   /**
3012      @brief
3013      Positions an index cursor to the index specified in argument. Fetches
3014      the row if available. If the key value is null, begin at the first key of
3015      the index.
3016      @returns @see index_read_map().
3017   */
3018   virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
3019                                  key_part_map keypart_map,
3020                                  enum ha_rkey_function find_flag);
3021   /// @returns @see index_read_map().
index_next(uchar * buf)3022   virtual int index_next(uchar * buf)
3023    { return  HA_ERR_WRONG_COMMAND; }
3024   /// @returns @see index_read_map().
index_prev(uchar * buf)3025   virtual int index_prev(uchar * buf)
3026    { return  HA_ERR_WRONG_COMMAND; }
3027   /// @returns @see index_read_map().
index_first(uchar * buf)3028   virtual int index_first(uchar * buf)
3029    { return  HA_ERR_WRONG_COMMAND; }
3030   /// @returns @see index_read_map().
index_last(uchar * buf)3031   virtual int index_last(uchar * buf)
3032    { return  HA_ERR_WRONG_COMMAND; }
3033   /// @returns @see index_read_map().
3034   virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
3035   /**
3036      @brief
3037      The following functions works like index_read, but it find the last
3038      row with the current key value or prefix.
3039      @returns @see index_read_map().
3040   */
index_read_last_map(uchar * buf,const uchar * key,key_part_map keypart_map)3041   virtual int index_read_last_map(uchar * buf, const uchar * key,
3042                                   key_part_map keypart_map)
3043   {
3044     uint key_len= calculate_key_len(table, active_index, keypart_map);
3045     return index_read_last(buf, key, key_len);
3046   }
3047 public:
3048 
3049   /**
3050     Notify storage engine about imminent index scan where a large number of
3051     rows is expected to be returned. Does not replace nor call index_init.
3052   */
prepare_index_scan(void)3053   virtual int prepare_index_scan(void) { return 0; }
3054 
3055   /**
3056     Notify storage engine about imminent index range scan.
3057   */
prepare_range_scan(const key_range * start_key,const key_range * end_key)3058   virtual int prepare_range_scan(const key_range *start_key,
3059                                  const key_range *end_key)
3060   {
3061     return 0;
3062   }
3063 
3064   /**
3065     Notify storage engine about imminent index read with a bitmap of used key
3066     parts.
3067   */
prepare_index_key_scan_map(const uchar * key,key_part_map keypart_map)3068   int prepare_index_key_scan_map(const uchar *key, key_part_map keypart_map)
3069   {
3070     uint key_len= calculate_key_len(table, active_index, keypart_map);
3071     return prepare_index_key_scan(key, key_len);
3072   }
3073 
3074   /**
3075     Query storage engine to see if it supports gap locks on this table.
3076   */
has_gap_locks()3077   virtual bool has_gap_locks() const { return false; }
3078 
3079   /**
3080     Query storage engine to see if it can support handling specific replication
3081     method in its current configuration.
3082   */
rpl_can_handle_stm_event()3083   virtual bool rpl_can_handle_stm_event() const
3084   {
3085     return true;
3086   }
3087 
3088 protected:
3089   static bool is_using_full_key(key_part_map keypart_map, uint actual_key_parts);
3090   bool is_using_full_unique_key(uint active_index,
3091                                 key_part_map keypart_map,
3092                                 enum ha_rkey_function find_flag) const;
3093   bool is_using_prohibited_gap_locks(TABLE* table,
3094                                      bool using_full_primary_key) const;
3095 
3096   /**
3097     Notify storage engine about imminent index read with key length.
3098   */
prepare_index_key_scan(const uchar * key,uint key_len)3099   virtual int prepare_index_key_scan(const uchar *key, uint key_len)
3100   {
3101     return 0;
3102   }
3103 
3104 public:
3105 
3106   virtual int read_range_first(const key_range *start_key,
3107                                const key_range *end_key,
3108                                bool eq_range, bool sorted);
3109   virtual int read_range_next();
3110 
3111   /**
3112     Set the end position for a range scan. This is used for checking
3113     for when to end the range scan and by the ICP code to determine
3114     that the next record is within the current range.
3115 
3116     @param range     The end value for the range scan
3117     @param direction Direction of the range scan
3118   */
3119   void set_end_range(const key_range* range,
3120                      enum_range_scan_direction direction);
3121   int compare_key(key_range *range);
3122   int compare_key_icp(const key_range *range) const;
3123   int compare_key_in_buffer(const uchar *buf) const;
ft_init()3124   virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
ft_end()3125   void ft_end() { ft_handler=NULL; }
ft_init_ext(uint flags,uint inx,String * key)3126   virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
3127     { return NULL; }
ft_init_ext_with_hints(uint inx,String * key,Ft_hints * hints)3128   virtual FT_INFO *ft_init_ext_with_hints(uint inx, String *key,
3129                                           Ft_hints *hints)
3130   {
3131     return ft_init_ext(hints->get_flags(), inx, key);
3132   }
ft_read(uchar * buf)3133   virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
3134 protected:
3135   /// @returns @see index_read_map().
3136   virtual int rnd_next(uchar *buf)=0;
3137   /// @returns @see index_read_map().
3138   virtual int rnd_pos(uchar * buf, uchar *pos)=0;
3139 public:
3140   /**
3141     This function only works for handlers having
3142     HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
3143     It will return the row with the PK given in the record argument.
3144   */
rnd_pos_by_record(uchar * record)3145   virtual int rnd_pos_by_record(uchar *record)
3146     {
3147       int error;
3148       assert(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION);
3149 
3150       error = ha_rnd_init(FALSE);
3151       if (error != 0)
3152             return error;
3153 
3154       position(record);
3155       error = ha_rnd_pos(record, ref);
3156       ha_rnd_end();
3157       return error;
3158 
3159     }
3160   virtual int read_first_row(uchar *buf, uint primary_key);
records_in_range(uint inx,key_range * min_key,key_range * max_key)3161   virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
3162     { return (ha_rows) 10; }
3163   /*
3164     If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
3165     (reference to the row, aka position, with the primary key given in
3166     the record).
3167     Otherwise it set ref to the current row.
3168   */
3169   virtual void position(const uchar *record)=0;
3170   virtual int info(uint)=0; // see my_base.h for full description
calculate_key_hash_value(Field ** field_array)3171   virtual uint32 calculate_key_hash_value(Field **field_array)
3172   { assert(0); return 0; }
extra(enum ha_extra_function operation)3173   virtual int extra(enum ha_extra_function operation)
3174   { return 0; }
extra_opt(enum ha_extra_function operation,ulong cache_size)3175   virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
3176   { return extra(operation); }
3177 
3178   /**
3179     Start read (before write) removal on the current table.
3180     @see HA_READ_BEFORE_WRITE_REMOVAL
3181   */
start_read_removal(void)3182   virtual bool start_read_removal(void)
3183   { assert(0); return false; }
3184 
3185   /**
3186     End read (before write) removal and return the number of rows
3187     really written
3188     @see HA_READ_BEFORE_WRITE_REMOVAL
3189   */
end_read_removal(void)3190   virtual ha_rows end_read_removal(void)
3191   { assert(0); return (ha_rows) 0; }
3192 
3193   /**
3194     In an UPDATE or DELETE, if the row under the cursor was locked by another
3195     transaction, and the engine used an optimistic read of the last
3196     committed row value under the cursor, then the engine returns 1 from this
3197     function. MySQL must NOT try to update this optimistic value. If the
3198     optimistic value does not match the WHERE condition, MySQL can decide to
3199     skip over this row. Currently only works for InnoDB. This can be used to
3200     avoid unnecessary lock waits.
3201 
3202     If this method returns nonzero, it will also signal the storage
3203     engine that the next read will be a locking re-read of the row.
3204   */
was_semi_consistent_read()3205   virtual bool was_semi_consistent_read() { return 0; }
3206   /**
3207     Tell the engine whether it should avoid unnecessary lock waits.
3208     If yes, in an UPDATE or DELETE, if the row under the cursor was locked
3209     by another transaction, the engine may try an optimistic read of
3210     the last committed row value under the cursor.
3211   */
try_semi_consistent_read(bool)3212   virtual void try_semi_consistent_read(bool) {}
unlock_row()3213   virtual void unlock_row() {}
start_stmt(THD * thd,thr_lock_type lock_type)3214   virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
3215   virtual void get_auto_increment(ulonglong offset, ulonglong increment,
3216                                   ulonglong nb_desired_values,
3217                                   ulonglong *first_value,
3218                                   ulonglong *nb_reserved_values);
set_next_insert_id(ulonglong id)3219   void set_next_insert_id(ulonglong id)
3220   {
3221     DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
3222     next_insert_id= id;
3223   }
restore_auto_increment(ulonglong prev_insert_id)3224   void restore_auto_increment(ulonglong prev_insert_id)
3225   {
3226     /*
3227       Insertion of a row failed, re-use the lastly generated auto_increment
3228       id, for the next row. This is achieved by resetting next_insert_id to
3229       what it was before the failed insertion (that old value is provided by
3230       the caller). If that value was 0, it was the first row of the INSERT;
3231       then if insert_id_for_cur_row contains 0 it means no id was generated
3232       for this first row, so no id was generated since the INSERT started, so
3233       we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
3234       is the generated id of the first and failed row, so we use it.
3235     */
3236     next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
3237       insert_id_for_cur_row;
3238   }
3239 
3240   /*
3241      This function allows the storage engine to adust the create_info before
3242      the frm is written based on it.
3243      This can be used for example to modify the create statement based on a
3244      storage engine specific setting.
3245    */
adjust_create_info_for_frm(HA_CREATE_INFO * create_info)3246   virtual void adjust_create_info_for_frm(HA_CREATE_INFO *create_info) {}
3247 
update_create_info(HA_CREATE_INFO * create_info)3248   virtual void update_create_info(HA_CREATE_INFO *create_info) {}
3249 
3250   int check_old_types();
assign_to_keycache(THD * thd,HA_CHECK_OPT * check_opt)3251   virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
3252   { return HA_ADMIN_NOT_IMPLEMENTED; }
preload_keys(THD * thd,HA_CHECK_OPT * check_opt)3253   virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
3254   { return HA_ADMIN_NOT_IMPLEMENTED; }
3255   /* end of the list of admin commands */
3256 
indexes_are_disabled(void)3257   virtual int indexes_are_disabled(void) {return 0;}
append_create_info(String * packet)3258   virtual void append_create_info(String *packet) {}
3259   /**
3260     If index == MAX_KEY then a check for table is made and if index <
3261     MAX_KEY then a check is made if the table has foreign keys and if
3262     a foreign key uses this index (and thus the index cannot be dropped).
3263 
3264     @param  index            Index to check if foreign key uses it
3265 
3266     @retval   TRUE            Foreign key defined on table or index
3267     @retval   FALSE           No foreign key defined
3268   */
is_fk_defined_on_table_or_index(uint index)3269   virtual bool is_fk_defined_on_table_or_index(uint index)
3270   { return FALSE; }
get_foreign_key_create_info()3271   virtual char* get_foreign_key_create_info()
3272   { return(NULL);}  /* gets foreign key create string from InnoDB */
3273   /**
3274     Used in ALTER TABLE to check if changing storage engine is allowed.
3275 
3276     @note Called without holding thr_lock.c lock.
3277 
3278     @retval true   Changing storage engine is allowed.
3279     @retval false  Changing storage engine not allowed.
3280   */
can_switch_engines()3281   virtual bool can_switch_engines() { return true; }
3282   /**
3283     Get the list of foreign keys in this table.
3284 
3285     @remark Returns the set of foreign keys where this table is the
3286             dependent or child table.
3287 
3288     @param thd  The thread handle.
3289     @param f_key_list[out]  The list of foreign keys.
3290 
3291     @return The handler error code or zero for success.
3292   */
3293   virtual int
get_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)3294   get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
3295   { return 0; }
3296   /**
3297     Get the list of foreign keys referencing this table.
3298 
3299     @remark Returns the set of foreign keys where this table is the
3300             referenced or parent table.
3301 
3302     @param thd  The thread handle.
3303     @param f_key_list[out]  The list of foreign keys.
3304 
3305     @return The handler error code or zero for success.
3306   */
3307   virtual int
get_parent_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)3308   get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
3309   { return 0; }
3310   /**
3311     Get the list of tables which are direct or indirect parents in foreign
3312     key with cascading actions for this table.
3313 
3314     @remarks Returns the set of parent tables connected by FK clause that
3315     can modify the given table.
3316 
3317     @param      thd             The thread handle.
3318     @param[out] fk_table_list   List of parent tables (including indirect parents).
3319                                 Elements of the list as well as buffers for database
3320                                 and schema names are allocated from the current
3321                                 memory root.
3322 
3323     @return The handler error code or zero for success
3324   */
3325   virtual int
get_cascade_foreign_key_table_list(THD * thd,List<st_handler_tablename> * fk_table_list)3326   get_cascade_foreign_key_table_list(THD *thd,
3327                                      List<st_handler_tablename> *fk_table_list)
3328   { return 0; }
referenced_by_foreign_key()3329   virtual uint referenced_by_foreign_key() { return 0;}
init_table_handle_for_HANDLER()3330   virtual void init_table_handle_for_HANDLER()
3331   { return; }       /* prepare InnoDB for HANDLER */
free_foreign_key_create_info(char * str)3332   virtual void free_foreign_key_create_info(char* str) {}
3333   /** The following can be called without an open handler */
3334   virtual const char *table_type() const =0;
3335   /**
3336     If frm_error() is called then we will use this to find out what file
3337     extentions exist for the storage engine. This is also used by the default
3338     rename_table and delete_table method in handler.cc.
3339 
3340     For engines that have two file name extentions (separate meta/index file
3341     and data file), the order of elements is relevant. First element of engine
3342     file name extentions array should be meta/index file extention. Second
3343     element - data file extention. This order is assumed by
3344     prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
3345   */
3346   virtual const char **bas_ext() const =0;
3347 
3348   virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
3349 
max_record_length()3350   uint max_record_length() const
3351   {
3352     return std::min(HA_MAX_REC_LENGTH, max_supported_record_length());
3353   }
max_keys()3354   uint max_keys() const
3355   {
3356     return std::min<uint>(MAX_KEY, max_supported_keys());
3357   }
max_key_parts()3358   uint max_key_parts() const
3359   {
3360     return std::min(MAX_REF_PARTS, max_supported_key_parts());
3361   }
max_key_length()3362   uint max_key_length() const
3363   {
3364     return std::min(MAX_KEY_LENGTH, max_supported_key_length());
3365   }
max_key_part_length(HA_CREATE_INFO * create_info)3366   uint max_key_part_length(HA_CREATE_INFO *create_info) const
3367   {
3368     return std::min(MAX_KEY_LENGTH, max_supported_key_part_length(create_info));
3369   }
3370 
max_supported_record_length()3371   virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
max_supported_keys()3372   virtual uint max_supported_keys() const { return 0; }
max_supported_key_parts()3373   virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
max_supported_key_length()3374   virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
max_supported_key_part_length(HA_CREATE_INFO * create_info MY_ATTRIBUTE ((unused)))3375   virtual uint max_supported_key_part_length(HA_CREATE_INFO
3376                             *create_info MY_ATTRIBUTE((unused))) const
3377   { return 255; }
min_record_length(uint options)3378   virtual uint min_record_length(uint options) const { return 1; }
3379 
low_byte_first()3380   virtual bool low_byte_first() const { return 1; }
checksum()3381   virtual ha_checksum checksum() const { return 0; }
is_crashed()3382   virtual bool is_crashed() const  { return 0; }
auto_repair()3383   virtual bool auto_repair() const { return 0; }
3384 
3385   void update_global_table_stats();
3386   void update_global_index_stats();
update_index_stats(uint current_index)3387   void update_index_stats(uint current_index)
3388   {
3389     rows_read++;
3390     if (current_index < MAX_KEY)
3391       index_rows_read[current_index]++;
3392     else
3393       index_rows_read[0]++;
3394   }
3395 
3396 #define CHF_CREATE_FLAG 0
3397 #define CHF_DELETE_FLAG 1
3398 #define CHF_RENAME_FLAG 2
3399 #define CHF_INDEX_FLAG  3
3400 
3401 
3402   /**
3403     @note lock_count() can return > 1 if the table is MERGE or partitioned.
3404   */
lock_count(void)3405   virtual uint lock_count(void) const { return 1; }
3406   /**
3407     Is not invoked for non-transactional temporary tables.
3408 
3409     @note store_lock() can return more than one lock if the table is MERGE
3410     or partitioned.
3411 
3412     @note that one can NOT rely on table->in_use in store_lock().  It may
3413     refer to a different thread if called from mysql_lock_abort_for_thread().
3414 
3415     @note If the table is MERGE, store_lock() can return less locks
3416     than lock_count() claimed. This can happen when the MERGE children
3417     are not attached when this is called from another thread.
3418   */
3419   virtual THR_LOCK_DATA **store_lock(THD *thd,
3420 				     THR_LOCK_DATA **to,
3421 				     enum thr_lock_type lock_type)=0;
3422 
3423   /** Type of table for caching query */
table_cache_type()3424   virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
3425 
3426 
3427   /**
3428     @brief Register a named table with a call back function to the query cache.
3429 
3430     @param thd The thread handle
3431     @param table_key A pointer to the table name in the table cache
3432     @param key_length The length of the table name
3433     @param[out] engine_callback The pointer to the storage engine call back
3434       function
3435     @param[out] engine_data Storage engine specific data which could be
3436       anything
3437 
3438     This method offers the storage engine, the possibility to store a reference
3439     to a table name which is going to be used with query cache.
3440     The method is called each time a statement is written to the cache and can
3441     be used to verify if a specific statement is cachable. It also offers
3442     the possibility to register a generic (but static) call back function which
3443     is called each time a statement is matched against the query cache.
3444 
3445     @note If engine_data supplied with this function is different from
3446       engine_data supplied with the callback function, and the callback returns
3447       FALSE, a table invalidation on the current table will occur.
3448 
3449     @return Upon success the engine_callback will point to the storage engine
3450       call back function, if any, and engine_data will point to any storage
3451       engine data used in the specific implementation.
3452       @retval TRUE Success
3453       @retval FALSE The specified table or current statement should not be
3454         cached
3455   */
3456 
register_query_cache_table(THD * thd,char * table_key,size_t key_length,qc_engine_callback * engine_callback,ulonglong * engine_data)3457   virtual my_bool register_query_cache_table(THD *thd, char *table_key,
3458                                              size_t key_length,
3459                                              qc_engine_callback
3460                                              *engine_callback,
3461                                              ulonglong *engine_data)
3462   {
3463     *engine_callback= 0;
3464     return TRUE;
3465   }
3466 
3467 
3468  /**
3469    Check if the primary key is clustered or not.
3470 
3471    @retval true  Primary key (if there is one) is a clustered
3472                  key covering all fields
3473    @retval false otherwise
3474  */
3475 
primary_key_is_clustered()3476  virtual bool primary_key_is_clustered() const { return false; }
cmp_ref(const uchar * ref1,const uchar * ref2)3477  virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
3478  {
3479    return memcmp(ref1, ref2, ref_length);
3480  }
3481 
3482  /*
3483    Condition pushdown to storage engines
3484  */
3485 
3486  /**
3487    Push condition down to the table handler.
3488 
3489    @param  cond   Condition to be pushed. The condition tree must not be
3490                   modified by the by the caller.
3491 
3492    @return
3493      The 'remainder' condition that caller must use to filter out records.
3494      NULL means the handler will not return rows that do not match the
3495      passed condition.
3496 
3497    @note
3498    The pushed conditions form a stack (from which one can remove the
3499    last pushed condition using cond_pop).
3500    The table handler filters out rows using (pushed_cond1 AND pushed_cond2
3501    AND ... AND pushed_condN)
3502    or less restrictive condition, depending on handler's capabilities.
3503 
3504    handler->ha_reset() call empties the condition stack.
3505    Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
3506    condition stack.
3507  */
cond_push(const Item * cond)3508  virtual const Item *cond_push(const Item *cond) { return cond; };
3509  /**
3510    Pop the top condition from the condition stack of the handler instance.
3511 
3512    Pops the top if condition stack, if stack is not empty.
3513  */
cond_pop()3514  virtual void cond_pop() { return; }
3515 
3516  /**
3517    Push down an index condition to the handler.
3518 
3519    The server will use this method to push down a condition it wants
3520    the handler to evaluate when retrieving records using a specified
3521    index. The pushed index condition will only refer to fields from
3522    this handler that is contained in the index (but it may also refer
3523    to fields in other handlers). Before the handler evaluates the
3524    condition it must read the content of the index entry into the
3525    record buffer.
3526 
3527    The handler is free to decide if and how much of the condition it
3528    will take responsibility for evaluating. Based on this evaluation
3529    it should return the part of the condition it will not evaluate.
3530    If it decides to evaluate the entire condition it should return
3531    NULL. If it decides not to evaluate any part of the condition it
3532    should return a pointer to the same condition as given as argument.
3533 
3534    @param keyno    the index number to evaluate the condition on
3535    @param idx_cond the condition to be evaluated by the handler
3536 
3537    @return The part of the pushed condition that the handler decides
3538            not to evaluate
3539   */
3540 
idx_cond_push(uint keyno,Item * idx_cond)3541  virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
3542 
3543  /** Reset information about pushed index conditions */
cancel_pushed_idx_cond()3544  virtual void cancel_pushed_idx_cond()
3545  {
3546    pushed_idx_cond= NULL;
3547    pushed_idx_cond_keyno= MAX_KEY;
3548    in_range_check_pushed_down= false;
3549  }
3550 
3551   /**
3552     Reports #tables included in pushed join which this
3553     handler instance is part of. ==0 -> Not pushed
3554   */
number_of_pushed_joins()3555   virtual uint number_of_pushed_joins() const
3556   { return 0; }
3557 
3558   /**
3559     If this handler instance is part of a pushed join sequence
3560     returned TABLE instance being root of the pushed query?
3561   */
root_of_pushed_join()3562   virtual const TABLE* root_of_pushed_join() const
3563   { return NULL; }
3564 
3565   /**
3566     If this handler instance is a child in a pushed join sequence
3567     returned TABLE instance being my parent?
3568   */
parent_of_pushed_join()3569   virtual const TABLE* parent_of_pushed_join() const
3570   { return NULL; }
3571 
index_read_pushed(uchar * buf,const uchar * key,key_part_map keypart_map)3572   virtual int index_read_pushed(uchar * buf, const uchar * key,
3573                              key_part_map keypart_map)
3574   { return  HA_ERR_WRONG_COMMAND; }
3575 
index_next_pushed(uchar * buf)3576   virtual int index_next_pushed(uchar * buf)
3577   { return  HA_ERR_WRONG_COMMAND; }
3578 
3579  /**
3580    Part of old, deprecated in-place ALTER API.
3581  */
check_if_incompatible_data(HA_CREATE_INFO * create_info,uint table_changes)3582  virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
3583 					 uint table_changes)
3584  { return COMPATIBLE_DATA_NO; }
3585 
3586  /* On-line/in-place ALTER TABLE interface. */
3587 
3588  /*
3589    Here is an outline of on-line/in-place ALTER TABLE execution through
3590    this interface.
3591 
3592    Phase 1 : Initialization
3593    ========================
3594    During this phase we determine which algorithm should be used
3595    for execution of ALTER TABLE and what level concurrency it will
3596    require.
3597 
3598    *) This phase starts by opening the table and preparing description
3599       of the new version of the table.
3600    *) Then we check if it is impossible even in theory to carry out
3601       this ALTER TABLE using the in-place algorithm. For example, because
3602       we need to change storage engine or the user has explicitly requested
3603       usage of the "copy" algorithm.
3604    *) If in-place ALTER TABLE is theoretically possible, we continue
3605       by compiling differences between old and new versions of the table
3606       in the form of HA_ALTER_FLAGS bitmap. We also build a few
3607       auxiliary structures describing requested changes and store
3608       all these data in the Alter_inplace_info object.
3609    *) Then the handler::check_if_supported_inplace_alter() method is called
3610       in order to find if the storage engine can carry out changes requested
3611       by this ALTER TABLE using the in-place algorithm. To determine this,
3612       the engine can rely on data in HA_ALTER_FLAGS/Alter_inplace_info
3613       passed to it as well as on its own checks. If the in-place algorithm
3614       can be used for this ALTER TABLE, the level of required concurrency for
3615       its execution is also returned.
3616       If any errors occur during the handler call, ALTER TABLE is aborted
3617       and no further handler functions are called.
3618    *) Locking requirements of the in-place algorithm are compared to any
3619       concurrency requirements specified by user. If there is a conflict
3620       between them, we either switch to the copy algorithm or emit an error.
3621 
3622    Phase 2 : Execution
3623    ===================
3624 
3625    In this phase the operations are executed.
3626 
3627    *) As the first step, we acquire a lock corresponding to the concurrency
3628       level which was returned by handler::check_if_supported_inplace_alter()
3629       and requested by the user. This lock is held for most of the
3630       duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
3631       or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an
3632       exclusive lock for duration of the next step only).
3633    *) After that we call handler::ha_prepare_inplace_alter_table() to give the
3634       storage engine a chance to update its internal structures with a higher
3635       lock level than the one that will be used for the main step of algorithm.
3636       After that we downgrade the lock if it is necessary.
3637    *) After that, the main step of this phase and algorithm is executed.
3638       We call the handler::ha_inplace_alter_table() method, which carries out the
3639       changes requested by ALTER TABLE but does not makes them visible to other
3640       connections yet.
3641    *) We ensure that no other connection uses the table by upgrading our
3642       lock on it to exclusive.
3643    *) a) If the previous step succeeds, handler::ha_commit_inplace_alter_table() is
3644          called to allow the storage engine to do any final updates to its structures,
3645          to make all earlier changes durable and visible to other connections.
3646       b) If we have failed to upgrade lock or any errors have occured during the
3647          handler functions calls (including commit), we call
3648          handler::ha_commit_inplace_alter_table()
3649          to rollback all changes which were done during previous steps.
3650 
3651   Phase 3 : Final
3652   ===============
3653 
3654   In this phase we:
3655 
3656   *) Update SQL-layer data-dictionary by installing .FRM file for the new version
3657      of the table.
3658   *) Inform the storage engine about this change by calling the
3659      handler::ha_notify_table_changed() method.
3660   *) Destroy the Alter_inplace_info and handler_ctx objects.
3661 
3662  */
3663 
3664  /**
3665     Check if a storage engine supports a particular alter table in-place
3666 
3667     @param    altered_table     TABLE object for new version of table.
3668     @param    ha_alter_info     Structure describing changes to be done
3669                                 by ALTER TABLE and holding data used
3670                                 during in-place alter.
3671 
3672     @retval   HA_ALTER_ERROR                  Unexpected error.
3673     @retval   HA_ALTER_INPLACE_NOT_SUPPORTED  Not supported, must use copy.
3674     @retval   HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
3675     @retval   HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
3676                                               Supported, but requires SNW lock
3677                                               during main phase. Prepare phase
3678                                               requires X lock.
3679     @retval   HA_ALTER_INPLACE_SHARED_LOCK    Supported, but requires SNW lock.
3680     @retval   HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
3681                                               Supported, concurrent reads/writes
3682                                               allowed. However, prepare phase
3683                                               requires X lock.
3684     @retval   HA_ALTER_INPLACE_NO_LOCK        Supported, concurrent
3685                                               reads/writes allowed.
3686 
3687     @note The default implementation uses the old in-place ALTER API
3688     to determine if the storage engine supports in-place ALTER or not.
3689 
3690     @note Called without holding thr_lock.c lock.
3691  */
3692  virtual enum_alter_inplace_result
3693  check_if_supported_inplace_alter(TABLE *altered_table,
3694                                   Alter_inplace_info *ha_alter_info);
3695 
3696 
3697  /**
3698     Public functions wrapping the actual handler call.
3699     @see prepare_inplace_alter_table()
3700  */
3701  bool ha_prepare_inplace_alter_table(TABLE *altered_table,
3702                                      Alter_inplace_info *ha_alter_info);
3703 
3704 
3705  /**
3706     Public function wrapping the actual handler call.
3707     @see inplace_alter_table()
3708  */
ha_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)3709  bool ha_inplace_alter_table(TABLE *altered_table,
3710                              Alter_inplace_info *ha_alter_info)
3711  {
3712    return inplace_alter_table(altered_table, ha_alter_info);
3713  }
3714 
3715 
3716  /**
3717     Public function wrapping the actual handler call.
3718     Allows us to enforce asserts regardless of handler implementation.
3719     @see commit_inplace_alter_table()
3720  */
3721  bool ha_commit_inplace_alter_table(TABLE *altered_table,
3722                                     Alter_inplace_info *ha_alter_info,
3723                                     bool commit);
3724 
3725 
3726  /**
3727     Public function wrapping the actual handler call.
3728     @see notify_table_changed()
3729  */
ha_notify_table_changed()3730  void ha_notify_table_changed()
3731  {
3732    notify_table_changed();
3733  }
3734 
3735 
3736 protected:
3737  /**
3738     Allows the storage engine to update internal structures with concurrent
3739     writes blocked. If check_if_supported_inplace_alter() returns
3740     HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE or
3741     HA_ALTER_INPLACE_SHARED_AFTER_PREPARE, this function is called with
3742     exclusive lock otherwise the same level of locking as for
3743     inplace_alter_table() will be used.
3744 
3745     @note Storage engines are responsible for reporting any errors by
3746     calling my_error()/print_error()
3747 
3748     @note If this function reports error, commit_inplace_alter_table()
3749     will be called with commit= false.
3750 
3751     @note For partitioning, failing to prepare one partition, means that
3752     commit_inplace_alter_table() will be called to roll back changes for
3753     all partitions. This means that commit_inplace_alter_table() might be
3754     called without prepare_inplace_alter_table() having been called first
3755     for a given partition.
3756 
3757     @param    altered_table     TABLE object for new version of table.
3758     @param    ha_alter_info     Structure describing changes to be done
3759                                 by ALTER TABLE and holding data used
3760                                 during in-place alter.
3761 
3762     @retval   true              Error
3763     @retval   false             Success
3764  */
prepare_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)3765  virtual bool prepare_inplace_alter_table(TABLE *altered_table,
3766                                           Alter_inplace_info *ha_alter_info)
3767  { return false; }
3768 
3769 
3770  /**
3771     Alter the table structure in-place with operations specified using HA_ALTER_FLAGS
3772     and Alter_inplace_info. The level of concurrency allowed during this
3773     operation depends on the return value from check_if_supported_inplace_alter().
3774 
3775     @note Storage engines are responsible for reporting any errors by
3776     calling my_error()/print_error()
3777 
3778     @note If this function reports error, commit_inplace_alter_table()
3779     will be called with commit= false.
3780 
3781     @param    altered_table     TABLE object for new version of table.
3782     @param    ha_alter_info     Structure describing changes to be done
3783                                 by ALTER TABLE and holding data used
3784                                 during in-place alter.
3785 
3786     @retval   true              Error
3787     @retval   false             Success
3788  */
inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)3789  virtual bool inplace_alter_table(TABLE *altered_table,
3790                                   Alter_inplace_info *ha_alter_info)
3791  { return false; }
3792 
3793 
3794  /**
3795     Commit or rollback the changes made during prepare_inplace_alter_table()
3796     and inplace_alter_table() inside the storage engine.
3797     Note that in case of rollback the allowed level of concurrency during
3798     this operation will be the same as for inplace_alter_table() and thus
3799     might be higher than during prepare_inplace_alter_table(). (For example,
3800     concurrent writes were blocked during prepare, but might not be during
3801     rollback).
3802 
3803     @note Storage engines are responsible for reporting any errors by
3804     calling my_error()/print_error()
3805 
3806     @note If this function with commit= true reports error, it will be called
3807     again with commit= false.
3808 
3809     @note In case of partitioning, this function might be called for rollback
3810     without prepare_inplace_alter_table() having been called first.
3811     Also partitioned tables sets ha_alter_info->group_commit_ctx to a NULL
3812     terminated array of the partitions handlers and if all of them are
3813     committed as one, then group_commit_ctx should be set to NULL to indicate
3814     to the partitioning handler that all partitions handlers are committed.
3815     @see prepare_inplace_alter_table().
3816 
3817     @param    altered_table     TABLE object for new version of table.
3818     @param    ha_alter_info     Structure describing changes to be done
3819                                 by ALTER TABLE and holding data used
3820                                 during in-place alter.
3821     @param    commit            True => Commit, False => Rollback.
3822 
3823     @retval   true              Error
3824     @retval   false             Success
3825  */
commit_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info,bool commit)3826  virtual bool commit_inplace_alter_table(TABLE *altered_table,
3827                                          Alter_inplace_info *ha_alter_info,
3828                                          bool commit)
3829 {
3830   /* Nothing to commit/rollback, mark all handlers committed! */
3831   ha_alter_info->group_commit_ctx= NULL;
3832   return false;
3833 }
3834 
3835 
3836  /**
3837     Notify the storage engine that the table structure (.FRM) has been updated.
3838 
3839     @note No errors are allowed during notify_table_changed().
3840  */
3841  virtual void notify_table_changed();
3842 
3843 public:
3844  /* End of On-line/in-place ALTER TABLE interface. */
3845 
3846   /**
3847     @brief Offload an update to the storage engine. See handler::fast_update()
3848     for details.
3849   */
3850   MY_NODISCARD int ha_fast_update(THD *thd,
3851                                   List<Item> &update_fields,
3852                                   List<Item> &update_values,
3853                                   Item *conds);
3854 
3855   /**
3856     @brief Offload an upsert to the storage engine. See handler::upsert()
3857     for details.
3858   */
3859   MY_NODISCARD int ha_upsert(THD *thd,
3860                              List<Item> &update_fields,
3861                              List<Item> &update_values);
3862 private:
3863   /**
3864     Offload an update to the storage engine implementation.
3865 
3866     @param    thd              The thread handle.
3867     @param    update_fields    The list of fields to update.
3868     @param    update_values    The list of new values for the fields
3869                                in update_fields.
3870     @param    conds            Conditions tree.
3871 
3872     @retval   0                if the storage engine handled the update.
3873     @retval   ENOTSUP          if the storage engine can not handle the
3874                                update and the slow update code path should
3875                                continue executing the update.
3876 
3877     @return an error if the update should be terminated.
3878 
3879     @note HA_READ_BEFORE_WRITE_REMOVAL flag doesn not fit there because
3880     handler::ha_update_row(...) does not accept conditions.
3881   */
fast_update(THD * thd,List<Item> & update_fields,List<Item> & update_values,Item * conds)3882   MY_NODISCARD virtual int fast_update(THD *thd,
3883                                        List<Item> &update_fields,
3884                                        List<Item> &update_values,
3885                                        Item *conds)
3886   { return ENOTSUP; }
3887 
3888   /**
3889     Offload an upsert to the storage engine implementation. Expects the row
3890     to be stored in record[0].
3891 
3892     @param    thd              The thread handle.
3893     @param    update_fields    The list of fields to update.
3894     @param    update_values    The list of new values for the fields
3895                                in update_fields.
3896 
3897     @retval   0                if the storage engine handled the upsert.
3898     @retval   ENOTSUP          if the storage engine can not handle the upsert
3899                                and the slow insert code path should continue
3900                                executing the insert.
3901 
3902     @return an error if the insert should be terminated.
3903   */
upsert(THD * thd,List<Item> & update_fields,List<Item> & update_values)3904   MY_NODISCARD virtual int upsert(THD *thd,
3905                                   List<Item> &update_fields,
3906                                   List<Item> &update_values)
3907   { return ENOTSUP; }
3908 
3909 public:
3910   /**
3911     use_hidden_primary_key() is called in case of an update/delete when
3912     (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
3913     but we don't have a primary key
3914   */
3915   virtual void use_hidden_primary_key();
3916 
3917 /**
3918   A helper function to mark a transaction as noop_read_write if it is started.
3919 */
3920   void mark_trx_noop_dml();
3921 
3922 protected:
3923   /* Service methods for use by storage engines. */
3924   void ha_statistic_increment(ulonglong SSV::*offset) const;
3925   THD *ha_thd(void) const;
3926 
3927   /**
3928     Acquire the instrumented table information from a table share.
3929     @param share a table share
3930     @return an instrumented table share, or NULL.
3931   */
3932   PSI_table_share *ha_table_share_psi(const TABLE_SHARE *share) const;
3933 
3934   /**
3935     Default rename_table() and delete_table() rename/delete files with a
3936     given name and extensions from bas_ext().
3937 
3938     These methods can be overridden, but their default implementation
3939     provide useful functionality.
3940   */
3941   virtual int rename_table(const char *from, const char *to);
3942   /**
3943     Delete a table in the engine. Called for base as well as temporary
3944     tables.
3945   */
3946   virtual int delete_table(const char *name);
3947 private:
3948   /* Private helpers */
3949   void mark_trx_read_write();
3950   /*
3951     Low-level primitives for storage engines.  These should be
3952     overridden by the storage engine class. To call these methods, use
3953     the corresponding 'ha_*' method above.
3954   */
3955 
3956   virtual int open(const char *name, int mode, uint test_if_locked)=0;
3957   virtual int close(void)=0;
index_init(uint idx,bool sorted)3958   virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
index_end()3959   virtual int index_end() { active_index= MAX_KEY; return 0; }
3960   /**
3961     rnd_init() can be called two times without rnd_end() in between
3962     (it only makes sense if scan=1).
3963     then the second call should prepare for the new table scan (e.g
3964     if rnd_init allocates the cursor, second call should position it
3965     to the start of the table, no need to deallocate and allocate it again
3966   */
3967   virtual int rnd_init(bool scan)= 0;
rnd_end()3968   virtual int rnd_end() { return 0; }
3969   /**
3970     Write a row.
3971 
3972     write_row() inserts a row. buf is a byte array of data, normally
3973     record[0].
3974 
3975     You can use the field information to extract the data from the native byte
3976     array type.
3977 
3978     Example of this would be:
3979     for (Field **field=table->field ; *field ; field++)
3980     {
3981       ...
3982     }
3983 
3984     @param buf  Buffer to write from.
3985 
3986     @return Operation status.
3987       @retval    0  Success.
3988       @retval != 0  Error code.
3989   */
write_row(uchar * buf MY_ATTRIBUTE ((unused)))3990   virtual int write_row(uchar *buf MY_ATTRIBUTE((unused)))
3991   {
3992     return HA_ERR_WRONG_COMMAND;
3993   }
3994 
3995   /**
3996     Update a single row.
3997 
3998     Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
3999     all columns of the row so MySQL can create an error message. If
4000     the columns required for the error message are not read, the error
4001     message will contain garbage.
4002   */
update_row(const uchar * old_data MY_ATTRIBUTE ((unused)),uchar * new_data MY_ATTRIBUTE ((unused)))4003   virtual int update_row(const uchar *old_data MY_ATTRIBUTE((unused)),
4004                          uchar *new_data MY_ATTRIBUTE((unused)))
4005   {
4006     return HA_ERR_WRONG_COMMAND;
4007   }
4008 
delete_row(const uchar * buf MY_ATTRIBUTE ((unused)))4009   virtual int delete_row(const uchar *buf MY_ATTRIBUTE((unused)))
4010   {
4011     return HA_ERR_WRONG_COMMAND;
4012   }
4013   /**
4014     Reset state of file to after 'open'.
4015     This function is called after every statement for all tables used
4016     by that statement.
4017   */
reset()4018   virtual int reset() { return 0; }
4019   virtual Table_flags table_flags(void) const= 0;
4020   /**
4021     Is not invoked for non-transactional temporary tables.
4022 
4023     Tells the storage engine that we intend to read or write data
4024     from the table. This call is prefixed with a call to handler::store_lock()
4025     and is invoked only for those handler instances that stored the lock.
4026 
4027     Calls to rnd_init/index_init are prefixed with this call. When table
4028     IO is complete, we call external_lock(F_UNLCK).
4029     A storage engine writer should expect that each call to
4030     ::external_lock(F_[RD|WR]LOCK is followed by a call to
4031     ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
4032 
4033     The name and signature originate from the first implementation
4034     in MyISAM, which would call fcntl to set/clear an advisory
4035     lock on the data file in this method.
4036 
4037     @param   lock_type    F_RDLCK, F_WRLCK, F_UNLCK
4038 
4039     @return  non-0 in case of failure, 0 in case of success.
4040     When lock_type is F_UNLCK, the return value is ignored.
4041   */
external_lock(THD * thd MY_ATTRIBUTE ((unused)),int lock_type MY_ATTRIBUTE ((unused)))4042   virtual int external_lock(THD *thd MY_ATTRIBUTE((unused)),
4043                             int lock_type MY_ATTRIBUTE((unused)))
4044   {
4045     return 0;
4046   }
release_auto_increment()4047   virtual void release_auto_increment() { return; };
4048   /** admin commands - called from mysql_admin_table */
check_for_upgrade(HA_CHECK_OPT * check_opt)4049   virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
4050   { return 0; }
check(THD * thd,HA_CHECK_OPT * check_opt)4051   virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
4052   { return HA_ADMIN_NOT_IMPLEMENTED; }
4053 
4054   /**
4055      In this method check_opt can be modified
4056      to specify CHECK option to use to call check()
4057      upon the table.
4058   */
repair(THD * thd,HA_CHECK_OPT * check_opt)4059   virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
4060   {
4061     assert(!(ha_table_flags() & HA_CAN_REPAIR));
4062     return HA_ADMIN_NOT_IMPLEMENTED;
4063   }
start_bulk_insert(ha_rows rows)4064   virtual void start_bulk_insert(ha_rows rows) {}
end_bulk_insert()4065   virtual int end_bulk_insert() { return 0; }
4066 protected:
index_read(uchar * buf,const uchar * key,uint key_len,enum ha_rkey_function find_flag)4067   virtual int index_read(uchar * buf, const uchar * key, uint key_len,
4068                          enum ha_rkey_function find_flag)
4069    { return  HA_ERR_WRONG_COMMAND; }
index_read_last(uchar * buf,const uchar * key,uint key_len)4070   virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
4071   {
4072     set_my_errno(HA_ERR_WRONG_COMMAND);
4073     return HA_ERR_WRONG_COMMAND;
4074   }
4075 public:
4076   /**
4077     This method is similar to update_row, however the handler doesn't need
4078     to execute the updates at this point in time. The handler can be certain
4079     that another call to bulk_update_row will occur OR a call to
4080     exec_bulk_update before the set of updates in this query is concluded.
4081 
4082     Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
4083     all columns of the row so MySQL can create an error message. If
4084     the columns required for the error message are not read, the error
4085     message will contain garbage.
4086 
4087     @param    old_data       Old record
4088     @param    new_data       New record
4089     @param    dup_key_found  Number of duplicate keys found
4090 
4091   */
bulk_update_row(const uchar * old_data,uchar * new_data,uint * dup_key_found)4092   virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
4093                               uint *dup_key_found)
4094   {
4095     assert(FALSE);
4096     return HA_ERR_WRONG_COMMAND;
4097   }
4098   /**
4099     This is called to delete all rows in a table
4100     If the handler don't support this, then this function will
4101     return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
4102     by one.
4103   */
delete_all_rows()4104   virtual int delete_all_rows()
4105   {
4106     set_my_errno(HA_ERR_WRONG_COMMAND);
4107     return HA_ERR_WRONG_COMMAND;
4108   }
4109   /**
4110     Quickly remove all rows from a table.
4111 
4112     @remark This method is responsible for implementing MySQL's TRUNCATE
4113             TABLE statement, which is a DDL operation. As such, a engine
4114             can bypass certain integrity checks and in some cases avoid
4115             fine-grained locking (e.g. row locks) which would normally be
4116             required for a DELETE statement.
4117 
4118     @remark Typically, truncate is not used if it can result in integrity
4119             violation. For example, truncate is not used when a foreign
4120             key references the table, but it might be used if foreign key
4121             checks are disabled.
4122 
4123     @remark Engine is responsible for resetting the auto-increment counter.
4124 
4125     @remark The table is locked in exclusive mode.
4126   */
truncate()4127   virtual int truncate()
4128   { return HA_ERR_WRONG_COMMAND; }
optimize(THD * thd,HA_CHECK_OPT * check_opt)4129   virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
4130   { return HA_ADMIN_NOT_IMPLEMENTED; }
analyze(THD * thd,HA_CHECK_OPT * check_opt)4131   virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
4132   { return HA_ADMIN_NOT_IMPLEMENTED; }
check_and_repair(THD * thd)4133   virtual bool check_and_repair(THD *thd) { return TRUE; }
disable_indexes(uint mode)4134   virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
enable_indexes(uint mode)4135   virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
discard_or_import_tablespace(my_bool discard)4136   virtual int discard_or_import_tablespace(my_bool discard)
4137   {
4138     set_my_errno(HA_ERR_WRONG_COMMAND);
4139     return HA_ERR_WRONG_COMMAND;
4140   }
4141   virtual void drop_table(const char *name);
4142   virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
4143 
create_handler_files(const char * name,const char * old_name,int action_flag,HA_CREATE_INFO * info)4144   virtual int create_handler_files(const char *name, const char *old_name,
4145                                    int action_flag, HA_CREATE_INFO *info)
4146   { return FALSE; }
4147 
set_ha_share_ref(Handler_share ** arg_ha_share)4148   virtual bool set_ha_share_ref(Handler_share **arg_ha_share)
4149   {
4150     assert(!ha_share);
4151     assert(arg_ha_share);
4152     if (ha_share || !arg_ha_share)
4153       return true;
4154     ha_share= arg_ha_share;
4155     return false;
4156   }
get_lock_type()4157   int get_lock_type() const { return m_lock_type; }
4158   /**
4159     This method is supposed to fill field definition objects with
4160     compression dictionary info (name and data).
4161     If the handler does not support compression dictionaries
4162     this method should be left empty (not overloaded).
4163 
4164     @param    thd          Thread handle
4165     @param    part_name    Full table name (including partition part).
4166                            Optional.
4167   */
update_field_defs_with_zip_dict_info(THD * thd,const char * part_name)4168   virtual void update_field_defs_with_zip_dict_info(THD* thd,
4169                                                     const char* part_name) {}
4170 
4171 public:
4172   /* Read-free replication interface */
4173 
4174   /**
4175      Determine whether the storage engine asks for row-based replication that
4176      may skip the lookup of the old row image.
4177 
4178      @return true if old rows should be read (the default)
4179              false if old rows should not be read
4180    */
rpl_lookup_rows()4181   virtual bool rpl_lookup_rows() { return true; }
4182   /*
4183      Storage engine hooks to be called before and after row write, delete, and
4184      update events
4185   */
rpl_before_write_rows()4186   virtual void rpl_before_write_rows() { }
rpl_after_write_rows()4187   virtual void rpl_after_write_rows() { }
rpl_before_delete_rows()4188   virtual void rpl_before_delete_rows() { }
rpl_after_delete_rows()4189   virtual void rpl_after_delete_rows() { }
rpl_before_update_rows()4190   virtual void rpl_before_update_rows() { }
rpl_after_update_rows()4191   virtual void rpl_after_update_rows() { }
4192 
4193   /**
4194     Callback function that will be called by my_prepare_gcolumn_template
4195     once the table has been opened.
4196   */
4197   typedef void (*my_gcolumn_template_callback_t)(const TABLE*, void*);
4198   static bool my_prepare_gcolumn_template(THD *thd,
4199                                           const char *db_name,
4200                                           const char *table_name,
4201                                           my_gcolumn_template_callback_t myc,
4202                                           void *ib_table);
4203   static bool my_eval_gcolumn_expr_with_open(THD *thd,
4204                                              const char *db_name,
4205                                              const char *table_name,
4206                                              const MY_BITMAP *const fields,
4207                                              uchar *record);
4208 
4209   /**
4210    Callback for computing generated column values.
4211 
4212    Storage engines that need to have virtual column values for a row
4213    can use this function to get the values computed. The storage
4214    engine must have filled in the values for the base columns that
4215    the virutal columns depend on.
4216 
4217    @param  thd	        thread handle
4218    @param  table	table object
4219    @param  fields	bitmap of field index of evaluated generated
4220 			column
4221    @param  record	buff of base columns generated column depends.
4222 			After calling this function, it will be
4223 			used to return the value of the generated
4224 			columns.
4225 
4226    @retval true in case of error
4227    @retval false on success.
4228   */
4229   static bool my_eval_gcolumn_expr(THD *thd, TABLE *table,
4230 				   const MY_BITMAP *const fields,
4231                                    uchar *record);
4232 
4233   /* This must be implemented if the handlerton's partition_flags() is set. */
get_partition_handler()4234   virtual Partition_handler *get_partition_handler()
4235   { return NULL; }
4236 
4237 protected:
4238   Handler_share *get_ha_share_ptr();
4239   void set_ha_share_ptr(Handler_share *arg_ha_share);
4240   void lock_shared_ha_data();
4241   void unlock_shared_ha_data();
4242 
4243 private:
4244   /**
4245     If true, the current handler is a clone. In that case certain invariants
4246     such as table->in_use == current_thd are relaxed to support cloning a
4247     handler belonging to a different thread. */
4248   bool cloned;
4249 };
4250 
4251 
4252 bool key_uses_partial_cols(TABLE *table, uint keyno);
4253 
4254 /*
4255   A Disk-Sweep MRR interface implementation
4256 
4257   This implementation makes range (and, in the future, 'ref') scans to read
4258   table rows in disk sweeps.
4259 
4260   Currently it is used by MyISAM and InnoDB. Potentially it can be used with
4261   any table handler that has non-clustered indexes and on-disk rows.
4262 */
4263 
4264 class DsMrr_impl
4265 {
4266 public:
4267   typedef void (handler::*range_check_toggle_func_t)(bool on);
4268 
DsMrr_impl()4269   DsMrr_impl() : h2(NULL) {}
4270 
~DsMrr_impl()4271   ~DsMrr_impl()
4272   {
4273     /*
4274       If ha_reset() has not been called then the h2 dialog might still
4275       exist. This must be closed and deleted (this is the case for
4276       internally created temporary tables).
4277     */
4278     if (h2)
4279       reset();
4280     assert(h2 == NULL);
4281   }
4282 
4283   /*
4284     The "owner" handler object (the one that calls dsmrr_XXX functions.
4285     It is used to retrieve full table rows by calling rnd_pos().
4286   */
4287   handler *h;
4288   TABLE *table; /* Always equal to h->table */
4289 private:
4290   /* Secondary handler object.  It is used for scanning the index */
4291   handler *h2;
4292 
4293   /* Buffer to store rowids, or (rowid, range_id) pairs */
4294   uchar *rowids_buf;
4295   uchar *rowids_buf_cur;   /* Current position when reading/writing */
4296   uchar *rowids_buf_last;  /* When reading: end of used buffer space */
4297   uchar *rowids_buf_end;   /* End of the buffer */
4298 
4299   bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */
4300 
4301   /* TRUE <=> need range association, buffer holds {rowid, range_id} pairs */
4302   bool is_mrr_assoc;
4303 
4304   bool use_default_impl; /* TRUE <=> shortcut all calls to default MRR impl */
4305 public:
4306   /**
4307     Initialize the DsMrr_impl object.
4308 
4309     This object is used for both doing default MRR scans and DS-MRR scans.
4310     This function just initializes the object. To do a DS-MRR scan,
4311     this must also be initialized by calling dsmrr_init().
4312 
4313     @param h_arg     pointer to the handler that owns this object
4314     @param table_arg pointer to the TABLE that owns the handler
4315   */
4316 
init(handler * h_arg,TABLE * table_arg)4317   void init(handler *h_arg, TABLE *table_arg)
4318   {
4319     assert(h_arg != NULL);
4320     assert(table_arg != NULL);
4321     h= h_arg;
4322     table= table_arg;
4323   }
4324 
4325   int dsmrr_init(handler *h, RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
4326                  uint n_ranges, uint mode, HANDLER_BUFFER *buf);
4327   void dsmrr_close();
4328 
4329   /**
4330     Resets the DS-MRR object to the state it had after being intialized.
4331 
4332     If there is an open scan then this will be closed.
4333 
4334     This function should be called by handler::ha_reset() which is called
4335     when a statement is completed in order to make the handler object ready
4336     for re-use by a different statement.
4337   */
4338 
4339   void reset();
4340   int dsmrr_fill_buffer();
4341   int dsmrr_next(char **range_info);
4342 
4343   ha_rows dsmrr_info(uint keyno, uint n_ranges, uint keys, uint *bufsz,
4344                      uint *flags, Cost_estimate *cost);
4345 
4346   ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
4347                             void *seq_init_param, uint n_ranges, uint *bufsz,
4348                             uint *flags, Cost_estimate *cost);
4349 private:
4350   bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz,
4351                        Cost_estimate *cost);
4352   bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
4353                                uint *buffer_size, Cost_estimate *cost);
4354 };
4355 	/* Some extern variables used with handlers */
4356 
4357 extern const char *ha_row_type[];
4358 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
4359 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
4360 extern TYPELIB tx_isolation_typelib;
4361 extern const char *myisam_stats_method_names[];
4362 extern ulong total_ha, total_ha_2pc;
4363 
4364 /* lookups */
4365 handlerton *ha_default_handlerton(THD *thd);
4366 handlerton *ha_default_temp_handlerton(THD *thd);
4367 handlerton *ha_enforce_handlerton(THD *thd);
4368 /**
4369   Resolve handlerton plugin by name, without checking for "DEFAULT" or
4370   HTON_NOT_USER_SELECTABLE.
4371 
4372   @param thd  Thread context.
4373   @param name Plugin name.
4374 
4375   @return plugin or NULL if not found.
4376 */
4377 plugin_ref ha_resolve_by_name_raw(THD *thd, const LEX_CSTRING &name);
4378 plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name,
4379                               bool is_temp_table);
4380 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
4381 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
4382 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
4383                          handlerton *db_type);
4384 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
4385                           bool no_substitute, bool report_error);
4386 
4387 
ha_legacy_type(const handlerton * db_type)4388 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
4389 {
4390   return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
4391 }
4392 
4393 const char *ha_resolve_storage_engine_name(const handlerton *db_type);
4394 
ha_check_storage_engine_flag(const handlerton * db_type,uint32 flag)4395 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
4396 {
4397   return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
4398 }
4399 
ha_storage_engine_is_enabled(const handlerton * db_type)4400 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
4401 {
4402   return (db_type && db_type->create) ?
4403          (db_type->state == SHOW_OPTION_YES) : FALSE;
4404 }
4405 
is_ha_partition_handlerton(const handlerton * db_type)4406 static inline bool is_ha_partition_handlerton(const handlerton *db_type)
4407 {
4408   return (db_type->db_type == DB_TYPE_PARTITION_DB);
4409 }
4410 
4411 /* basic stuff */
4412 int ha_init_errors(void);
4413 int ha_init(void);
4414 void ha_end();
4415 int ha_initialize_handlerton(st_plugin_int *plugin);
4416 int ha_finalize_handlerton(st_plugin_int *plugin);
4417 
4418 TYPELIB* ha_known_exts();
4419 int ha_panic(enum ha_panic_function flag);
4420 void ha_close_connection(THD* thd);
4421 void ha_kill_connection(THD *thd);
4422 /**
4423   Flush the log(s) of storage engine(s).
4424 
4425   @param hton Handlerton of storage engine.
4426   @param binlog_group_flush true if we got invoked by binlog group
4427   commit during flush stage, false in other cases.
4428   @retval false Succeed
4429   @retval true Error
4430 */
4431 bool ha_flush_logs(handlerton *db_type, bool binlog_group_flush= false);
4432 void ha_drop_database(char* path);
4433 
4434 class Create_field;
4435 int ha_create_table(THD *thd, const char *path,
4436                     const char *db, const char *table_name,
4437                     HA_CREATE_INFO *create_info,
4438                     const List<Create_field> *create_fields,
4439                     bool update_create_info,
4440                     bool is_temp_table= false);
4441 
4442 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
4443                     const char *db, const char *alias, bool generate_warning);
4444 
4445 /* statistics and info */
4446 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
4447 
4448 /* discovery */
4449 int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
4450 bool ha_check_if_table_exists(THD* thd, const char *db, const char *name,
4451                              bool *exists);
4452 int ha_discover(THD* thd, const char* dbname, const char* name,
4453                 uchar** frmblob, size_t* frmlen);
4454 int ha_find_files(THD *thd,const char *db,const char *path,
4455                   const char *wild, bool dir, List<LEX_STRING>* files);
4456 int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
4457 bool ha_is_supported_system_table(handlerton *hton, const char *db,
4458                                   const char *table_name);
4459 bool ha_is_valid_system_or_user_table(handlerton *hton, const char *db,
4460                                       const char *table_name);
4461 
4462 /* key cache */
4463 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
4464 int ha_resize_key_cache(KEY_CACHE *key_cache);
4465 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
4466 
4467 /* report to InnoDB that control passes to the client */
4468 int ha_release_temporary_latches(THD *thd);
4469 
4470 /* transactions: interface to handlerton functions */
4471 int ha_start_consistent_snapshot(THD *thd);
4472 int ha_store_binlog_info(THD *thd);
4473 int ha_commit_trans(THD *thd, bool all, bool ignore_global_read_lock= false);
4474 int ha_commit_attachable(THD *thd);
4475 int ha_rollback_trans(THD *thd, bool all);
4476 int ha_prepare(THD *thd);
4477 
4478 
4479 /**
4480   recover() step of xa.
4481 
4482   @note
4483     there are three modes of operation:
4484     - automatic recover after a crash
4485     in this case commit_list != 0, tc_heuristic_recover==TC_HEURISTIC_NOT_USED
4486     all xids from commit_list are committed, others are rolled back
4487     - manual (heuristic) recover
4488     in this case commit_list==0, tc_heuristic_recover != TC_HEURISTIC_NOT_USED
4489     DBA has explicitly specified that all prepared transactions should
4490     be committed (or rolled back).
4491     - no recovery (MySQL did not detect a crash)
4492     in this case commit_list==0, tc_heuristic_recover == TC_HEURISTIC_NOT_USED
4493     there should be no prepared transactions in this case.
4494 */
4495 
4496 int ha_recover(HASH *commit_list);
4497 
4498 /*
4499  transactions: interface to low-level handlerton functions. These are
4500  intended to be used by the transaction coordinators to
4501  commit/prepare/rollback transactions in the engines.
4502 */
4503 int ha_commit_low(THD *thd, bool all, bool run_after_commit= true);
4504 int ha_prepare_low(THD *thd, bool all);
4505 int ha_rollback_low(THD *thd, bool all);
4506 
4507 bool ha_flush_changed_page_bitmaps();
4508 bool ha_purge_changed_page_bitmaps(ulonglong lsn);
4509 
4510 /* transactions: these functions never call handlerton functions directly */
4511 int ha_enable_transaction(THD *thd, bool on);
4512 
4513 /* savepoints */
4514 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
4515 bool ha_rollback_to_savepoint_can_release_mdl(THD *thd);
4516 int ha_savepoint(THD *thd, SAVEPOINT *sv);
4517 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
4518 
4519 /* Build pushed joins in handlers implementing this feature */
4520 int ha_make_pushed_joins(THD *thd, const AQP::Join_plan* plan);
4521 
4522 /* these are called by storage engines */
4523 void trans_register_ha(THD *thd, bool all, handlerton *ht,
4524                        const ulonglong *trxid);
4525 /*
4526   Storage engine has to assume the transaction will end up with 2pc if
4527    - there is more than one 2pc-capable storage engine available
4528    - in the current transaction 2pc was not disabled yet
4529 */
4530 #define trans_need_2pc(thd, all)                   ((total_ha_2pc > 1) && \
4531         !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
4532 
4533 int ha_reset_logs(THD *thd);
4534 int ha_binlog_index_purge_file(THD *thd, const char *file);
4535 void ha_reset_slave(THD *thd);
4536 void ha_binlog_log_query(THD *thd, handlerton *db_type,
4537                          enum_binlog_command binlog_command,
4538                          const char *query, size_t query_length,
4539                          const char *db, const char *table_name);
4540 void ha_binlog_wait(THD *thd);
4541 
4542 /* It is required by basic binlog features on both MySQL server and libmysqld */
4543 int ha_binlog_end(THD *thd);
4544 
4545 const char *ha_legacy_type_name(legacy_db_type legacy_type);
4546 const char *get_canonical_filename(handler *file, const char *path,
4547                                    char *tmp_path);
4548 
table_case_name(HA_CREATE_INFO * info,const char * name)4549 inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
4550 {
4551   return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
4552 }
4553 
4554 void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag);
4555 void print_keydup_error(TABLE *table, KEY *key, myf errflag);
4556 
4557 void ha_set_normalized_disabled_se_str(const std::string &disabled_se_str);
4558 bool ha_is_storage_engine_disabled(handlerton *se_engine);
4559 
4560 bool ha_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key,
4561                              ha_notification_type notification_type,
4562                              bool *victimized);
4563 bool ha_notify_alter_table(THD *thd, const MDL_key *mdl_key,
4564                            ha_notification_type notification_type);
4565 
4566 int commit_owned_gtids(THD *thd, bool all, bool *need_clear_ptr);
4567 int commit_owned_gtid_by_partial_command(THD *thd);
4568 bool set_tx_isolation(THD *thd,
4569                       enum_tx_isolation tx_isolation,
4570                       bool one_shot);
4571 bool ha_check_reserved_db_name(const char *name);
4572 
4573 #endif /* HANDLER_INCLUDED */
4574