1 #ifndef HANDLER_INCLUDED
2 #define HANDLER_INCLUDED
3 
4 /*
5    Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
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 <fcntl.h>
31 #include <float.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <time.h>
35 #include <algorithm>
36 #include <bitset>
37 #include <functional>
38 #include <map>
39 #include <random>  // std::mt19937
40 #include <set>
41 #include <string>
42 
43 #include <mysql/components/services/page_track_service.h>
44 #include "ft_global.h"  // ft_hints
45 #include "lex_string.h"
46 #include "m_ctype.h"
47 #include "map_helpers.h"
48 #include "my_alloc.h"
49 #include "my_base.h"
50 #include "my_bitmap.h"
51 #include "my_compiler.h"
52 #include "my_dbug.h"
53 #include "my_double2ulonglong.h"
54 #include "my_inttypes.h"
55 #include "my_io.h"
56 #include "my_sys.h"
57 #include "my_table_map.h"
58 #include "my_thread_local.h"  // my_errno
59 #include "mysql/components/services/psi_table_bits.h"
60 #include "sql/dd/object_id.h"  // dd::Object_id
61 #include "sql/dd/string_type.h"
62 #include "sql/dd/types/object_table.h"  // dd::Object_table
63 #include "sql/discrete_interval.h"      // Discrete_interval
64 #include "sql/key.h"
65 #include "sql/sql_const.h"       // SHOW_COMP_OPTION
66 #include "sql/sql_list.h"        // SQL_I_List
67 #include "sql/sql_plugin_ref.h"  // plugin_ref
68 #include "thr_lock.h"            // thr_lock_type
69 #include "typelib.h"
70 
71 class Alter_info;
72 class Candidate_table_order;
73 class Create_field;
74 class Field;
75 class Item;
76 class JOIN;
77 class Json_dom;
78 class Partition_handler;
79 class Plugin_table;
80 class Plugin_tablespace;
81 class Record_buffer;
82 class SE_cost_constants;  // see opt_costconstants.h
83 class String;
84 class THD;
85 class handler;
86 class partition_info;
87 struct System_status_var;
88 
89 namespace dd {
90 class Properties;
91 }  // namespace dd
92 struct KEY_CACHE;
93 struct LEX;
94 struct MY_BITMAP;
95 struct SAVEPOINT;
96 struct TABLE;
97 struct TABLE_LIST;
98 struct TABLE_SHARE;
99 struct Tablespace_options;
100 struct handlerton;
101 
102 typedef struct xid_t XID;
103 typedef struct st_xarecover_txn XA_recover_txn;
104 struct MDL_key;
105 
106 namespace dd {
107 enum class enum_column_types;
108 class Table;
109 class Tablespace;
110 }  // namespace dd
111 
112 /** Id for identifying Table SDIs */
113 constexpr const uint32 SDI_TYPE_TABLE = 1;
114 
115 /** Id for identifying Tablespace SDIs */
116 constexpr const uint32 SDI_TYPE_TABLESPACE = 2;
117 
118 /** Key to identify a dictionary object */
119 struct sdi_key_t {
120   /** Type of Object, For ex: column, index, etc */
121   uint32 type;
122 
123   /** Object id which should be unique in tablespsace */
124   uint64 id;
125 };
126 
127 using sdi_container = std::vector<sdi_key_t>;
128 struct sdi_vector_t {
129   sdi_container m_vec;
130 };
131 
132 typedef bool (*qc_engine_callback)(THD *thd, const char *table_key,
133                                    uint key_length, ulonglong *engine_data);
134 
135 typedef bool(stat_print_fn)(THD *thd, const char *type, size_t type_len,
136                             const char *file, size_t file_len,
137                             const char *status, size_t status_len);
138 
139 class ha_statistics;
140 class ha_tablespace_statistics;
141 
142 namespace AQP {
143 class Table_access;
144 }  // namespace AQP
145 class Unique_on_insert;
146 
147 extern ulong savepoint_alloc_size;
148 
149 /// Maps from slot to plugin. May return NULL if plugin has been unloaded.
150 st_plugin_int *hton2plugin(uint slot);
151 /// Returns the size of the array holding pointers to plugins.
152 size_t num_hton2plugins();
153 
154 /**
155   For unit testing.
156   Insert plugin into arbitrary slot in array.
157   Remove plugin from arbitrary slot in array.
158 */
159 st_plugin_int *insert_hton2plugin(uint slot, st_plugin_int *plugin);
160 st_plugin_int *remove_hton2plugin(uint slot);
161 
162 extern const char *ha_row_type[];
163 extern const char *tx_isolation_names[];
164 extern const char *binlog_format_names[];
165 extern TYPELIB tx_isolation_typelib;
166 extern ulong total_ha_2pc;
167 
168 // the following is for checking tables
169 
170 #define HA_ADMIN_ALREADY_DONE 1
171 #define HA_ADMIN_OK 0
172 #define HA_ADMIN_NOT_IMPLEMENTED -1
173 #define HA_ADMIN_FAILED -2
174 #define HA_ADMIN_CORRUPT -3
175 #define HA_ADMIN_INTERNAL_ERROR -4
176 #define HA_ADMIN_INVALID -5
177 #define HA_ADMIN_REJECT -6
178 #define HA_ADMIN_TRY_ALTER -7
179 #define HA_ADMIN_WRONG_CHECKSUM -8
180 #define HA_ADMIN_NOT_BASE_TABLE -9
181 #define HA_ADMIN_NEEDS_UPGRADE -10
182 #define HA_ADMIN_NEEDS_ALTER -11
183 #define HA_ADMIN_NEEDS_CHECK -12
184 #define HA_ADMIN_STATS_UPD_ERR -13
185 /** User needs to dump and re-create table to fix pre 5.0 decimal types */
186 #define HA_ADMIN_NEEDS_DUMP_UPGRADE -14
187 
188 /**
189    Return values for check_if_supported_inplace_alter().
190 
191    @see check_if_supported_inplace_alter() for description of
192    the individual values.
193 */
194 enum enum_alter_inplace_result {
195   HA_ALTER_ERROR,
196   HA_ALTER_INPLACE_NOT_SUPPORTED,
197   HA_ALTER_INPLACE_EXCLUSIVE_LOCK,
198   HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE,
199   HA_ALTER_INPLACE_SHARED_LOCK,
200   HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE,
201   HA_ALTER_INPLACE_NO_LOCK,
202   HA_ALTER_INPLACE_INSTANT
203 };
204 
205 /* Bits in table_flags() to show what database can do */
206 
207 #define HA_NO_TRANSACTIONS (1 << 0)     /* Doesn't support transactions */
208 #define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
209 /*
210   Used to avoid scanning full tables on an index. If this flag is set then
211   the handler always has a primary key (hidden if not defined) and this
212   index is used for scanning rather than a full table scan in all
213   situations. No separate data/index file.
214 */
215 #define HA_TABLE_SCAN_ON_INDEX (1 << 2)
216 
217 /// Not in use.
218 #define HA_UNUSED3 (1 << 3)
219 
220 /*
221   Can the storage engine handle spatial data.
222   Used to check that no spatial attributes are declared unless
223   the storage engine is capable of handling it.
224 */
225 #define HA_CAN_GEOMETRY (1 << 4)
226 /*
227   Reading keys in random order is as fast as reading keys in sort order
228   (Used by filesort to decide if we should sort key + data or key +
229   pointer-to-row.)
230 */
231 #define HA_FAST_KEY_READ (1 << 5)
232 /*
233   Set the following flag if we on delete should force all key to be read
234   and on update read all keys that changes
235 */
236 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
237 /*
238   Is NULL values allowed in indexes.
239   If this is not allowed then it is not possible to use an index on a
240   NULLable field.
241 */
242 #define HA_NULL_IN_KEY (1 << 7)
243 /*
244   Tells that we can the position for the conflicting duplicate key
245   record is stored in table->file->dupp_ref. (insert uses rnd_pos() on
246   this to find the duplicated row)
247 */
248 #define HA_DUPLICATE_POS (1 << 8)
249 #define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
250 /*
251   Is the storage engine capable of defining an index of a prefix on
252   a BLOB attribute.
253 */
254 #define HA_CAN_INDEX_BLOBS (1 << 10)
255 /*
256   Auto increment fields can be part of a multi-part key. For second part
257   auto-increment keys, the auto_incrementing is done in handler.cc
258 */
259 #define HA_AUTO_PART_KEY (1 << 11)
260 /*
261   Can't define a table without primary key (and cannot handle a table
262   with hidden primary key)
263 */
264 #define HA_REQUIRE_PRIMARY_KEY (1 << 12)
265 /*
266   Does the counter of records after the info call specify an exact
267   value or not. If it does this flag is set.
268 */
269 #define HA_STATS_RECORDS_IS_EXACT (1 << 13)
270 /// Not in use.
271 #define HA_UNUSED14 (1 << 14)
272 /*
273   This parameter is set when the handler will also return the primary key
274   when doing read-only-key on another index, i.e., if we get the primary
275   key columns for free when we do an index read (usually, it also implies
276   that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION flag is set).
277 */
278 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
279 /*
280   If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
281   uses a primary key given by the record argument.
282   Without primary key, we can't call position().
283   If not set, the position is returned as the current rows position
284   regardless of what argument is given.
285 */
286 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
287 #define HA_CAN_RTREEKEYS (1 << 17)
288 /// Not in use.
289 #define HA_UNUSED18
290 /*
291   The following is we need to a primary key to delete (and update) a row.
292   If there is no primary key, all columns needs to be read on update and delete
293 */
294 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
295 /*
296   Indexes on prefixes of character fields are not allowed.
297 */
298 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
299 /*
300   Does the storage engine support fulltext indexes.
301 */
302 #define HA_CAN_FULLTEXT (1 << 21)
303 /*
304   Can the HANDLER interface in the MySQL API be used towards this
305   storage engine.
306 */
307 #define HA_CAN_SQL_HANDLER (1 << 22)
308 /*
309   Set if the storage engine does not support auto increment fields.
310 */
311 #define HA_NO_AUTO_INCREMENT (1 << 23)
312 /*
313   Supports CHECKSUM option in CREATE TABLE (MyISAM feature).
314 */
315 #define HA_HAS_CHECKSUM (1 << 24)
316 /*
317   Table data are stored in separate files (for lower_case_table_names).
318   Should file names always be in lower case (used by engines that map
319   table names to file names.
320 */
321 #define HA_FILE_BASED (1 << 26)
322 #define HA_NO_VARCHAR (1 << 27)
323 /*
324   Is the storage engine capable of handling bit fields.
325 */
326 #define HA_CAN_BIT_FIELD (1 << 28)
327 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
328 #define HA_NO_COPY_ON_ALTER (1LL << 31)
329 #define HA_COUNT_ROWS_INSTANT (1LL << 32) /* records() gives exact count*/
330 /* Has it's own method of binlog logging */
331 #define HA_HAS_OWN_BINLOGGING (1LL << 33)
332 /*
333   Engine is capable of row-format and statement-format logging,
334   respectively
335 */
336 #define HA_BINLOG_ROW_CAPABLE (1LL << 34)
337 #define HA_BINLOG_STMT_CAPABLE (1LL << 35)
338 /*
339     When a multiple key conflict happens in a REPLACE command mysql
340     expects the conflicts to be reported in the ascending order of
341     key names.
342 
343     For e.g.
344 
345     CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
346                      NULL, INDEX(c));
347 
348     REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
349 
350     MySQL expects the conflict with 'a' to be reported before the conflict with
351     'b'.
352 
353     If the underlying storage engine does not report the conflicting keys in
354     ascending order, it causes unexpected errors when the REPLACE command is
355     executed.
356 
357     This flag helps the underlying SE to inform the server that the keys are not
358     ordered.
359 */
360 #define HA_DUPLICATE_KEY_NOT_IN_ORDER (1LL << 36)
361 /*
362   Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
363   incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
364   will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
365 */
366 #define HA_CAN_REPAIR (1LL << 37)
367 
368 /*
369   Set of all binlog flags. Currently only contain the capabilities
370   flags.
371  */
372 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
373 
374 /**
375   The handler supports read before write removal optimization
376 
377   Read before write removal may be used for storage engines which support
378   write without previous read of the row to be updated. Handler returning
379   this flag must implement start_read_removal() and end_read_removal().
380   The handler may return "fake" rows constructed from the key of the row
381   asked for. This is used to optimize UPDATE and DELETE by reducing the
382   number of round-trips between handler and storage engine.
383 
384   Example:
385   UPDATE a=1 WHERE pk IN (@<keys@>)
386 
387   @verbatim
388   mysql_update()
389   {
390     if (<conditions for starting read removal>)
391       start_read_removal()
392       -> handler returns true if read removal supported for this table/query
393 
394     while(read_record("pk=<key>"))
395       -> handler returns fake row with column "pk" set to <key>
396 
397       ha_update_row()
398       -> handler sends write "a=1" for row with "pk=<key>"
399 
400     end_read_removal()
401     -> handler returns the number of rows actually written
402   }
403   @endverbatim
404 
405   @note This optimization in combination with batching may be used to
406         remove even more round-trips.
407 */
408 #define HA_READ_BEFORE_WRITE_REMOVAL (1LL << 38)
409 
410 /*
411   Engine supports extended fulltext API
412  */
413 #define HA_CAN_FULLTEXT_EXT (1LL << 39)
414 
415 /*
416   Storage engine doesn't synchronize result set with expected table contents.
417   Used by replication slave to check if it is possible to retrieve rows from
418   the table when deciding whether to do a full table scan, index scan or hash
419   scan while applying a row event.
420  */
421 #define HA_READ_OUT_OF_SYNC (1LL << 40)
422 
423 /*
424   Storage engine supports table export using the
425   FLUSH TABLE <table_list> FOR EXPORT statement.
426  */
427 #define HA_CAN_EXPORT (1LL << 41)
428 
429 /*
430   The handler don't want accesses to this table to
431   be const-table optimized
432 */
433 #define HA_BLOCK_CONST_TABLE (1LL << 42)
434 
435 /*
436   Handler supports FULLTEXT hints
437 */
438 #define HA_CAN_FULLTEXT_HINTS (1LL << 43)
439 
440 /**
441   Storage engine doesn't support LOCK TABLE ... READ LOCAL locks
442   but doesn't want to use handler::store_lock() API for upgrading
443   them to LOCK TABLE ... READ locks, for example, because it doesn't
444   use THR_LOCK locks at all.
445 */
446 #define HA_NO_READ_LOCAL_LOCK (1LL << 44)
447 
448 /**
449   A storage engine is compatible with the attachable transaction requirements
450   means that
451 
452     - either SE detects the fact that THD::ha_data was reset and starts a new
453       attachable transaction, closes attachable transaction on close_connection
454       and resumes regular (outer) transaction when THD::ha_data is restored;
455 
456     - or SE completely ignores THD::ha_data and close_connection like MyISAM
457       does.
458 */
459 #define HA_ATTACHABLE_TRX_COMPATIBLE (1LL << 45)
460 
461 /**
462   Handler supports Generated Columns
463 */
464 #define HA_GENERATED_COLUMNS (1LL << 46)
465 
466 /**
467   Supports index on virtual generated column
468 */
469 #define HA_CAN_INDEX_VIRTUAL_GENERATED_COLUMN (1LL << 47)
470 
471 /**
472   Supports descending indexes
473 */
474 #define HA_DESCENDING_INDEX (1LL << 48)
475 
476 /**
477   Supports partial update of BLOB columns.
478 */
479 #define HA_BLOB_PARTIAL_UPDATE (1LL << 49)
480 
481 /**
482   If this isn't defined, only columns/indexes with Cartesian coordinate systems
483   (projected SRS or SRID 0) is supported. Columns/indexes without SRID
484   restriction is also supported if this isn't defined.
485 */
486 #define HA_SUPPORTS_GEOGRAPHIC_GEOMETRY_COLUMN (1LL << 50)
487 
488 /**
489   Handler supports expressions as DEFAULT for a column.
490 */
491 #define HA_SUPPORTS_DEFAULT_EXPRESSION (1LL << 51)
492 
493 /**
494   Handlers with this flag set do not support UPDATE operations.
495 */
496 #define HA_UPDATE_NOT_SUPPORTED (1LL << 52)
497 
498 /**
499   Handlers with this flag set do not support DELETE operations.
500 */
501 #define HA_DELETE_NOT_SUPPORTED (1LL << 53)
502 
503 /**
504   The storage engine does not support using indexes for access. Indexes can only
505   be used for estimating cost.
506 */
507 #define HA_NO_INDEX_ACCESS (1LL << 54)
508 
509 /**
510   Supports multi-valued index
511 */
512 #define HA_MULTI_VALUED_KEY_SUPPORT (1LL << 55)
513 
514 /*
515   Bits in index_flags(index_number) for what you can do with index.
516   If you do not implement indexes, just return zero here.
517 */
518 /*
519   Does the index support read next, this is assumed in the server
520   code and never checked so all indexes must support this.
521   Note that the handler can be used even if it doesn't have any index.
522 */
523 #define HA_READ_NEXT 1 /* TODO really use this flag */
524 /*
525   Can the index be used to scan backwards (supports ::index_prev).
526 */
527 #define HA_READ_PREV 2
528 /*
529   Can the index deliver its record in index order. Typically true for
530   all ordered indexes and not true for hash indexes. Used to set keymap
531   part_of_sortkey.
532   This keymap is only used to find indexes usable for resolving an ORDER BY
533   in the query. Thus in most cases index_read will work just fine without
534   order in result production. When this flag is set it is however safe to
535   order all output started by index_read since most engines do this. With
536   read_multi_range calls there is a specific flag setting order or not
537   order so in those cases ordering of index output can be avoided.
538 */
539 #define HA_READ_ORDER 4
540 /*
541   Specify whether index can handle ranges, typically true for all
542   ordered indexes and not true for hash indexes.
543   Used by optimiser to check if ranges (as key >= 5) can be optimised
544   by index.
545 */
546 #define HA_READ_RANGE 8
547 /*
548   Can't use part key searches. This is typically true for hash indexes
549   and typically not true for ordered indexes.
550 */
551 #define HA_ONLY_WHOLE_INDEX 16
552 /*
553   Does the storage engine support index-only scans on this index.
554   Enables use of HA_EXTRA_KEYREAD and HA_EXTRA_NO_KEYREAD
555   Used to set Key_map keys_for_keyread and to check in optimiser for
556   index-only scans.  When doing a read under HA_EXTRA_KEYREAD the handler
557   only have to fill in the columns the key covers. If
558   HA_PRIMARY_KEY_IN_READ_INDEX is set then also the PRIMARY KEY columns
559   must be updated in the row.
560 */
561 #define HA_KEYREAD_ONLY 64
562 /*
563   Index scan will not return records in rowid order. Not guaranteed to be
564   set for unordered (e.g. HASH) indexes.
565 */
566 #define HA_KEY_SCAN_NOT_ROR 128
567 #define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */
568 
569 /* operations for disable/enable indexes */
570 #define HA_KEY_SWITCH_NONUNIQ 0
571 #define HA_KEY_SWITCH_ALL 1
572 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
573 #define HA_KEY_SWITCH_ALL_SAVE 3
574 
575 /*
576   Use this instead of 0 as the initial value for the slot number of
577   handlerton, so that we can distinguish uninitialized slot number
578   from slot 0.
579 */
580 #define HA_SLOT_UNDEF ((uint)-1)
581 
582 /*
583   Parameters for open() (in register form->filestat)
584   HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
585 */
586 
587 #define HA_OPEN_KEYFILE 1
588 #define HA_OPEN_RNDFILE 2
589 #define HA_GET_INDEX 4
590 #define HA_GET_INFO 8   /* do a handler::info() after open */
591 #define HA_READ_ONLY 16 /* File opened as readonly */
592 /* Try readonly if can't open with read and write */
593 #define HA_TRY_READ_ONLY 32
594 #define HA_WAIT_IF_LOCKED 64   /* Wait if locked on open */
595 #define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
596 #define HA_BLOCK_LOCK 256      /* unlock when reading some records */
597 #define HA_OPEN_TEMPORARY 512
598 
599 /* Some key definitions */
600 #define HA_KEY_NULL_LENGTH 1
601 #define HA_KEY_BLOB_LENGTH 2
602 
603 #define HA_LEX_CREATE_TMP_TABLE 1
604 #define HA_LEX_CREATE_IF_NOT_EXISTS 2
605 #define HA_LEX_CREATE_TABLE_LIKE 4
606 #define HA_LEX_CREATE_INTERNAL_TMP_TABLE 8
607 #define HA_MAX_REC_LENGTH 65535U
608 
609 /**
610   Options for the START TRANSACTION statement.
611 
612   Note that READ ONLY and READ WRITE are logically mutually exclusive.
613   This is enforced by the parser and depended upon by trans_begin().
614 
615   We need two flags instead of one in order to differentiate between
616   situation when no READ WRITE/ONLY clause were given and thus transaction
617   is implicitly READ WRITE and the case when READ WRITE clause was used
618   explicitly.
619 */
620 
621 // WITH CONSISTENT SNAPSHOT option
622 static const uint MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT = 1;
623 // READ ONLY option
624 static const uint MYSQL_START_TRANS_OPT_READ_ONLY = 2;
625 // READ WRITE option
626 static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4;
627 // HIGH PRIORITY option
628 static const uint MYSQL_START_TRANS_OPT_HIGH_PRIORITY = 8;
629 
630 enum legacy_db_type {
631   DB_TYPE_UNKNOWN = 0,
632   DB_TYPE_DIAB_ISAM = 1,
633   DB_TYPE_HASH,
634   DB_TYPE_MISAM,
635   DB_TYPE_PISAM,
636   DB_TYPE_RMS_ISAM,
637   DB_TYPE_HEAP,
638   DB_TYPE_ISAM,
639   DB_TYPE_MRG_ISAM,
640   DB_TYPE_MYISAM,
641   DB_TYPE_MRG_MYISAM,
642   DB_TYPE_BERKELEY_DB,
643   DB_TYPE_INNODB,
644   DB_TYPE_GEMINI,
645   DB_TYPE_NDBCLUSTER,
646   DB_TYPE_EXAMPLE_DB,
647   DB_TYPE_ARCHIVE_DB,
648   DB_TYPE_CSV_DB,
649   DB_TYPE_FEDERATED_DB,
650   DB_TYPE_BLACKHOLE_DB,
651   DB_TYPE_PARTITION_DB,  // No longer used.
652   DB_TYPE_BINLOG,
653   DB_TYPE_SOLID,
654   DB_TYPE_PBXT,
655   DB_TYPE_TABLE_FUNCTION,
656   DB_TYPE_MEMCACHE,
657   DB_TYPE_FALCON,
658   DB_TYPE_MARIA,
659   /** Performance schema engine. */
660   DB_TYPE_PERFORMANCE_SCHEMA,
661   DB_TYPE_TEMPTABLE,
662   DB_TYPE_FIRST_DYNAMIC = 42,
663   DB_TYPE_DEFAULT = 127  // Must be last
664 };
665 
666 enum row_type : int {
667   ROW_TYPE_NOT_USED = -1,
668   ROW_TYPE_DEFAULT,
669   ROW_TYPE_FIXED,
670   ROW_TYPE_DYNAMIC,
671   ROW_TYPE_COMPRESSED,
672   ROW_TYPE_REDUNDANT,
673   ROW_TYPE_COMPACT,
674   /** Unused. Reserved for future versions. */
675   ROW_TYPE_PAGED
676 };
677 
678 enum enum_binlog_func {
679   BFN_RESET_LOGS = 1,
680   BFN_RESET_SLAVE = 2,
681   BFN_BINLOG_WAIT = 3,
682   BFN_BINLOG_END = 4,
683   BFN_BINLOG_PURGE_FILE = 5
684 };
685 
686 enum enum_binlog_command {
687   LOGCOM_CREATE_TABLE,
688   LOGCOM_ALTER_TABLE,
689   LOGCOM_RENAME_TABLE,
690   LOGCOM_DROP_TABLE,
691   LOGCOM_CREATE_DB,
692   LOGCOM_ALTER_DB,
693   LOGCOM_DROP_DB,
694 };
695 
696 enum class enum_sampling_method { SYSTEM, NONE };
697 
698 /* Bits in used_fields */
699 #define HA_CREATE_USED_AUTO (1L << 0)
700 #define HA_CREATE_USED_RAID (1L << 1)  // RAID is no longer availble
701 #define HA_CREATE_USED_UNION (1L << 2)
702 #define HA_CREATE_USED_INSERT_METHOD (1L << 3)
703 #define HA_CREATE_USED_MIN_ROWS (1L << 4)
704 #define HA_CREATE_USED_MAX_ROWS (1L << 5)
705 #define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
706 #define HA_CREATE_USED_PACK_KEYS (1L << 7)
707 #define HA_CREATE_USED_CHARSET (1L << 8)
708 #define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
709 #define HA_CREATE_USED_DATADIR (1L << 10)
710 #define HA_CREATE_USED_INDEXDIR (1L << 11)
711 #define HA_CREATE_USED_ENGINE (1L << 12)
712 #define HA_CREATE_USED_CHECKSUM (1L << 13)
713 #define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
714 #define HA_CREATE_USED_ROW_FORMAT (1L << 15)
715 #define HA_CREATE_USED_COMMENT (1L << 16)
716 #define HA_CREATE_USED_PASSWORD (1L << 17)
717 #define HA_CREATE_USED_CONNECTION (1L << 18)
718 #define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
719 /** Unused. Reserved for future versions. */
720 #define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
721 /** Unused. Reserved for future versions. */
722 #define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
723 /** This is set whenever STATS_PERSISTENT=0|1|default has been
724 specified in CREATE/ALTER TABLE. See also HA_OPTION_STATS_PERSISTENT in
725 include/my_base.h. It is possible to distinguish whether
726 STATS_PERSISTENT=default has been specified or no STATS_PERSISTENT= is
727 given at all. */
728 #define HA_CREATE_USED_STATS_PERSISTENT (1L << 22)
729 /**
730    This is set whenever STATS_AUTO_RECALC=0|1|default has been
731    specified in CREATE/ALTER TABLE. See enum_stats_auto_recalc.
732    It is possible to distinguish whether STATS_AUTO_RECALC=default
733    has been specified or no STATS_AUTO_RECALC= is given at all.
734 */
735 #define HA_CREATE_USED_STATS_AUTO_RECALC (1L << 23)
736 /**
737    This is set whenever STATS_SAMPLE_PAGES=N|default has been
738    specified in CREATE/ALTER TABLE. It is possible to distinguish whether
739    STATS_SAMPLE_PAGES=default has been specified or no STATS_SAMPLE_PAGES= is
740    given at all.
741 */
742 #define HA_CREATE_USED_STATS_SAMPLE_PAGES (1L << 24)
743 
744 /**
745    This is set whenever a 'TABLESPACE=...' phrase is used on CREATE TABLE
746 */
747 #define HA_CREATE_USED_TABLESPACE (1L << 25)
748 
749 /** COMPRESSION="zlib|lz4|none" used during table create. */
750 #define HA_CREATE_USED_COMPRESS (1L << 26)
751 
752 /** ENCRYPTION="Y" used during table create. */
753 #define HA_CREATE_USED_ENCRYPT (1L << 27)
754 
755 /**
756   CREATE|ALTER SCHEMA|DATABASE|TABLE has an explicit COLLATE clause.
757 
758   Implies HA_CREATE_USED_DEFAULT_CHARSET.
759 */
760 #define HA_CREATE_USED_DEFAULT_COLLATE (1L << 28)
761 
762 /** SECONDARY_ENGINE used during table create. */
763 #define HA_CREATE_USED_SECONDARY_ENGINE (1L << 29)
764 
765 /**
766   CREATE|ALTER SCHEMA|DATABASE has an explicit ENCRYPTION clause.
767 
768   Implies HA_CREATE_USED_DEFAULT_ENCRYPTION.
769 */
770 #define HA_CREATE_USED_DEFAULT_ENCRYPTION (1L << 30)
771 
772 /**
773   This option is used to convey that the create table should not
774   commit the operation and keep the transaction started.
775 */
776 constexpr const uint64_t HA_CREATE_USED_START_TRANSACTION{1ULL << 31};
777 
778 constexpr const uint64_t HA_CREATE_USED_ENGINE_ATTRIBUTE{1ULL << 32};
779 constexpr const uint64_t HA_CREATE_USED_SECONDARY_ENGINE_ATTRIBUTE{1ULL << 33};
780 
781 /*
782   End of bits used in used_fields
783 */
784 
785 /*
786   Structure to hold list of database_name.table_name.
787   This is used at both mysqld and storage engine layer.
788 */
789 struct st_handler_tablename {
790   const char *db;
791   const char *tablename;
792 };
793 
794 #define MAXGTRIDSIZE 64
795 #define MAXBQUALSIZE 64
796 
797 #define COMPATIBLE_DATA_YES 0
798 #define COMPATIBLE_DATA_NO 1
799 
800 /*
801   These structures are used to pass information from a set of SQL commands
802   on add/drop/change tablespace definitions to the proper hton.
803 */
804 #define UNDEF_NODEGROUP 65535
805 
806 // FUTURE: Combine these two enums into one enum class
807 enum ts_command_type {
808   TS_CMD_NOT_DEFINED = -1,
809   CREATE_TABLESPACE = 0,
810   ALTER_TABLESPACE = 1,
811   CREATE_LOGFILE_GROUP = 2,
812   ALTER_LOGFILE_GROUP = 3,
813   DROP_TABLESPACE = 4,
814   DROP_LOGFILE_GROUP = 5,
815   CHANGE_FILE_TABLESPACE = 6,
816   ALTER_ACCESS_MODE_TABLESPACE = 7,
817   CREATE_UNDO_TABLESPACE = 8,
818   ALTER_UNDO_TABLESPACE = 9,
819   DROP_UNDO_TABLESPACE = 10
820 };
821 
822 enum ts_alter_tablespace_type {
823   TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
824   ALTER_TABLESPACE_ADD_FILE = 1,
825   ALTER_TABLESPACE_DROP_FILE = 2,
826   ALTER_TABLESPACE_RENAME = 3,
827   ALTER_TABLESPACE_OPTIONS = 4,
828   ALTER_UNDO_TABLESPACE_SET_ACTIVE = 5,
829   ALTER_UNDO_TABLESPACE_SET_INACTIVE = 6
830 };
831 
832 /**
833   Legacy struct for passing tablespace information to SEs.
834 
835   FUTURE: Pass all info through dd objects
836  */
837 class st_alter_tablespace {
838  public:
839   const char *tablespace_name = nullptr;
840   const char *logfile_group_name = nullptr;
841   ts_command_type ts_cmd_type = TS_CMD_NOT_DEFINED;
842   enum ts_alter_tablespace_type ts_alter_tablespace_type =
843       TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED;
844   const char *data_file_name = nullptr;
845   const char *undo_file_name = nullptr;
846   ulonglong extent_size = 1024 * 1024;           // Default 1 MByte
847   ulonglong undo_buffer_size = 8 * 1024 * 1024;  // Default 8 MByte
848   ulonglong redo_buffer_size = 8 * 1024 * 1024;  // Default 8 MByte
849   ulonglong initial_size = 128 * 1024 * 1024;    // Default 128 MByte
850   ulonglong autoextend_size = 0;                 // No autoextension as default
851   ulonglong max_size = 0;         // Max size == initial size => no extension
852   ulonglong file_block_size = 0;  // 0=default or must be a valid Page Size
853   uint nodegroup_id = UNDEF_NODEGROUP;
854   bool wait_until_completed = true;
855   const char *ts_comment = nullptr;
856 
is_tablespace_command()857   bool is_tablespace_command() {
858     return ts_cmd_type == CREATE_TABLESPACE ||
859            ts_cmd_type == ALTER_TABLESPACE || ts_cmd_type == DROP_TABLESPACE ||
860            ts_cmd_type == CHANGE_FILE_TABLESPACE ||
861            ts_cmd_type == ALTER_ACCESS_MODE_TABLESPACE;
862   }
863 
864   /**
865     Proper constructor even for all-public class simplifies initialization and
866     allows members to be const.
867 
868     FUTURE: With constructor all members can be made const, and do not need
869     default initializers.
870 
871     @param tablespace name of tabelspace (nullptr for logfile group statements)
872     @param logfile_group name of logfile group or nullptr
873     @param cmd main statement type
874     @param alter_tablespace_cmd subcommand type for ALTER TABLESPACE
875     @param datafile tablespace file for CREATE and ALTER ... ADD ...
876     @param undofile only applies to logfile group statements. nullptr otherwise.
877     @param opts options provided by parser
878   */
879   st_alter_tablespace(const char *tablespace, const char *logfile_group,
880                       ts_command_type cmd,
881                       enum ts_alter_tablespace_type alter_tablespace_cmd,
882                       const char *datafile, const char *undofile,
883                       const Tablespace_options &opts);
884 };
885 
886 /*
887   Make sure that the order of schema_tables and enum_schema_tables are the same.
888 */
889 enum enum_schema_tables : int {
890   SCH_FIRST = 0,
891   SCH_COLUMN_PRIVILEGES = SCH_FIRST,
892   SCH_ENGINES,
893   SCH_OPEN_TABLES,
894   SCH_OPTIMIZER_TRACE,
895   SCH_PLUGINS,
896   SCH_PROCESSLIST,
897   SCH_PROFILES,
898   SCH_SCHEMA_PRIVILEGES,
899   SCH_TABLESPACES,
900   SCH_TABLE_PRIVILEGES,
901   SCH_USER_PRIVILEGES,
902   SCH_TMP_TABLE_COLUMNS,
903   SCH_TMP_TABLE_KEYS,
904   SCH_LAST = SCH_TMP_TABLE_KEYS
905 };
906 
907 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
908 enum ha_notification_type : int { HA_NOTIFY_PRE_EVENT, HA_NOTIFY_POST_EVENT };
909 
910 /** Clone start operation mode */
911 enum Ha_clone_mode {
912   /** Start a new clone operation */
913   HA_CLONE_MODE_START,
914 
915   /** Re-start a clone operation after failure */
916   HA_CLONE_MODE_RESTART,
917 
918   /** Add a new task to a running clone operation */
919   HA_CLONE_MODE_ADD_TASK,
920 
921   /** Get version for transfer data format */
922   HA_CLONE_MODE_VERSION,
923 
924   /** Max value for clone mode */
925   HA_CLONE_MODE_MAX
926 };
927 
928 /** Clone operation types. */
929 enum Ha_clone_type : size_t {
930   /** Caller must block all write operation to the SE. */
931   HA_CLONE_BLOCKING,
932 
933   /** For transactional SE, archive redo to support concurrent dml */
934   HA_CLONE_REDO,
935 
936   /** For transactional SE, track page changes to support concurrent dml */
937   HA_CLONE_PAGE,
938 
939   /** For transactional SE, use both page tracking and redo to optimize
940   clone with concurrent dml. Currently supported by Innodb. */
941   HA_CLONE_HYBRID,
942 
943   /** SE supports multiple threads for clone */
944   HA_CLONE_MULTI_TASK,
945 
946   /** SE supports restarting clone after network failure */
947   HA_CLONE_RESTART,
948 
949   /** Maximum value of clone type */
950   HA_CLONE_TYPE_MAX
951 };
952 
953 using Ha_clone_flagset = std::bitset<HA_CLONE_TYPE_MAX>;
954 
955 void set_externally_disabled_storage_engine_names(const char *);
956 bool ha_is_externally_disabled(const handlerton &);
957 
958 /** File reference for clone */
959 struct Ha_clone_file {
960   /** File reference type */
961   enum {
962     /** File handle */
963     FILE_HANDLE,
964 
965     /** File descriptor */
966     FILE_DESC
967 
968   } type;
969 
970   /** File reference */
971   union {
972     /** File descriptor */
973     int file_desc;
974 
975     /** File handle for windows */
976     void *file_handle;
977   };
978 };
979 
980 /* Abstract callback interface to stream data back to the caller. */
981 class Ha_clone_cbk {
982  protected:
983   /** Constructor to initialize members. */
Ha_clone_cbk()984   Ha_clone_cbk()
985       : m_hton(),
986         m_loc_idx(),
987         m_client_buff_size(),
988         m_data_desc(),
989         m_desc_len(),
990         m_src_name(),
991         m_dest_name(),
992         m_state_estimate(),
993         m_flag() {}
994 
995  public:
996   /** Callback providing data from current position of a
997   file descriptor of specific length.
998   @param[in]  from_file  source file to read from
999   @param[in]  len        data length
1000   @return error code */
1001   virtual int file_cbk(Ha_clone_file from_file, uint len) = 0;
1002 
1003   /** Callback providing data in buffer of specific length.
1004   @param[in]  from_buffer  source buffer to read from
1005   @param[in]  len          data length
1006   @return error code */
1007   virtual int buffer_cbk(uchar *from_buffer, uint len) = 0;
1008 
1009   /** Callback providing a file descriptor to write data starting
1010   from current position.
1011   @param[in]  to_file  destination file to write data
1012   @return error code */
1013   virtual int apply_file_cbk(Ha_clone_file to_file) = 0;
1014 
1015   /** Callback to get data in buffer.
1016   @param[out]  to_buffer  data buffer
1017   @param[out]  len        data length
1018   @return error code */
1019   virtual int apply_buffer_cbk(uchar *&to_buffer, uint &len) = 0;
1020 
1021   /** virtual destructor. */
~Ha_clone_cbk()1022   virtual ~Ha_clone_cbk() {}
1023 
1024   /** Set current storage engine handlerton.
1025   @param[in]  hton  SE handlerton */
set_hton(handlerton * hton)1026   void set_hton(handlerton *hton) { m_hton = hton; }
1027 
1028   /** Get current storage engine handlerton.
1029   @return SE handlerton */
get_hton()1030   handlerton *get_hton() { return (m_hton); }
1031 
1032   /** Set caller's transfer buffer size. SE can adjust the data chunk size
1033   based on this parameter.
1034   @param[in]  size  buffer size in bytes */
set_client_buffer_size(uint size)1035   void set_client_buffer_size(uint size) { m_client_buff_size = size; }
1036 
1037   /** Get caller's transfer buffer size.
1038   @return buffer size in bytes */
get_client_buffer_size()1039   uint get_client_buffer_size() { return (m_client_buff_size); }
1040 
1041   /** Set current SE index.
1042   @param[in]  idx  SE index in locator array */
set_loc_index(uint idx)1043   void set_loc_index(uint idx) { m_loc_idx = idx; }
1044 
1045   /** Get current SE index.
1046   @return SE index in locator array */
get_loc_index()1047   uint get_loc_index() { return (m_loc_idx); }
1048 
1049   /** Set data descriptor. SE specific descriptor for the
1050   data transferred by the callbacks.
1051   @param[in]  desc  serialized data descriptor
1052   @param[in]  len   length of the descriptor byte stream  */
set_data_desc(const uchar * desc,uint len)1053   void set_data_desc(const uchar *desc, uint len) {
1054     m_data_desc = desc;
1055     m_desc_len = len;
1056   }
1057 
1058   /** Get data descriptor. SE specific descriptor for the
1059   data transferred by the callbacks.
1060   @param[out]  lenp  length of the descriptor byte stream
1061   @return pointer to the serialized data descriptor */
get_data_desc(uint * lenp)1062   const uchar *get_data_desc(uint *lenp) {
1063     if (lenp != nullptr) {
1064       *lenp = m_desc_len;
1065     }
1066 
1067     return (m_data_desc);
1068   }
1069 
1070   /** Get SE source file name. Used for debug printing and error message.
1071   @return null terminated string for source file name */
get_source_name()1072   const char *get_source_name() { return (m_src_name); }
1073 
1074   /** Set SE source file name.
1075   @param[in]   name  null terminated string for source file name */
set_source_name(const char * name)1076   void set_source_name(const char *name) { m_src_name = name; }
1077 
1078   /** Get SE destination file name. Used for debug printing and error message.
1079   @return null terminated string for destination file name */
get_dest_name()1080   const char *get_dest_name() { return (m_dest_name); }
1081 
1082   /** Set SE destination file name.
1083   @param[in]   name  null terminated string for destination file name */
set_dest_name(const char * name)1084   void set_dest_name(const char *name) { m_dest_name = name; }
1085 
1086   /** Clear all flags set by SE */
clear_flags()1087   void clear_flags() { m_flag = 0; }
1088 
1089   /** Mark that ACK is needed for the data transfer before returning
1090   from callback. Set by SE. */
set_ack()1091   void set_ack() { m_flag |= HA_CLONE_ACK; }
1092 
1093   /** Check if ACK is needed for the data transfer
1094   @return true if ACK is needed */
is_ack_needed()1095   bool is_ack_needed() const { return (m_flag & HA_CLONE_ACK); }
1096 
1097   /** Mark that the file descriptor is opened for read/write
1098   with OS buffer cache. For O_DIRECT, the flag is not set. */
set_os_buffer_cache()1099   void set_os_buffer_cache() { m_flag |= HA_CLONE_FILE_CACHE; }
1100 
1101   /** Check if the file descriptor is opened for read/write with OS
1102   buffer cache. Currently clone avoids using zero copy (sendfile on linux),
1103   if SE is using O_DIRECT. This improves data copy performance.
1104   @return true if O_DIRECT is not used */
is_os_buffer_cache()1105   bool is_os_buffer_cache() const { return (m_flag & HA_CLONE_FILE_CACHE); }
1106 
1107   /** Mark that the file can be transferred with zero copy. */
set_zero_copy()1108   void set_zero_copy() { m_flag |= HA_CLONE_ZERO_COPY; }
1109 
1110   /** Check if zero copy optimization is suggested. */
is_zero_copy()1111   bool is_zero_copy() const { return (m_flag & HA_CLONE_ZERO_COPY); }
1112 
1113   /** Mark that data needs secure transfer. */
set_secure()1114   void set_secure() { m_flag |= HA_CLONE_SECURE; }
1115 
1116   /** Check if data needs secure transfer. */
is_secure()1117   bool is_secure() const { return (m_flag & HA_CLONE_SECURE); }
1118 
1119   /** Set state information and notify state change.
1120   @param[in]	estimate	estimated bytes for current state. */
mark_state_change(uint64_t estimate)1121   void mark_state_change(uint64_t estimate) {
1122     m_flag |= HA_CLONE_STATE_CHANGE;
1123     m_state_estimate = estimate;
1124   }
1125 
1126   /** Check if SE notified state change. */
is_state_change(uint64_t & estimate)1127   bool is_state_change(uint64_t &estimate) {
1128     estimate = m_state_estimate;
1129     return (m_flag & HA_CLONE_STATE_CHANGE);
1130   }
1131 
1132  private:
1133   /** Handlerton for the SE */
1134   handlerton *m_hton;
1135 
1136   /** SE index in caller's locator array */
1137   uint m_loc_idx;
1138 
1139   /** Caller's transfer buffer size. */
1140   uint m_client_buff_size;
1141 
1142   /** SE's Serialized data descriptor */
1143   const uchar *m_data_desc;
1144 
1145   /** SE's Serialized descriptor length. */
1146   uint m_desc_len;
1147 
1148   /** Current source file name */
1149   const char *m_src_name;
1150 
1151   /** Current destination file name */
1152   const char *m_dest_name;
1153 
1154   /** Estimated bytes to be transferred. */
1155   uint64_t m_state_estimate;
1156 
1157   /** Flag storing data related options */
1158   int m_flag;
1159 
1160   /** Acknowledgement is needed for the data transfer. */
1161   const int HA_CLONE_ACK = 0x01;
1162 
1163   /** Data file is opened for read/write with OS buffer cache. */
1164   const int HA_CLONE_FILE_CACHE = 0x02;
1165 
1166   /** Data file can be transferred with zero copy. */
1167   const int HA_CLONE_ZERO_COPY = 0x04;
1168 
1169   /** Data needs to be transferred securely over SSL connection. */
1170   const int HA_CLONE_SECURE = 0x08;
1171 
1172   /** State change notification by SE. */
1173   const int HA_CLONE_STATE_CHANGE = 0x10;
1174 };
1175 
1176 /**
1177   Column type description for foreign key columns compatibility check.
1178 
1179   Contains subset of information from dd::Column class. It is inconvenient
1180   to use dd::Column class directly for such checks because it requires valid
1181   dd::Table object and in some cases we want to produce Ha_fk_column_type
1182   right from column description in Create_field format.
1183 */
1184 struct Ha_fk_column_type {
1185   dd::enum_column_types type;
1186   /*
1187     Note that both dd::Column::char_length() and length here are really
1188     in bytes.
1189   */
1190   size_t char_length;
1191   const CHARSET_INFO *field_charset;
1192   size_t elements_count;
1193   uint numeric_scale;
1194   bool is_unsigned;
1195 };
1196 
1197 /* handlerton methods */
1198 
1199 /**
1200   close_connection is only called if
1201   thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
1202   this storage area - set it to something, so that MySQL would know
1203   this storage engine was accessed in this connection
1204 */
1205 typedef int (*close_connection_t)(handlerton *hton, THD *thd);
1206 
1207 /** Terminate connection/statement notification. */
1208 typedef void (*kill_connection_t)(handlerton *hton, THD *thd);
1209 
1210 /**
1211   Shut down all storage engine background tasks that might access
1212   the data dictionary, before the main shutdown.
1213 */
1214 typedef void (*pre_dd_shutdown_t)(handlerton *hton);
1215 
1216 /**
1217   sv points to a storage area, that was earlier passed
1218   to the savepoint_set call
1219 */
1220 typedef int (*savepoint_rollback_t)(handlerton *hton, THD *thd, void *sv);
1221 
1222 /**
1223   sv points to an uninitialized storage area of requested size
1224   (see savepoint_offset description)
1225 */
1226 typedef int (*savepoint_set_t)(handlerton *hton, THD *thd, void *sv);
1227 
1228 /**
1229   Check if storage engine allows to release metadata locks which were
1230   acquired after the savepoint if rollback to savepoint is done.
1231   @return true  - If it is safe to release MDL locks.
1232           false - If it is not.
1233 */
1234 typedef bool (*savepoint_rollback_can_release_mdl_t)(handlerton *hton,
1235                                                      THD *thd);
1236 
1237 typedef int (*savepoint_release_t)(handlerton *hton, THD *thd, void *sv);
1238 
1239 /**
1240   'all' is true if it's a real commit, that makes persistent changes
1241   'all' is false if it's not in fact a commit but an end of the
1242   statement that is part of the transaction.
1243   NOTE 'all' is also false in auto-commit mode where 'end of statement'
1244   and 'real commit' mean the same event.
1245 */
1246 typedef int (*commit_t)(handlerton *hton, THD *thd, bool all);
1247 
1248 typedef int (*rollback_t)(handlerton *hton, THD *thd, bool all);
1249 
1250 typedef int (*prepare_t)(handlerton *hton, THD *thd, bool all);
1251 
1252 typedef int (*recover_t)(handlerton *hton, XA_recover_txn *xid_list, uint len,
1253                          MEM_ROOT *mem_root);
1254 
1255 /** X/Open XA distributed transaction status codes */
1256 enum xa_status_code {
1257   /**
1258     normal execution
1259   */
1260   XA_OK = 0,
1261 
1262   /**
1263     asynchronous operation already outstanding
1264   */
1265   XAER_ASYNC = -2,
1266 
1267   /**
1268     a resource manager error  occurred in the transaction branch
1269   */
1270   XAER_RMERR = -3,
1271 
1272   /**
1273     the XID is not valid
1274   */
1275   XAER_NOTA = -4,
1276 
1277   /**
1278     invalid arguments were given
1279   */
1280   XAER_INVAL = -5,
1281 
1282   /**
1283     routine invoked in an improper context
1284   */
1285   XAER_PROTO = -6,
1286 
1287   /**
1288     resource manager unavailable
1289   */
1290   XAER_RMFAIL = -7,
1291 
1292   /**
1293     the XID already exists
1294   */
1295   XAER_DUPID = -8,
1296 
1297   /**
1298     resource manager doing work outside transaction
1299   */
1300   XAER_OUTSIDE = -9
1301 };
1302 
1303 typedef xa_status_code (*commit_by_xid_t)(handlerton *hton, XID *xid);
1304 
1305 typedef xa_status_code (*rollback_by_xid_t)(handlerton *hton, XID *xid);
1306 
1307 /**
1308   Create handler object for the table in the storage engine.
1309 
1310   @param hton         Handlerton object for the storage engine.
1311   @param table        TABLE_SHARE for the table, can be NULL if caller
1312                       didn't perform full-blown open of table definition.
1313   @param partitioned  Indicates whether table is partitioned.
1314   @param mem_root     Memory root to be used for allocating handler
1315                       object.
1316 */
1317 typedef handler *(*create_t)(handlerton *hton, TABLE_SHARE *table,
1318                              bool partitioned, MEM_ROOT *mem_root);
1319 
1320 typedef void (*drop_database_t)(handlerton *hton, char *path);
1321 
1322 typedef int (*panic_t)(handlerton *hton, enum ha_panic_function flag);
1323 
1324 typedef int (*start_consistent_snapshot_t)(handlerton *hton, THD *thd);
1325 
1326 /**
1327   Flush the log(s) of storage engine(s).
1328 
1329   @param hton Handlerton of storage engine.
1330   @param binlog_group_flush true if we got invoked by binlog group
1331     commit during flush stage, false in other cases.
1332   @retval false Succeed
1333   @retval true Error
1334 */
1335 typedef bool (*flush_logs_t)(handlerton *hton, bool binlog_group_flush);
1336 
1337 typedef bool (*show_status_t)(handlerton *hton, THD *thd, stat_print_fn *print,
1338                               enum ha_stat_type stat);
1339 
1340 /**
1341   The flag values are defined in sql_partition.h.
1342   If this function is set, then it implies that the handler supports
1343   partitioned tables.
1344   If this function exists, then handler::get_partition_handler must also be
1345   implemented.
1346 */
1347 typedef uint (*partition_flags_t)();
1348 
1349 /**
1350   SE specific validation of the tablespace name.
1351 
1352   This function will ask the relevant SE whether the submitted tablespace
1353   name is valid.
1354 
1355   @param ts_cmd             Purpose of usage - is this tablespace DDL?
1356   @param tablespace_name    Name of the tablespace.
1357 
1358   @return Tablespace name validity.
1359     @retval == false: The tablespace name is invalid.
1360     @retval == true:  The tablespace name is valid.
1361 */
1362 typedef bool (*is_valid_tablespace_name_t)(ts_command_type ts_cmd,
1363                                            const char *tablespace_name);
1364 
1365 /**
1366   Get the tablespace name from the SE for the given schema and table.
1367 
1368   @param       thd              Thread context.
1369   @param       db_name          Name of the relevant schema.
1370   @param       table_name       Name of the relevant table.
1371   @param [out] tablespace_name  Name of the tablespace containing the table.
1372 
1373   @return Operation status.
1374     @retval == 0  Success.
1375     @retval != 0  Error (handler error code returned).
1376 */
1377 typedef int (*get_tablespace_t)(THD *thd, LEX_CSTRING db_name,
1378                                 LEX_CSTRING table_name,
1379                                 LEX_CSTRING *tablespace_name);
1380 
1381 /**
1382   Create/drop or alter tablespace in the storage engine.
1383 
1384   @param          hton        Hadlerton of the SE.
1385   @param          thd         Thread context.
1386   @param          ts_info     Description of tablespace and specific
1387                               operation on it.
1388   @param          old_ts_def  dd::Tablespace object describing old version
1389                               of tablespace.
1390   @param [in,out] new_ts_def  dd::Tablespace object describing new version
1391                               of tablespace. Engines which support atomic DDL
1392                               can adjust this object. The updated information
1393                               will be saved to the data-dictionary.
1394 
1395   @return Operation status.
1396     @retval == 0  Success.
1397     @retval != 0  Error (handler error code returned).
1398 */
1399 typedef int (*alter_tablespace_t)(handlerton *hton, THD *thd,
1400                                   st_alter_tablespace *ts_info,
1401                                   const dd::Tablespace *old_ts_def,
1402                                   dd::Tablespace *new_ts_def);
1403 
1404 /**
1405   SE interface for getting tablespace extension.
1406   @return Extension of tablespace datafile name.
1407 */
1408 typedef const char *(*get_tablespace_filename_ext_t)();
1409 
1410 /**
1411   Get the tablespace data from SE and insert it into Data dictionary
1412 
1413   @param    thd         Thread context
1414 
1415   @return Operation status.
1416   @retval == 0  Success.
1417   @retval != 0  Error (handler error code returned)
1418 */
1419 typedef int (*upgrade_tablespace_t)(THD *thd);
1420 
1421 /**
1422   Get the tablespace data from SE and insert it into Data dictionary
1423 
1424   @param[in]  tablespace     tablespace object
1425 
1426   @return Operation status.
1427   @retval == 0  Success.
1428   @retval != 0  Error (handler error code returned)
1429 */
1430 typedef bool (*upgrade_space_version_t)(dd::Tablespace *tablespace);
1431 
1432 /**
1433   Finish upgrade process inside storage engines.
1434   This includes resetting flags to indicate upgrade process
1435   and cleanup after upgrade.
1436 
1437   @param    thd      Thread context
1438 
1439   @return Operation status.
1440   @retval == 0  Success.
1441   @retval != 0  Error (handler error code returned)
1442 */
1443 typedef int (*finish_upgrade_t)(THD *thd, bool failed_upgrade);
1444 
1445 /**
1446   Upgrade logs after the checkpoint from where upgrade
1447   process can only roll forward.
1448 
1449   @param    thd      Thread context
1450 
1451   @return Operation status.
1452   @retval == 0  Success.
1453   @retval != 0  Error (handler error code returned)
1454 */
1455 typedef int (*upgrade_logs_t)(THD *thd);
1456 
1457 enum class Tablespace_type {
1458   SPACE_TYPE_DICTIONARY,
1459   SPACE_TYPE_SYSTEM,
1460   SPACE_TYPE_UNDO,
1461   SPACE_TYPE_TEMPORARY,
1462   SPACE_TYPE_SHARED,
1463   SPACE_TYPE_IMPLICIT
1464 };
1465 
1466 /**
1467   Get the tablespace type from the SE.
1468 
1469   @param[in]  space          tablespace object
1470   @param[out] space_type     type of space
1471 
1472   @return Operation status.
1473   @retval false on success and true for failure.
1474 */
1475 typedef bool (*get_tablespace_type_t)(const dd::Tablespace &space,
1476                                       Tablespace_type *space_type);
1477 
1478 /**
1479   Get the tablespace type given the name, from the SE.
1480 
1481   @param[in]  tablespace_name tablespace name
1482   @param[out] space_type      type of space
1483 
1484   @return Operation status.
1485   @retval false on success and true for failure.
1486 */
1487 typedef bool (*get_tablespace_type_by_name_t)(const char *tablespace_name,
1488                                               Tablespace_type *space_type);
1489 
1490 typedef int (*fill_is_table_t)(handlerton *hton, THD *thd, TABLE_LIST *tables,
1491                                class Item *cond, enum enum_schema_tables);
1492 
1493 typedef int (*binlog_func_t)(handlerton *hton, THD *thd, enum_binlog_func fn,
1494                              void *arg);
1495 
1496 typedef void (*binlog_log_query_t)(handlerton *hton, THD *thd,
1497                                    enum_binlog_command binlog_command,
1498                                    const char *query, uint query_length,
1499                                    const char *db, const char *table_name);
1500 
1501 typedef void (*acl_notify_t)(THD *thd,
1502                              const class Acl_change_notification *notice);
1503 
1504 typedef int (*discover_t)(handlerton *hton, THD *thd, const char *db,
1505                           const char *name, uchar **frmblob, size_t *frmlen);
1506 
1507 typedef int (*find_files_t)(handlerton *hton, THD *thd, const char *db,
1508                             const char *path, const char *wild, bool dir,
1509                             List<LEX_STRING> *files);
1510 
1511 typedef int (*table_exists_in_engine_t)(handlerton *hton, THD *thd,
1512                                         const char *db, const char *name);
1513 
1514 /**
1515   Check if the given db.tablename is a system table for this SE.
1516 
1517   @param db                         Database name to check.
1518   @param table_name                 table name to check.
1519   @param is_sql_layer_system_table  if the supplied db.table_name is a SQL
1520                                     layer system table.
1521 
1522   @see example_is_supported_system_table in ha_example.cc
1523 
1524   is_sql_layer_system_table is supplied to make more efficient
1525   checks possible for SEs that support all SQL layer tables.
1526 
1527   This interface is optional, so every SE need not implement it.
1528 */
1529 typedef bool (*is_supported_system_table_t)(const char *db,
1530                                             const char *table_name,
1531                                             bool is_sql_layer_system_table);
1532 
1533 /**
1534   Create SDI in a tablespace. This API should be used when upgrading
1535   a tablespace with no SDI or after invoking sdi_drop().
1536   @param[in]  tablespace     tablespace object
1537   @retval     false          success
1538   @retval     true           failure
1539 */
1540 typedef bool (*sdi_create_t)(dd::Tablespace *tablespace);
1541 
1542 /**
1543   Drop SDI in a tablespace. This API should be used only when
1544   SDI is corrupted.
1545   @param[in]  tablespace  tablespace object
1546   @retval     false       success
1547   @retval     true        failure
1548 */
1549 typedef bool (*sdi_drop_t)(dd::Tablespace *tablespace);
1550 
1551 /**
1552   Get the SDI keys in a tablespace into vector.
1553   @param[in]      tablespace  tablespace object
1554   @param[in,out]  vector      vector of SDI Keys
1555   @retval         false       success
1556   @retval         true        failure
1557 */
1558 typedef bool (*sdi_get_keys_t)(const dd::Tablespace &tablespace,
1559                                sdi_vector_t &vector);
1560 
1561 /**
1562   Retrieve SDI for a given SDI key.
1563 
1564   Since the caller of this api will not know the SDI length, SDI retrieval
1565   should be done in the following way.
1566 
1567   i.   Allocate initial memory of some size (Lets say 64KB)
1568   ii.  Pass the allocated memory to the below api.
1569   iii. If passed buffer is sufficient, sdi_get_by_id() copies the sdi
1570        to the buffer passed and returns success, else sdi_len is modified
1571        with the actual length of the SDI (and returns false on failure).
1572        For genuine errors, sdi_len is returned as UINT64_MAX
1573   iv.  If sdi_len != UINT64_MAX, retry the call after allocating the memory
1574        of sdi_len
1575   v.   Free the memory after using SDI (responsibility of caller)
1576 
1577   @param[in]      tablespace  tablespace object
1578   @param[in]      sdi_key     SDI key to uniquely identify SDI obj
1579   @param[in,out]  sdi         SDI retrieved from tablespace
1580                               A non-null pointer must be passed in
1581   @param[in,out]  sdi_len     in: length of the memory allocated
1582                               out: actual length of SDI
1583   @retval         false       success
1584   @retval         true        failure
1585 */
1586 typedef bool (*sdi_get_t)(const dd::Tablespace &tablespace,
1587                           const sdi_key_t *sdi_key, void *sdi, uint64 *sdi_len);
1588 
1589 /**
1590   Insert/Update SDI for a given SDI key.
1591   @param[in]  hton        handlerton object
1592   @param[in]  tablespace  tablespace object
1593   @param[in]  sdi_key     SDI key to uniquely identify SDI obj
1594   @param[in]  sdi         SDI to write into the tablespace
1595   @param[in]  sdi_len     length of SDI BLOB returned
1596   @retval     false       success
1597   @retval     true        failure, my_error() should be called
1598                           by SE
1599 */
1600 typedef bool (*sdi_set_t)(handlerton *hton, const dd::Tablespace &tablespace,
1601                           const dd::Table *table, const sdi_key_t *sdi_key,
1602                           const void *sdi, uint64 sdi_len);
1603 
1604 /**
1605   Delete SDI for a given SDI key.
1606   @param[in]  tablespace  tablespace object
1607   @param[in]  sdi_key     SDI key to uniquely identify SDI obj
1608   @retval     false       success
1609   @retval     true        failure, my_error() should be called
1610                           by SE
1611 */
1612 typedef bool (*sdi_delete_t)(const dd::Tablespace &tablespace,
1613                              const dd::Table *table, const sdi_key_t *sdi_key);
1614 
1615 /**
1616   Check if the DDSE is started in a way that leaves thd DD being read only.
1617 
1618   @retval true    The data dictionary can only be read.
1619   @retval false   The data dictionary can be read and written.
1620  */
1621 typedef bool (*is_dict_readonly_t)();
1622 
1623 /**
1624   Drop all temporary tables which have been left from previous server
1625   run belonging to this SE. Used on server start-up.
1626 
1627   @param[in]      hton   Handlerton for storage engine.
1628   @param[in]      thd    Thread context.
1629   @param[in,out]  files  List of files in directories for temporary files
1630                          which match tmp_file_prefix and thus can belong to
1631                          temporary tables (but not necessarily in this SE).
1632                          It is recommended to remove file from the list if
1633                          SE recognizes it as belonging to temporary table
1634                          in this SE and deletes it.
1635 */
1636 typedef bool (*rm_tmp_tables_t)(handlerton *hton, THD *thd,
1637                                 List<LEX_STRING> *files);
1638 
1639 /**
1640   Retrieve cost constants to be used for this storage engine.
1641 
1642   A storage engine that wants to provide its own cost constants to
1643   be used in the optimizer cost model, should implement this function.
1644   The server will call this function to get a cost constant object
1645   that will be used for tables stored in this storage engine instead
1646   of using the default cost constants.
1647 
1648   Life cycle for the cost constant object: The storage engine must
1649   allocate the cost constant object on the heap. After the function
1650   returns, the server takes over the ownership of this object.
1651   The server will eventually delete the object by calling delete.
1652 
1653   @note In the initial version the storage_category parameter will
1654   not be used. The only valid value this will have is DEFAULT_STORAGE_CLASS
1655   (see declaration in opt_costconstants.h).
1656 
1657   @param storage_category the storage type that the cost constants will
1658                           be used for
1659 
1660   @return a pointer to the cost constant object, if NULL is returned
1661           the default cost constants will be used
1662 */
1663 typedef SE_cost_constants *(*get_cost_constants_t)(uint storage_category);
1664 
1665 /**
1666   @param[in,out]  thd          pointer to THD
1667   @param[in]      new_trx_arg  pointer to replacement transaction
1668   @param[out]     ptr_trx_arg  double pointer to being replaced transaction
1669 
1670   Associated with THD engine's native transaction is replaced
1671   with @c new_trx_arg. The old value is returned through a buffer if non-null
1672   pointer is provided with @c ptr_trx_arg.
1673   The method is adapted by XA start and XA prepare handlers to
1674   handle XA transaction that is logged as two parts by slave applier.
1675 
1676   This interface concerns engines that are aware of XA transaction.
1677 */
1678 typedef void (*replace_native_transaction_in_thd_t)(THD *thd, void *new_trx_arg,
1679                                                     void **ptr_trx_arg);
1680 
1681 /** Mode for initializing the data dictionary. */
1682 enum dict_init_mode_t {
1683   DICT_INIT_CREATE_FILES,      ///< Create all required SE files
1684   DICT_INIT_CHECK_FILES,       ///< Verify existence of expected files
1685   DICT_INIT_UPGRADE_57_FILES,  ///< Used for upgrade from mysql-5.7
1686   DICT_INIT_IGNORE_FILES       ///< Don't care about files at all
1687 };
1688 
1689 /**
1690   Initialize the SE for being used to store the DD tables. Create
1691   the required files according to the dict_init_mode. Create strings
1692   representing the required DDSE tables, i.e., tables that the DDSE
1693   expects to exist in the DD, and add them to the appropriate out
1694   parameter.
1695 
1696   @note There are two variants of this function type, one is to be
1697   used by the DDSE, and has a different type of output parameters
1698   because the SQL layer needs more information about the DDSE tables
1699   in order to support upgrade.
1700 
1701   @param dict_init_mode         How to initialize files
1702   @param version                Target DD version if a new
1703                                 server is being installed.
1704                                 0 if restarting an existing
1705                                 server.
1706   @param [out] DDSE_tables      List of SQL DDL statements
1707                                 for creating DD tables that
1708                                 are needed by the DDSE.
1709   @param [out] DDSE_tablespaces List of meta data for predefined
1710                                 tablespaces created by the DDSE.
1711 
1712   @retval true                  An error occurred.
1713   @retval false                 Success - no errors.
1714  */
1715 
1716 typedef bool (*dict_init_t)(dict_init_mode_t dict_init_mode, uint version,
1717                             List<const Plugin_table> *DDSE_tables,
1718                             List<const Plugin_tablespace> *DDSE_tablespaces);
1719 
1720 typedef bool (*ddse_dict_init_t)(
1721     dict_init_mode_t dict_init_mode, uint version,
1722     List<const dd::Object_table> *DDSE_tables,
1723     List<const Plugin_tablespace> *DDSE_tablespaces);
1724 
1725 /**
1726   Initialize the set of hard coded DD table ids.
1727 */
1728 typedef void (*dict_register_dd_table_id_t)(dd::Object_id hard_coded_tables);
1729 
1730 /**
1731   Invalidate an entry in the local dictionary cache.
1732 
1733   Needed during bootstrap to make sure the contents in the DDSE
1734   dictionary cache is in sync with the global DD.
1735 
1736   @param   schema_name    Schema name.
1737   @param   table_name     Table name.
1738  */
1739 
1740 typedef void (*dict_cache_reset_t)(const char *schema_name,
1741                                    const char *table_name);
1742 
1743 /**
1744   Invalidate all table and tablespace entries in the local dictionary cache.
1745 
1746   Needed for recovery during server restart.
1747  */
1748 
1749 typedef void (*dict_cache_reset_tables_and_tablespaces_t)();
1750 
1751 /** Mode for data dictionary recovery. */
1752 enum dict_recovery_mode_t {
1753   DICT_RECOVERY_INITIALIZE_SERVER,       ///< First start of a new server
1754   DICT_RECOVERY_INITIALIZE_TABLESPACES,  ///< First start, create tablespaces
1755   DICT_RECOVERY_RESTART_SERVER           ///< Restart of an existing server
1756 };
1757 
1758 /**
1759   Do recovery in the DDSE as part of initializing the data dictionary.
1760   The dict_recovery_mode indicates what kind of recovery should be
1761   done.
1762 
1763   @param dict_recovery_mode   How to do recovery
1764   @param version              Target DD version if a new
1765                               server is being installed.
1766                               Actual DD version if restarting
1767                               an existing server.
1768 
1769   @retval true                An error occurred.
1770   @retval false               Success - no errors.
1771  */
1772 
1773 typedef bool (*dict_recover_t)(dict_recovery_mode_t dict_recovery_mode,
1774                                uint version);
1775 
1776 /**
1777   Get the server version id stored in the header of the
1778   dictionary tablespace.
1779 
1780   @param [out] version  Version number from the DD
1781                         tablespace header.
1782 
1783   @retval Operation outcome, false if no error, otherwise true.
1784 */
1785 typedef bool (*dict_get_server_version_t)(uint *version);
1786 
1787 /**
1788   Store the current server version number into the
1789   header of the dictionary tablespace.
1790 
1791   @retval Operation outcome, false if no error, otherwise true.
1792 */
1793 typedef bool (*dict_set_server_version_t)();
1794 
1795 /**
1796   Notify/get permission from storage engine before acquisition or after
1797   release of exclusive metadata lock on object represented by key.
1798 
1799   @param thd                Thread context.
1800   @param mdl_key            MDL key identifying object on which exclusive
1801                             lock is to be acquired/was released.
1802   @param notification_type  Indicates whether this is pre-acquire or
1803                             post-release notification.
1804   @param victimized        'true' if locking failed as we were selected
1805                             as a victim in order to avoid possible deadlocks.
1806 
1807   @note Notification is done only for objects from TABLESPACE, SCHEMA,
1808         TABLE, FUNCTION, PROCEDURE, TRIGGER and EVENT namespaces.
1809 
1810   @note Problems during notification are to be reported as warnings, MDL
1811         subsystem will report generic error if pre-acquire notification
1812         fails/SE refuses lock acquisition.
1813   @note Return value is ignored/error is not reported in case of
1814         post-release notification.
1815 
1816   @note In some cases post-release notification might happen even if
1817         there were no prior pre-acquire notification. For example,
1818         when SE was loaded after exclusive lock acquisition, or when
1819         we need notify SEs which permitted lock acquisition that it
1820         didn't happen because one of SEs didn't allow it (in such case
1821         we will do post-release notification for all SEs for simplicity).
1822 
1823   @return False - if notification was successful/lock can be acquired,
1824           True - if it has failed/lock should not be acquired.
1825 */
1826 typedef bool (*notify_exclusive_mdl_t)(THD *thd, const MDL_key *mdl_key,
1827                                        ha_notification_type notification_type,
1828                                        bool *victimized);
1829 
1830 /**
1831   Notify/get permission from storage engine before or after execution of
1832   ALTER TABLE operation on the table identified by the MDL key.
1833 
1834   @param thd                Thread context.
1835   @param mdl_key            MDL key identifying table which is going to be
1836                             or was ALTERed.
1837   @param notification_type  Indicates whether this is pre-ALTER TABLE or
1838                             post-ALTER TABLE notification.
1839 
1840   @note This hook is necessary because for ALTER TABLE upgrade to X
1841         metadata lock happens fairly late during the execution process,
1842         so it can be expensive to abort ALTER TABLE operation at this
1843         stage by returning failure from notify_exclusive_mdl() hook.
1844 
1845   @note This hook follows the same error reporting convention as
1846         @see notify_exclusive_mdl().
1847 
1848   @note Similarly to notify_exclusive_mdl() in some cases post-ALTER
1849         notification might happen even if there were no prior pre-ALTER
1850         notification.
1851 
1852   @note Post-ALTER notification can happen before post-release notification
1853         for exclusive metadata lock acquired by this ALTER TABLE.
1854 
1855   @return False - if notification was successful/ALTER TABLE can proceed.
1856           True - if it has failed/ALTER TABLE should be aborted.
1857 */
1858 typedef bool (*notify_alter_table_t)(THD *thd, const MDL_key *mdl_key,
1859                                      ha_notification_type notification_type);
1860 
1861 /**
1862   @brief
1863   Initiate master key rotation
1864 
1865   @returns false on success,
1866            true on failure
1867 */
1868 typedef bool (*rotate_encryption_master_key_t)(void);
1869 
1870 /**
1871   @brief
1872   Enable or Disable SE write ahead logging.
1873 
1874   @param[in] thd    server thread handle
1875   @param[in] enable enable/disable redo logging
1876 
1877   @return true iff failed.
1878 */
1879 typedef bool (*redo_log_set_state_t)(THD *thd, bool enable);
1880 
1881 /**
1882   @brief
1883   Retrieve ha_statistics from SE.
1884 
1885   @param db_name                  Name of schema
1886   @param table_name               Name of table
1887   @param se_private_id            SE private id of the table.
1888   @param ts_se_private_data       Tablespace SE private data.
1889   @param tbl_se_private_data      Table SE private data.
1890   @param flags                    Type of statistics to retrieve.
1891   @param[out] stats               Contains statistics read from SE.
1892 
1893   @note Handlers that implement this callback/API should adhere
1894         to servers expectation that, the implementation would invoke
1895         my_error() before returning 'true'/failure from this function.
1896 
1897   @returns false on success,
1898            true on failure
1899 */
1900 typedef bool (*get_table_statistics_t)(
1901     const char *db_name, const char *table_name, dd::Object_id se_private_id,
1902     const dd::Properties &ts_se_private_data,
1903     const dd::Properties &tbl_se_private_data, uint flags,
1904     ha_statistics *stats);
1905 
1906 /**
1907   @brief
1908   Retrieve index column cardinality from SE.
1909 
1910   @param db_name                  Name of schema
1911   @param table_name               Name of table
1912   @param index_name               Name of index
1913   @param index_ordinal_position   Position of index.
1914   @param column_ordinal_position  Position of column in index.
1915   @param se_private_id            SE private id of the table.
1916   @param[out] cardinality         cardinality being returned by SE.
1917 
1918   @note Handlers that implement this callback/API should adhere
1919         to servers expectation that, the implementation would invoke
1920         my_error() before returning 'true'/failure from this function.
1921 
1922   @returns false on success,
1923            true on failure
1924 */
1925 typedef bool (*get_index_column_cardinality_t)(
1926     const char *db_name, const char *table_name, const char *index_name,
1927     uint index_ordinal_position, uint column_ordinal_position,
1928     dd::Object_id se_private_id, ulonglong *cardinality);
1929 
1930 /**
1931   Retrieve ha_tablespace_statistics from SE.
1932 
1933   @param tablespace_name          Tablespace_name
1934   @param file_name                Tablespace file name.
1935   @param ts_se_private_data       Tablespace SE private data.
1936   @param[out] stats               Contains tablespace
1937                                   statistics read from SE.
1938 
1939   @note Handlers that implement this callback/API should adhere
1940         to servers expectation that, the implementation would invoke
1941         my_error() before returning 'true'/failure from this function.
1942 
1943   @returns false on success, true on failure
1944 */
1945 typedef bool (*get_tablespace_statistics_t)(
1946     const char *tablespace_name, const char *file_name,
1947     const dd::Properties &ts_se_private_data, ha_tablespace_statistics *stats);
1948 
1949 /* Database physical clone interfaces */
1950 
1951 /** Get capability flags for clone operation
1952 @param[out]     flags   capability flag */
1953 using Clone_capability_t = void (*)(Ha_clone_flagset &flags);
1954 
1955 /** Begin copy from source database
1956 @param[in]      hton    handlerton for SE
1957 @param[in]      thd     server thread handle
1958 @param[in,out]  loc     locator
1959 @param[in,out]  loc_len locator length
1960 @param[out]     task_id task identifier
1961 @param[in]      type    clone type
1962 @param[in]      mode    mode for starting clone
1963 @return error code */
1964 using Clone_begin_t = int (*)(handlerton *hton, THD *thd, const uchar *&loc,
1965                               uint &loc_len, uint &task_id, Ha_clone_type type,
1966                               Ha_clone_mode mode);
1967 
1968 /** Copy data from source database in chunks via callback
1969 @param[in]      hton    handlerton for SE
1970 @param[in]      thd     server thread handle
1971 @param[in]      loc     locator
1972 @param[in]      loc_len locator length in bytes
1973 @param[in]      task_id task identifier
1974 @param[in]      cbk     callback interface for sending data
1975 @return error code */
1976 using Clone_copy_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
1977                              uint loc_len, uint task_id, Ha_clone_cbk *cbk);
1978 
1979 /** Acknowledge data transfer to source database
1980 @param[in]      hton    handlerton for SE
1981 @param[in]      thd     server thread handle
1982 @param[in]      loc     locator
1983 @param[in]      loc_len locator length in bytes
1984 @param[in]      task_id task identifier
1985 @param[in]      in_err  inform any error occurred
1986 @param[in]      cbk     callback interface
1987 @return error code */
1988 using Clone_ack_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
1989                             uint loc_len, uint task_id, int in_err,
1990                             Ha_clone_cbk *cbk);
1991 
1992 /** End copy from source database
1993 @param[in]      hton    handlerton for SE
1994 @param[in]      thd     server thread handle
1995 @param[in]      loc     locator
1996 @param[in]	loc_len	locator length in bytes
1997 @param[in]      task_id task identifier
1998 @param[in]      in_err  error code when ending after error
1999 @return error code */
2000 using Clone_end_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2001                             uint loc_len, uint task_id, int in_err);
2002 
2003 /** Begin apply to destination database
2004 @param[in]      hton            handlerton for SE
2005 @param[in]      thd             server thread handle
2006 @param[in,out]  loc             locator
2007 @param[in,out]  loc_len         locator length
2008 @param[in]      task_id         task identifier
2009 @param[in]      mode            mode for starting clone
2010 @param[in]      data_dir        target data directory
2011 @return error code */
2012 using Clone_apply_begin_t = int (*)(handlerton *hton, THD *thd,
2013                                     const uchar *&loc, uint &loc_len,
2014                                     uint &task_id, Ha_clone_mode mode,
2015                                     const char *data_dir);
2016 
2017 /** Apply data to destination database in chunks via callback
2018 @param[in]      hton    handlerton for SE
2019 @param[in]      thd     server thread handle
2020 @param[in]      loc     locator
2021 @param[in]	loc_len	locator length in bytes
2022 @param[in]      task_id task identifier
2023 @param[in]      in_err  inform any error occurred
2024 @param[in]      cbk     callback interface for receiving data
2025 @return error code */
2026 using Clone_apply_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2027                               uint loc_len, uint task_id, int in_err,
2028                               Ha_clone_cbk *cbk);
2029 
2030 /** End apply to destination database
2031 @param[in]      hton    handlerton for SE
2032 @param[in]      thd     server thread handle
2033 @param[in]      loc     locator
2034 @param[in]	loc_len	locator length in bytes
2035 @param[in]      task_id task identifier
2036 @param[in]      in_err  error code when ending after error
2037 @return error code */
2038 using Clone_apply_end_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2039                                   uint loc_len, uint task_id, int in_err);
2040 
2041 struct Clone_interface_t {
2042   /* Get clone capabilities of an SE */
2043   Clone_capability_t clone_capability;
2044 
2045   /* Interfaces to copy data. */
2046   Clone_begin_t clone_begin;
2047   Clone_copy_t clone_copy;
2048   Clone_ack_t clone_ack;
2049   Clone_end_t clone_end;
2050 
2051   /* Interfaces to apply data. */
2052   Clone_apply_begin_t clone_apply_begin;
2053   Clone_apply_t clone_apply;
2054   Clone_apply_end_t clone_apply_end;
2055 };
2056 
2057 /**
2058   Perform post-commit/rollback cleanup after DDL statement (e.g. in
2059   case of DROP TABLES really remove table files from disk).
2060 
2061   @note This hook will be invoked after DDL commit or rollback only
2062         for storage engines supporting atomic DDL.
2063 
2064   @note Problems during execution of this method should be reported to
2065         error log and as warnings/notes to user. Since this method is
2066         called after successful commit of the statement we can't fail
2067         statement with error.
2068 */
2069 typedef void (*post_ddl_t)(THD *thd);
2070 
2071 /**
2072   Perform SE-specific cleanup after recovery of transactions.
2073 
2074   @note Particularly SEs supporting atomic DDL can use this call
2075         to perform post-DDL actions for DDL statements which were
2076         committed or rolled back during recovery stage.
2077 */
2078 typedef void (*post_recover_t)(void);
2079 
2080 /**
2081   Lock a handlerton (resource) log to collect log information.
2082 */
2083 
2084 typedef bool (*lock_hton_log_t)(handlerton *hton);
2085 
2086 /**
2087   Unlock a handlerton (resource) log after collecting log information.
2088 */
2089 
2090 typedef bool (*unlock_hton_log_t)(handlerton *hton);
2091 
2092 /**
2093   Collect a handlerton (resource) log information.
2094 */
2095 
2096 typedef bool (*collect_hton_log_info_t)(handlerton *hton, Json_dom *json);
2097 
2098 /**
2099   Check SE considers types of child and parent columns in foreign key
2100   to be compatible.
2101 
2102   @param  child_column_type   Child column type description.
2103   @param  parent_column_type  Parent column type description.
2104   @param  check_charsets      Indicates whether we need to check
2105                               that charsets of string columns
2106                               match. Which is true in most cases.
2107 
2108   @returns True if types are compatible, False if not.
2109 */
2110 
2111 typedef bool (*check_fk_column_compat_t)(
2112     const Ha_fk_column_type *child_column_type,
2113     const Ha_fk_column_type *parent_column_type, bool check_charsets);
2114 
2115 typedef bool (*is_reserved_db_name_t)(handlerton *hton, const char *name);
2116 
2117 /**
2118   Prepare the secondary engine for executing a statement. This function is
2119   called right after the secondary engine TABLE objects have been opened by
2120   open_secondary_engine_tables(), before the statement is optimized and
2121   executed. Secondary engines will typically create a context object in this
2122   function, which they can use to store state that is needed during the
2123   optimization and execution phases.
2124 
2125   @param thd  thread context
2126   @param lex  the statement to execute
2127   @return true on error, false on success
2128 */
2129 using prepare_secondary_engine_t = bool (*)(THD *thd, LEX *lex);
2130 
2131 /**
2132   Optimize a statement for execution on a secondary storage engine. This
2133   function is called when the optimization of a statement has completed, just
2134   before the statement is executed. Secondary engines can use this function to
2135   apply engine-specific optimizations to the execution plan. They can also
2136   reject executing the query by raising an error, in which case the query will
2137   be reprepared and executed by the primary storage engine.
2138 
2139   @param thd  thread context
2140   @param lex  the statement being optimized
2141   @return true on error, false on success
2142 */
2143 using optimize_secondary_engine_t = bool (*)(THD *thd, LEX *lex);
2144 
2145 /**
2146   Compares the cost of two join plans in the secondary storage engine. The cost
2147   of the current candidate is compared with the cost of the best plan seen so
2148   far.
2149 
2150   @param thd thread context
2151   @param join the JOIN to evaluate
2152   @param table_order the ordering of the tables in the candidate plan
2153   @param optimizer_cost the cost estimate calculated by the optimizer
2154   @param[out] cheaper true if the candidate is the best plan seen so far for
2155                       this JOIN (must be true if it is the first plan seen),
2156                       false otherwise
2157   @param[out] secondary_engine_cost the cost estimated by the secondary engine
2158 
2159   @return false on success, or true if an error has been raised
2160 */
2161 using compare_secondary_engine_cost_t = bool (*)(
2162     THD *thd, const JOIN &join, const Candidate_table_order &table_order,
2163     double optimizer_cost, bool *cheaper, double *secondary_engine_cost);
2164 
2165 // FIXME: Temporary workaround to enable storage engine plugins to use the
2166 // before_commit hook. Remove after WL#11320 has been completed.
2167 typedef void (*se_before_commit_t)(void *arg);
2168 
2169 // FIXME: Temporary workaround to enable storage engine plugins to use the
2170 // after_commit hook. Remove after WL#11320 has been completed.
2171 typedef void (*se_after_commit_t)(void *arg);
2172 
2173 // FIXME: Temporary workaround to enable storage engine plugins to use the
2174 // before_rollback hook. Remove after WL#11320 has been completed.
2175 typedef void (*se_before_rollback_t)(void *arg);
2176 
2177 /*
2178   Page Tracking : interfaces to handlerton functions which starts/stops page
2179   tracking, and purges/fetches page tracking information.
2180 */
2181 
2182 /**
2183   Start page tracking.
2184 
2185   @param[out]    start_id      SE specific sequence number [LSN for InnoDB]
2186   indicating when the tracking was started
2187 
2188   @return Operation status.
2189     @retval 0 Success
2190     @retval other ER_* mysql error. Get error details from THD.
2191 */
2192 using page_track_start_t = int (*)(uint64_t *start_id);
2193 
2194 /**
2195   Stop page tracking.
2196 
2197   @param[out]    stop_id      SE specific sequence number [LSN for InnoDB]
2198   indicating when the tracking was stopped
2199 
2200   @return Operation status.
2201     @retval 0 Success
2202     @retval other ER_* mysql error. Get error details from THD.
2203 */
2204 using page_track_stop_t = int (*)(uint64_t *stop_id);
2205 
2206 /**
2207   Purge page tracking data.
2208 
2209   @param[in,out] purge_id     SE specific sequence number [LSN for InnoDB]
2210   initially indicating till where the data needs to be purged and finally
2211   updated to until where it was actually purged
2212 
2213   @return Operation status.
2214     @retval 0 Success
2215     @retval other ER_* mysql error. Get error details from THD.
2216 */
2217 using page_track_purge_t = int (*)(uint64_t *purge_id);
2218 
2219 /**
2220   Fetch tracked pages.
2221 
2222   @param[in]     cbk_func     callback function return page IDs
2223   @param[in]     cbk_ctx      caller's context for callback
2224   @param[in,out] start_id     SE specific sequence number [LSN for InnoDB] from
2225   where the pages tracked would be returned.
2226   @note The range might get expanded and the actual start_id used for the
2227   querying will be updated.
2228   @param[in,out] stop_id      SE specific sequence number [LSN for InnoDB]
2229   until where the pages tracked would be returned.
2230   @note The range might get expanded and the actual stop_id used for the
2231   querying will be updated.
2232   @param[out]    buffer       allocated buffer to copy page IDs
2233   @param[in]     buffer_len   length of buffer in bytes
2234 
2235   @return Operation status.
2236     @retval 0 Success
2237     @retval other ER_* mysql error. Get error details from THD.
2238 */
2239 using page_track_get_page_ids_t = int (*)(Page_Track_Callback cbk_func,
2240                                           void *cbk_ctx, uint64_t *start_id,
2241                                           uint64_t *stop_id,
2242                                           unsigned char *buffer,
2243                                           size_t buffer_len);
2244 
2245 /**
2246   Fetch approximate number of tracked pages in the given range.
2247 
2248   @param[in,out] start_id     SE specific sequence number [LSN for InnoDB] from
2249   where the pages tracked would be returned.
2250   @note the range might get expanded and the actual start_id used for the
2251   querying will be updated.
2252   @param[in,out] stop_id      SE specific sequence number [LSN for InnoDB]
2253   until where the pages tracked would be returned.
2254   @note the range might get expanded and the actual stop_id used for the
2255   querying will be updated.
2256   @param[out]	 num_pages    number of pages tracked
2257 
2258   @return Operation status.
2259     @retval 0 Success
2260     @retval other ER_* mysql error. Get error details from THD.
2261 */
2262 using page_track_get_num_page_ids_t = int (*)(uint64_t *start_id,
2263                                               uint64_t *stop_id,
2264                                               uint64_t *num_pages);
2265 
2266 /** Fetch the status of the page tracking system.
2267 @param[out]	status	vector of a pair of (ID, bool) where ID is the
2268 start/stop point and bool is true if the ID is a start point else false */
2269 using page_track_get_status_t =
2270     void (*)(std::vector<std::pair<uint64_t, bool>> &status);
2271 
2272 /** Page track interface */
2273 struct Page_track_t {
2274   page_track_start_t start;
2275   page_track_stop_t stop;
2276   page_track_purge_t purge;
2277   page_track_get_page_ids_t get_page_ids;
2278   page_track_get_num_page_ids_t get_num_page_ids;
2279   page_track_get_status_t get_status;
2280 };
2281 
2282 /**
2283   handlerton is a singleton structure - one instance per storage engine -
2284   to provide access to storage engine functionality that works on the
2285   "global" level (unlike handler class that works on a per-table basis).
2286 
2287   usually handlerton instance is defined statically in ha_xxx.cc as
2288 
2289   static handlerton { ... } xxx_hton;
2290 
2291   savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
2292 */
2293 struct handlerton {
2294   /**
2295     Historical marker for if the engine is available or not.
2296   */
2297   SHOW_COMP_OPTION state;
2298 
2299   /**
2300     Historical number used for frm file to determine the correct storage engine.
2301     This is going away and new engines will just use "name" for this.
2302   */
2303   enum legacy_db_type db_type;
2304   /**
2305     Each storage engine has it's own memory area (actually a pointer)
2306     in the thd, for storing per-connection information.
2307     It is accessed as
2308 
2309       thd->ha_data[xxx_hton.slot]
2310 
2311      slot number is initialized by MySQL after xxx_init() is called.
2312    */
2313   uint slot;
2314   /**
2315     To store per-savepoint data storage engine is provided with an area
2316     of a requested size (0 is ok here).
2317     savepoint_offset must be initialized statically to the size of
2318     the needed memory to store per-savepoint information.
2319     After xxx_init it is changed to be an offset to savepoint storage
2320     area and need not be used by storage engine.
2321     see binlog_hton and binlog_savepoint_set/rollback for an example.
2322    */
2323   uint savepoint_offset;
2324 
2325   /* handlerton methods */
2326 
2327   close_connection_t close_connection;
2328   kill_connection_t kill_connection;
2329   pre_dd_shutdown_t pre_dd_shutdown;
2330   savepoint_set_t savepoint_set;
2331   savepoint_rollback_t savepoint_rollback;
2332   savepoint_rollback_can_release_mdl_t savepoint_rollback_can_release_mdl;
2333   savepoint_release_t savepoint_release;
2334   commit_t commit;
2335   rollback_t rollback;
2336   prepare_t prepare;
2337   recover_t recover;
2338   commit_by_xid_t commit_by_xid;
2339   rollback_by_xid_t rollback_by_xid;
2340   create_t create;
2341   drop_database_t drop_database;
2342   panic_t panic;
2343   start_consistent_snapshot_t start_consistent_snapshot;
2344   flush_logs_t flush_logs;
2345   show_status_t show_status;
2346   partition_flags_t partition_flags;
2347   is_valid_tablespace_name_t is_valid_tablespace_name;
2348   get_tablespace_t get_tablespace;
2349   alter_tablespace_t alter_tablespace;
2350   get_tablespace_filename_ext_t get_tablespace_filename_ext;
2351   upgrade_tablespace_t upgrade_tablespace;
2352   upgrade_space_version_t upgrade_space_version;
2353   get_tablespace_type_t get_tablespace_type;
2354   get_tablespace_type_by_name_t get_tablespace_type_by_name;
2355   upgrade_logs_t upgrade_logs;
2356   finish_upgrade_t finish_upgrade;
2357   fill_is_table_t fill_is_table;
2358   dict_init_t dict_init;
2359   ddse_dict_init_t ddse_dict_init;
2360   dict_register_dd_table_id_t dict_register_dd_table_id;
2361   dict_cache_reset_t dict_cache_reset;
2362   dict_cache_reset_tables_and_tablespaces_t
2363       dict_cache_reset_tables_and_tablespaces;
2364   dict_recover_t dict_recover;
2365   dict_get_server_version_t dict_get_server_version;
2366   dict_set_server_version_t dict_set_server_version;
2367   is_reserved_db_name_t is_reserved_db_name;
2368 
2369   /** Global handler flags. */
2370   uint32 flags;
2371 
2372   /*
2373     Those handlerton functions below are properly initialized at handler
2374     init.
2375   */
2376 
2377   binlog_func_t binlog_func;
2378   binlog_log_query_t binlog_log_query;
2379   acl_notify_t acl_notify;
2380   discover_t discover;
2381   find_files_t find_files;
2382   table_exists_in_engine_t table_exists_in_engine;
2383   is_supported_system_table_t is_supported_system_table;
2384 
2385   /*
2386     APIs for retrieving Serialized Dictionary Information by tablespace id
2387   */
2388 
2389   sdi_create_t sdi_create;
2390   sdi_drop_t sdi_drop;
2391   sdi_get_keys_t sdi_get_keys;
2392   sdi_get_t sdi_get;
2393   sdi_set_t sdi_set;
2394   sdi_delete_t sdi_delete;
2395 
2396   /**
2397     Null-ended array of file extentions that exist for the storage engine.
2398     Used by frm_error() and the default handler::rename_table and delete_table
2399     methods in handler.cc.
2400 
2401     For engines that have two file name extentions (separate meta/index file
2402     and data file), the order of elements is relevant. First element of engine
2403     file name extentions array should be meta/index file extention. Second
2404     element - data file extention. This order is assumed by
2405     prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
2406 
2407     For engines that don't have files, file_extensions is NULL.
2408 
2409     Currently, the following alternatives are used:
2410       - file_extensions == NULL;
2411       - file_extensions[0] != NULL, file_extensions[1] == NULL;
2412       - file_extensions[0] != NULL, file_extensions[1] != NULL,
2413         file_extensions[2] == NULL;
2414   */
2415   const char **file_extensions;
2416 
2417   is_dict_readonly_t is_dict_readonly;
2418   rm_tmp_tables_t rm_tmp_tables;
2419   get_cost_constants_t get_cost_constants;
2420   replace_native_transaction_in_thd_t replace_native_transaction_in_thd;
2421   notify_exclusive_mdl_t notify_exclusive_mdl;
2422   notify_alter_table_t notify_alter_table;
2423   rotate_encryption_master_key_t rotate_encryption_master_key;
2424   redo_log_set_state_t redo_log_set_state;
2425 
2426   get_table_statistics_t get_table_statistics;
2427   get_index_column_cardinality_t get_index_column_cardinality;
2428   get_tablespace_statistics_t get_tablespace_statistics;
2429 
2430   post_ddl_t post_ddl;
2431   post_recover_t post_recover;
2432 
2433   /** Clone data transfer interfaces */
2434   Clone_interface_t clone_interface;
2435 
2436   /** Flag for Engine License. */
2437   uint32 license;
2438   /** Location for engines to keep personal structures. */
2439   void *data;
2440 
2441   /*
2442     Log_resource functions that must be supported by storage engines
2443     with relevant log information to be collected.
2444   */
2445   lock_hton_log_t lock_hton_log;
2446   unlock_hton_log_t unlock_hton_log;
2447   collect_hton_log_info_t collect_hton_log_info;
2448 
2449   /** Flags describing details of foreign key support by storage engine. */
2450   uint32 foreign_keys_flags;
2451 
2452   check_fk_column_compat_t check_fk_column_compat;
2453 
2454   /**
2455     Suffix for auto-generated foreign key names for tables using this storage
2456     engine. If such suffix is specified by SE then its generated foreign key
2457     names follow (table name)(SE-specific FK name suffix)(FK number) pattern.
2458     Length of such suffix should not exceed MAX_FK_NAME_SUFFIX_LENGTH bytes.
2459     If no suffix is specified then FK_NAME_DEFAULT_SUFFIX is used as
2460     default.
2461   */
2462   LEX_CSTRING fk_name_suffix;
2463 
2464   /**
2465     Pointer to a function that prepares a secondary engine for executing a
2466     statement.
2467 
2468     @see prepare_secondary_engine_t for function signature.
2469   */
2470   prepare_secondary_engine_t prepare_secondary_engine;
2471 
2472   /**
2473     Pointer to a function that optimizes the current statement for
2474     execution on the secondary storage engine represented by this
2475     handlerton.
2476 
2477     @see optimize_secondary_engine_t for function signature.
2478   */
2479   optimize_secondary_engine_t optimize_secondary_engine;
2480 
2481   /**
2482     Pointer to a function that estimates the cost of executing a join in a
2483     secondary storage engine.
2484 
2485     @see compare_secondary_engine_cost_t for function signature.
2486   */
2487   compare_secondary_engine_cost_t compare_secondary_engine_cost;
2488 
2489   se_before_commit_t se_before_commit;
2490   se_after_commit_t se_after_commit;
2491   se_before_rollback_t se_before_rollback;
2492 
2493   /** Page tracking interface */
2494   Page_track_t page_track;
2495 };
2496 
2497 /* Possible flags of a handlerton (there can be 32 of them) */
2498 #define HTON_NO_FLAGS 0
2499 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
2500 #define HTON_ALTER_NOT_SUPPORTED (1 << 1)  // Engine does not support alter
2501 #define HTON_CAN_RECREATE (1 << 2)         // Delete all is used fro truncate
2502 #define HTON_HIDDEN (1 << 3)               // Engine does not appear in lists
2503 /*
2504   Bit 4 was occupied by BDB-specific HTON_FLUSH_AFTER_RENAME flag and is no
2505   longer used.
2506 */
2507 #define HTON_NOT_USER_SELECTABLE (1 << 5)
2508 #define HTON_TEMPORARY_NOT_SUPPORTED \
2509   (1 << 6)  // Having temporary tables not supported
2510 #define HTON_SUPPORT_LOG_TABLES (1 << 7)  // Engine supports log tables
2511 #define HTON_NO_PARTITION (1 << 8)        // You can not partition these tables
2512 
2513 /*
2514   This flag should be set when deciding that the engine does not allow row based
2515   binary logging (RBL) optimizations.
2516 
2517   Currently, setting this flag, means that table's read/write_set will be left
2518   untouched when logging changes to tables in this engine. In practice this
2519   means that the server will not mess around with table->write_set and/or
2520   table->read_set when using RBL and deciding whether to log full or minimal
2521   rows.
2522 
2523   It's valuable for instance for virtual tables, eg: Performance Schema which
2524   have no meaning for replication.
2525 */
2526 #define HTON_NO_BINLOG_ROW_OPT (1 << 9)
2527 
2528 /**
2529   Engine supports extended keys. The flag allows to
2530   use 'extended key' feature if the engine is able to
2531   do it (has primary key values in the secondary key).
2532   Note that handler flag HA_PRIMARY_KEY_IN_READ_INDEX is
2533   actually partial case of HTON_SUPPORTS_EXTENDED_KEYS.
2534 */
2535 
2536 #define HTON_SUPPORTS_EXTENDED_KEYS (1 << 10)
2537 
2538 // Engine support foreign key constraint.
2539 
2540 #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 11)
2541 
2542 /**
2543   Engine supports atomic DDL. That is rollback of transaction for DDL
2544   statement will also rollback all changes in SE, commit of transaction
2545   of DDL statement will make it durable.
2546 */
2547 
2548 #define HTON_SUPPORTS_ATOMIC_DDL (1 << 12)
2549 
2550 /* Engine supports packed keys. */
2551 #define HTON_SUPPORTS_PACKED_KEYS (1 << 13)
2552 
2553 /** Engine is a secondary storage engine. */
2554 #define HTON_IS_SECONDARY_ENGINE (1 << 14)
2555 
2556 /** Engine supports secondary storage engines. */
2557 #define HTON_SUPPORTS_SECONDARY_ENGINE (1 << 15)
2558 
2559 /** Engine supports table or tablespace encryption . */
2560 #define HTON_SUPPORTS_TABLE_ENCRYPTION (1 << 16)
2561 
decltype(handlerton::flags)2562 constexpr const decltype(handlerton::flags) HTON_SUPPORTS_ENGINE_ATTRIBUTE{
2563     1 << 17};
2564 
ddl_is_atomic(const handlerton * hton)2565 inline bool ddl_is_atomic(const handlerton *hton) {
2566   return (hton->flags & HTON_SUPPORTS_ATOMIC_DDL) != 0;
2567 }
2568 
2569 /* Bits for handlerton::foreign_keys_flags bitmap. */
2570 
2571 /**
2572   Engine supports both unique and non-unique parent keys for
2573   foreign keys which contain full foreign key as its prefix.
2574 
2575   Storage engines which support foreign keys but do not have
2576   this flag set are assumed to support only parent keys which
2577   are primary/unique and contain exactly the same columns as
2578   the foreign key, possibly, in different order.
2579 */
2580 
2581 static const uint32 HTON_FKS_WITH_PREFIX_PARENT_KEYS = (1 << 0);
2582 
2583 /**
2584   Storage engine supports hash keys as supporting keys for foreign
2585   keys. Hash key should contain all foreign key columns and only
2586   them (altough in any order).
2587 
2588   Storage engines which support foreign keys but do not have this
2589   flag set are assumed to not allow hash keys as supporting keys.
2590 */
2591 
2592 static const uint32 HTON_FKS_WITH_SUPPORTING_HASH_KEYS = (1 << 1);
2593 
2594 /**
2595   Storage engine supports non-hash keys which have common prefix
2596   with the foreign key as supporting keys for it. If there are
2597   several such keys, one which shares biggest prefix with FK is
2598   chosen.
2599 
2600   Storage engines which support foreign keys but do not have this
2601   flag set are assumed to require that supporting key contains full
2602   foreign key as its prefix.
2603 */
2604 
2605 static const uint32 HTON_FKS_WITH_ANY_PREFIX_SUPPORTING_KEYS = (1 << 2);
2606 
2607 /**
2608   Storage engine does not support using the same key for both parent
2609   and supporting key, but requires the two to be different.
2610 */
2611 
2612 static const uint32 HTON_FKS_NEED_DIFFERENT_PARENT_AND_SUPPORTING_KEYS =
2613     (1 << 3);
2614 
2615 /**
2616   Engine takes into account hidden part of key (coming from primary key)
2617   when determines if it can serve as parent key for a foreign key.
2618 
2619   Implies HTON_FKS_WITH_PREFIX_PARENT_KEYS and is related to
2620   HTON_SUPPORTS_EXTENDED_KEYS.
2621 */
2622 
2623 static const uint32 HTON_FKS_WITH_EXTENDED_PARENT_KEYS = (1 << 4);
2624 
2625 /**
2626   Maximum possible length of SE-specific suffixes for auto-generated
2627   foreign key names.
2628 */
2629 static const size_t MAX_FK_NAME_SUFFIX_LENGTH = 16;
2630 
2631 /**
2632   Suffix for auto-generated foreign key names for tables in SE's which
2633   don't specify own suffix. I.e. for foreign keys on tables in such
2634   SE's generated names follow (table name)FK_NAME_DEFAULT_SUFFIX(FK number)
2635   pattern.
2636 */
2637 static const LEX_CSTRING FK_NAME_DEFAULT_SUFFIX = {STRING_WITH_LEN("_fk_")};
2638 
2639 enum enum_tx_isolation : int {
2640   ISO_READ_UNCOMMITTED,
2641   ISO_READ_COMMITTED,
2642   ISO_REPEATABLE_READ,
2643   ISO_SERIALIZABLE
2644 };
2645 
2646 enum enum_stats_auto_recalc : int {
2647   HA_STATS_AUTO_RECALC_DEFAULT = 0,
2648   HA_STATS_AUTO_RECALC_ON,
2649   HA_STATS_AUTO_RECALC_OFF
2650 };
2651 
2652 /* struct to hold information about the table that should be created */
2653 struct HA_CREATE_INFO {
2654   const CHARSET_INFO *table_charset{nullptr};
2655   const CHARSET_INFO *default_table_charset{nullptr};
2656   LEX_STRING connect_string{nullptr, 0};
2657   const char *password{nullptr};
2658   const char *tablespace{nullptr};
2659   LEX_STRING comment{nullptr, 0};
2660 
2661   /**
2662   Algorithm (and possible options) to be used for InnoDB's transparent
2663   page compression. If this attribute is set then it is hint to the
2664   storage engine to try and compress the data using the specified algorithm
2665   where possible. Note: this value is interpreted by the storage engine only.
2666   and ignored by the Server layer. */
2667 
2668   LEX_STRING compress{nullptr, 0};
2669 
2670   /**
2671   This attibute is used for InnoDB's transparent page encryption.
2672   If this attribute is set then it is hint to the storage engine to encrypt
2673   the data. Note: this value is interpreted by the storage engine only.
2674   and ignored by the Server layer. */
2675 
2676   LEX_STRING encrypt_type{nullptr, 0};
2677 
2678   /**
2679    * Secondary engine of the table.
2680    * Is nullptr if no secondary engine defined.
2681    */
2682   LEX_CSTRING secondary_engine{nullptr, 0};
2683 
2684   const char *data_file_name{nullptr};
2685   const char *index_file_name{nullptr};
2686   const char *alias{nullptr};
2687   ulonglong max_rows{0};
2688   ulonglong min_rows{0};
2689   ulonglong auto_increment_value{0};
2690   ulong table_options{0};
2691   ulong avg_row_length{0};
2692   uint64_t used_fields{0};
2693   ulong key_block_size{0};
2694   uint stats_sample_pages{0}; /* number of pages to sample during
2695                            stats estimation, if used, otherwise 0. */
2696   enum_stats_auto_recalc stats_auto_recalc{HA_STATS_AUTO_RECALC_DEFAULT};
2697   SQL_I_List<TABLE_LIST> merge_list;
2698   handlerton *db_type{nullptr};
2699   /**
2700     Row type of the table definition.
2701 
2702     Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
2703     For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
2704 
2705     Can be changed either explicitly by the parser.
2706     If nothing specified inherits the value of the original table (if present).
2707   */
2708   enum row_type row_type = ROW_TYPE_DEFAULT;
2709   uint null_bits{0}; /* NULL bits at start of record */
2710   uint options{0};   /* OR of HA_CREATE_ options */
2711   uint merge_insert_method{0};
2712   ha_storage_media storage_media{HA_SM_DEFAULT}; /* DEFAULT, DISK or MEMORY */
2713 
2714   /*
2715     A flag to indicate if this table should be marked as a hidden table in
2716     the data dictionary. One use case is to mark the temporary tables
2717     created by ALTER to be marked as hidden.
2718   */
2719   bool m_hidden{false};
2720 
2721   /*
2722     A flag to indicate if this table should be created but not committed at
2723     the end of statement.
2724   */
2725   bool m_transactional_ddl{false};
2726 
2727   LEX_CSTRING engine_attribute = NULL_CSTR;
2728   LEX_CSTRING secondary_engine_attribute = NULL_CSTR;
2729 
2730   /**
2731     Fill HA_CREATE_INFO to be used by ALTER as well as upgrade code.
2732     This function separates code from mysql_prepare_alter_table() to be
2733     used by upgrade code as well to reduce code duplication.
2734     For ALTER code path, this lets new create options override the old
2735     ones.
2736 
2737     @param[in]  share        TABLE_SHARE object
2738     @param[in]  used_fields  If a given create option is not flagged, old
2739                              value be copied from the TABLE_SHARE.
2740   */
2741 
2742   void init_create_options_from_share(const TABLE_SHARE *share,
2743                                       uint used_fields);
2744 };
2745 
2746 /**
2747   Structure describing changes to an index to be caused by ALTER TABLE.
2748 */
2749 
2750 struct KEY_PAIR {
2751   /**
2752     Pointer to KEY object describing old version of index in
2753     TABLE::key_info array for TABLE instance representing old
2754     version of table.
2755   */
2756   KEY *old_key;
2757   /**
2758     Pointer to KEY object describing new version of index in
2759     Alter_inplace_info::key_info_buffer array.
2760   */
2761   KEY *new_key;
2762 };
2763 
2764 /**
2765   In-place alter handler context.
2766 
2767   This is a superclass intended to be subclassed by individual handlers
2768   in order to store handler unique context between in-place alter API calls.
2769 
2770   The handler is responsible for creating the object. This can be done
2771   as early as during check_if_supported_inplace_alter().
2772 
2773   The SQL layer is responsible for destroying the object.
2774 
2775   @see Alter_inplace_info
2776 */
2777 
2778 class inplace_alter_handler_ctx {
2779  public:
inplace_alter_handler_ctx()2780   inplace_alter_handler_ctx() {}
2781 
set_shared_data(const inplace_alter_handler_ctx * ctx MY_ATTRIBUTE ((unused)))2782   virtual void set_shared_data(
2783       const inplace_alter_handler_ctx *ctx MY_ATTRIBUTE((unused))) {}
~inplace_alter_handler_ctx()2784   virtual ~inplace_alter_handler_ctx() {}
2785 };
2786 
2787 /**
2788   Class describing changes to be done by ALTER TABLE.
2789   Instance of this class is passed to storage engine in order
2790   to determine if this ALTER TABLE can be done using in-place
2791   algorithm. It is also used for executing the ALTER TABLE
2792   using in-place algorithm.
2793 */
2794 
2795 class Alter_inplace_info {
2796  public:
2797   /**
2798      Bits to show in detail what operations the storage engine is
2799      to execute.
2800 
2801      All these operations are supported as in-place operations by the
2802      SQL layer. This means that operations that by their nature must
2803      be performed by copying the table to a temporary table, will not
2804      have their own flags here (e.g. ALTER TABLE FORCE, ALTER TABLE
2805      ENGINE).
2806 
2807      We generally try to specify handler flags only if there are real
2808      changes. But in cases when it is cumbersome to determine if some
2809      attribute has really changed we might choose to set flag
2810      pessimistically, for example, relying on parser output only.
2811   */
2812   typedef ulonglong HA_ALTER_FLAGS;
2813 
2814   // Add non-unique, non-primary index
2815   static const HA_ALTER_FLAGS ADD_INDEX = 1ULL << 0;
2816 
2817   // Drop non-unique, non-primary index
2818   static const HA_ALTER_FLAGS DROP_INDEX = 1ULL << 1;
2819 
2820   // Add unique, non-primary index
2821   static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1ULL << 2;
2822 
2823   // Drop unique, non-primary index
2824   static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1ULL << 3;
2825 
2826   // Add primary index
2827   static const HA_ALTER_FLAGS ADD_PK_INDEX = 1ULL << 4;
2828 
2829   // Drop primary index
2830   static const HA_ALTER_FLAGS DROP_PK_INDEX = 1ULL << 5;
2831 
2832   // Add column
2833 
2834   // Virtual generated column
2835   static const HA_ALTER_FLAGS ADD_VIRTUAL_COLUMN = 1ULL << 6;
2836   // Stored base (non-generated) column
2837   static const HA_ALTER_FLAGS ADD_STORED_BASE_COLUMN = 1ULL << 7;
2838   // Stored generated column
2839   static const HA_ALTER_FLAGS ADD_STORED_GENERATED_COLUMN = 1ULL << 8;
2840   // Add generic column (convience constant).
2841   static const HA_ALTER_FLAGS ADD_COLUMN =
2842       ADD_VIRTUAL_COLUMN | ADD_STORED_BASE_COLUMN | ADD_STORED_GENERATED_COLUMN;
2843 
2844   // Drop column
2845   static const HA_ALTER_FLAGS DROP_VIRTUAL_COLUMN = 1ULL << 9;
2846   static const HA_ALTER_FLAGS DROP_STORED_COLUMN = 1ULL << 10;
2847   static const HA_ALTER_FLAGS DROP_COLUMN =
2848       DROP_VIRTUAL_COLUMN | DROP_STORED_COLUMN;
2849 
2850   // Rename column
2851   static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1ULL << 11;
2852 
2853   // Change column datatype
2854   static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_TYPE = 1ULL << 12;
2855   static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_TYPE = 1ULL << 13;
2856 
2857   /**
2858     Change column datatype in such way that new type has compatible
2859     packed representation with old type, so it is theoretically
2860     possible to perform change by only updating data dictionary
2861     without changing table rows.
2862   */
2863   static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1ULL << 14;
2864 
2865   /// A virtual column has changed its position
2866   static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_ORDER = 1ULL << 15;
2867 
2868   /// A stored column has changed its position (disregarding virtual columns)
2869   static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_ORDER = 1ULL << 16;
2870 
2871   // Change column from NOT NULL to NULL
2872   static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1ULL << 17;
2873 
2874   // Change column from NULL to NOT NULL
2875   static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE = 1ULL << 18;
2876 
2877   // Set or remove default column value
2878   static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1ULL << 19;
2879 
2880   // Change column generation expression
2881   static const HA_ALTER_FLAGS ALTER_VIRTUAL_GCOL_EXPR = 1ULL << 20;
2882   static const HA_ALTER_FLAGS ALTER_STORED_GCOL_EXPR = 1ULL << 21;
2883 
2884   // Add foreign key
2885   static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1ULL << 22;
2886 
2887   // Drop foreign key
2888   static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1ULL << 23;
2889 
2890   // table_options changed, see HA_CREATE_INFO::used_fields for details.
2891   static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1ULL << 24;
2892 
2893   // Table is renamed
2894   static const HA_ALTER_FLAGS ALTER_RENAME = 1ULL << 25;
2895 
2896   // Change the storage type of column
2897   static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1ULL << 26;
2898 
2899   // Change the column format of column
2900   static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1ULL << 27;
2901 
2902   // Add partition
2903   static const HA_ALTER_FLAGS ADD_PARTITION = 1ULL << 28;
2904 
2905   // Drop partition
2906   static const HA_ALTER_FLAGS DROP_PARTITION = 1ULL << 29;
2907 
2908   // Changing partition options
2909   static const HA_ALTER_FLAGS ALTER_PARTITION = 1ULL << 30;
2910 
2911   // Coalesce partition
2912   static const HA_ALTER_FLAGS COALESCE_PARTITION = 1ULL << 31;
2913 
2914   // Reorganize partition ... into
2915   static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1ULL << 32;
2916 
2917   // Reorganize partition
2918   static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1ULL << 33;
2919 
2920   // Remove partitioning
2921   static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING = 1ULL << 34;
2922 
2923   // Partition operation with ALL keyword
2924   static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1ULL << 35;
2925 
2926   /**
2927     Rename index. Note that we set this flag only if there are no other
2928     changes to the index being renamed. Also for simplicity we don't
2929     detect renaming of indexes which is done by dropping index and then
2930     re-creating index with identical definition under different name.
2931   */
2932   static const HA_ALTER_FLAGS RENAME_INDEX = 1ULL << 36;
2933 
2934   /**
2935     Recreate the table for ALTER TABLE FORCE, ALTER TABLE ENGINE
2936     and OPTIMIZE TABLE operations.
2937   */
2938   static const HA_ALTER_FLAGS RECREATE_TABLE = 1ULL << 37;
2939 
2940   // Add spatial index
2941   static const HA_ALTER_FLAGS ADD_SPATIAL_INDEX = 1ULL << 38;
2942 
2943   // Alter index comment
2944   static const HA_ALTER_FLAGS ALTER_INDEX_COMMENT = 1ULL << 39;
2945 
2946   // New/changed virtual generated column require validation
2947   static const HA_ALTER_FLAGS VALIDATE_VIRTUAL_COLUMN = 1ULL << 40;
2948 
2949   /**
2950     Change index option in a way which is likely not to require index
2951     recreation. For example, change COMMENT or KEY::is_algorithm_explicit
2952     flag (without change of index algorithm itself).
2953   */
2954   static const HA_ALTER_FLAGS CHANGE_INDEX_OPTION = 1LL << 41;
2955 
2956   // Rebuild partition
2957   static const HA_ALTER_FLAGS ALTER_REBUILD_PARTITION = 1ULL << 42;
2958 
2959   /**
2960     Change in index length such that it does not require index rebuild.
2961     For example, change in index length due to column expansion like
2962     varchar(X) changed to varchar(X + N).
2963   */
2964   static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH = 1ULL << 43;
2965 
2966   /**
2967     Change to one of columns on which virtual generated column depends,
2968     so its values require re-evaluation.
2969   */
2970   static const HA_ALTER_FLAGS VIRTUAL_GCOL_REEVAL = 1ULL << 44;
2971 
2972   /**
2973     Change to one of columns on which stored generated column depends,
2974     so its values require re-evaluation.
2975   */
2976   static const HA_ALTER_FLAGS STORED_GCOL_REEVAL = 1ULL << 45;
2977 
2978   // Add check constraint.
2979   static const HA_ALTER_FLAGS ADD_CHECK_CONSTRAINT = 1ULL << 46;
2980 
2981   // Drop check constraint.
2982   static const HA_ALTER_FLAGS DROP_CHECK_CONSTRAINT = 1ULL << 47;
2983 
2984   // Suspend check constraint.
2985   static const HA_ALTER_FLAGS SUSPEND_CHECK_CONSTRAINT = 1ULL << 48;
2986 
2987   /**
2988     Create options (like MAX_ROWS) for the new version of table.
2989 
2990     @note The referenced instance of HA_CREATE_INFO object was already
2991           used to create new .FRM file for table being altered. So it
2992           has been processed by mysql_prepare_create_table() already.
2993           For example, this means that it has HA_OPTION_PACK_RECORD
2994           flag in HA_CREATE_INFO::table_options member correctly set.
2995   */
2996   HA_CREATE_INFO *create_info;
2997 
2998   /**
2999     Alter options, fields and keys for the new version of table.
3000 
3001     @note The referenced instance of Alter_info object was already
3002           used to create new .FRM file for table being altered. So it
3003           has been processed by mysql_prepare_create_table() already.
3004           In particular, this means that in Create_field objects for
3005           fields which were present in some form in the old version
3006           of table, Create_field::field member points to corresponding
3007           Field instance for old version of table.
3008   */
3009   Alter_info *alter_info;
3010 
3011   /**
3012     Indicates whether operation should fail if table is non-empty.
3013     Storage engines should not suggest/allow execution of such operations
3014     using INSTANT algorithm since check whether table is empty done from
3015     SQL-layer is not "instant". Also SEs might choose different algorithm for
3016     ALTER TABLE execution knowing that it will be allowed to proceed only if
3017     table is empty.
3018 
3019     Unlike for Alter_table_ctx::error_if_not_empty, we use bool for this flag
3020     and not bitmap, since SEs are really interested in the fact that ALTER
3021     will fail if table is not empty and not in exact reason behind this fact,
3022     and because we want to avoid extra dependency between Alter_table_ctx and
3023     Alter_inplace_info.
3024   */
3025   bool error_if_not_empty;
3026 
3027   /**
3028     Array of KEYs for new version of table - including KEYs to be added.
3029 
3030     @note Currently this array is produced as result of
3031           mysql_prepare_create_table() call.
3032           This means that it follows different convention for
3033           KEY_PART_INFO::fieldnr values than objects in TABLE::key_info
3034           array.
3035 
3036     @todo This is mainly due to the fact that we need to keep compatibility
3037           with removed handler::add_index() call. We plan to switch to
3038           TABLE::key_info numbering later.
3039 
3040     KEYs are sorted - see sort_keys().
3041   */
3042   KEY *key_info_buffer;
3043 
3044   /** Size of key_info_buffer array. */
3045   uint key_count;
3046 
3047   /** Size of index_drop_buffer array. */
3048   uint index_drop_count;
3049 
3050   /**
3051      Array of pointers to KEYs to be dropped belonging to the TABLE instance
3052      for the old version of the table.
3053   */
3054   KEY **index_drop_buffer;
3055 
3056   /** Size of index_add_buffer array. */
3057   uint index_add_count;
3058 
3059   /**
3060      Array of indexes into key_info_buffer for KEYs to be added,
3061      sorted in increasing order.
3062   */
3063   uint *index_add_buffer;
3064 
3065   /** Size of index_rename_buffer array. */
3066   uint index_rename_count;
3067 
3068   /** Size of index_rename_buffer array. */
3069   uint index_altered_visibility_count;
3070 
3071   /**
3072     Array of KEY_PAIR objects describing indexes being renamed.
3073     For each index renamed it contains object with KEY_PAIR::old_key
3074     pointing to KEY object belonging to the TABLE instance for old
3075     version of table representing old version of index and with
3076     KEY_PAIR::new_key pointing to KEY object for new version of
3077     index in key_info_buffer member.
3078   */
3079   KEY_PAIR *index_rename_buffer;
3080   KEY_PAIR *index_altered_visibility_buffer;
3081 
3082   /** Number of virtual columns to be added. */
3083   uint virtual_column_add_count;
3084 
3085   /** number of virtual columns to be dropped. */
3086   uint virtual_column_drop_count;
3087 
3088   /**
3089      Context information to allow handlers to keep context between in-place
3090      alter API calls.
3091 
3092      @see inplace_alter_handler_ctx for information about object lifecycle.
3093   */
3094   inplace_alter_handler_ctx *handler_ctx;
3095 
3096   /**
3097     If the table uses several handlers, like ha_partition uses one handler
3098     per partition, this contains a Null terminated array of ctx pointers
3099     that should all be committed together.
3100     Or NULL if only handler_ctx should be committed.
3101     Set to NULL if the low level handler::commit_inplace_alter_table uses it,
3102     to signal to the main handler that everything was committed as atomically.
3103 
3104     @see inplace_alter_handler_ctx for information about object lifecycle.
3105   */
3106   inplace_alter_handler_ctx **group_commit_ctx;
3107 
3108   /**
3109      Flags describing in detail which operations the storage engine is to
3110      execute.
3111   */
3112   HA_ALTER_FLAGS handler_flags;
3113 
3114   /**
3115      Partition_info taking into account the partition changes to be performed.
3116      Contains all partitions which are present in the old version of the table
3117      with partitions to be dropped or changed marked as such + all partitions
3118      to be added in the new version of table marked as such.
3119   */
3120   partition_info *modified_part_info;
3121 
3122   /** true for online operation (LOCK=NONE) */
3123   bool online;
3124 
3125   /**
3126     Can be set by handler along with handler_ctx. The difference is that
3127     this flag can be used to store SE-specific in-place ALTER context in cases
3128     when constructing full-blown inplace_alter_handler_ctx descendant is
3129     inconvenient.
3130   */
3131   uint handler_trivial_ctx;
3132 
3133   /**
3134      Can be set by handler to describe why a given operation cannot be done
3135      in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
3136      online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE)
3137      If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
3138      results from handler::check_if_supported_inplace_alter() doesn't match
3139      requirements set by user. If not set, the more generic
3140      ER_ALTER_OPERATION_NOT_SUPPORTED will be used.
3141 
3142      Please set to a properly localized string, for example using
3143      my_get_err_msg(), so that the error message as a whole is localized.
3144   */
3145   const char *unsupported_reason;
3146 
Alter_inplace_info(HA_CREATE_INFO * create_info_arg,Alter_info * alter_info_arg,bool error_if_not_empty_arg,KEY * key_info_arg,uint key_count_arg,partition_info * modified_part_info_arg)3147   Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
3148                      Alter_info *alter_info_arg, bool error_if_not_empty_arg,
3149                      KEY *key_info_arg, uint key_count_arg,
3150                      partition_info *modified_part_info_arg)
3151       : create_info(create_info_arg),
3152         alter_info(alter_info_arg),
3153         error_if_not_empty(error_if_not_empty_arg),
3154         key_info_buffer(key_info_arg),
3155         key_count(key_count_arg),
3156         index_drop_count(0),
3157         index_drop_buffer(nullptr),
3158         index_add_count(0),
3159         index_add_buffer(nullptr),
3160         index_rename_count(0),
3161         index_altered_visibility_count(0),
3162         index_rename_buffer(nullptr),
3163         virtual_column_add_count(0),
3164         virtual_column_drop_count(0),
3165         handler_ctx(nullptr),
3166         group_commit_ctx(nullptr),
3167         handler_flags(0),
3168         modified_part_info(modified_part_info_arg),
3169         online(false),
3170         handler_trivial_ctx(0),
3171         unsupported_reason(nullptr) {}
3172 
~Alter_inplace_info()3173   ~Alter_inplace_info() { destroy(handler_ctx); }
3174 
3175   /**
3176     Used after check_if_supported_inplace_alter() to report
3177     error if the result does not match the LOCK/ALGORITHM
3178     requirements set by the user.
3179 
3180     @param not_supported  Part of statement that was not supported.
3181     @param try_instead    Suggestion as to what the user should
3182                           replace not_supported with.
3183   */
3184   void report_unsupported_error(const char *not_supported,
3185                                 const char *try_instead);
3186 
3187   /** Add old and new version of key to array of indexes to be renamed. */
add_renamed_key(KEY * old_key,KEY * new_key)3188   void add_renamed_key(KEY *old_key, KEY *new_key) {
3189     KEY_PAIR *key_pair = index_rename_buffer + index_rename_count++;
3190     key_pair->old_key = old_key;
3191     key_pair->new_key = new_key;
3192     DBUG_PRINT("info",
3193                ("index renamed: '%s' to '%s'", old_key->name, new_key->name));
3194   }
3195 
add_altered_index_visibility(KEY * old_key,KEY * new_key)3196   void add_altered_index_visibility(KEY *old_key, KEY *new_key) {
3197     KEY_PAIR *key_pair =
3198         index_altered_visibility_buffer + index_altered_visibility_count++;
3199     key_pair->old_key = old_key;
3200     key_pair->new_key = new_key;
3201     DBUG_PRINT("info", ("index had visibility altered: %i to %i",
3202                         old_key->is_visible, new_key->is_visible));
3203   }
3204 
3205   /**
3206     Add old and new version of modified key to arrays of indexes to
3207     be dropped and added (correspondingly).
3208   */
add_modified_key(KEY * old_key,KEY * new_key)3209   void add_modified_key(KEY *old_key, KEY *new_key) {
3210     index_drop_buffer[index_drop_count++] = old_key;
3211     index_add_buffer[index_add_count++] = (uint)(new_key - key_info_buffer);
3212     DBUG_PRINT("info", ("index changed: '%s'", old_key->name));
3213   }
3214 
3215   /** Drop key to array of indexes to be dropped. */
add_dropped_key(KEY * old_key)3216   void add_dropped_key(KEY *old_key) {
3217     index_drop_buffer[index_drop_count++] = old_key;
3218     DBUG_PRINT("info", ("index dropped: '%s'", old_key->name));
3219   }
3220 
3221   /** Add key to array of indexes to be added. */
add_added_key(KEY * new_key)3222   void add_added_key(KEY *new_key) {
3223     index_add_buffer[index_add_count++] = (uint)(new_key - key_info_buffer);
3224     DBUG_PRINT("info", ("index added: '%s'", new_key->name));
3225   }
3226 };
3227 
3228 struct HA_CHECK_OPT {
3229   uint flags{0};     /* isam layer flags (e.g. for myisamchk) */
3230   uint sql_flags{0}; /* sql layer flags - for something myisamchk cannot do */
3231   KEY_CACHE *key_cache; /* new key cache when changing key cache */
3232 };
3233 
3234 /*
3235   This is a buffer area that the handler can use to store rows.
3236   'end_of_used_area' should be kept updated after calls to
3237   read-functions so that other parts of the code can use the
3238   remaining area (until next read calls is issued).
3239 */
3240 
3241 struct HANDLER_BUFFER {
3242   uchar *buffer;           /* Buffer one can start using */
3243   uchar *buffer_end;       /* End of buffer */
3244   uchar *end_of_used_area; /* End of area that was used by handler */
3245 };
3246 
3247 typedef void *range_seq_t;
3248 
3249 struct RANGE_SEQ_IF {
3250   /*
3251     Initialize the traversal of range sequence
3252 
3253     SYNOPSIS
3254       init()
3255         init_params  The seq_init_param parameter
3256         n_ranges     The number of ranges obtained
3257         flags        A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
3258 
3259     RETURN
3260       An opaque value to be used as RANGE_SEQ_IF::next() parameter
3261   */
3262   range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
3263 
3264   /*
3265     Get the next range in the range sequence
3266 
3267     SYNOPSIS
3268       next()
3269         seq    The value returned by RANGE_SEQ_IF::init()
3270         range  OUT Information about the next range
3271 
3272     RETURN
3273       0 - Ok, the range structure filled with info about the next range
3274       1 - No more ranges
3275   */
3276   uint (*next)(range_seq_t seq, KEY_MULTI_RANGE *range);
3277 
3278   /*
3279     Check whether range_info orders to skip the next record
3280 
3281     SYNOPSIS
3282       skip_record()
3283         seq         The value returned by RANGE_SEQ_IF::init()
3284         range_info  Information about the next range
3285                     (Ignored if MRR_NO_ASSOCIATION is set)
3286         rowid       Rowid of the record to be checked (ignored if set to 0)
3287 
3288     RETURN
3289       1 - Record with this range_info and/or this rowid shall be filtered
3290           out from the stream of records returned by ha_multi_range_read_next()
3291       0 - The record shall be left in the stream
3292   */
3293   bool (*skip_record)(range_seq_t seq, char *range_info, uchar *rowid);
3294 
3295   /*
3296     Check if the record combination matches the index condition
3297     SYNOPSIS
3298       skip_index_tuple()
3299         seq         The value returned by RANGE_SEQ_IF::init()
3300         range_info  Information about the next range
3301 
3302     RETURN
3303       0 - The record combination satisfies the index condition
3304       1 - Otherwise
3305   */
3306   bool (*skip_index_tuple)(range_seq_t seq, char *range_info);
3307 };
3308 
3309 /**
3310   Used to store optimizer cost estimates.
3311 
3312   The class consists of PODs only: default operator=, copy constructor
3313   and destructor are used.
3314  */
3315 class Cost_estimate {
3316  private:
3317   double io_cost;      ///< cost of I/O operations
3318   double cpu_cost;     ///< cost of CPU operations
3319   double import_cost;  ///< cost of remote operations
3320   double mem_cost;     ///< memory used (bytes)
3321 
3322  public:
Cost_estimate()3323   Cost_estimate() : io_cost(0), cpu_cost(0), import_cost(0), mem_cost(0) {}
3324 
3325   /// Returns sum of time-consuming costs, i.e., not counting memory cost
total_cost()3326   double total_cost() const { return io_cost + cpu_cost + import_cost; }
get_io_cost()3327   double get_io_cost() const { return io_cost; }
get_cpu_cost()3328   double get_cpu_cost() const { return cpu_cost; }
get_import_cost()3329   double get_import_cost() const { return import_cost; }
get_mem_cost()3330   double get_mem_cost() const { return mem_cost; }
3331 
3332   /**
3333     Whether or not all costs in the object are zero
3334 
3335     @return true if all costs are zero, false otherwise
3336   */
is_zero()3337   bool is_zero() const {
3338     return !(io_cost || cpu_cost || import_cost || mem_cost);
3339   }
3340   /**
3341     Whether or not the total cost is the maximal double
3342 
3343     @return true if total cost is the maximal double, false otherwise
3344   */
is_max_cost()3345   bool is_max_cost() const { return io_cost == DBL_MAX; }
3346   /// Reset all costs to zero
reset()3347   void reset() { io_cost = cpu_cost = import_cost = mem_cost = 0; }
3348   /// Set current cost to the maximal double
set_max_cost()3349   void set_max_cost() {
3350     reset();
3351     io_cost = DBL_MAX;
3352   }
3353 
3354   /// Multiply io, cpu and import costs by parameter
multiply(double m)3355   void multiply(double m) {
3356     DBUG_ASSERT(!is_max_cost());
3357 
3358     io_cost *= m;
3359     cpu_cost *= m;
3360     import_cost *= m;
3361     /* Don't multiply mem_cost */
3362   }
3363 
3364   Cost_estimate &operator+=(const Cost_estimate &other) {
3365     DBUG_ASSERT(!is_max_cost() && !other.is_max_cost());
3366 
3367     io_cost += other.io_cost;
3368     cpu_cost += other.cpu_cost;
3369     import_cost += other.import_cost;
3370     mem_cost += other.mem_cost;
3371 
3372     return *this;
3373   }
3374 
3375   Cost_estimate operator+(const Cost_estimate &other) {
3376     Cost_estimate result = *this;
3377     result += other;
3378 
3379     return result;
3380   }
3381 
3382   Cost_estimate operator-(const Cost_estimate &other) {
3383     Cost_estimate result;
3384 
3385     DBUG_ASSERT(!other.is_max_cost());
3386 
3387     result.io_cost = io_cost - other.io_cost;
3388     result.cpu_cost = cpu_cost - other.cpu_cost;
3389     result.import_cost = import_cost - other.import_cost;
3390     result.mem_cost = mem_cost - other.mem_cost;
3391     return result;
3392   }
3393 
3394   bool operator>(const Cost_estimate &other) const {
3395     return total_cost() > other.total_cost() ? true : false;
3396   }
3397 
3398   bool operator<(const Cost_estimate &other) const {
3399     return other > *this ? true : false;
3400   }
3401 
3402   /// Add to IO cost
add_io(double add_io_cost)3403   void add_io(double add_io_cost) {
3404     DBUG_ASSERT(!is_max_cost());
3405     io_cost += add_io_cost;
3406   }
3407 
3408   /// Add to CPU cost
add_cpu(double add_cpu_cost)3409   void add_cpu(double add_cpu_cost) {
3410     DBUG_ASSERT(!is_max_cost());
3411     cpu_cost += add_cpu_cost;
3412   }
3413 
3414   /// Add to import cost
add_import(double add_import_cost)3415   void add_import(double add_import_cost) {
3416     DBUG_ASSERT(!is_max_cost());
3417     import_cost += add_import_cost;
3418   }
3419 
3420   /// Add to memory cost
add_mem(double add_mem_cost)3421   void add_mem(double add_mem_cost) {
3422     DBUG_ASSERT(!is_max_cost());
3423     mem_cost += add_mem_cost;
3424   }
3425 };
3426 
3427 void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
3428                          Cost_estimate *cost);
3429 
3430 /*
3431   The below two are not used (and not handled) in this milestone of this WL
3432   entry because there seems to be no use for them at this stage of
3433   implementation.
3434 */
3435 #define HA_MRR_SINGLE_POINT 1
3436 #define HA_MRR_FIXED_KEY 2
3437 
3438 /*
3439   Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
3440   'range' parameter.
3441 */
3442 #define HA_MRR_NO_ASSOCIATION 4
3443 
3444 /*
3445   The MRR user will provide ranges in key order, and MRR implementation
3446   must return rows in key order.
3447   Passing this flag to multi_read_range_init() may cause the
3448   default MRR handler to be used even if HA_MRR_USE_DEFAULT_IMPL
3449   was not specified.
3450   (If the native MRR impl. can not provide SORTED result)
3451 */
3452 #define HA_MRR_SORTED 8
3453 
3454 /* MRR implementation doesn't have to retrieve full records */
3455 #define HA_MRR_INDEX_ONLY 16
3456 
3457 /*
3458   The passed memory buffer is of maximum possible size, the caller can't
3459   assume larger buffer.
3460 */
3461 #define HA_MRR_LIMITS 32
3462 
3463 /*
3464   Flag set <=> default MRR implementation is used
3465   (The choice is made by **_info[_const]() function which may set this
3466    flag. SQL layer remembers the flag value and then passes it to
3467    multi_read_range_init().
3468 */
3469 #define HA_MRR_USE_DEFAULT_IMPL 64
3470 
3471 /*
3472   Used only as parameter to multi_range_read_info():
3473   Flag set <=> the caller guarantees that the bounds of the scanned ranges
3474   will not have NULL values.
3475 */
3476 #define HA_MRR_NO_NULL_ENDPOINTS 128
3477 
3478 /*
3479   Set by the MRR implementation to signal that it will natively
3480   produced sorted result if multi_range_read_init() is called with
3481   the HA_MRR_SORTED flag - Else multi_range_read_init(HA_MRR_SORTED)
3482   will revert to use the default MRR implementation.
3483 */
3484 #define HA_MRR_SUPPORT_SORTED 256
3485 
3486 class ha_statistics {
3487  public:
3488   ulonglong data_file_length;     /* Length off data file */
3489   ulonglong max_data_file_length; /* Length off data file */
3490   ulonglong index_file_length;
3491   ulonglong max_index_file_length;
3492   ulonglong delete_length; /* Free bytes */
3493   ulonglong auto_increment_value;
3494   /*
3495     The number of records in the table.
3496       0    - means the table has exactly 0 rows
3497     other  - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
3498                the value is the exact number of records in the table
3499              else
3500                it is an estimate
3501   */
3502   ha_rows records;
3503   ha_rows deleted;       /* Deleted records */
3504   ulong mean_rec_length; /* physical reclength */
3505   /* TODO: create_time should be retrieved from the new DD. Remove this. */
3506   time_t create_time; /* When table was created */
3507   ulong check_time;
3508   ulong update_time;
3509   uint block_size; /* index block size */
3510 
3511   /*
3512     number of buffer bytes that native mrr implementation needs,
3513   */
3514   uint mrr_length_per_rec;
3515 
3516   /**
3517     Estimate for how much of the table that is availabe in a memory
3518     buffer. Valid range is [0..1]. If it has the special value
3519     IN_MEMORY_ESTIMATE_UNKNOWN (defined in structs.h), it means that
3520     the storage engine has not supplied any value for it.
3521   */
3522   double table_in_mem_estimate;
3523 
ha_statistics()3524   ha_statistics()
3525       : data_file_length(0),
3526         max_data_file_length(0),
3527         index_file_length(0),
3528         delete_length(0),
3529         auto_increment_value(0),
3530         records(0),
3531         deleted(0),
3532         mean_rec_length(0),
3533         create_time(0),
3534         check_time(0),
3535         update_time(0),
3536         block_size(0),
3537         table_in_mem_estimate(IN_MEMORY_ESTIMATE_UNKNOWN) {}
3538 };
3539 
3540 /**
3541   Calculates length of key.
3542 
3543   Given a key index and a map of key parts return length of buffer used by key
3544   parts.
3545 
3546   @param  table        Table containing the key
3547   @param  key          Key index
3548   @param  keypart_map  which key parts that is used
3549 
3550   @return Length of used key parts.
3551 */
3552 uint calculate_key_len(TABLE *table, uint key, key_part_map keypart_map);
3553 /*
3554   bitmap with first N+1 bits set
3555   (keypart_map for a key prefix of [0..N] keyparts)
3556 */
3557 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
3558 /*
3559   bitmap with first N bits set
3560   (keypart_map for a key prefix of [0..N-1] keyparts)
3561 */
3562 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
3563 
3564 /** Base class to be used by handlers different shares */
3565 class Handler_share {
3566  public:
Handler_share()3567   Handler_share() {}
~Handler_share()3568   virtual ~Handler_share() {}
3569 };
3570 
3571 /**
3572   Wrapper for struct ft_hints.
3573 */
3574 
3575 class Ft_hints {
3576  private:
3577   struct ft_hints hints;
3578 
3579  public:
Ft_hints(uint ft_flags)3580   Ft_hints(uint ft_flags) {
3581     hints.flags = ft_flags;
3582     hints.op_type = FT_OP_UNDEFINED;
3583     hints.op_value = 0.0;
3584     hints.limit = HA_POS_ERROR;
3585   }
3586 
3587   /**
3588     Set comparison operation type and and value for master MATCH function.
3589 
3590      @param type   comparison operation type
3591      @param value  comparison operation value
3592   */
set_hint_op(enum ft_operation type,double value)3593   void set_hint_op(enum ft_operation type, double value) {
3594     hints.op_type = type;
3595     hints.op_value = value;
3596   }
3597 
3598   /**
3599     Set Ft_hints flag.
3600 
3601     @param ft_flag Ft_hints flag
3602   */
set_hint_flag(uint ft_flag)3603   void set_hint_flag(uint ft_flag) { hints.flags |= ft_flag; }
3604 
3605   /**
3606     Set Ft_hints limit.
3607 
3608     @param ft_limit limit
3609   */
set_hint_limit(ha_rows ft_limit)3610   void set_hint_limit(ha_rows ft_limit) { hints.limit = ft_limit; }
3611 
3612   /**
3613     Get Ft_hints limit.
3614 
3615     @return Ft_hints limit
3616   */
get_limit()3617   ha_rows get_limit() { return hints.limit; }
3618 
3619   /**
3620     Get Ft_hints operation value.
3621 
3622     @return operation value
3623   */
get_op_value()3624   double get_op_value() { return hints.op_value; }
3625 
3626   /**
3627     Get Ft_hints operation type.
3628 
3629     @return operation type
3630   */
get_op_type()3631   enum ft_operation get_op_type() { return hints.op_type; }
3632 
3633   /**
3634     Get Ft_hints flags.
3635 
3636     @return Ft_hints flags
3637   */
get_flags()3638   uint get_flags() { return hints.flags; }
3639 
3640   /**
3641      Get ft_hints struct.
3642 
3643      @return pointer to ft_hints struct
3644    */
get_hints()3645   struct ft_hints *get_hints() {
3646     return &hints;
3647   }
3648 };
3649 
3650 /**
3651   The handler class is the interface for dynamically loadable
3652   storage engines. Do not add ifdefs and take care when adding or
3653   changing virtual functions to avoid vtable confusion
3654 
3655   Functions in this class accept and return table columns data. Two data
3656   representation formats are used:
3657   1. TableRecordFormat - Used to pass [partial] table records to/from
3658      storage engine
3659 
3660   2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
3661      storage engine. See opt_range.cc for description of this format.
3662 
3663   TableRecordFormat
3664   =================
3665   [Warning: this description is work in progress and may be incomplete]
3666   The table record is stored in a fixed-size buffer:
3667 
3668     record: null_bytes, column1_data, column2_data, ...
3669 
3670   The offsets of the parts of the buffer are also fixed: every column has
3671   an offset to its column{i}_data, and if it is nullable it also has its own
3672   bit in null_bytes.
3673 
3674   The record buffer only includes data about columns that are marked in the
3675   relevant column set (table->read_set and/or table->write_set, depending on
3676   the situation).
3677   <not-sure>It could be that it is required that null bits of non-present
3678   columns are set to 1</not-sure>
3679 
3680   VARIOUS EXCEPTIONS AND SPECIAL CASES
3681 
3682   If the table has no nullable columns, then null_bytes is still
3683   present, its length is one byte <not-sure> which must be set to 0xFF
3684   at all times. </not-sure>
3685 
3686   If the table has columns of type BIT, then certain bits from those columns
3687   may be stored in null_bytes as well. Grep around for Field_bit for
3688   details.
3689 
3690   For blob columns (see Field_blob), the record buffer stores length of the
3691   data, following by memory pointer to the blob data. The pointer is owned
3692   by the storage engine and is valid until the next operation.
3693 
3694   If a blob column has NULL value, then its length and blob data pointer
3695   must be set to 0.
3696 
3697 
3698   Overview of main modules of the handler API
3699   ===========================================
3700   The overview below was copied from the storage/partition/ha_partition.h when
3701   support for non-native partitioning was removed.
3702 
3703   -------------------------------------------------------------------------
3704   MODULE create/delete handler object
3705   -------------------------------------------------------------------------
3706   Object create/delete method. Normally called when a table object
3707   exists.
3708 
3709   -------------------------------------------------------------------------
3710   MODULE meta data changes
3711   -------------------------------------------------------------------------
3712   Meta data routines to CREATE, DROP, RENAME table are often used at
3713   ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..).
3714 
3715   Methods:
3716     delete_table()
3717     rename_table()
3718     create()
3719     update_create_info()
3720 
3721   -------------------------------------------------------------------------
3722   MODULE open/close object
3723   -------------------------------------------------------------------------
3724   Open and close handler object to ensure all underlying files and
3725   objects allocated and deallocated for query handling is handled
3726   properly.
3727 
3728   A handler object is opened as part of its initialisation and before
3729   being used for normal queries (not before meta-data changes always.
3730   If the object was opened it will also be closed before being deleted.
3731 
3732   Methods:
3733     open()
3734     close()
3735 
3736   -------------------------------------------------------------------------
3737   MODULE start/end statement
3738   -------------------------------------------------------------------------
3739   This module contains methods that are used to understand start/end of
3740   statements, transaction boundaries, and aid for proper concurrency
3741   control.
3742 
3743   Methods:
3744     store_lock()
3745     external_lock()
3746     start_stmt()
3747     lock_count()
3748     unlock_row()
3749     was_semi_consistent_read()
3750     try_semi_consistent_read()
3751 
3752   -------------------------------------------------------------------------
3753   MODULE change record
3754   -------------------------------------------------------------------------
3755   This part of the handler interface is used to change the records
3756   after INSERT, DELETE, UPDATE, REPLACE method calls but also other
3757   special meta-data operations as ALTER TABLE, LOAD DATA, TRUNCATE.
3758 
3759   These methods are used for insert (write_row), update (update_row)
3760   and delete (delete_row). All methods to change data always work on
3761   one row at a time. update_row and delete_row also contains the old
3762   row.
3763   delete_all_rows will delete all rows in the table in one call as a
3764   special optimization for DELETE from table;
3765 
3766   Bulk inserts are supported if all underlying handlers support it.
3767   start_bulk_insert and end_bulk_insert is called before and after a
3768   number of calls to write_row.
3769 
3770   Methods:
3771     write_row()
3772     update_row()
3773     delete_row()
3774     delete_all_rows()
3775     start_bulk_insert()
3776     end_bulk_insert()
3777 
3778   -------------------------------------------------------------------------
3779   MODULE full table scan
3780   -------------------------------------------------------------------------
3781   This module is used for the most basic access method for any table
3782   handler. This is to fetch all data through a full table scan. No
3783   indexes are needed to implement this part.
3784   It contains one method to start the scan (rnd_init) that can also be
3785   called multiple times (typical in a nested loop join). Then proceeding
3786   to the next record (rnd_next) and closing the scan (rnd_end).
3787   To remember a record for later access there is a method (position)
3788   and there is a method used to retrieve the record based on the stored
3789   position.
3790   The position can be a file position, a primary key, a ROWID dependent
3791   on the handler below.
3792 
3793   All functions that retrieve records and are callable through the
3794   handler interface must indicate whether a record is present after the call
3795   or not. Record found is indicated by returning 0 and setting table status
3796   to "has row". Record not found is indicated by returning a non-zero value
3797   and setting table status to "no row".
3798   @see TABLE::set_found_row() and TABLE::set_no_row().
3799   By enforcing these rules in the handler interface, storage handler functions
3800   need not set any status in struct TABLE. These notes also apply to module
3801   index scan, documented below.
3802 
3803   Methods:
3804 
3805     rnd_init()
3806     rnd_end()
3807     rnd_next()
3808     rnd_pos()
3809     rnd_pos_by_record()
3810     position()
3811 
3812   -------------------------------------------------------------------------
3813   MODULE index scan
3814   -------------------------------------------------------------------------
3815   This part of the handler interface is used to perform access through
3816   indexes. The interface is defined as a scan interface but the handler
3817   can also use key lookup if the index is a unique index or a primary
3818   key index.
3819   Index scans are mostly useful for SELECT queries but are an important
3820   part also of UPDATE, DELETE, REPLACE and CREATE TABLE table AS SELECT
3821   and so forth.
3822   Naturally an index is needed for an index scan and indexes can either
3823   be ordered, hash based. Some ordered indexes can return data in order
3824   but not necessarily all of them.
3825   There are many flags that define the behavior of indexes in the
3826   various handlers. These methods are found in the optimizer module.
3827 
3828   index_read is called to start a scan of an index. The find_flag defines
3829   the semantics of the scan. These flags are defined in
3830   include/my_base.h
3831   index_read_idx is the same but also initializes index before calling doing
3832   the same thing as index_read. Thus it is similar to index_init followed
3833   by index_read. This is also how we implement it.
3834 
3835   index_read/index_read_idx does also return the first row. Thus for
3836   key lookups, the index_read will be the only call to the handler in
3837   the index scan.
3838 
3839   index_init initializes an index before using it and index_end does
3840   any end processing needed.
3841 
3842   Methods:
3843     index_read_map()
3844     index_init()
3845     index_end()
3846     index_read_idx_map()
3847     index_next()
3848     index_prev()
3849     index_first()
3850     index_last()
3851     index_next_same()
3852     index_read_last_map()
3853     read_range_first()
3854     read_range_next()
3855 
3856   -------------------------------------------------------------------------
3857   MODULE information calls
3858   -------------------------------------------------------------------------
3859   This calls are used to inform the handler of specifics of the ongoing
3860   scans and other actions. Most of these are used for optimisation
3861   purposes.
3862 
3863   Methods:
3864     info()
3865     get_dynamic_partition_info
3866     extra()
3867     extra_opt()
3868     reset()
3869 
3870   -------------------------------------------------------------------------
3871   MODULE optimizer support
3872   -------------------------------------------------------------------------
3873   NOTE:
3874   One important part of the public handler interface that is not depicted in
3875   the methods is the attribute records which is defined in the base class.
3876   This is looked upon directly and is set by calling info(HA_STATUS_INFO) ?
3877 
3878   Methods:
3879     min_rows_for_estimate()
3880     get_biggest_used_partition()
3881     scan_time()
3882     read_time()
3883     records_in_range()
3884     estimate_rows_upper_bound()
3885     records()
3886 
3887   -------------------------------------------------------------------------
3888   MODULE print messages
3889   -------------------------------------------------------------------------
3890   This module contains various methods that returns text messages for
3891   table types, index type and error messages.
3892 
3893   Methods:
3894     table_type()
3895     get_row_type()
3896     print_error()
3897     get_error_message()
3898 
3899   -------------------------------------------------------------------------
3900   MODULE handler characteristics
3901   -------------------------------------------------------------------------
3902   This module contains a number of methods defining limitations and
3903   characteristics of the handler (see also documentation regarding the
3904   individual flags).
3905 
3906   Methods:
3907     table_flags()
3908     index_flags()
3909     min_of_the_max_uint()
3910     max_supported_record_length()
3911     max_supported_keys()
3912     max_supported_key_parts()
3913     max_supported_key_length()
3914     max_supported_key_part_length()
3915     low_byte_first()
3916     extra_rec_buf_length()
3917     min_record_length(uint options)
3918     primary_key_is_clustered()
3919     ha_key_alg get_default_index_algorithm()
3920     is_index_algorithm_supported()
3921 
3922   -------------------------------------------------------------------------
3923   MODULE compare records
3924   -------------------------------------------------------------------------
3925   cmp_ref checks if two references are the same. For most handlers this is
3926   a simple memcmp of the reference. However some handlers use primary key
3927   as reference and this can be the same even if memcmp says they are
3928   different. This is due to character sets and end spaces and so forth.
3929 
3930   Methods:
3931     cmp_ref()
3932 
3933   -------------------------------------------------------------------------
3934   MODULE auto increment
3935   -------------------------------------------------------------------------
3936   This module is used to handle the support of auto increments.
3937 
3938   This variable in the handler is used as part of the handler interface
3939   It is maintained by the parent handler object and should not be
3940   touched by child handler objects (see handler.cc for its use).
3941 
3942   Methods:
3943     get_auto_increment()
3944     release_auto_increment()
3945 
3946   -------------------------------------------------------------------------
3947   MODULE initialize handler for HANDLER call
3948   -------------------------------------------------------------------------
3949   This method is a special InnoDB method called before a HANDLER query.
3950 
3951   Methods:
3952     init_table_handle_for_HANDLER()
3953 
3954   -------------------------------------------------------------------------
3955   MODULE fulltext index
3956   -------------------------------------------------------------------------
3957   Fulltext index support.
3958 
3959   Methods:
3960     ft_init_ext_with_hints()
3961     ft_init()
3962     ft_init_ext()
3963     ft_read()
3964 
3965   -------------------------------------------------------------------------
3966   MODULE in-place ALTER TABLE
3967   -------------------------------------------------------------------------
3968   Methods for in-place ALTER TABLE support (implemented by InnoDB and NDB).
3969 
3970   Methods:
3971     check_if_supported_inplace_alter()
3972     prepare_inplace_alter_table()
3973     inplace_alter_table()
3974     commit_inplace_alter_table()
3975     notify_table_changed()
3976 
3977   -------------------------------------------------------------------------
3978   MODULE tablespace support
3979   -------------------------------------------------------------------------
3980   Methods:
3981     discard_or_import_tablespace()
3982 
3983   -------------------------------------------------------------------------
3984   MODULE administrative DDL
3985   -------------------------------------------------------------------------
3986   Methods:
3987     optimize()
3988     analyze()
3989     check()
3990     repair()
3991     check_and_repair()
3992     auto_repair()
3993     is_crashed()
3994     check_for_upgrade()
3995     checksum()
3996     assign_to_keycache()
3997 
3998   -------------------------------------------------------------------------
3999   MODULE enable/disable indexes
4000   -------------------------------------------------------------------------
4001   Enable/Disable Indexes are only supported by HEAP and MyISAM.
4002 
4003   Methods:
4004     disable_indexes()
4005     enable_indexes()
4006     indexes_are_disabled()
4007 
4008   -------------------------------------------------------------------------
4009   MODULE append_create_info
4010   -------------------------------------------------------------------------
4011   Only used by MyISAM MERGE tables.
4012 
4013   Methods:
4014     append_create_info()
4015 
4016   -------------------------------------------------------------------------
4017   MODULE partitioning specific handler API
4018   -------------------------------------------------------------------------
4019   Methods:
4020     get_partition_handler()
4021 */
4022 
4023 class handler {
4024   friend class Partition_handler;
4025 
4026  public:
4027   typedef ulonglong Table_flags;
4028 
4029  protected:
4030   TABLE_SHARE *table_share;       /* The table definition */
4031   TABLE *table;                   /* The current open table */
4032   Table_flags cached_table_flags; /* Set on init() and open() */
4033 
4034   ha_rows estimation_rows_to_insert;
4035 
4036  public:
4037   handlerton *ht; /* storage engine of this handler */
4038   /** Pointer to current row */
4039   uchar *ref;
4040   /** Pointer to duplicate row */
4041   uchar *dup_ref;
4042 
4043   ha_statistics stats;
4044 
4045   /* MultiRangeRead-related members: */
4046   range_seq_t mrr_iter;   /* Interator to traverse the range sequence */
4047   RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
4048   HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
4049   uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
4050   /* true <=> source MRR ranges and the output are ordered */
4051   bool mrr_is_output_sorted;
4052 
4053   /* true <=> we're currently traversing a range in mrr_cur_range. */
4054   bool mrr_have_range;
4055   /* Current range (the one we're now returning rows from) */
4056   KEY_MULTI_RANGE mrr_cur_range;
4057 
4058   /*
4059     The direction of the current range or index scan. This is used by
4060     the ICP implementation to determine if it has reached the end
4061     of the current range.
4062   */
4063   enum enum_range_scan_direction { RANGE_SCAN_ASC, RANGE_SCAN_DESC };
4064 
4065  private:
4066   Record_buffer *m_record_buffer = nullptr;  ///< Buffer for multi-row reads.
4067   /*
4068     Storage space for the end range value. Should only be accessed using
4069     the end_range pointer. The content is invalid when end_range is NULL.
4070   */
4071   key_range save_end_range;
4072   enum_range_scan_direction range_scan_direction;
4073   int key_compare_result_on_equal;
4074 
4075   /**
4076     Pointer to the handler of the table in the primary storage engine,
4077     if this handler represents a table in a secondary storage engine.
4078   */
4079   handler *m_primary_handler{nullptr};
4080 
4081  protected:
4082   KEY_PART_INFO *range_key_part;
4083   bool eq_range;
4084   /*
4085     true <=> the engine guarantees that returned records are within the range
4086     being scanned.
4087   */
4088   bool in_range_check_pushed_down;
4089 
4090  public:
4091   /**
4092     End value for a range scan. If this is NULL the range scan has no
4093     end value. Should also be NULL when there is no ongoing range scan.
4094     Used by the read_range() functions and also evaluated by pushed
4095     index conditions.
4096   */
4097   key_range *end_range;
4098   /**
4099     Flag which tells if #end_range contains a virtual generated column.
4100     The content is invalid when #end_range is @c nullptr.
4101   */
4102   bool m_virt_gcol_in_end_range = false;
4103   uint errkey; /* Last dup key */
4104   uint key_used_on_scan;
4105   uint active_index;
4106   /** Length of ref (1-8 or the clustered key length) */
4107   uint ref_length;
4108   FT_INFO *ft_handler;
4109   enum { NONE = 0, INDEX, RND, SAMPLING } inited;
4110   bool implicit_emptied; /* Can be !=0 only if HEAP */
4111   const Item *pushed_cond;
4112 
4113   Item *pushed_idx_cond;
4114   uint pushed_idx_cond_keyno; /* The index which the above condition is for */
4115 
4116   /**
4117     next_insert_id is the next value which should be inserted into the
4118     auto_increment column: in a inserting-multi-row statement (like INSERT
4119     SELECT), for the first row where the autoinc value is not specified by the
4120     statement, get_auto_increment() called and asked to generate a value,
4121     next_insert_id is set to the next value, then for all other rows
4122     next_insert_id is used (and increased each time) without calling
4123     get_auto_increment().
4124   */
4125   ulonglong next_insert_id;
4126   /**
4127     insert id for the current row (*autogenerated*; if not
4128     autogenerated, it's 0).
4129     At first successful insertion, this variable is stored into
4130     THD::first_successful_insert_id_in_cur_stmt.
4131   */
4132   ulonglong insert_id_for_cur_row;
4133   /**
4134     Interval returned by get_auto_increment() and being consumed by the
4135     inserter.
4136   */
4137   Discrete_interval auto_inc_interval_for_cur_row;
4138   /**
4139      Number of reserved auto-increment intervals. Serves as a heuristic
4140      when we have no estimation of how many records the statement will insert:
4141      the more intervals we have reserved, the bigger the next one. Reset in
4142      handler::ha_release_auto_increment().
4143   */
4144   uint auto_inc_intervals_count;
4145 
4146   /**
4147     Instrumented table associated with this handler.
4148   */
4149   PSI_table *m_psi;
4150 
4151   std::mt19937 m_random_number_engine;
4152   double m_sampling_percentage;
4153 
4154  private:
4155   /** Internal state of the batch instrumentation. */
4156   enum batch_mode_t {
4157     /** Batch mode not used. */
4158     PSI_BATCH_MODE_NONE,
4159     /** Batch mode used, before first table io. */
4160     PSI_BATCH_MODE_STARTING,
4161     /** Batch mode used, after first table io. */
4162     PSI_BATCH_MODE_STARTED
4163   };
4164   /**
4165     Batch mode state.
4166     @sa start_psi_batch_mode.
4167     @sa end_psi_batch_mode.
4168   */
4169   batch_mode_t m_psi_batch_mode;
4170   /**
4171     The number of rows in the batch.
4172     @sa start_psi_batch_mode.
4173     @sa end_psi_batch_mode.
4174   */
4175   ulonglong m_psi_numrows;
4176   /**
4177     The current event in a batch.
4178     @sa start_psi_batch_mode.
4179     @sa end_psi_batch_mode.
4180   */
4181   PSI_table_locker *m_psi_locker;
4182   /**
4183     Storage for the event in a batch.
4184     @sa start_psi_batch_mode.
4185     @sa end_psi_batch_mode.
4186   */
4187   PSI_table_locker_state m_psi_locker_state;
4188 
4189  public:
4190   void unbind_psi();
4191   void rebind_psi();
4192   /**
4193     Put the handler in 'batch' mode when collecting
4194     table io instrumented events.
4195     When operating in batch mode:
4196     - a single start event is generated in the performance schema.
4197     - all table io performed between @c start_psi_batch_mode
4198       and @c end_psi_batch_mode is not instrumented:
4199       the number of rows affected is counted instead in @c m_psi_numrows.
4200     - a single end event is generated in the performance schema
4201       when the batch mode ends with @c end_psi_batch_mode.
4202   */
4203   void start_psi_batch_mode();
4204   /** End a batch started with @c start_psi_batch_mode. */
4205   void end_psi_batch_mode();
4206   /**
4207      If a PSI batch was started, turn if off.
4208      @returns true if it was started.
4209   */
end_psi_batch_mode_if_started()4210   bool end_psi_batch_mode_if_started() {
4211     bool rc = m_psi_batch_mode;
4212     if (rc) end_psi_batch_mode();
4213     return rc;
4214   }
4215 
4216  private:
4217   /**
4218     The lock type set by when calling::ha_external_lock(). This is
4219     propagated down to the storage engine. The reason for also storing
4220     it here, is that when doing MRR we need to create/clone a second handler
4221     object. This cloned handler object needs to know about the lock_type used.
4222   */
4223   int m_lock_type;
4224   /**
4225     Pointer where to store/retrieve the Handler_share pointer.
4226     For non partitioned handlers this is &TABLE_SHARE::ha_share.
4227   */
4228   Handler_share **ha_share;
4229 
4230   /**
4231     Some non-virtual ha_* functions, responsible for reading rows,
4232     like ha_rnd_pos(), must ensure that virtual generated columns are
4233     calculated before they return. For that, they should set this
4234     member to true at their start, and check it before they return: if
4235     the member is still true, it means they should calculate; if it's
4236     false, it means the calculation has been done by some called
4237     lower-level function and does not need to be re-done (which is why
4238     we need this status flag: to avoid redundant calculations, for
4239     performance).
4240 
4241     Note that when updating generated fields, the NULL row status in
4242     the underlying TABLE objects matter, so be sure to reset them if needed!
4243   */
4244   bool m_update_generated_read_fields;
4245 
4246   /* Filter row ids to weed out duplicates when multi-valued index is used */
4247   Unique_on_insert *m_unique;
4248 
4249  public:
handler(handlerton * ht_arg,TABLE_SHARE * share_arg)4250   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
4251       : table_share(share_arg),
4252         table(nullptr),
4253         estimation_rows_to_insert(0),
4254         ht(ht_arg),
4255         ref(nullptr),
4256         range_scan_direction(RANGE_SCAN_ASC),
4257         in_range_check_pushed_down(false),
4258         end_range(nullptr),
4259         key_used_on_scan(MAX_KEY),
4260         active_index(MAX_KEY),
4261         ref_length(sizeof(my_off_t)),
4262         ft_handler(nullptr),
4263         inited(NONE),
4264         implicit_emptied(false),
4265         pushed_cond(nullptr),
4266         pushed_idx_cond(nullptr),
4267         pushed_idx_cond_keyno(MAX_KEY),
4268         next_insert_id(0),
4269         insert_id_for_cur_row(0),
4270         auto_inc_intervals_count(0),
4271         m_psi(nullptr),
4272         m_psi_batch_mode(PSI_BATCH_MODE_NONE),
4273         m_psi_numrows(0),
4274         m_psi_locker(nullptr),
4275         m_lock_type(F_UNLCK),
4276         ha_share(nullptr),
4277         m_update_generated_read_fields(false),
4278         m_unique(nullptr) {
4279     DBUG_PRINT("info", ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
4280                         F_UNLCK, F_RDLCK, F_WRLCK));
4281   }
4282 
~handler(void)4283   virtual ~handler(void) {
4284     DBUG_ASSERT(m_psi == nullptr);
4285     DBUG_ASSERT(m_psi_batch_mode == PSI_BATCH_MODE_NONE);
4286     DBUG_ASSERT(m_psi_locker == nullptr);
4287     DBUG_ASSERT(m_lock_type == F_UNLCK);
4288     DBUG_ASSERT(inited == NONE);
4289   }
4290 
4291   /**
4292     Return extra handler specific text for EXPLAIN.
4293   */
explain_extra()4294   virtual std::string explain_extra() const { return ""; }
4295 
4296   /*
4297     @todo reorganize functions, make proper public/protected/private qualifiers
4298   */
4299   virtual handler *clone(const char *name, MEM_ROOT *mem_root);
4300   /** This is called after create to allow us to set up cached variables */
init()4301   void init() { cached_table_flags = table_flags(); }
4302   /* ha_ methods: public wrappers for private virtual API */
4303 
4304   /**
4305     Set a record buffer that the storage engine can use for multi-row reads.
4306     The buffer has to be provided prior to the first read from an index or a
4307     table.
4308 
4309     @param buffer the buffer to use for multi-row reads
4310   */
ha_set_record_buffer(Record_buffer * buffer)4311   void ha_set_record_buffer(Record_buffer *buffer) { m_record_buffer = buffer; }
4312 
4313   /**
4314     Get the record buffer that was set with ha_set_record_buffer().
4315 
4316     @return the buffer to use for multi-row reads, or nullptr if there is none
4317   */
ha_get_record_buffer()4318   Record_buffer *ha_get_record_buffer() const { return m_record_buffer; }
4319 
4320   /**
4321     Does this handler want to get a Record_buffer for multi-row reads
4322     via the ha_set_record_buffer() function? And if so, what is the
4323     maximum number of records to allocate space for in the buffer?
4324 
4325     Storage engines that support using a Record_buffer should override
4326     handler::is_record_buffer_wanted().
4327 
4328     @param[out] max_rows  gets set to the maximum number of records to
4329                           allocate space for in the buffer if the function
4330                           returns true
4331 
4332     @retval true   if the handler would like a Record_buffer
4333     @retval false  if the handler does not want a Record_buffer
4334   */
ha_is_record_buffer_wanted(ha_rows * const max_rows)4335   bool ha_is_record_buffer_wanted(ha_rows *const max_rows) const {
4336     return is_record_buffer_wanted(max_rows);
4337   }
4338 
4339   int ha_open(TABLE *table, const char *name, int mode, int test_if_locked,
4340               const dd::Table *table_def);
4341   int ha_close(void);
4342   int ha_index_init(uint idx, bool sorted);
4343   int ha_index_end();
4344   int ha_rnd_init(bool scan);
4345   int ha_rnd_end();
4346   int ha_rnd_next(uchar *buf);
4347   // See the comment on m_update_generated_read_fields.
4348   int ha_rnd_pos(uchar *buf, uchar *pos);
4349   int ha_index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map,
4350                         enum ha_rkey_function find_flag);
4351   int ha_index_read_last_map(uchar *buf, const uchar *key,
4352                              key_part_map keypart_map);
4353   int ha_index_read_idx_map(uchar *buf, uint index, const uchar *key,
4354                             key_part_map keypart_map,
4355                             enum ha_rkey_function find_flag);
4356   int ha_index_next(uchar *buf);
4357   int ha_index_prev(uchar *buf);
4358   int ha_index_first(uchar *buf);
4359   int ha_index_last(uchar *buf);
4360   int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
4361   int ha_reset();
4362   /* this is necessary in many places, e.g. in HANDLER command */
ha_index_or_rnd_end()4363   int ha_index_or_rnd_end() {
4364     return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
4365   }
4366   /**
4367     The cached_table_flags is set at ha_open and ha_external_lock
4368   */
ha_table_flags()4369   Table_flags ha_table_flags() const { return cached_table_flags; }
4370   /**
4371     These functions represent the public interface to *users* of the
4372     handler class, hence they are *not* virtual. For the inheritance
4373     interface, see the (private) functions write_row(), update_row(),
4374     and delete_row() below.
4375   */
4376   int ha_external_lock(THD *thd, int lock_type);
4377   int ha_write_row(uchar *buf);
4378   /**
4379     Update the current row.
4380 
4381     @param old_data  the old contents of the row
4382     @param new_data  the new contents of the row
4383     @return error status (zero on success, HA_ERR_* error code on error)
4384   */
4385   int ha_update_row(const uchar *old_data, uchar *new_data);
4386   int ha_delete_row(const uchar *buf);
4387   void ha_release_auto_increment();
4388 
4389   int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
4390   /** to be actually called to get 'check()' functionality*/
4391   int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
4392   int ha_repair(THD *thd, HA_CHECK_OPT *check_opt);
4393   void ha_start_bulk_insert(ha_rows rows);
4394   int ha_end_bulk_insert();
4395   int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
4396                          uint *dup_key_found);
4397   int ha_delete_all_rows();
4398   int ha_truncate(dd::Table *table_def);
4399   int ha_optimize(THD *thd, HA_CHECK_OPT *check_opt);
4400   int ha_analyze(THD *thd, HA_CHECK_OPT *check_opt);
4401   bool ha_check_and_repair(THD *thd);
4402   int ha_disable_indexes(uint mode);
4403   int ha_enable_indexes(uint mode);
4404   int ha_discard_or_import_tablespace(bool discard, dd::Table *table_def);
4405   int ha_rename_table(const char *from, const char *to,
4406                       const dd::Table *from_table_def, dd::Table *to_table_def);
4407   int ha_delete_table(const char *name, const dd::Table *table_def);
4408   void ha_drop_table(const char *name);
4409 
4410   int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info,
4411                 dd::Table *table_def);
4412 
4413   int ha_prepare_load_table(const TABLE &table);
4414 
4415   int ha_load_table(const TABLE &table);
4416 
4417   int ha_unload_table(const char *db_name, const char *table_name,
4418                       bool error_if_not_loaded);
4419 
4420   /**
4421     Initializes a parallel scan. It creates a parallel_scan_ctx that has to
4422     be used across all parallel_scan methods. Also, gets the number of
4423     threads that would be spawned for parallel scan.
4424     @param[out] scan_ctx   The parallel scan context.
4425     @param[out] num_threads Number of threads used for the scan.
4426     @return error code
4427     @retval 0 on success
4428   */
parallel_scan_init(void * & scan_ctx MY_ATTRIBUTE ((unused)),size_t & num_threads MY_ATTRIBUTE ((unused)))4429   virtual int parallel_scan_init(void *&scan_ctx MY_ATTRIBUTE((unused)),
4430                                  size_t &num_threads MY_ATTRIBUTE((unused))) {
4431     return (0);
4432   }
4433 
4434   /**
4435     This callback is called by each parallel load thread at the beginning of
4436     the parallel load for the adapter scan.
4437     @param cookie      The cookie for this thread
4438     @param ncols       Number of columns in each row
4439     @param row_len     The size of a row in bytes
4440     @param col_offsets An array of size ncols, where each element represents
4441                        the offset of a column in the row data. The memory of
4442                        this array belongs to the caller and will be free-ed
4443                        after the pload_end_cbk call.
4444     @param null_byte_offsets An array of size ncols, where each element
4445                        represents the offset of a column in the row data. The
4446                        memory of this array belongs to the caller and will be
4447                        free-ed after the pload_end_cbk call.
4448     @param null_bitmasks An array of size ncols, where each element
4449                        represents the bitmask required to get the null bit. The
4450                        memory of this array belongs to the caller and will be
4451                      free-ed after the pload_end_cbk call.
4452   */
4453   using Load_init_cbk = std::function<bool(
4454       void *cookie, ulong ncols, ulong row_len, const ulong *col_offsets,
4455       const ulong *null_byte_offsets, const ulong *null_bitmasks)>;
4456 
4457   /**
4458     This callback is called by each parallel load thread when processing
4459     of rows is required for the adapter scan.
4460     @param[in] cookie       The cookie for this thread
4461     @param[in] nrows        The nrows that are available
4462     @param[in] rowdata      The mysql-in-memory row data buffer. This is a
4463     memory buffer for nrows records. The length of each record is fixed and
4464     communicated via Load_init_cbk
4465     @param[in] partition_id Partition id if it's a partitioned table, else
4466     std::numeric_limits<uint64_t>::max()
4467     @returns true if there is an error, false otherwise.
4468   */
4469   using Load_cbk = std::function<bool(void *cookie, uint nrows, void *rowdata,
4470                                       uint64_t partition_id)>;
4471 
4472   /**
4473     This callback is called by each parallel load thread when processing
4474     of rows has ended for the adapter scan.
4475     @param[in] cookie    The cookie for this thread
4476   */
4477   using Load_end_cbk = std::function<void(void *cookie)>;
4478 
4479   /**
4480     Run the parallel read of data.
4481     @param[in]  scan_ctx Scan context of the parallel read.
4482     @param[in,out] thread_ctxs Caller thread contexts.
4483     @param[in]  init_fn  Callback called by each parallel load
4484                          thread at the beginning of the parallel load.
4485     @param[in]  load_fn  Callback called by each parallel load
4486                          thread when processing of rows is required.
4487     @param[in]  end_fn   Callback called by each parallel load
4488                          thread when processing of rows has ended.
4489     @return error code
4490     @retval 0 on success
4491   */
parallel_scan(void * scan_ctx MY_ATTRIBUTE ((unused)),void ** thread_ctxs MY_ATTRIBUTE ((unused)),Load_init_cbk init_fn MY_ATTRIBUTE ((unused)),Load_cbk load_fn MY_ATTRIBUTE ((unused)),Load_end_cbk end_fn MY_ATTRIBUTE ((unused)))4492   virtual int parallel_scan(void *scan_ctx MY_ATTRIBUTE((unused)),
4493                             void **thread_ctxs MY_ATTRIBUTE((unused)),
4494                             Load_init_cbk init_fn MY_ATTRIBUTE((unused)),
4495                             Load_cbk load_fn MY_ATTRIBUTE((unused)),
4496                             Load_end_cbk end_fn MY_ATTRIBUTE((unused))) {
4497     return (0);
4498   }
4499 
4500   /**
4501     End of the parallel scan.
4502     @param[in]      scan_ctx      A scan context created by parallel_scan_init.
4503   */
parallel_scan_end(void * scan_ctx MY_ATTRIBUTE ((unused)))4504   virtual void parallel_scan_end(void *scan_ctx MY_ATTRIBUTE((unused))) {
4505     return;
4506   }
4507 
4508   /**
4509     Submit a dd::Table object representing a core DD table having
4510     hardcoded data to be filled in by the DDSE. This function can be
4511     used for retrieving the hard coded SE private data for the
4512     mysql.dd_properties table, before creating or opening it, or for
4513     retrieving the hard coded SE private data for a core table,
4514     before creating or opening them.
4515 
4516     @param dd_table [in,out]    A dd::Table object representing
4517                                 a core DD table.
4518     @param reset                Reset counters.
4519 
4520     @retval true                An error occurred.
4521     @retval false               Success - no errors.
4522    */
4523 
4524   bool ha_get_se_private_data(dd::Table *dd_table, bool reset);
4525 
4526   void adjust_next_insert_id_after_explicit_value(ulonglong nr);
4527   int update_auto_increment();
4528   virtual void print_error(int error, myf errflag);
4529   virtual bool get_error_message(int error, String *buf);
4530   uint get_dup_key(int error);
4531   /**
4532     Retrieves the names of the table and the key for which there was a
4533     duplicate entry in the case of HA_ERR_FOREIGN_DUPLICATE_KEY.
4534 
4535     If any of the table or key name is not available this method will return
4536     false and will not change any of child_table_name or child_key_name.
4537 
4538     @param [out] child_table_name    Table name
4539     @param [in] child_table_name_len Table name buffer size
4540     @param [out] child_key_name      Key name
4541     @param [in] child_key_name_len   Key name buffer size
4542 
4543     @retval  true                  table and key names were available
4544                                    and were written into the corresponding
4545                                    out parameters.
4546     @retval  false                 table and key names were not available,
4547                                    the out parameters were not touched.
4548   */
4549   virtual bool get_foreign_dup_key(char *child_table_name,
4550                                    uint child_table_name_len,
4551                                    char *child_key_name,
4552                                    uint child_key_name_len);
4553   /**
4554     Change the internal TABLE_SHARE pointer.
4555 
4556     @param table_arg    TABLE object
4557     @param share        New share to use
4558 
4559     @note Is used in error handling in ha_delete_table.
4560   */
4561 
change_table_ptr(TABLE * table_arg,TABLE_SHARE * share)4562   virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) {
4563     table = table_arg;
4564     table_share = share;
4565   }
get_table_share()4566   const TABLE_SHARE *get_table_share() const { return table_share; }
4567 
4568   /* Estimates calculation */
4569 
4570   /**
4571     @deprecated This function is deprecated and will be removed in a future
4572                 version. Use table_scan_cost() instead.
4573   */
4574 
scan_time()4575   virtual double scan_time() {
4576     return ulonglong2double(stats.data_file_length) / IO_SIZE + 2;
4577   }
4578 
4579   /**
4580     The cost of reading a set of ranges from the table using an index
4581     to access it.
4582 
4583     @deprecated This function is deprecated and will be removed in a future
4584                 version. Use read_cost() instead.
4585 
4586     @param index  The index number.
4587     @param ranges The number of ranges to be read.
4588     @param rows   Total number of rows to be read.
4589 
4590     This method can be used to calculate the total cost of scanning a table
4591     using an index by calling it using read_time(index, 1, table_size).
4592   */
4593 
read_time(uint index MY_ATTRIBUTE ((unused)),uint ranges,ha_rows rows)4594   virtual double read_time(uint index MY_ATTRIBUTE((unused)), uint ranges,
4595                            ha_rows rows) {
4596     return rows2double(ranges + rows);
4597   }
4598 
4599   /**
4600     @deprecated This function is deprecated and will be removed in a future
4601                 version. Use index_scan_cost() instead.
4602   */
4603 
4604   virtual double index_only_read_time(uint keynr, double records);
4605 
4606   /**
4607     Cost estimate for doing a complete table scan.
4608 
4609     @note For this version it is recommended that storage engines continue
4610     to override scan_time() instead of this function.
4611 
4612     @returns the estimated cost
4613   */
4614 
4615   virtual Cost_estimate table_scan_cost();
4616 
4617   /**
4618     Cost estimate for reading a number of ranges from an index.
4619 
4620     The cost estimate will only include the cost of reading data that
4621     is contained in the index. If the records need to be read, use
4622     read_cost() instead.
4623 
4624     @note The ranges parameter is currently ignored and is not taken
4625     into account in the cost estimate.
4626 
4627     @note For this version it is recommended that storage engines continue
4628     to override index_only_read_time() instead of this function.
4629 
4630     @param index  the index number
4631     @param ranges the number of ranges to be read
4632     @param rows   total number of rows to be read
4633 
4634     @returns the estimated cost
4635   */
4636 
4637   virtual Cost_estimate index_scan_cost(uint index, double ranges, double rows);
4638 
4639   /**
4640     Cost estimate for reading a set of ranges from the table using an index
4641     to access it.
4642 
4643     @note For this version it is recommended that storage engines continue
4644     to override read_time() instead of this function.
4645 
4646     @param index  the index number
4647     @param ranges the number of ranges to be read
4648     @param rows   total number of rows to be read
4649 
4650     @returns the estimated cost
4651   */
4652 
4653   virtual Cost_estimate read_cost(uint index, double ranges, double rows);
4654 
4655   /**
4656     Return an estimate on the amount of memory the storage engine will
4657     use for caching data in memory. If this is unknown or the storage
4658     engine does not cache data in memory -1 is returned.
4659   */
get_memory_buffer_size()4660   virtual longlong get_memory_buffer_size() const { return -1; }
4661 
4662   /**
4663     Return an estimate of how much of the table that is currently stored
4664     in main memory.
4665 
4666     This estimate should be the fraction of the table that currently
4667     is available in a main memory buffer. The estimate should be in the
4668     range from 0.0 (nothing in memory) to 1.0 (entire table in memory).
4669 
4670     @return The fraction of the table in main memory buffer
4671   */
4672 
4673   double table_in_memory_estimate() const;
4674 
4675   /**
4676     Return an estimate of how much of the index that is currently stored
4677     in main memory.
4678 
4679     This estimate should be the fraction of the index that currently
4680     is available in a main memory buffer. The estimate should be in the
4681     range from 0.0 (nothing in memory) to 1.0 (entire index in memory).
4682 
4683     @param keyno the index to get an estimate for
4684 
4685     @return The fraction of the index in main memory buffer
4686   */
4687 
4688   double index_in_memory_estimate(uint keyno) const;
4689 
4690   /**
4691     Initialize sampling.
4692 
4693     @param[out] scan_ctx  A scan context created by this method that has to be
4694     used in sample_next
4695     @param[in]  sampling_percentage percentage of records that need to be
4696     sampled
4697     @param[in]  sampling_seed       random seed that the random generator will
4698     use
4699     @param[in]  sampling_method     sampling method to be used; currently only
4700     SYSTEM sampling is supported
4701 
4702     @return 0 for success, else one of the HA_xxx values in case of error.
4703   */
4704   int ha_sample_init(void *&scan_ctx, double sampling_percentage,
4705                      int sampling_seed, enum_sampling_method sampling_method);
4706 
4707   /**
4708     Get the next record for sampling.
4709 
4710     @param[in]  scan_ctx  Scan context of the sampling
4711     @param[in]  buf       buffer to place the read record
4712 
4713     @return 0 for success, else one of the HA_xxx values in case of error.
4714   */
4715   int ha_sample_next(void *scan_ctx, uchar *buf);
4716 
4717   /**
4718     End sampling.
4719 
4720     @param[in] scan_ctx  Scan context of the sampling
4721 
4722     @return 0 for success, else one of the HA_xxx values in case of error.
4723   */
4724   int ha_sample_end(void *scan_ctx);
4725 
4726  private:
4727   int check_collation_compatibility();
4728 
4729   /**
4730     Make a guestimate for how much of a table or index is in a memory
4731     buffer in the case where the storage engine has not provided any
4732     estimate for this.
4733 
4734     @param table_index_size size of the table or index
4735 
4736     @return The fraction of the table or index in main memory buffer
4737   */
4738 
4739   double estimate_in_memory_buffer(ulonglong table_index_size) const;
4740 
4741  public:
4742   virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
4743                                               void *seq_init_param,
4744                                               uint n_ranges, uint *bufsz,
4745                                               uint *flags, Cost_estimate *cost);
4746   virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
4747                                         uint *bufsz, uint *flags,
4748                                         Cost_estimate *cost);
4749   virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
4750                                     uint n_ranges, uint mode,
4751                                     HANDLER_BUFFER *buf);
4752 
4753   int ha_multi_range_read_next(char **range_info);
4754 
4755   int ha_read_range_first(const key_range *start_key, const key_range *end_key,
4756                           bool eq_range, bool sorted);
4757   int ha_read_range_next();
4758 
has_transactions()4759   bool has_transactions() {
4760     return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0;
4761   }
extra_rec_buf_length()4762   virtual uint extra_rec_buf_length() const { return 0; }
4763 
4764   /**
4765     @brief Determine whether an error can be ignored or not.
4766 
4767     @details This method is used to analyze the error to see whether the
4768     error is ignorable or not. Such errors will be reported as warnings
4769     instead of errors for IGNORE statements. This means that the statement
4770     will not abort, but instead continue to the next row.
4771 
4772     HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
4773     same thing as HA_ERR_FOUND_DUP_KEY, but can in some cases lead to
4774     a slightly different error message.
4775 
4776     @param error  error code received from the handler interface (HA_ERR_...)
4777 
4778     @return   whether the error is ignorablel or not
4779       @retval true  the error is ignorable
4780       @retval false the error is not ignorable
4781   */
4782 
4783   virtual bool is_ignorable_error(int error);
4784 
4785   /**
4786     @brief Determine whether an error is fatal or not.
4787 
4788     @details This method is used to analyze the error to see whether the
4789     error is fatal or not. A fatal error is an error that will not be
4790     possible to handle with SP handlers and will not be subject to
4791     retry attempts on the slave.
4792 
4793     @param error  error code received from the handler interface (HA_ERR_...)
4794 
4795     @return   whether the error is fatal or not
4796       @retval true  the error is fatal
4797       @retval false the error is not fatal
4798   */
4799 
4800   virtual bool is_fatal_error(int error);
4801 
4802  protected:
4803   virtual int multi_range_read_next(char **range_info);
4804 
4805   /**
4806     Number of rows in table. If HA_COUNT_ROWS_INSTANT is set, count is
4807     available instantly. Else do a table scan.
4808 
4809     @param num_rows [out]  num_rows number of rows in table.
4810 
4811     @retval 0 for OK, one of the HA_xxx values in case of error.
4812   */
4813   virtual int records(ha_rows *num_rows);
4814 
4815   /**
4816     Number of rows in table counted using the secondary index chosen by
4817     optimizer. See comments in optimize_aggregated_query() .
4818 
4819       @param num_rows [out]  Number of rows in table.
4820       @param index           Index chosen by optimizer for counting.
4821 
4822       @retval 0 for OK, one of the HA_xxx values in case of error.
4823   */
4824   virtual int records_from_index(ha_rows *num_rows, uint index);
4825 
4826  private:
4827   /**
4828     Function will handle the error code from call to records() and
4829     records_from_index().
4830 
4831       @param error     return code from records() and records_from_index().
4832       @param num_rows  Check if it contains HA_POS_ERROR in case error < 0.
4833 
4834       @retval 0 for OK, one of the HA_xxx values in case of error.
4835   */
4836   int handle_records_error(int error, ha_rows *num_rows);
4837 
4838  public:
4839   /**
4840     Wrapper function to call records() in storage engine.
4841 
4842       @param num_rows [out]  Number of rows in table.
4843 
4844       @retval 0 for OK, one of the HA_xxx values in case of error.
4845   */
ha_records(ha_rows * num_rows)4846   int ha_records(ha_rows *num_rows) {
4847     return handle_records_error(records(num_rows), num_rows);
4848   }
4849 
4850   /**
4851     Wrapper function to call records_from_index() in storage engine.
4852 
4853       @param num_rows [out]  Number of rows in table.
4854       @param index           Index chosen by optimizer for counting.
4855 
4856       @retval 0 for OK, one of the HA_xxx values in case of error.
4857   */
ha_records(ha_rows * num_rows,uint index)4858   int ha_records(ha_rows *num_rows, uint index) {
4859     return handle_records_error(records_from_index(num_rows, index), num_rows);
4860   }
4861 
4862   /**
4863     Return upper bound of current number of records in the table
4864     (max. of how many records one will retrieve when doing a full table scan)
4865     If upper bound is not known, HA_POS_ERROR should be returned as a max
4866     possible upper bound.
4867   */
estimate_rows_upper_bound()4868   virtual ha_rows estimate_rows_upper_bound() {
4869     return stats.records + EXTRA_RECORDS;
4870   }
4871 
4872   /**
4873     Get real row type for the table created based on one specified by user,
4874     CREATE TABLE options and SE capabilities.
4875   */
get_real_row_type(const HA_CREATE_INFO * create_info)4876   virtual enum row_type get_real_row_type(
4877       const HA_CREATE_INFO *create_info) const {
4878     return (create_info->table_options & HA_OPTION_COMPRESS_RECORD)
4879                ? ROW_TYPE_COMPRESSED
4880                : ((create_info->table_options & HA_OPTION_PACK_RECORD)
4881                       ? ROW_TYPE_DYNAMIC
4882                       : ROW_TYPE_FIXED);
4883   }
4884 
4885   /**
4886     Get default key algorithm for SE. It is used when user has not provided
4887     algorithm explicitly or when algorithm specified is not supported by SE.
4888   */
get_default_index_algorithm()4889   virtual enum ha_key_alg get_default_index_algorithm() const {
4890     return HA_KEY_ALG_SE_SPECIFIC;
4891   }
4892 
4893   /**
4894     Check if SE supports specific key algorithm.
4895 
4896     @note This method is never used for FULLTEXT or SPATIAL keys.
4897           We rely on handler::ha_table_flags() to check if such keys
4898           are supported.
4899   */
is_index_algorithm_supported(enum ha_key_alg key_alg)4900   virtual bool is_index_algorithm_supported(enum ha_key_alg key_alg) const {
4901     return key_alg == HA_KEY_ALG_SE_SPECIFIC;
4902   }
4903 
4904   /**
4905     Signal that the table->read_set and table->write_set table maps changed
4906     The handler is allowed to set additional bits in the above map in this
4907     call. Normally the handler should ignore all calls until we have done
4908     a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
4909     as there may be several calls to this routine.
4910   */
4911   virtual void column_bitmaps_signal();
get_index(void)4912   uint get_index(void) const { return active_index; }
4913 
4914   /**
4915     @retval  false   Bulk update used by handler
4916     @retval  true    Bulk update not used, normal operation used
4917   */
start_bulk_update()4918   virtual bool start_bulk_update() { return true; }
4919   /**
4920     @retval  false   Bulk delete used by handler
4921     @retval  true    Bulk delete not used, normal operation used
4922   */
start_bulk_delete()4923   virtual bool start_bulk_delete() { return true; }
4924   /**
4925     After this call all outstanding updates must be performed. The number
4926     of duplicate key errors are reported in the duplicate key parameter.
4927     It is allowed to continue to the batched update after this call, the
4928     handler has to wait until end_bulk_update with changing state.
4929 
4930     @param    dup_key_found       Number of duplicate keys found
4931 
4932     @retval  0           Success
4933     @retval  >0          Error code
4934   */
exec_bulk_update(uint * dup_key_found MY_ATTRIBUTE ((unused)))4935   virtual int exec_bulk_update(uint *dup_key_found MY_ATTRIBUTE((unused))) {
4936     DBUG_ASSERT(false);
4937     return HA_ERR_WRONG_COMMAND;
4938   }
4939   /**
4940     Perform any needed clean-up, no outstanding updates are there at the
4941     moment.
4942   */
end_bulk_update()4943   virtual void end_bulk_update() { return; }
4944   /**
4945     Execute all outstanding deletes and close down the bulk delete.
4946 
4947     @retval 0             Success
4948     @retval >0            Error code
4949   */
end_bulk_delete()4950   virtual int end_bulk_delete() {
4951     DBUG_ASSERT(false);
4952     return HA_ERR_WRONG_COMMAND;
4953   }
4954 
4955  protected:
4956   /**
4957      @brief
4958      Positions an index cursor to the index specified in the handle
4959      ('active_index'). Fetches the row if available. If the key value is null,
4960      begin at the first key of the index.
4961      @returns 0 if success (found a record); non-zero if no record.
4962   */
index_read_map(uchar * buf,const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag)4963   virtual int index_read_map(uchar *buf, const uchar *key,
4964                              key_part_map keypart_map,
4965                              enum ha_rkey_function find_flag) {
4966     uint key_len = calculate_key_len(table, active_index, keypart_map);
4967     return index_read(buf, key, key_len, find_flag);
4968   }
4969   /**
4970     Positions an index cursor to the index specified in argument. Fetches
4971     the row if available. If the key value is null, begin at the first key of
4972     the index.
4973     @sa index_read_map()
4974   */
4975   virtual int index_read_idx_map(uchar *buf, uint index, const uchar *key,
4976                                  key_part_map keypart_map,
4977                                  enum ha_rkey_function find_flag);
4978 
4979   /*
4980     These methods are used to jump to next or previous entry in the index
4981     scan. There are also methods to jump to first and last entry.
4982   */
4983   /// @see index_read_map().
index_next(uchar *)4984   virtual int index_next(uchar *) { return HA_ERR_WRONG_COMMAND; }
4985 
4986   /// @see index_read_map().
index_prev(uchar *)4987   virtual int index_prev(uchar *) { return HA_ERR_WRONG_COMMAND; }
4988 
4989   /// @see index_read_map().
index_first(uchar *)4990   virtual int index_first(uchar *) { return HA_ERR_WRONG_COMMAND; }
4991 
4992   /// @see index_read_map().
index_last(uchar *)4993   virtual int index_last(uchar *) { return HA_ERR_WRONG_COMMAND; }
4994 
4995   /// @see index_read_map().
4996   virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
4997   /**
4998     The following functions works like index_read, but it find the last
4999     row with the current key value or prefix.
5000     @see index_read_map().
5001   */
index_read_last_map(uchar * buf,const uchar * key,key_part_map keypart_map)5002   virtual int index_read_last_map(uchar *buf, const uchar *key,
5003                                   key_part_map keypart_map) {
5004     uint key_len = calculate_key_len(table, active_index, keypart_map);
5005     return index_read_last(buf, key, key_len);
5006   }
5007 
5008   virtual int read_range_first(const key_range *start_key,
5009                                const key_range *end_key, bool eq_range,
5010                                bool sorted);
5011   virtual int read_range_next();
5012 
5013  public:
5014   /**
5015     Set the end position for a range scan. This is used for checking
5016     for when to end the range scan and by the ICP code to determine
5017     that the next record is within the current range.
5018 
5019     @param range     The end value for the range scan
5020     @param direction Direction of the range scan
5021   */
5022   void set_end_range(const key_range *range,
5023                      enum_range_scan_direction direction);
5024   int compare_key(key_range *range);
5025   int compare_key_icp(const key_range *range) const;
5026   int compare_key_in_buffer(const uchar *buf) const;
ft_init()5027   virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
ft_end()5028   void ft_end() { ft_handler = nullptr; }
ft_init_ext(uint flags MY_ATTRIBUTE ((unused)),uint inx MY_ATTRIBUTE ((unused)),String * key MY_ATTRIBUTE ((unused)))5029   virtual FT_INFO *ft_init_ext(uint flags MY_ATTRIBUTE((unused)),
5030                                uint inx MY_ATTRIBUTE((unused)),
5031                                String *key MY_ATTRIBUTE((unused))) {
5032     return nullptr;
5033   }
ft_init_ext_with_hints(uint inx,String * key,Ft_hints * hints)5034   virtual FT_INFO *ft_init_ext_with_hints(uint inx, String *key,
5035                                           Ft_hints *hints) {
5036     return ft_init_ext(hints->get_flags(), inx, key);
5037   }
5038   int ha_ft_read(uchar *buf);
5039   int ha_read_first_row(uchar *buf, uint primary_key);
5040 
5041  protected:
5042   /// @see index_read_map().
5043   virtual int rnd_next(uchar *buf) = 0;
5044   /// @see index_read_map().
5045   virtual int rnd_pos(uchar *buf, uchar *pos) = 0;
5046 
ft_read(uchar *)5047   virtual int ft_read(uchar *) { return HA_ERR_WRONG_COMMAND; }
5048 
5049  public:
5050   /**
5051     This function only works for handlers having
5052     HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
5053     It will return the row with the PK given in the record argument.
5054   */
rnd_pos_by_record(uchar * record)5055   virtual int rnd_pos_by_record(uchar *record) {
5056     int error;
5057     DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION);
5058 
5059     error = ha_rnd_init(false);
5060     if (error != 0) return error;
5061 
5062     position(record);
5063     error = ha_rnd_pos(record, ref);
5064 
5065     ha_rnd_end();
5066     return error;
5067   }
5068 
5069   /**
5070     Find number of records in a range.
5071 
5072     Given a starting key, and an ending key estimate the number of rows that
5073     will exist between the two. max_key may be empty which in case determine
5074     if start_key matches any rows. Used by optimizer to calculate cost of
5075     using a particular index.
5076 
5077     @param inx      Index number
5078     @param min_key  Start of range
5079     @param max_key  End of range
5080 
5081     @return Number of rows in range.
5082   */
5083 
records_in_range(uint inx MY_ATTRIBUTE ((unused)),key_range * min_key MY_ATTRIBUTE ((unused)),key_range * max_key MY_ATTRIBUTE ((unused)))5084   virtual ha_rows records_in_range(uint inx MY_ATTRIBUTE((unused)),
5085                                    key_range *min_key MY_ATTRIBUTE((unused)),
5086                                    key_range *max_key MY_ATTRIBUTE((unused))) {
5087     return (ha_rows)10;
5088   }
5089   /*
5090     If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
5091     (reference to the row, aka position, with the primary key given in
5092     the record).
5093     Otherwise it set ref to the current row.
5094   */
5095   virtual void position(const uchar *record) = 0;
5096 
5097   /**
5098     General method to gather info from handler
5099 
5100     ::info() is used to return information to the optimizer.
5101     SHOW also makes use of this data Another note, if your handler
5102     doesn't proved exact record count, you will probably want to
5103     have the following in your code:
5104     if (records < 2)
5105       records = 2;
5106     The reason is that the server will optimize for cases of only a single
5107     record. If in a table scan you don't know the number of records
5108     it will probably be better to set records to two so you can return
5109     as many records as you need.
5110 
5111     Along with records a few more variables you may wish to set are:
5112       records
5113       deleted
5114       data_file_length
5115       index_file_length
5116       delete_length
5117       check_time
5118     Take a look at the public variables in handler.h for more information.
5119     See also my_base.h for a full description.
5120 
5121     @param   flag          Specifies what info is requested
5122   */
5123 
5124   virtual int info(uint flag) = 0;
calculate_key_hash_value(Field ** field_array MY_ATTRIBUTE ((unused)))5125   virtual uint32 calculate_key_hash_value(
5126       Field **field_array MY_ATTRIBUTE((unused))) {
5127     DBUG_ASSERT(0);
5128     return 0;
5129   }
5130   /**
5131     Request storage engine to do an extra operation: enable,disable or run some
5132     functionality.
5133 
5134     @param  operation  the operation to perform
5135 
5136     @returns
5137       0     on success
5138       error otherwise
5139   */
5140   int ha_extra(enum ha_extra_function operation);
5141 
5142  private:
5143   /**
5144     Storage engine specific implementation of ha_extra()
5145 
5146     @param  operation  the operation to perform
5147 
5148     @returns
5149       0     on success
5150       error otherwise
5151   */
extra(enum ha_extra_function operation MY_ATTRIBUTE ((unused)))5152   virtual int extra(enum ha_extra_function operation MY_ATTRIBUTE((unused))) {
5153     return 0;
5154   }
5155 
5156  public:
extra_opt(enum ha_extra_function operation,ulong cache_size MY_ATTRIBUTE ((unused)))5157   virtual int extra_opt(enum ha_extra_function operation,
5158                         ulong cache_size MY_ATTRIBUTE((unused))) {
5159     return extra(operation);
5160   }
5161 
5162   /**
5163     Let storage engine inspect the optimized 'plan' and pick whatever
5164     it like for being pushed down to the engine. (Join, conditions, ..)
5165 
5166     The handler implementation should keep track of what it 'pushed',
5167     such that later calls to the handlers access methods should
5168     activate the pushed (part of) the execution plan on the storage
5169     engines.
5170 
5171     @param  table
5172             Abstract Query Plan 'table' object for the table
5173             being pushed to
5174 
5175     @returns
5176       0     on success
5177       error otherwise
5178   */
engine_push(AQP::Table_access * table MY_ATTRIBUTE ((unused)))5179   virtual int engine_push(AQP::Table_access *table MY_ATTRIBUTE((unused))) {
5180     return 0;
5181   }
5182 
5183   /**
5184     Start read (before write) removal on the current table.
5185     @see HA_READ_BEFORE_WRITE_REMOVAL
5186   */
start_read_removal(void)5187   virtual bool start_read_removal(void) {
5188     DBUG_ASSERT(0);
5189     return false;
5190   }
5191 
5192   /**
5193     End read (before write) removal and return the number of rows
5194     really written
5195     @see HA_READ_BEFORE_WRITE_REMOVAL
5196   */
end_read_removal(void)5197   virtual ha_rows end_read_removal(void) {
5198     DBUG_ASSERT(0);
5199     return (ha_rows)0;
5200   }
5201 
5202   /**
5203     Normally, when running UPDATE or DELETE queries, we need to wait for other
5204     transactions to release their locks on a given row before we can read it and
5205     potentially update it. However, in READ UNCOMMITTED and READ COMMITTED, we
5206     can ignore these locks if we don't intend to modify the row (e.g., because
5207     it failed a WHERE). This is signaled through enabling “semi-consistent
5208     read”, by calling try_semi_consistent_read(true) (and then setting it back
5209     to false after finishing the query).
5210 
5211     If semi-consistent read is enabled, and we are in READ UNCOMMITTED or READ
5212     COMMITTED, the storage engine is permitted to return rows that are locked
5213     and thus un-updatable. If the optimizer doesn't want the row, e.g., because
5214     it got filtered out, it can call unlock_row() as usual. However, if it
5215     intends to update the row, it needs to call was_semi_consistent_read()
5216     before doing so. If was_semi_consistent_read() returns false, the row was
5217     never locked to begin with and can be updated as usual. However, if it
5218     returns 1, it was read optimistically, must be discarded (ie., do not try to
5219     update the row) and must be re-read with locking enabled. The next read call
5220     after was_semi_consistent_read() will automatically re-read the same row,
5221     this time with locking enabled.
5222 
5223     Thus, typical use in an UPDATE scenario would look like this:
5224 
5225         file->try_semi_consistent_read(true);
5226         file->ha_rnd_init(true);
5227         while (file->ha_rnd_next(table->record[0]) == 0) {
5228           if (row is filtered...) {
5229             file->unlock_row();
5230             continue;
5231           }
5232           if (file->was_semi_consistent_read()) {
5233             // Discard the row; next ha_rnd_next() will read it again with
5234             // locking.
5235             continue;
5236           }
5237           // Process row here.
5238         }
5239         file->ha_rnd_end();
5240         file->try_semi_consistent_read(false);
5241 
5242     If the transaction isolation level is REPEATABLE READ or SERIALIZABLE,
5243     enabling this flag has no effect.
5244    */
was_semi_consistent_read()5245   virtual bool was_semi_consistent_read() { return false; }
5246   /**
5247     Tell the engine whether it should avoid unnecessary lock waits.
5248     If yes, in an UPDATE or DELETE, if the row under the cursor was locked
5249     by another transaction, the engine may try an optimistic read of
5250     the last committed row value under the cursor.
5251   */
try_semi_consistent_read(bool)5252   virtual void try_semi_consistent_read(bool) {}
5253 
5254   /**
5255     Unlock last accessed row.
5256 
5257     Record currently processed was not in the result set of the statement
5258     and is thus unlocked. Used for UPDATE and DELETE queries.
5259   */
5260 
unlock_row()5261   virtual void unlock_row() {}
5262 
5263   /**
5264     Start a statement when table is locked
5265 
5266     This method is called instead of external lock when the table is locked
5267     before the statement is executed.
5268 
5269     @param thd                  Thread object.
5270     @param lock_type            Type of external lock.
5271 
5272     @retval   >0                 Error code.
5273     @retval    0                 Success.
5274   */
5275 
start_stmt(THD * thd MY_ATTRIBUTE ((unused)),thr_lock_type lock_type MY_ATTRIBUTE ((unused)))5276   virtual int start_stmt(THD *thd MY_ATTRIBUTE((unused)),
5277                          thr_lock_type lock_type MY_ATTRIBUTE((unused))) {
5278     return 0;
5279   }
5280   virtual void get_auto_increment(ulonglong offset, ulonglong increment,
5281                                   ulonglong nb_desired_values,
5282                                   ulonglong *first_value,
5283                                   ulonglong *nb_reserved_values);
set_next_insert_id(ulonglong id)5284   void set_next_insert_id(ulonglong id) {
5285     DBUG_PRINT("info", ("auto_increment: next value %lu", (ulong)id));
5286     next_insert_id = id;
5287   }
restore_auto_increment(ulonglong prev_insert_id)5288   void restore_auto_increment(ulonglong prev_insert_id) {
5289     /*
5290       Insertion of a row failed, re-use the lastly generated auto_increment
5291       id, for the next row. This is achieved by resetting next_insert_id to
5292       what it was before the failed insertion (that old value is provided by
5293       the caller). If that value was 0, it was the first row of the INSERT;
5294       then if insert_id_for_cur_row contains 0 it means no id was generated
5295       for this first row, so no id was generated since the INSERT started, so
5296       we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
5297       is the generated id of the first and failed row, so we use it.
5298     */
5299     next_insert_id =
5300         (prev_insert_id > 0) ? prev_insert_id : insert_id_for_cur_row;
5301   }
5302 
5303   /**
5304     Update create info as part of ALTER TABLE.
5305 
5306     Forward this handler call to the storage engine foreach
5307     partition handler.  The data_file_name for each partition may
5308     need to be reset if the tablespace was moved.  Use a dummy
5309     HA_CREATE_INFO structure and transfer necessary data.
5310 
5311     @param    create_info         Create info from ALTER TABLE.
5312   */
5313 
update_create_info(HA_CREATE_INFO * create_info MY_ATTRIBUTE ((unused)))5314   virtual void update_create_info(
5315       HA_CREATE_INFO *create_info MY_ATTRIBUTE((unused))) {}
assign_to_keycache(THD *,HA_CHECK_OPT *)5316   virtual int assign_to_keycache(THD *, HA_CHECK_OPT *) {
5317     return HA_ADMIN_NOT_IMPLEMENTED;
5318   }
preload_keys(THD *,HA_CHECK_OPT *)5319   virtual int preload_keys(THD *, HA_CHECK_OPT *) {
5320     return HA_ADMIN_NOT_IMPLEMENTED;
5321   }
5322   /* end of the list of admin commands */
5323 
5324   /**
5325     Check if indexes are disabled.
5326 
5327     @retval   0                         Indexes are enabled.
5328     @retval   != 0                      Indexes are disabled.
5329   */
5330 
indexes_are_disabled(void)5331   virtual int indexes_are_disabled(void) { return 0; }
append_create_info(String * packet MY_ATTRIBUTE ((unused)))5332   virtual void append_create_info(String *packet MY_ATTRIBUTE((unused))) {}
init_table_handle_for_HANDLER()5333   virtual void init_table_handle_for_HANDLER() {
5334     return;
5335   } /* prepare InnoDB for HANDLER */
5336   /** The following can be called without an open handler */
5337   virtual const char *table_type() const = 0;
5338 
5339   virtual ulong index_flags(uint idx, uint part, bool all_parts) const = 0;
5340 
max_record_length()5341   uint max_record_length() const {
5342     return std::min(HA_MAX_REC_LENGTH, max_supported_record_length());
5343   }
max_keys()5344   uint max_keys() const {
5345     return std::min<uint>(MAX_KEY, max_supported_keys());
5346   }
max_key_parts()5347   uint max_key_parts() const {
5348     return std::min(MAX_REF_PARTS, max_supported_key_parts());
5349   }
max_key_length()5350   uint max_key_length() const {
5351     return std::min(MAX_KEY_LENGTH, max_supported_key_length());
5352   }
max_key_part_length(HA_CREATE_INFO * create_info)5353   uint max_key_part_length(HA_CREATE_INFO *create_info) const {
5354     return std::min(MAX_KEY_LENGTH, max_supported_key_part_length(create_info));
5355   }
5356 
max_supported_record_length()5357   virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
max_supported_keys()5358   virtual uint max_supported_keys() const { return 0; }
max_supported_key_parts()5359   virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
max_supported_key_length()5360   virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
max_supported_key_part_length(HA_CREATE_INFO * create_info MY_ATTRIBUTE ((unused)))5361   virtual uint max_supported_key_part_length(
5362       HA_CREATE_INFO *create_info MY_ATTRIBUTE((unused))) const {
5363     return 255;
5364   }
min_record_length(uint options MY_ATTRIBUTE ((unused)))5365   virtual uint min_record_length(uint options MY_ATTRIBUTE((unused))) const {
5366     return 1;
5367   }
5368 
low_byte_first()5369   virtual bool low_byte_first() const { return true; }
checksum()5370   virtual ha_checksum checksum() const { return 0; }
5371 
5372   /**
5373     Check if the table is crashed.
5374 
5375     @retval true  Crashed
5376     @retval false Not crashed
5377   */
5378 
is_crashed()5379   virtual bool is_crashed() const { return false; }
5380 
5381   /**
5382     Check if the table can be automatically repaired.
5383 
5384     @retval true  Can be auto repaired
5385     @retval false Cannot be auto repaired
5386   */
5387 
auto_repair()5388   virtual bool auto_repair() const { return false; }
5389 
5390   /**
5391     Get number of lock objects returned in store_lock.
5392 
5393     Returns the number of store locks needed in call to store lock.
5394     We return number of partitions we will lock multiplied with number of
5395     locks needed by each partition. Assists the above functions in allocating
5396     sufficient space for lock structures.
5397 
5398     @returns Number of locks returned in call to store_lock.
5399 
5400     @note lock_count() can return > 1 if the table is MERGE or partitioned.
5401   */
5402 
lock_count(void)5403   virtual uint lock_count(void) const { return 1; }
5404 
5405   /**
5406     Is not invoked for non-transactional temporary tables.
5407 
5408     @note store_lock() can return more than one lock if the table is MERGE
5409     or partitioned.
5410 
5411     @note that one can NOT rely on table->in_use in store_lock().  It may
5412     refer to a different thread if called from mysql_lock_abort_for_thread().
5413 
5414     @note If the table is MERGE, store_lock() can return less locks
5415     than lock_count() claimed. This can happen when the MERGE children
5416     are not attached when this is called from another thread.
5417 
5418     The idea with handler::store_lock() is the following:
5419 
5420     The statement decided which locks we should need for the table
5421     for updates/deletes/inserts we get WRITE locks, for SELECT... we get
5422     read locks.
5423 
5424     Before adding the lock into the table lock handler (see thr_lock.c)
5425     mysqld calls store lock with the requested locks.  Store lock can now
5426     modify a write lock to a read lock (or some other lock), ignore the
5427     lock (if we don't want to use MySQL table locks at all) or add locks
5428     for many tables (like we do when we are using a MERGE handler).
5429 
5430     In some exceptional cases MySQL may send a request for a TL_IGNORE;
5431     This means that we are requesting the same lock as last time and this
5432     should also be ignored.
5433 
5434     Called from lock.cc by get_lock_data().
5435   */
5436   virtual THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to,
5437                                      enum thr_lock_type lock_type) = 0;
5438 
5439   /**
5440     Check if the primary key is clustered or not.
5441 
5442     @retval true  Primary key (if there is one) is a clustered
5443                   key covering all fields
5444     @retval false otherwise
5445   */
5446 
primary_key_is_clustered()5447   virtual bool primary_key_is_clustered() const { return false; }
5448 
5449   /**
5450     Compare two positions.
5451 
5452     @param   ref1                   First position.
5453     @param   ref2                   Second position.
5454 
5455     @retval  <0                     ref1 < ref2.
5456     @retval  0                      Equal.
5457     @retval  >0                     ref1 > ref2.
5458   */
5459 
cmp_ref(const uchar * ref1,const uchar * ref2)5460   virtual int cmp_ref(const uchar *ref1, const uchar *ref2) const {
5461     return memcmp(ref1, ref2, ref_length);
5462   }
5463 
5464   /*
5465     Condition pushdown to storage engines
5466   */
5467 
5468   /**
5469     Push condition down to the table handler.
5470 
5471     @param  cond          Condition to be pushed. The condition tree
5472                           must not be modified by the caller.
5473     @param  other_tbls_ok Are other tables than than 'this' allowed to
5474                           be referred by the condition terms being pushed.
5475 
5476     @return
5477       The 'remainder' condition that caller must use to filter out records.
5478       NULL means the handler will not return rows that do not match the
5479       passed condition.
5480 
5481     @note
5482     handler->ha_reset() call discard any pushed conditions.
5483     Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
5484     pushed conditions.
5485   */
cond_push(const Item * cond,bool other_tbls_ok MY_ATTRIBUTE ((unused)))5486   virtual const Item *cond_push(const Item *cond,
5487                                 bool other_tbls_ok MY_ATTRIBUTE((unused))) {
5488     DBUG_ASSERT(pushed_cond == nullptr);
5489     return cond;
5490   }
5491 
5492   /**
5493     Push down an index condition to the handler.
5494 
5495     The server will use this method to push down a condition it wants
5496     the handler to evaluate when retrieving records using a specified
5497     index. The pushed index condition will only refer to fields from
5498     this handler that is contained in the index (but it may also refer
5499     to fields in other handlers). Before the handler evaluates the
5500     condition it must read the content of the index entry into the
5501     record buffer.
5502 
5503     The handler is free to decide if and how much of the condition it
5504     will take responsibility for evaluating. Based on this evaluation
5505     it should return the part of the condition it will not evaluate.
5506     If it decides to evaluate the entire condition it should return
5507     NULL. If it decides not to evaluate any part of the condition it
5508     should return a pointer to the same condition as given as argument.
5509 
5510     @param keyno    the index number to evaluate the condition on
5511     @param idx_cond the condition to be evaluated by the handler
5512 
5513     @return The part of the pushed condition that the handler decides
5514             not to evaluate
5515    */
5516 
idx_cond_push(uint keyno MY_ATTRIBUTE ((unused)),Item * idx_cond)5517   virtual Item *idx_cond_push(uint keyno MY_ATTRIBUTE((unused)),
5518                               Item *idx_cond) {
5519     return idx_cond;
5520   }
5521 
5522   /** Reset information about pushed index conditions */
cancel_pushed_idx_cond()5523   virtual void cancel_pushed_idx_cond() {
5524     pushed_idx_cond = nullptr;
5525     pushed_idx_cond_keyno = MAX_KEY;
5526     in_range_check_pushed_down = false;
5527   }
5528 
5529   /**
5530     Reports number of tables included in pushed join which this
5531     handler instance is part of. ==0 -> Not pushed
5532   */
number_of_pushed_joins()5533   virtual uint number_of_pushed_joins() const { return 0; }
5534 
5535   /**
5536     If this handler instance is part of a pushed join sequence
5537     returned TABLE instance being root of the pushed query?
5538   */
member_of_pushed_join()5539   virtual const TABLE *member_of_pushed_join() const { return nullptr; }
5540 
5541   /**
5542     If this handler instance is a child in a pushed join sequence
5543     returned TABLE instance being my parent?
5544   */
parent_of_pushed_join()5545   virtual const TABLE *parent_of_pushed_join() const { return nullptr; }
5546 
5547   /// @returns a map of the tables involved in this pushed join, or 0 if not
5548   ///   part of a pushed join.
tables_in_pushed_join()5549   virtual table_map tables_in_pushed_join() const { return 0; }
5550 
5551   int ha_index_read_pushed(uchar *buf, const uchar *key,
5552                            key_part_map keypart_map);
5553 
5554   int ha_index_next_pushed(uchar *buf);
5555 
5556  protected:
index_read_pushed(uchar *,const uchar *,key_part_map)5557   virtual int index_read_pushed(uchar *, const uchar *, key_part_map) {
5558     return HA_ERR_WRONG_COMMAND;
5559   }
5560 
index_next_pushed(uchar *)5561   virtual int index_next_pushed(uchar *) { return HA_ERR_WRONG_COMMAND; }
5562 
5563  public:
5564   /**
5565     Part of old, deprecated in-place ALTER API.
5566   */
check_if_incompatible_data(HA_CREATE_INFO * create_info MY_ATTRIBUTE ((unused)),uint table_changes MY_ATTRIBUTE ((unused)))5567   virtual bool check_if_incompatible_data(
5568       HA_CREATE_INFO *create_info MY_ATTRIBUTE((unused)),
5569       uint table_changes MY_ATTRIBUTE((unused))) {
5570     return COMPATIBLE_DATA_NO;
5571   }
5572 
5573   /* On-line/in-place/instant ALTER TABLE interface. */
5574 
5575   /*
5576     Here is an outline of on-line/in-place ALTER TABLE execution through
5577     this interface.
5578 
5579     Phase 1 : Initialization
5580     ========================
5581     During this phase we determine which algorithm should be used
5582     for execution of ALTER TABLE and what level concurrency it will
5583     require.
5584 
5585     *) This phase starts by opening the table and preparing description
5586        of the new version of the table.
5587     *) Then we check if it is impossible even in theory to carry out
5588        this ALTER TABLE using the in-place/instant algorithm. For example,
5589        because we need to change storage engine or the user has explicitly
5590        requested usage of the "copy" algorithm.
5591     *) If in-place/instant ALTER TABLE is theoretically possible, we continue
5592        by compiling differences between old and new versions of the table
5593        in the form of HA_ALTER_FLAGS bitmap. We also build a few
5594        auxiliary structures describing requested changes and store
5595        all these data in the Alter_inplace_info object.
5596     *) Then the handler::check_if_supported_inplace_alter() method is called
5597        in order to find if the storage engine can carry out changes requested
5598        by this ALTER TABLE using the in-place or instant algorithm.
5599        To determine this, the engine can rely on data in HA_ALTER_FLAGS/
5600        Alter_inplace_info passed to it as well as on its own checks.
5601        If the in-place algorithm can be used for this ALTER TABLE, the level
5602        of required concurrency for its execution is also returned.
5603        If any errors occur during the handler call, ALTER TABLE is aborted
5604        and no further handler functions are called.
5605        Note that in cases when there is difference between in-place and
5606        instant algorithm and user explicitly asked for usage of in-place
5607        algorithm storage engine MUST return one of values corresponding
5608        to in-place algorithm and not HA_ALTER_INPLACE_INSTANT from this
5609        method.
5610     *) Locking requirements of the in-place algorithm are compared to any
5611        concurrency requirements specified by user. If there is a conflict
5612        between them, we either switch to the copy algorithm or emit an error.
5613 
5614     Phase 2 : Execution
5615     ===================
5616 
5617     In this phase the operations are executed.
5618 
5619     *) As the first step, we acquire a lock corresponding to the concurrency
5620        level which was returned by handler::check_if_supported_inplace_alter()
5621        and requested by the user. This lock is held for most of the
5622        duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
5623        or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an
5624        exclusive lock for duration of the next step only).
5625        For HA_ALTER_INPLACE_INSTANT we keep shared upgradable metadata lock
5626        which was acquired at table open time.
5627     *) After that we call handler::ha_prepare_inplace_alter_table() to give the
5628        storage engine a chance to update its internal structures with a higher
5629        lock level than the one that will be used for the main step of algorithm.
5630        After that we downgrade the lock if it is necessary.
5631        This step should be no-op for instant algorithm.
5632     *) After that, the main step of this phase and algorithm is executed.
5633        We call the handler::ha_inplace_alter_table() method, which carries out
5634        the changes requested by ALTER TABLE but does not makes them visible to
5635        other connections yet.
5636        This step should be no-op for instant algorithm as well.
5637     *) We ensure that no other connection uses the table by upgrading our
5638        lock on it to exclusive.
5639     *) a) If the previous step succeeds,
5640     handler::ha_commit_inplace_alter_table() is called to allow the storage
5641     engine to do any final updates to its structures, to make all earlier
5642     changes durable and visible to other connections.
5643     For instant algorithm this is the step during which SE changes are done.
5644     Engines that support atomic DDL only prepare for the commit during this
5645     step but do not finalize it. Real commit happens later when the whole
5646     statement is committed. Also in some situations statement might be rolled
5647     back after call to commit_inplace_alter_table() for such storage engines.
5648     In the latter special case SE might require call to
5649     handlerton::dict_cache_reset() in order to invalidate its internal table
5650     definition cache after rollback.
5651     b) If we have failed to upgrade lock or any errors have occurred during
5652     the handler functions calls (including commit), we call
5653     handler::ha_commit_inplace_alter_table() to rollback all changes which
5654     were done during previous steps.
5655 
5656     All the above calls to SE are provided with dd::Table objects describing old
5657     and new version of table being altered. Engines which support atomic DDL are
5658     allowed to adjust object corresponding to the new version. During phase 3
5659     these changes are saved to the data-dictionary.
5660 
5661 
5662     Phase 3 : Final
5663     ===============
5664 
5665     In this phase we:
5666 
5667     a) For engines which don't support atomic DDL:
5668 
5669        *) Update the SQL-layer data-dictionary by replacing description of old
5670           version of the table with its new version. This change is immediately
5671           committed.
5672        *) Inform the storage engine about this change by calling the
5673           handler::ha_notify_table_changed() method.
5674        *) Process the RENAME clause by calling handler::ha_rename_table() and
5675           updating the data-dictionary accordingly. Again this change is
5676           immediately committed.
5677        *) Destroy the Alter_inplace_info and handler_ctx objects.
5678 
5679     b) For engines which support atomic DDL:
5680 
5681        *) Update the SQL-layer data-dictionary by replacing description of old
5682           version of the table with its new version.
5683        *) Process the RENAME clause by calling handler::ha_rename_table() and
5684           updating the data-dictionary accordingly.
5685        *) Commit the statement/transaction.
5686        *) Finalize atomic DDL operation by calling handlerton::post_ddl() hook
5687           for the storage engine.
5688        *) Additionally inform the storage engine about completion of ALTER TABLE
5689           for the table by calling the handler::ha_notify_table_changed()
5690     method.
5691        *) Destroy the Alter_inplace_info and handler_ctx objects.
5692   */
5693 
5694   /**
5695      Check if a storage engine supports a particular alter table in-place
5696 
5697      @param    altered_table     TABLE object for new version of table.
5698      @param    ha_alter_info     Structure describing changes to be done
5699                                  by ALTER TABLE and holding data used
5700                                  during in-place alter.
5701 
5702      @retval   HA_ALTER_ERROR                  Unexpected error.
5703      @retval   HA_ALTER_INPLACE_NOT_SUPPORTED  Not supported, must use copy.
5704      @retval   HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
5705      @retval   HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
5706                                                Supported, but requires SNW lock
5707                                                during main phase. Prepare phase
5708                                                requires X lock.
5709      @retval   HA_ALTER_INPLACE_SHARED_LOCK    Supported, but requires SNW lock.
5710      @retval   HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
5711                                                Supported, concurrent
5712      reads/writes allowed. However, prepare phase requires X lock.
5713      @retval   HA_ALTER_INPLACE_NO_LOCK        Supported, concurrent
5714                                                reads/writes allowed.
5715      @retval   HA_ALTER_INPLACE_INSTANT        Instant algorithm is supported.
5716                                                Prepare and main phases are
5717                                                no-op. Changes happen during
5718                                                commit phase and it should be
5719                                                "instant". We keep SU lock,
5720                                                allowing concurrent reads and
5721                                                writes during no-op phases and
5722                                                upgrade it to X lock before
5723                                                commit phase.
5724 
5725      @note The default implementation uses the old in-place ALTER API
5726      to determine if the storage engine supports in-place ALTER or not.
5727 
5728      @note In cases when there is difference between in-place and instant
5729      algorithm and explicit ALGORITHM=INPLACE clause was provided SE MUST
5730      return one of values corresponding to in-place algorithm and not
5731      HA_ALTER_INPLACE_INSTANT from this method.
5732 
5733      @note Called without holding thr_lock.c lock.
5734   */
5735   virtual enum_alter_inplace_result check_if_supported_inplace_alter(
5736       TABLE *altered_table, Alter_inplace_info *ha_alter_info);
5737 
5738   /**
5739      Public functions wrapping the actual handler call.
5740      @see prepare_inplace_alter_table()
5741   */
5742   bool ha_prepare_inplace_alter_table(TABLE *altered_table,
5743                                       Alter_inplace_info *ha_alter_info,
5744                                       const dd::Table *old_table_def,
5745                                       dd::Table *new_table_def);
5746 
5747   /**
5748      Public function wrapping the actual handler call.
5749      @see inplace_alter_table()
5750   */
ha_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info,const dd::Table * old_table_def,dd::Table * new_table_def)5751   bool ha_inplace_alter_table(TABLE *altered_table,
5752                               Alter_inplace_info *ha_alter_info,
5753                               const dd::Table *old_table_def,
5754                               dd::Table *new_table_def) {
5755     return inplace_alter_table(altered_table, ha_alter_info, old_table_def,
5756                                new_table_def);
5757   }
5758 
5759   /**
5760      Public function wrapping the actual handler call.
5761      Allows us to enforce asserts regardless of handler implementation.
5762      @see commit_inplace_alter_table()
5763   */
5764   bool ha_commit_inplace_alter_table(TABLE *altered_table,
5765                                      Alter_inplace_info *ha_alter_info,
5766                                      bool commit,
5767                                      const dd::Table *old_table_def,
5768                                      dd::Table *new_table_def);
5769 
5770   /**
5771      Public function wrapping the actual handler call.
5772 
5773      @see notify_table_changed()
5774   */
ha_notify_table_changed(Alter_inplace_info * ha_alter_info)5775   void ha_notify_table_changed(Alter_inplace_info *ha_alter_info) {
5776     notify_table_changed(ha_alter_info);
5777   }
5778 
5779  protected:
5780   /**
5781      Allows the storage engine to update internal structures with concurrent
5782      writes blocked. If check_if_supported_inplace_alter() returns
5783      HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE or
5784      HA_ALTER_INPLACE_SHARED_AFTER_PREPARE, this function is called with
5785      exclusive lock otherwise the same level of locking as for
5786      inplace_alter_table() will be used.
5787 
5788      @note Should be no-op for instant algorithm.
5789 
5790      @note Storage engines are responsible for reporting any errors by
5791      calling my_error()/print_error()
5792 
5793      @note If this function reports error, commit_inplace_alter_table()
5794      will be called with commit= false.
5795 
5796      @note For partitioning, failing to prepare one partition, means that
5797      commit_inplace_alter_table() will be called to roll back changes for
5798      all partitions. This means that commit_inplace_alter_table() might be
5799      called without prepare_inplace_alter_table() having been called first
5800      for a given partition.
5801 
5802      @param    altered_table     TABLE object for new version of table.
5803      @param    ha_alter_info     Structure describing changes to be done
5804                                  by ALTER TABLE and holding data used
5805                                  during in-place alter.
5806      @param    old_table_def     dd::Table object describing old version of
5807                                  the table.
5808      @param    new_table_def     dd::Table object for the new version of the
5809                                  table. Can be adjusted by this call if SE
5810                                  supports atomic DDL. These changes to the
5811                                  table definition will be persisted in the
5812                                  data-dictionary at statement commit time.
5813 
5814      @retval   true              Error
5815      @retval   false             Success
5816   */
prepare_inplace_alter_table(TABLE * altered_table MY_ATTRIBUTE ((unused)),Alter_inplace_info * ha_alter_info MY_ATTRIBUTE ((unused)),const dd::Table * old_table_def MY_ATTRIBUTE ((unused)),dd::Table * new_table_def MY_ATTRIBUTE ((unused)))5817   virtual bool prepare_inplace_alter_table(
5818       TABLE *altered_table MY_ATTRIBUTE((unused)),
5819       Alter_inplace_info *ha_alter_info MY_ATTRIBUTE((unused)),
5820       const dd::Table *old_table_def MY_ATTRIBUTE((unused)),
5821       dd::Table *new_table_def MY_ATTRIBUTE((unused))) {
5822     return false;
5823   }
5824 
5825   /**
5826      Alter the table structure in-place with operations specified using
5827      HA_ALTER_FLAGS and Alter_inplace_info. The level of concurrency allowed
5828      during this operation depends on the return value from
5829      check_if_supported_inplace_alter().
5830 
5831      @note Should be no-op for instant algorithm.
5832 
5833      @note Storage engines are responsible for reporting any errors by
5834      calling my_error()/print_error()
5835 
5836      @note If this function reports error, commit_inplace_alter_table()
5837      will be called with commit= false.
5838 
5839      @param    altered_table     TABLE object for new version of table.
5840      @param    ha_alter_info     Structure describing changes to be done
5841                                  by ALTER TABLE and holding data used
5842                                  during in-place alter.
5843      @param    old_table_def     dd::Table object describing old version of
5844                                  the table.
5845      @param    new_table_def     dd::Table object for the new version of the
5846                                  table. Can be adjusted by this call if SE
5847                                  supports atomic DDL. These changes to the
5848                                  table definition will be persisted in the
5849                                  data-dictionary at statement commit time.
5850 
5851      @retval   true              Error
5852      @retval   false             Success
5853   */
inplace_alter_table(TABLE * altered_table MY_ATTRIBUTE ((unused)),Alter_inplace_info * ha_alter_info MY_ATTRIBUTE ((unused)),const dd::Table * old_table_def MY_ATTRIBUTE ((unused)),dd::Table * new_table_def MY_ATTRIBUTE ((unused)))5854   virtual bool inplace_alter_table(
5855       TABLE *altered_table MY_ATTRIBUTE((unused)),
5856       Alter_inplace_info *ha_alter_info MY_ATTRIBUTE((unused)),
5857       const dd::Table *old_table_def MY_ATTRIBUTE((unused)),
5858       dd::Table *new_table_def MY_ATTRIBUTE((unused))) {
5859     return false;
5860   }
5861 
5862   /**
5863      Commit or rollback the changes made during prepare_inplace_alter_table()
5864      and inplace_alter_table() inside the storage engine.
5865      Note that in case of rollback the allowed level of concurrency during
5866      this operation will be the same as for inplace_alter_table() and thus
5867      might be higher than during prepare_inplace_alter_table(). (For example,
5868      concurrent writes were blocked during prepare, but might not be during
5869      rollback).
5870 
5871      @note This is the place where SE changes happen for instant algorithm.
5872 
5873      @note For storage engines supporting atomic DDL this method should only
5874      prepare for the commit but do not finalize it. Real commit should happen
5875      later when the whole statement is committed. Also in some situations
5876      statement might be rolled back after call to commit_inplace_alter_table()
5877      for such storage engines. In the latter special case SE might require call
5878      to handlerton::dict_cache_reset() in order to invalidate its internal
5879      table definition cache after rollback.
5880 
5881      @note Storage engines are responsible for reporting any errors by
5882      calling my_error()/print_error()
5883 
5884      @note If this function with commit= true reports error, it will be called
5885      again with commit= false.
5886 
5887      @note In case of partitioning, this function might be called for rollback
5888      without prepare_inplace_alter_table() having been called first.
5889      Also partitioned tables sets ha_alter_info->group_commit_ctx to a NULL
5890      terminated array of the partitions handlers and if all of them are
5891      committed as one, then group_commit_ctx should be set to NULL to indicate
5892      to the partitioning handler that all partitions handlers are committed.
5893      @see prepare_inplace_alter_table().
5894 
5895      @param    altered_table     TABLE object for new version of table.
5896      @param    ha_alter_info     Structure describing changes to be done
5897                                  by ALTER TABLE and holding data used
5898                                  during in-place alter.
5899      @param    commit            True => Commit, False => Rollback.
5900      @param    old_table_def     dd::Table object describing old version of
5901                                  the table.
5902      @param    new_table_def     dd::Table object for the new version of the
5903                                  table. Can be adjusted by this call if SE
5904                                  supports atomic DDL. These changes to the
5905                                  table definition will be persisted in the
5906                                  data-dictionary at statement commit time.
5907 
5908      @retval   true              Error
5909      @retval   false             Success
5910   */
commit_inplace_alter_table(TABLE * altered_table MY_ATTRIBUTE ((unused)),Alter_inplace_info * ha_alter_info MY_ATTRIBUTE ((unused)),bool commit MY_ATTRIBUTE ((unused)),const dd::Table * old_table_def MY_ATTRIBUTE ((unused)),dd::Table * new_table_def MY_ATTRIBUTE ((unused)))5911   virtual bool commit_inplace_alter_table(
5912       TABLE *altered_table MY_ATTRIBUTE((unused)),
5913       Alter_inplace_info *ha_alter_info MY_ATTRIBUTE((unused)),
5914       bool commit MY_ATTRIBUTE((unused)),
5915       const dd::Table *old_table_def MY_ATTRIBUTE((unused)),
5916       dd::Table *new_table_def MY_ATTRIBUTE((unused))) {
5917     /* Nothing to commit/rollback, mark all handlers committed! */
5918     ha_alter_info->group_commit_ctx = nullptr;
5919     return false;
5920   }
5921 
5922   /**
5923      Notify the storage engine that the table definition has been updated.
5924 
5925      @param    ha_alter_info     Structure describing changes done by
5926                                  ALTER TABLE and holding data used
5927                                  during in-place alter.
5928 
5929      @note No errors are allowed during notify_table_changed().
5930 
5931      @note For storage engines supporting atomic DDL this method is invoked
5932            after the whole ALTER TABLE is completed and committed.
5933            Particularly this means that for ALTER TABLE statements with RENAME
5934            clause TABLE/handler object used for invoking this method will be
5935            associated with new table name. If storage engine needs to know
5936            the old schema and table name in this method for some reason it
5937            has to use ha_alter_info object to figure it out.
5938   */
notify_table_changed(Alter_inplace_info * ha_alter_info MY_ATTRIBUTE ((unused)))5939   virtual void notify_table_changed(
5940       Alter_inplace_info *ha_alter_info MY_ATTRIBUTE((unused))) {}
5941 
5942  public:
5943   /* End of On-line/in-place ALTER TABLE interface. */
5944 
5945   /**
5946     use_hidden_primary_key() is called in case of an update/delete when
5947     (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
5948     but we don't have a primary key
5949   */
5950   virtual void use_hidden_primary_key();
5951 
5952  protected:
5953   /* Service methods for use by storage engines. */
5954   void ha_statistic_increment(ulonglong System_status_var::*offset) const;
5955   THD *ha_thd(void) const;
5956 
5957   /**
5958     Acquire the instrumented table information from a table share.
5959     @param share a table share
5960     @return an instrumented table share, or NULL.
5961   */
5962   PSI_table_share *ha_table_share_psi(const TABLE_SHARE *share) const;
5963 
5964   /**
5965     Default rename_table() and delete_table() rename/delete files with a
5966     given name and extensions from handlerton::file_extensions.
5967 
5968     These methods can be overridden, but their default implementation
5969     provide useful functionality.
5970 
5971     @param [in]     from            Path for the old table name.
5972     @param [in]     to              Path for the new table name.
5973     @param [in]     from_table_def  Old version of definition for table
5974                                     being renamed (i.e. prior to rename).
5975     @param [in,out] to_table_def    New version of definition for table
5976                                     being renamed. Storage engines which
5977                                     support atomic DDL (i.e. having
5978                                     HTON_SUPPORTS_ATOMIC_DDL flag set)
5979                                     are allowed to adjust this object.
5980 
5981     @retval   >0               Error.
5982     @retval    0               Success.
5983   */
5984   virtual int rename_table(const char *from, const char *to,
5985                            const dd::Table *from_table_def,
5986                            dd::Table *to_table_def);
5987 
5988   /**
5989     Delete a table.
5990 
5991     Used to delete a table. By the time delete_table() has been called all
5992     opened references to this table will have been closed (and your globally
5993     shared references released. The variable name will just be the name of
5994     the table. You will need to remove any files you have created at this
5995     point. Called for base as well as temporary tables.
5996 
5997     @param    name             Full path of table name.
5998     @param    table_def        dd::Table describing table being deleted
5999                                (can be NULL for temporary tables created
6000                                by optimizer).
6001 
6002     @retval   >0               Error.
6003     @retval    0               Success.
6004   */
6005   virtual int delete_table(const char *name, const dd::Table *table_def);
6006 
6007  private:
6008   /* Private helpers */
6009   void mark_trx_read_write();
6010   /*
6011     Low-level primitives for storage engines.  These should be
6012     overridden by the storage engine class. To call these methods, use
6013     the corresponding 'ha_*' method above.
6014   */
6015 
6016   virtual int open(const char *name, int mode, uint test_if_locked,
6017                    const dd::Table *table_def) = 0;
6018   virtual int close(void) = 0;
index_init(uint idx,bool sorted MY_ATTRIBUTE ((unused)))6019   virtual int index_init(uint idx, bool sorted MY_ATTRIBUTE((unused))) {
6020     active_index = idx;
6021     return 0;
6022   }
index_end()6023   virtual int index_end() {
6024     active_index = MAX_KEY;
6025     return 0;
6026   }
6027   /**
6028     rnd_init() can be called two times without rnd_end() in between
6029     (it only makes sense if scan=1).
6030     then the second call should prepare for the new table scan (e.g
6031     if rnd_init allocates the cursor, second call should position it
6032     to the start of the table, no need to deallocate and allocate it again
6033   */
6034   virtual int rnd_init(bool scan) = 0;
rnd_end()6035   virtual int rnd_end() { return 0; }
6036   /**
6037     Write a row.
6038 
6039     write_row() inserts a row. buf is a byte array of data, normally
6040     record[0].
6041 
6042     You can use the field information to extract the data from the native byte
6043     array type.
6044 
6045     Example of this would be:
6046     for (Field **field=table->field ; *field ; field++)
6047     {
6048       ...
6049     }
6050 
6051     @param buf  Buffer to write from.
6052 
6053     @return Operation status.
6054       @retval    0  Success.
6055       @retval != 0  Error code.
6056   */
write_row(uchar * buf MY_ATTRIBUTE ((unused)))6057   virtual int write_row(uchar *buf MY_ATTRIBUTE((unused))) {
6058     return HA_ERR_WRONG_COMMAND;
6059   }
6060 
6061   /**
6062     Update a single row.
6063 
6064     Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
6065     all columns of the row so MySQL can create an error message. If
6066     the columns required for the error message are not read, the error
6067     message will contain garbage.
6068   */
update_row(const uchar * old_data MY_ATTRIBUTE ((unused)),uchar * new_data MY_ATTRIBUTE ((unused)))6069   virtual int update_row(const uchar *old_data MY_ATTRIBUTE((unused)),
6070                          uchar *new_data MY_ATTRIBUTE((unused))) {
6071     return HA_ERR_WRONG_COMMAND;
6072   }
6073 
delete_row(const uchar * buf MY_ATTRIBUTE ((unused)))6074   virtual int delete_row(const uchar *buf MY_ATTRIBUTE((unused))) {
6075     return HA_ERR_WRONG_COMMAND;
6076   }
6077   /**
6078     Reset state of file to after 'open'.
6079     This function is called after every statement for all tables used
6080     by that statement.
6081   */
reset()6082   virtual int reset() { return 0; }
6083   virtual Table_flags table_flags(void) const = 0;
6084   /**
6085     Is not invoked for non-transactional temporary tables.
6086 
6087     Tells the storage engine that we intend to read or write data
6088     from the table. This call is prefixed with a call to handler::store_lock()
6089     and is invoked only for those handler instances that stored the lock.
6090 
6091     Calls to @c rnd_init / @c index_init are prefixed with this call. When table
6092     IO is complete, we call @code external_lock(F_UNLCK) @endcode.
6093     A storage engine writer should expect that each call to
6094     @code ::external_lock(F_[RD|WR]LOCK @endcode is followed by a call to
6095     @code ::external_lock(F_UNLCK) @endcode. If it is not, it is a bug in MySQL.
6096 
6097     The name and signature originate from the first implementation
6098     in MyISAM, which would call @c fcntl to set/clear an advisory
6099     lock on the data file in this method.
6100 
6101     Originally this method was used to set locks on file level to enable
6102     several MySQL Servers to work on the same data. For transactional
6103     engines it has been "abused" to also mean start and end of statements
6104     to enable proper rollback of statements and transactions. When LOCK
6105     TABLES has been issued the start_stmt method takes over the role of
6106     indicating start of statement but in this case there is no end of
6107     statement indicator(?).
6108 
6109     Called from lock.cc by lock_external() and unlock_external(). Also called
6110     from sql_table.cc by copy_data_between_tables().
6111 
6112     @param   thd          the current thread
6113     @param   lock_type    F_RDLCK, F_WRLCK, F_UNLCK
6114 
6115     @return  non-0 in case of failure, 0 in case of success.
6116     When lock_type is F_UNLCK, the return value is ignored.
6117   */
external_lock(THD * thd MY_ATTRIBUTE ((unused)),int lock_type MY_ATTRIBUTE ((unused)))6118   virtual int external_lock(THD *thd MY_ATTRIBUTE((unused)),
6119                             int lock_type MY_ATTRIBUTE((unused))) {
6120     return 0;
6121   }
release_auto_increment()6122   virtual void release_auto_increment() { return; }
6123   /** admin commands - called from mysql_admin_table */
check_for_upgrade(HA_CHECK_OPT *)6124   virtual int check_for_upgrade(HA_CHECK_OPT *) { return 0; }
check(THD *,HA_CHECK_OPT *)6125   virtual int check(THD *, HA_CHECK_OPT *) { return HA_ADMIN_NOT_IMPLEMENTED; }
6126 
6127   /**
6128      In this method check_opt can be modified
6129      to specify CHECK option to use to call check()
6130      upon the table.
6131   */
repair(THD *,HA_CHECK_OPT *)6132   virtual int repair(THD *, HA_CHECK_OPT *) {
6133     DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR));
6134     return HA_ADMIN_NOT_IMPLEMENTED;
6135   }
start_bulk_insert(ha_rows)6136   virtual void start_bulk_insert(ha_rows) {}
end_bulk_insert()6137   virtual int end_bulk_insert() { return 0; }
6138 
6139   /**
6140     Does this handler want to get a Record_buffer for multi-row reads
6141     via the ha_set_record_buffer() function? And if so, what is the
6142     maximum number of records to allocate space for in the buffer?
6143 
6144     Storage engines that support using a Record_buffer should override
6145     this function and return true for scans that could benefit from a
6146     buffer.
6147 
6148     @param[out] max_rows  gets set to the maximum number of records to
6149                           allocate space for in the buffer if the function
6150                           returns true
6151 
6152     @retval true   if the handler would like a Record_buffer
6153     @retval false  if the handler does not want a Record_buffer
6154   */
is_record_buffer_wanted(ha_rows * const max_rows)6155   virtual bool is_record_buffer_wanted(ha_rows *const max_rows) const {
6156     *max_rows = 0;
6157     return false;
6158   }
6159 
6160   // Set se_private_id and se_private_data during upgrade
upgrade_table(THD * thd MY_ATTRIBUTE ((unused)),const char * dbname MY_ATTRIBUTE ((unused)),const char * table_name MY_ATTRIBUTE ((unused)),dd::Table * dd_table MY_ATTRIBUTE ((unused)))6161   virtual bool upgrade_table(THD *thd MY_ATTRIBUTE((unused)),
6162                              const char *dbname MY_ATTRIBUTE((unused)),
6163                              const char *table_name MY_ATTRIBUTE((unused)),
6164                              dd::Table *dd_table MY_ATTRIBUTE((unused))) {
6165     return false;
6166   }
6167 
6168   /** Initialize sampling.
6169   @param[out] scan_ctx  A scan context created by this method that has to be
6170   used in sample_next
6171   @param[in]  sampling_percentage percentage of records that need to be sampled
6172   @param[in]  sampling_seed       random seed
6173   @param[in]  sampling_method     sampling method to be used; currently only
6174   SYSTEM sampling is supported
6175   @return 0 for success, else failure. */
6176   virtual int sample_init(void *&scan_ctx, double sampling_percentage,
6177                           int sampling_seed,
6178                           enum_sampling_method sampling_method);
6179 
6180   /** Get the next record for sampling.
6181   @param[in] scan_ctx   Scan context of the sampling
6182   @param[in] buf        buffer to place the read record
6183   @return 0 for success, else failure. */
6184   virtual int sample_next(void *scan_ctx, uchar *buf);
6185 
6186   /** End sampling.
6187   @param[in] scan_ctx  Scan context of the sampling
6188   @return 0 for success, else failure. */
6189   virtual int sample_end(void *scan_ctx);
6190 
6191   /**
6192    * Prepares secondary engine for loading a table.
6193    *
6194    * @param table Table opened in primary storage engine. Its read_set tells
6195    * which columns to load.
6196    *
6197    * @return 0 if success, error code otherwise.
6198    */
prepare_load_table(const TABLE & table MY_ATTRIBUTE ((unused)))6199   virtual int prepare_load_table(const TABLE &table MY_ATTRIBUTE((unused))) {
6200     DBUG_ASSERT(false);
6201     return HA_ERR_WRONG_COMMAND;
6202   }
6203 
6204   /**
6205    * Loads a table into its defined secondary storage engine.
6206    *
6207    * @param table Table opened in primary storage engine. Its read_set tells
6208    * which columns to load.
6209    *
6210    * @return 0 if success, error code otherwise.
6211    */
load_table(const TABLE & table MY_ATTRIBUTE ((unused)))6212   virtual int load_table(const TABLE &table MY_ATTRIBUTE((unused))) {
6213     /* purecov: begin inspected */
6214     DBUG_ASSERT(false);
6215     return HA_ERR_WRONG_COMMAND;
6216     /* purecov: end */
6217   }
6218 
6219   /**
6220    * Unloads a table from its defined secondary storage engine.
6221    *
6222    * @param db_name             Database name.
6223    * @param table_name          Table name.
6224    * @param error_if_not_loaded If true, then errors will be reported by this
6225    *                            function. If false, no errors will be reported
6226    *                            (silently fail). This case of false is useful
6227    *                            during DROP TABLE where a failure to unload
6228    *                            should not prevent dropping the whole table.
6229    * @return 0 if success, error code otherwise.
6230    */
unload_table(const char * db_name MY_ATTRIBUTE ((unused)),const char * table_name MY_ATTRIBUTE ((unused)),bool error_if_not_loaded MY_ATTRIBUTE ((unused)))6231   virtual int unload_table(const char *db_name MY_ATTRIBUTE((unused)),
6232                            const char *table_name MY_ATTRIBUTE((unused)),
6233                            bool error_if_not_loaded MY_ATTRIBUTE((unused))) {
6234     /* purecov: begin inspected */
6235     DBUG_ASSERT(false);
6236     return HA_ERR_WRONG_COMMAND;
6237     /* purecov: end */
6238   }
6239 
6240  protected:
index_read(uchar * buf MY_ATTRIBUTE ((unused)),const uchar * key MY_ATTRIBUTE ((unused)),uint key_len MY_ATTRIBUTE ((unused)),enum ha_rkey_function find_flag MY_ATTRIBUTE ((unused)))6241   virtual int index_read(uchar *buf MY_ATTRIBUTE((unused)),
6242                          const uchar *key MY_ATTRIBUTE((unused)),
6243                          uint key_len MY_ATTRIBUTE((unused)),
6244                          enum ha_rkey_function find_flag
6245                              MY_ATTRIBUTE((unused))) {
6246     return HA_ERR_WRONG_COMMAND;
6247   }
index_read_last(uchar * buf MY_ATTRIBUTE ((unused)),const uchar * key MY_ATTRIBUTE ((unused)),uint key_len MY_ATTRIBUTE ((unused)))6248   virtual int index_read_last(uchar *buf MY_ATTRIBUTE((unused)),
6249                               const uchar *key MY_ATTRIBUTE((unused)),
6250                               uint key_len MY_ATTRIBUTE((unused))) {
6251     set_my_errno(HA_ERR_WRONG_COMMAND);
6252     return HA_ERR_WRONG_COMMAND;
6253   }
6254 
6255  public:
6256   /**
6257     This method is similar to update_row, however the handler doesn't need
6258     to execute the updates at this point in time. The handler can be certain
6259     that another call to bulk_update_row will occur OR a call to
6260     exec_bulk_update before the set of updates in this query is concluded.
6261 
6262     Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
6263     all columns of the row so MySQL can create an error message. If
6264     the columns required for the error message are not read, the error
6265     message will contain garbage.
6266 
6267     @param    old_data       Old record
6268     @param    new_data       New record
6269     @param    dup_key_found  Number of duplicate keys found
6270 
6271   */
bulk_update_row(const uchar * old_data MY_ATTRIBUTE ((unused)),uchar * new_data MY_ATTRIBUTE ((unused)),uint * dup_key_found MY_ATTRIBUTE ((unused)))6272   virtual int bulk_update_row(const uchar *old_data MY_ATTRIBUTE((unused)),
6273                               uchar *new_data MY_ATTRIBUTE((unused)),
6274                               uint *dup_key_found MY_ATTRIBUTE((unused))) {
6275     DBUG_ASSERT(false);
6276     return HA_ERR_WRONG_COMMAND;
6277   }
6278   /**
6279     Delete all rows in a table.
6280 
6281     This is called both for cases of truncate and for cases where the
6282     optimizer realizes that all rows will be removed as a result of an
6283     SQL statement.
6284 
6285     If the handler don't support this, then this function will
6286     return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
6287     by one.
6288   */
delete_all_rows()6289   virtual int delete_all_rows() {
6290     set_my_errno(HA_ERR_WRONG_COMMAND);
6291     return HA_ERR_WRONG_COMMAND;
6292   }
6293   /**
6294     Quickly remove all rows from a table.
6295 
6296     @param[in,out]  table_def  dd::Table object for table being truncated.
6297 
6298     @remark This method is responsible for implementing MySQL's TRUNCATE
6299             TABLE statement, which is a DDL operation. As such, a engine
6300             can bypass certain integrity checks and in some cases avoid
6301             fine-grained locking (e.g. row locks) which would normally be
6302             required for a DELETE statement.
6303 
6304     @remark Typically, truncate is not used if it can result in integrity
6305             violation. For example, truncate is not used when a foreign
6306             key references the table, but it might be used if foreign key
6307             checks are disabled.
6308 
6309     @remark Engine is responsible for resetting the auto-increment counter.
6310 
6311     @remark The table is locked in exclusive mode. All open TABLE/handler
6312             instances except the one which is used for truncate() call
6313             are closed.
6314 
6315     @note   It is assumed that transactional storage engines implementing
6316             this method can revert its effects if transaction is rolled
6317             back (e.g. because we failed to write statement to the binary
6318             log).
6319 
6320     @note   Changes to dd::Table object done by this method will be saved
6321             to data-dictionary only if storage engine supports atomic DDL
6322             (i.e. has HTON_SUPPORTS_ATOMIC_DDL flag set).
6323   */
truncate(dd::Table * table_def MY_ATTRIBUTE ((unused)))6324   virtual int truncate(dd::Table *table_def MY_ATTRIBUTE((unused))) {
6325     return HA_ERR_WRONG_COMMAND;
6326   }
optimize(THD *,HA_CHECK_OPT *)6327   virtual int optimize(THD *, HA_CHECK_OPT *) {
6328     return HA_ADMIN_NOT_IMPLEMENTED;
6329   }
analyze(THD *,HA_CHECK_OPT *)6330   virtual int analyze(THD *, HA_CHECK_OPT *) {
6331     return HA_ADMIN_NOT_IMPLEMENTED;
6332   }
6333 
6334   /**
6335     @brief Check and repair the table if necessary.
6336 
6337     @param thd    Thread object
6338 
6339     @retval true  Error/Not supported
6340     @retval false Success
6341 
6342     @note Called if open_table_from_share fails and is_crashed().
6343   */
6344 
check_and_repair(THD * thd MY_ATTRIBUTE ((unused)))6345   virtual bool check_and_repair(THD *thd MY_ATTRIBUTE((unused))) {
6346     return true;
6347   }
6348 
6349   /**
6350     Disable indexes for a while.
6351 
6352     @param    mode                      Mode.
6353 
6354     @retval   0                         Success.
6355     @retval   != 0                      Error.
6356   */
6357 
disable_indexes(uint mode MY_ATTRIBUTE ((unused)))6358   virtual int disable_indexes(uint mode MY_ATTRIBUTE((unused))) {
6359     return HA_ERR_WRONG_COMMAND;
6360   }
6361 
6362   /**
6363     Enable indexes again.
6364 
6365     @param    mode                      Mode.
6366 
6367     @retval   0                         Success.
6368     @retval   != 0                      Error.
6369   */
6370 
enable_indexes(uint mode MY_ATTRIBUTE ((unused)))6371   virtual int enable_indexes(uint mode MY_ATTRIBUTE((unused))) {
6372     return HA_ERR_WRONG_COMMAND;
6373   }
6374 
6375   /**
6376     Discard or import tablespace.
6377 
6378     @param  [in]      discard   Indicates whether this is discard operation.
6379     @param  [in,out]  table_def dd::Table object describing the table
6380                                 in which tablespace needs to be discarded
6381                                 or imported. This object can be adjusted by
6382                                 storage engine if it supports atomic DDL
6383                                 (i.e. has HTON_SUPPORTS_ATOMIC_DDL flag set).
6384                                 These changes will be persisted in the
6385                                 data-dictionary.
6386     @retval   0     Success.
6387     @retval   != 0  Error.
6388   */
6389 
discard_or_import_tablespace(bool discard MY_ATTRIBUTE ((unused)),dd::Table * table_def MY_ATTRIBUTE ((unused)))6390   virtual int discard_or_import_tablespace(bool discard MY_ATTRIBUTE((unused)),
6391                                            dd::Table *table_def
6392                                                MY_ATTRIBUTE((unused))) {
6393     set_my_errno(HA_ERR_WRONG_COMMAND);
6394     return HA_ERR_WRONG_COMMAND;
6395   }
6396 
6397   virtual void drop_table(const char *name);
6398 
6399   /**
6400     Create table (implementation).
6401 
6402     @param  [in]      name      Table name.
6403     @param  [in]      form      TABLE object describing the table to be
6404                                 created.
6405     @param  [in]      info      HA_CREATE_INFO describing table.
6406     @param  [in,out]  table_def dd::Table object describing the table
6407                                 to be created. This object can be
6408                                 adjusted by storage engine if it
6409                                 supports atomic DDL (i.e. has
6410                                 HTON_SUPPORTS_ATOMIC_DDL flag set).
6411                                 These changes will be persisted in the
6412                                 data-dictionary. Can be NULL for
6413                                 temporary tables created by optimizer.
6414 
6415     @retval  0      Success.
6416     @retval  non-0  Error.
6417   */
6418   virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info,
6419                      dd::Table *table_def) = 0;
6420 
get_se_private_data(dd::Table * dd_table MY_ATTRIBUTE ((unused)),bool reset MY_ATTRIBUTE ((unused)))6421   virtual bool get_se_private_data(dd::Table *dd_table MY_ATTRIBUTE((unused)),
6422                                    bool reset MY_ATTRIBUTE((unused))) {
6423     return false;
6424   }
6425 
6426   /**
6427     Adjust definition of table to be created by adding implicit columns
6428     and indexes necessary for the storage engine.
6429 
6430     @param  [in]      create_info   HA_CREATE_INFO describing the table.
6431     @param  [in]      create_list   List of columns in the table.
6432     @param  [in]      key_info      Array of KEY objects describing table
6433                                     indexes.
6434     @param  [in]      key_count     Number of indexes in the table.
6435     @param  [in,out]  table_obj     dd::Table object describing the table
6436                                     to be created. Implicit columns and
6437                                     indexes are to be added to this object.
6438                                     Adjusted table description will be
6439                                     saved into the data-dictionary.
6440 
6441     @retval  0      Success.
6442     @retval  non-0  Error.
6443   */
get_extra_columns_and_keys(const HA_CREATE_INFO * create_info MY_ATTRIBUTE ((unused)),const List<Create_field> * create_list MY_ATTRIBUTE ((unused)),const KEY * key_info MY_ATTRIBUTE ((unused)),uint key_count MY_ATTRIBUTE ((unused)),dd::Table * table_obj MY_ATTRIBUTE ((unused)))6444   virtual int get_extra_columns_and_keys(
6445       const HA_CREATE_INFO *create_info MY_ATTRIBUTE((unused)),
6446       const List<Create_field> *create_list MY_ATTRIBUTE((unused)),
6447       const KEY *key_info MY_ATTRIBUTE((unused)),
6448       uint key_count MY_ATTRIBUTE((unused)),
6449       dd::Table *table_obj MY_ATTRIBUTE((unused))) {
6450     return 0;
6451   }
6452 
set_ha_share_ref(Handler_share ** arg_ha_share)6453   virtual bool set_ha_share_ref(Handler_share **arg_ha_share) {
6454     ha_share = arg_ha_share;
6455     return false;
6456   }
get_lock_type()6457   int get_lock_type() const { return m_lock_type; }
6458 
6459   /**
6460     Callback function that will be called by my_prepare_gcolumn_template
6461     once the table has been opened.
6462   */
6463   typedef void (*my_gcolumn_template_callback_t)(const TABLE *, void *);
6464   static bool my_prepare_gcolumn_template(THD *thd, const char *db_name,
6465                                           const char *table_name,
6466                                           my_gcolumn_template_callback_t myc,
6467                                           void *ib_table);
6468   static bool my_eval_gcolumn_expr_with_open(THD *thd, const char *db_name,
6469                                              const char *table_name,
6470                                              const MY_BITMAP *const fields,
6471                                              uchar *record,
6472                                              const char **mv_data_ptr,
6473                                              ulong *mv_length);
6474 
6475   /**
6476     Callback for computing generated column values.
6477 
6478     Storage engines that need to have virtual column values for a row
6479     can use this function to get the values computed. The storage
6480     engine must have filled in the values for the base columns that
6481     the virtual columns depend on.
6482 
6483     @param         thd    thread handle
6484     @param         table  table object
6485     @param         fields bitmap of field index of evaluated generated
6486                           column
6487     @param[in,out] record buff of base columns generated column depends.
6488                           After calling this function, it will be
6489                           used to return the value of the generated
6490                           columns.
6491     @param[out]           mv_data_ptr When given (not null) and the field
6492                           needs to be calculated is a typed array field, it
6493                           will contain pointer to field's calculated value.
6494     @param[out]           mv_length Length of the data above
6495 
6496     @retval true in case of error
6497     @retval false on success
6498   */
6499   static bool my_eval_gcolumn_expr(THD *thd, TABLE *table,
6500                                    const MY_BITMAP *const fields, uchar *record,
6501                                    const char **mv_data_ptr, ulong *mv_length);
6502 
6503   /* This must be implemented if the handlerton's partition_flags() is set. */
get_partition_handler()6504   virtual Partition_handler *get_partition_handler() { return nullptr; }
6505 
6506   /**
6507   Set se_private_id and se_private_data during upgrade
6508 
6509     @param   thd         Pointer of THD
6510     @param   dbname      Database name
6511     @param   table_name  Table name
6512     @param   dd_table    dd::Table for the table
6513     @param   table_arg   TABLE object for the table.
6514 
6515     @return Operation status
6516       @retval false     Success
6517       @retval true      Error
6518   */
6519 
6520   bool ha_upgrade_table(THD *thd, const char *dbname, const char *table_name,
6521                         dd::Table *dd_table, TABLE *table_arg);
6522 
6523   /**
6524     Store a pointer to the handler of the primary table that
6525     corresponds to the secondary table in this handler.
6526   */
6527   void ha_set_primary_handler(handler *primary_handler);
6528 
6529   /**
6530     Get a pointer to a handler for the table in the primary storage
6531     engine, if this handler is for a table in a secondary storage
6532     engine.
6533   */
ha_get_primary_handler()6534   handler *ha_get_primary_handler() const { return m_primary_handler; }
6535 
6536   /**
6537     Return max limits for a single set of multi-valued keys
6538 
6539     @param[out]  num_keys      number of keys to store
6540     @param[out]  keys_length   total length of keys, bytes
6541   */
ha_mv_key_capacity(uint * num_keys,size_t * keys_length)6542   void ha_mv_key_capacity(uint *num_keys, size_t *keys_length) const {
6543     return mv_key_capacity(num_keys, keys_length);
6544   }
6545 
6546  private:
6547   /**
6548     Engine-specific function for ha_can_store_mv_keys().
6549     Dummy function. SE's overloaded method is used instead.
6550   */
6551   /* purecov: begin inspected */
mv_key_capacity(uint * num_keys,size_t * keys_length)6552   virtual void mv_key_capacity(uint *num_keys, size_t *keys_length) const {
6553     *num_keys = 0;
6554     *keys_length = 0;
6555   }
6556   /* purecov: end */
6557 
6558   /**
6559     Filter duplicate records when multi-valued index is used for retrieval
6560 
6561     @returns
6562       true  duplicate, such row id was already seen
6563       false row id is seen for the first time
6564   */
6565   bool filter_dup_records();
6566 
6567  protected:
6568   Handler_share *get_ha_share_ptr();
6569   void set_ha_share_ptr(Handler_share *arg_ha_share);
6570   void lock_shared_ha_data();
6571   void unlock_shared_ha_data();
6572 
6573   friend class DsMrr_impl;
6574 };
6575 
6576 /**
6577   Function identifies any old data type present in table.
6578 
6579   This function was handler::check_old_types().
6580   Function is not part of SE API. It is now converted to
6581   auxiliary standalone function.
6582 
6583   @param[in]  table    TABLE object
6584   @param[in]  check_temporal_upgrade  Check if temporal upgrade is needed
6585 
6586   @retval 0            ON SUCCESS
6587   @retval error code   ON FAILURE
6588 */
6589 
6590 int check_table_for_old_types(const TABLE *table, bool check_temporal_upgrade);
6591 
6592 /*
6593   A Disk-Sweep MRR interface implementation
6594 
6595   This implementation makes range (and, in the future, 'ref') scans to read
6596   table rows in disk sweeps.
6597 
6598   Currently it is used by MyISAM and InnoDB. Potentially it can be used with
6599   any table handler that has non-clustered indexes and on-disk rows.
6600 */
6601 
6602 class DsMrr_impl {
6603  public:
DsMrr_impl(handler * owner)6604   DsMrr_impl(handler *owner) : h(owner), table(nullptr), h2(nullptr) {}
6605 
~DsMrr_impl()6606   ~DsMrr_impl() {
6607     /*
6608       If ha_reset() has not been called then the h2 dialog might still
6609       exist. This must be closed and deleted (this is the case for
6610       internally created temporary tables).
6611     */
6612     if (h2) reset();
6613     DBUG_ASSERT(h2 == nullptr);
6614   }
6615 
6616  private:
6617   /*
6618     The "owner" handler object (the one that calls dsmrr_XXX functions.
6619     It is used to retrieve full table rows by calling rnd_pos().
6620   */
6621   handler *const h;
6622   TABLE *table; /* Always equal to h->table */
6623 
6624   /* Secondary handler object.  It is used for scanning the index */
6625   handler *h2;
6626 
6627   /* Buffer to store rowids, or (rowid, range_id) pairs */
6628   uchar *rowids_buf;
6629   uchar *rowids_buf_cur;  /* Current position when reading/writing */
6630   uchar *rowids_buf_last; /* When reading: end of used buffer space */
6631   uchar *rowids_buf_end;  /* End of the buffer */
6632 
6633   bool dsmrr_eof; /* true <=> We have reached EOF when reading index tuples */
6634 
6635   /* true <=> need range association, buffer holds {rowid, range_id} pairs */
6636   bool is_mrr_assoc;
6637 
6638   bool use_default_impl; /* true <=> shortcut all calls to default MRR impl */
6639  public:
6640   /**
6641     Initialize the DsMrr_impl object.
6642 
6643     This object is used for both doing default MRR scans and DS-MRR scans.
6644     This function just initializes the object. To do a DS-MRR scan,
6645     this must also be initialized by calling dsmrr_init().
6646 
6647     @param table_arg pointer to the TABLE that owns the handler
6648   */
6649 
init(TABLE * table_arg)6650   void init(TABLE *table_arg) {
6651     DBUG_ASSERT(table_arg != nullptr);
6652     table = table_arg;
6653   }
6654 
6655   int dsmrr_init(RANGE_SEQ_IF *seq_funcs, void *seq_init_param, uint n_ranges,
6656                  uint mode, HANDLER_BUFFER *buf);
6657   void dsmrr_close();
6658 
6659   /**
6660     Resets the DS-MRR object to the state it had after being intialized.
6661 
6662     If there is an open scan then this will be closed.
6663 
6664     This function should be called by handler::ha_reset() which is called
6665     when a statement is completed in order to make the handler object ready
6666     for re-use by a different statement.
6667   */
6668 
6669   void reset();
6670   int dsmrr_fill_buffer();
6671   int dsmrr_next(char **range_info);
6672 
6673   ha_rows dsmrr_info(uint keyno, uint n_ranges, uint keys, uint *bufsz,
6674                      uint *flags, Cost_estimate *cost);
6675 
6676   ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, void *seq_init_param,
6677                            uint n_ranges, uint *bufsz, uint *flags,
6678                            Cost_estimate *cost);
6679 
6680  private:
6681   bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz,
6682                        Cost_estimate *cost);
6683   bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
6684                                uint *buffer_size, Cost_estimate *cost);
6685 };
6686 
6687 /* lookups */
6688 handlerton *ha_default_handlerton(THD *thd);
6689 handlerton *ha_default_temp_handlerton(THD *thd);
6690 /**
6691   Resolve handlerton plugin by name, without checking for "DEFAULT" or
6692   HTON_NOT_USER_SELECTABLE.
6693 
6694   @param thd  Thread context.
6695   @param name Plugin name.
6696 
6697   @return plugin or NULL if not found.
6698 */
6699 plugin_ref ha_resolve_by_name_raw(THD *thd, const LEX_CSTRING &name);
6700 plugin_ref ha_resolve_by_name(THD *thd, const LEX_CSTRING *name,
6701                               bool is_temp_table);
6702 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
6703 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
6704 handler *get_new_handler(TABLE_SHARE *share, bool partitioned, MEM_ROOT *alloc,
6705                          handlerton *db_type);
6706 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
6707                          bool no_substitute, bool report_error);
6708 
6709 /**
6710   Get default handlerton, if handler supplied is null.
6711 
6712   @param thd   Thread context.
6713   @param hton  The handlerton passed.
6714 
6715   @returns pointer to handlerton.
6716 */
get_default_handlerton(THD * thd,handlerton * hton)6717 inline handlerton *get_default_handlerton(THD *thd, handlerton *hton) {
6718   if (!hton) {
6719     hton = ha_checktype(thd, DB_TYPE_UNKNOWN, false, false);
6720     DBUG_ASSERT(hton);
6721   }
6722   return hton;
6723 }
6724 
ha_legacy_type(const handlerton * db_type)6725 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type) {
6726   return (db_type == nullptr) ? DB_TYPE_UNKNOWN : db_type->db_type;
6727 }
6728 
6729 const char *ha_resolve_storage_engine_name(const handlerton *db_type);
6730 
ha_check_storage_engine_flag(const handlerton * db_type,uint32 flag)6731 static inline bool ha_check_storage_engine_flag(const handlerton *db_type,
6732                                                 uint32 flag) {
6733   return db_type == nullptr ? false : (db_type->flags & flag);
6734 }
6735 
6736 /**
6737   Predicate to determine if a storage engine, represented by a handlerton*, is
6738   enabled.
6739   @note "Enabled" in this context refers only the state of the handlerton
6740   object, and does not consider the disabled_storage_engines system variable.
6741   This leads to the very counter-intuitive and confusing situation that it is
6742   possible for a storage engine to be enabled, but at the same time also be
6743   disabled.
6744   */
ha_storage_engine_is_enabled(const handlerton * db_type)6745 inline bool ha_storage_engine_is_enabled(const handlerton *db_type) {
6746   return (db_type && db_type->create) ? (db_type->state == SHOW_OPTION_YES)
6747                                       : false;
6748 }
6749 
6750 /* basic stuff */
6751 int ha_init_errors(void);
6752 int ha_init(void);
6753 void ha_end();
6754 int ha_initialize_handlerton(st_plugin_int *plugin);
6755 int ha_finalize_handlerton(st_plugin_int *plugin);
6756 
6757 TYPELIB *ha_known_exts();
6758 int ha_panic(enum ha_panic_function flag);
6759 void ha_close_connection(THD *thd);
6760 void ha_kill_connection(THD *thd);
6761 /** Invoke handlerton::pre_dd_shutdown() on every storage engine plugin. */
6762 void ha_pre_dd_shutdown(void);
6763 
6764 /**
6765   Flush the log(s) of storage engine(s).
6766 
6767   @param binlog_group_flush true if we got invoked by binlog group
6768   commit during flush stage, false in other cases.
6769   @retval false Succeed
6770   @retval true Error
6771 */
6772 bool ha_flush_logs(bool binlog_group_flush = false);
6773 void ha_drop_database(char *path);
6774 int ha_create_table(THD *thd, const char *path, const char *db,
6775                     const char *table_name, HA_CREATE_INFO *create_info,
6776                     bool update_create_info, bool is_temp_table,
6777                     dd::Table *table_def);
6778 
6779 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
6780                     const char *db, const char *alias,
6781                     const dd::Table *table_def, bool generate_warning);
6782 bool ha_check_reserved_db_name(const char *name);
6783 
6784 /* statistics and info */
6785 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
6786 
6787 typedef bool Log_func(THD *, TABLE *, bool, const uchar *, const uchar *);
6788 
6789 int binlog_log_row(TABLE *table, const uchar *before_record,
6790                    const uchar *after_record, Log_func *log_func);
6791 
6792 /* discovery */
6793 int ha_create_table_from_engine(THD *thd, const char *db, const char *name);
6794 bool ha_check_if_table_exists(THD *thd, const char *db, const char *name,
6795                               bool *exists);
6796 int ha_find_files(THD *thd, const char *db, const char *path, const char *wild,
6797                   bool dir, List<LEX_STRING> *files);
6798 int ha_table_exists_in_engine(THD *thd, const char *db, const char *name);
6799 bool ha_check_if_supported_system_table(handlerton *hton, const char *db,
6800                                         const char *table_name);
6801 bool ha_rm_tmp_tables(THD *thd, List<LEX_STRING> *files);
6802 bool default_rm_tmp_tables(handlerton *hton, THD *thd, List<LEX_STRING> *files);
6803 
6804 /* key cache */
6805 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
6806 int ha_resize_key_cache(KEY_CACHE *key_cache);
6807 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
6808 
6809 /* transactions: interface to handlerton functions */
6810 int ha_start_consistent_snapshot(THD *thd);
6811 int ha_commit_trans(THD *thd, bool all, bool ignore_global_read_lock = false);
6812 int ha_commit_attachable(THD *thd);
6813 int ha_rollback_trans(THD *thd, bool all);
6814 
6815 /* interface to handlerton function to prepare XA transaction */
6816 int ha_xa_prepare(THD *thd);
6817 
6818 /**
6819   recover() step of xa.
6820 
6821   @note
6822     there are three modes of operation:
6823     - automatic recover after a crash
6824     in this case commit_list != 0, tc_heuristic_recover==TC_HEURISTIC_NOT_USED
6825     all xids from commit_list are committed, others are rolled back
6826     - manual (heuristic) recover
6827     in this case commit_list==0, tc_heuristic_recover != TC_HEURISTIC_NOT_USED
6828     DBA has explicitly specified that all prepared transactions should
6829     be committed (or rolled back).
6830     - no recovery (MySQL did not detect a crash)
6831     in this case commit_list==0, tc_heuristic_recover == TC_HEURISTIC_NOT_USED
6832     there should be no prepared transactions in this case.
6833 */
6834 
6835 typedef ulonglong my_xid;  // this line is the same as in log_event.h
6836 int ha_recover(const mem_root_unordered_set<my_xid> *commit_list);
6837 
6838 /**
6839   Perform SE-specific cleanup after recovery of transactions.
6840 
6841   @note SE supporting atomic DDL can use this method to perform
6842         post-DDL actions for DDL statements which were committed
6843         or rolled back during recovery stage.
6844 */
6845 void ha_post_recover();
6846 
6847 /*
6848  transactions: interface to low-level handlerton functions. These are
6849  intended to be used by the transaction coordinators to
6850  commit/prepare/rollback transactions in the engines.
6851 */
6852 int ha_commit_low(THD *thd, bool all, bool run_after_commit = true);
6853 int ha_prepare_low(THD *thd, bool all);
6854 int ha_rollback_low(THD *thd, bool all);
6855 
6856 /* transactions: these functions never call handlerton functions directly */
6857 int ha_enable_transaction(THD *thd, bool on);
6858 
6859 /* savepoints */
6860 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
6861 bool ha_rollback_to_savepoint_can_release_mdl(THD *thd);
6862 int ha_savepoint(THD *thd, SAVEPOINT *sv);
6863 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
6864 
6865 /* these are called by storage engines */
6866 void trans_register_ha(THD *thd, bool all, handlerton *ht,
6867                        const ulonglong *trxid);
6868 
6869 int ha_reset_logs(THD *thd);
6870 int ha_binlog_index_purge_file(THD *thd, const char *file);
6871 void ha_reset_slave(THD *thd);
6872 void ha_binlog_log_query(THD *thd, handlerton *db_type,
6873                          enum_binlog_command binlog_command, const char *query,
6874                          size_t query_length, const char *db,
6875                          const char *table_name);
6876 void ha_acl_notify(THD *thd, class Acl_change_notification *);
6877 void ha_binlog_wait(THD *thd);
6878 
6879 /* It is required by basic binlog features on both MySQL server and libmysqld */
6880 int ha_binlog_end(THD *thd);
6881 
6882 const char *get_canonical_filename(handler *file, const char *path,
6883                                    char *tmp_path);
6884 
6885 const char *table_case_name(const HA_CREATE_INFO *info, const char *name);
6886 
6887 void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag,
6888                         const char *org_table_name);
6889 void print_keydup_error(TABLE *table, KEY *key, myf errflag,
6890                         const char *org_table_name);
6891 
print_keydup_error(TABLE * table,KEY * key,const char * msg,myf errflag)6892 inline void print_keydup_error(TABLE *table, KEY *key, const char *msg,
6893                                myf errflag) {
6894   print_keydup_error(table, key, msg, errflag, nullptr);
6895 }
print_keydup_error(TABLE * table,KEY * key,myf errflag)6896 inline void print_keydup_error(TABLE *table, KEY *key, myf errflag) {
6897   print_keydup_error(table, key, errflag, nullptr);
6898 }
6899 
6900 bool ha_is_storage_engine_disabled(handlerton *se_engine);
6901 
6902 bool ha_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key,
6903                              ha_notification_type notification_type,
6904                              bool *victimized);
6905 bool ha_notify_alter_table(THD *thd, const MDL_key *mdl_key,
6906                            ha_notification_type notification_type);
6907 
6908 std::pair<int, bool> commit_owned_gtids(THD *thd, bool all);
6909 bool set_tx_isolation(THD *thd, enum_tx_isolation tx_isolation, bool one_shot);
6910 bool is_index_access_error(int error);
6911 
6912 /*
6913   This class is used by INFORMATION_SCHEMA.FILES to read SE specific
6914   tablespace dynamic metadata. Some member like m_type and id, is not
6915   really dynamic, but as this information is not stored in data dictionary
6916   in a generic format and still is SE specific Some member like m_type and
6917   id, is not really dynamic, but as this information is not stored in data
6918   dictionary in a generic format and still needs SE specific decision, we
6919   are requesting the same from SE.
6920 */
6921 
6922 class ha_tablespace_statistics {
6923  public:
ha_tablespace_statistics()6924   ha_tablespace_statistics()
6925       : m_id(0),
6926         m_logfile_group_number(-1),
6927         m_free_extents(0),
6928         m_total_extents(0),
6929         m_extent_size(0),
6930         m_initial_size(0),
6931         m_maximum_size(0),
6932         m_autoextend_size(0),
6933         m_version(-1),
6934         m_data_free(0) {}
6935 
6936   ulonglong m_id;
6937   dd::String_type m_type;
6938   dd::String_type m_logfile_group_name;  // NDB only
6939   ulonglong m_logfile_group_number;      // NDB only
6940   ulonglong m_free_extents;
6941   ulonglong m_total_extents;
6942   ulonglong m_extent_size;
6943   ulonglong m_initial_size;
6944   ulonglong m_maximum_size;
6945   ulonglong m_autoextend_size;
6946   ulonglong m_version;           // NDB only
6947   dd::String_type m_row_format;  // NDB only
6948   ulonglong m_data_free;         // InnoDB
6949   dd::String_type m_status;
6950   dd::String_type m_extra;  // NDB only
6951 };
6952 
6953 #endif /* HANDLER_INCLUDED */
6954