1 #ifndef HANDLER_INCLUDED
2 #define HANDLER_INCLUDED
3 /*
4    Copyright (c) 2000, 2019, Oracle and/or its affiliates.
5    Copyright (c) 2009, 2021, MariaDB
6 
7    This program is free software; you can redistribute it and/or
8    modify it under the terms of the GNU General Public License
9    as published by the Free Software Foundation; version 2 of
10    the License.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA
20 */
21 
22 /* Definitions for parameters to do with handler-routines */
23 
24 #ifdef USE_PRAGMA_INTERFACE
25 #pragma interface			/* gcc class implementation */
26 #endif
27 
28 #include "sql_const.h"
29 #include "sql_basic_types.h"
30 #include "mysqld.h"                             /* server_id */
31 #include "sql_plugin.h"        /* plugin_ref, st_plugin_int, plugin */
32 #include "thr_lock.h"          /* thr_lock_type, THR_LOCK_DATA */
33 #include "sql_cache.h"
34 #include "structs.h"                            /* SHOW_COMP_OPTION */
35 #include "sql_array.h"          /* Dynamic_array<> */
36 #include "mdl.h"
37 #include "vers_string.h"
38 
39 #include "sql_analyze_stmt.h" // for Exec_time_tracker
40 
41 #include <my_compare.h>
42 #include <ft_global.h>
43 #include <keycache.h>
44 #include <mysql/psi/mysql_table.h>
45 #include "sql_sequence.h"
46 #include "mem_root_array.h"
47 
48 class Alter_info;
49 class Virtual_column_info;
50 class sequence_definition;
51 class Rowid_filter;
52 class Field_string;
53 class Field_varstring;
54 class Field_blob;
55 class Column_definition;
56 
57 // the following is for checking tables
58 
59 #define HA_ADMIN_ALREADY_DONE	  1
60 #define HA_ADMIN_OK               0
61 #define HA_ADMIN_NOT_IMPLEMENTED -1
62 #define HA_ADMIN_FAILED		 -2
63 #define HA_ADMIN_CORRUPT         -3
64 #define HA_ADMIN_INTERNAL_ERROR  -4
65 #define HA_ADMIN_INVALID         -5
66 #define HA_ADMIN_REJECT          -6
67 #define HA_ADMIN_TRY_ALTER       -7
68 #define HA_ADMIN_WRONG_CHECKSUM  -8
69 #define HA_ADMIN_NOT_BASE_TABLE  -9
70 #define HA_ADMIN_NEEDS_UPGRADE  -10
71 #define HA_ADMIN_NEEDS_ALTER    -11
72 #define HA_ADMIN_NEEDS_CHECK    -12
73 #define HA_ADMIN_COMMIT_ERROR   -13
74 
75 /**
76    Return values for check_if_supported_inplace_alter().
77 
78    @see check_if_supported_inplace_alter() for description of
79    the individual values.
80 */
81 enum enum_alter_inplace_result {
82   HA_ALTER_ERROR,
83   HA_ALTER_INPLACE_COPY_NO_LOCK,
84   HA_ALTER_INPLACE_COPY_LOCK,
85   HA_ALTER_INPLACE_NOCOPY_LOCK,
86   HA_ALTER_INPLACE_NOCOPY_NO_LOCK,
87   HA_ALTER_INPLACE_INSTANT,
88   HA_ALTER_INPLACE_NOT_SUPPORTED,
89   HA_ALTER_INPLACE_EXCLUSIVE_LOCK,
90   HA_ALTER_INPLACE_SHARED_LOCK,
91   HA_ALTER_INPLACE_NO_LOCK
92 };
93 
94 /* Flags for create_partitioning_metadata() */
95 
96 enum chf_create_flags {
97   CHF_CREATE_FLAG,
98   CHF_DELETE_FLAG,
99   CHF_RENAME_FLAG,
100   CHF_INDEX_FLAG
101 };
102 
103 /* Bits in table_flags() to show what database can do */
104 
105 #define HA_NO_TRANSACTIONS     (1ULL << 0) /* Doesn't support transactions */
106 #define HA_PARTIAL_COLUMN_READ (1ULL << 1) /* read may not return all columns */
107 #define HA_TABLE_SCAN_ON_INDEX (1ULL << 2) /* No separate data/index file */
108 /*
109   The following should be set if the following is not true when scanning
110   a table with rnd_next()
111   - We will see all rows (including deleted ones)
112   - Row positions are 'table->s->db_record_offset' apart
113   If this flag is not set, filesort will do a position() call for each matched
114   row to be able to find the row later.
115 */
116 #define HA_REC_NOT_IN_SEQ      (1ULL << 3)
117 #define HA_CAN_GEOMETRY        (1ULL << 4)
118 /*
119   Reading keys in random order is as fast as reading keys in sort order
120   (Used in records.cc to decide if we should use a record cache and by
121   filesort to decide if we should sort key + data or key + pointer-to-row
122 */
123 #define HA_FAST_KEY_READ       (1ULL << 5)
124 /*
125   Set the following flag if we on delete should force all key to be read
126   and on update read all keys that changes
127 */
128 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1ULL << 6)
129 #define HA_NULL_IN_KEY         (1ULL << 7) /* One can have keys with NULL */
130 #define HA_DUPLICATE_POS       (1ULL << 8)    /* ha_position() gives dup row */
131 #define HA_NO_BLOBS            (1ULL << 9) /* Doesn't support blobs */
132 #define HA_CAN_INDEX_BLOBS     (1ULL << 10)
133 #define HA_AUTO_PART_KEY       (1ULL << 11) /* auto-increment in multi-part key */
134 /*
135   The engine requires every table to have a user-specified PRIMARY KEY.
136   Do not set the flag if the engine can generate a hidden primary key internally.
137   This flag is ignored if a SEQUENCE is created (which, in turn, needs
138   HA_CAN_TABLES_WITHOUT_ROLLBACK flag)
139 */
140 #define HA_REQUIRE_PRIMARY_KEY (1ULL << 12)
141 #define HA_STATS_RECORDS_IS_EXACT (1ULL << 13) /* stats.records is exact */
142 /*
143   INSERT_DELAYED only works with handlers that uses MySQL internal table
144   level locks
145 */
146 #define HA_CAN_INSERT_DELAYED  (1ULL << 14)
147 /*
148   If we get the primary key columns for free when we do an index read
149   (usually, it also implies that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
150   flag is set).
151 */
152 #define HA_PRIMARY_KEY_IN_READ_INDEX (1ULL << 15)
153 /*
154   If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
155   uses a primary key given by the record argument.
156   Without primary key, we can't call position().
157   If not set, the position is returned as the current rows position
158   regardless of what argument is given.
159 */
160 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1ULL << 16)
161 #define HA_CAN_RTREEKEYS       (1ULL << 17)
162 #define HA_NOT_DELETE_WITH_CACHE (1ULL << 18) /* unused */
163 /*
164   The following is we need to a primary key to delete (and update) a row.
165   If there is no primary key, all columns needs to be read on update and delete
166 */
167 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1ULL << 19)
168 #define HA_NO_PREFIX_CHAR_KEYS (1ULL << 20)
169 #define HA_CAN_FULLTEXT        (1ULL << 21)
170 #define HA_CAN_SQL_HANDLER     (1ULL << 22)
171 #define HA_NO_AUTO_INCREMENT   (1ULL << 23)
172 /* Has automatic checksums and uses the old checksum format */
173 #define HA_HAS_OLD_CHECKSUM    (1ULL << 24)
174 /* Table data are stored in separate files (for lower_case_table_names) */
175 #define HA_FILE_BASED	       (1ULL << 26)
176 #define HA_CAN_BIT_FIELD       (1ULL << 28) /* supports bit fields */
177 #define HA_NEED_READ_RANGE_BUFFER (1ULL << 29) /* for read_multi_range */
178 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1ULL << 30)
179 #define HA_NO_COPY_ON_ALTER    (1ULL << 31)
180 #define HA_HAS_RECORDS	       (1ULL << 32) /* records() gives exact count*/
181 /* Has it's own method of binlog logging */
182 #define HA_HAS_OWN_BINLOGGING  (1ULL << 33)
183 /*
184   Engine is capable of row-format and statement-format logging,
185   respectively
186 */
187 #define HA_BINLOG_ROW_CAPABLE  (1ULL << 34)
188 #define HA_BINLOG_STMT_CAPABLE (1ULL << 35)
189 
190 /*
191     When a multiple key conflict happens in a REPLACE command mysql
192     expects the conflicts to be reported in the ascending order of
193     key names.
194 
195     For e.g.
196 
197     CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
198                      NULL, INDEX(c));
199 
200     REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
201 
202     MySQL expects the conflict with 'a' to be reported before the conflict with
203     'b'.
204 
205     If the underlying storage engine does not report the conflicting keys in
206     ascending order, it causes unexpected errors when the REPLACE command is
207     executed.
208 
209     This flag helps the underlying SE to inform the server that the keys are not
210     ordered.
211 */
212 #define HA_DUPLICATE_KEY_NOT_IN_ORDER    (1ULL << 36)
213 
214 /*
215   Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
216   incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
217   will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
218 */
219 #define HA_CAN_REPAIR                    (1ULL << 37)
220 
221 /* Has automatic checksums and uses the new checksum format */
222 #define HA_HAS_NEW_CHECKSUM    (1ULL << 38)
223 #define HA_CAN_VIRTUAL_COLUMNS (1ULL << 39)
224 #define HA_MRR_CANT_SORT       (1ULL << 40)
225 /* All of VARCHAR is stored, including bytes after real varchar data */
226 #define HA_RECORD_MUST_BE_CLEAN_ON_WRITE (1ULL << 41)
227 
228 /*
229   This storage engine supports condition pushdown
230 */
231 #define HA_CAN_TABLE_CONDITION_PUSHDOWN (1ULL << 42)
232 /* old name for the same flag */
233 #define HA_MUST_USE_TABLE_CONDITION_PUSHDOWN HA_CAN_TABLE_CONDITION_PUSHDOWN
234 
235 /**
236   The handler supports read before write removal optimization
237 
238   Read before write removal may be used for storage engines which support
239   write without previous read of the row to be updated. Handler returning
240   this flag must implement start_read_removal() and end_read_removal().
241   The handler may return "fake" rows constructed from the key of the row
242   asked for. This is used to optimize UPDATE and DELETE by reducing the
243   number of roundtrips between handler and storage engine.
244 
245   Example:
246   UPDATE a=1 WHERE pk IN (<keys>)
247 
248   mysql_update()
249   {
250     if (<conditions for starting read removal>)
251       start_read_removal()
252       -> handler returns true if read removal supported for this table/query
253 
254     while(read_record("pk=<key>"))
255       -> handler returns fake row with column "pk" set to <key>
256 
257       ha_update_row()
258       -> handler sends write "a=1" for row with "pk=<key>"
259 
260     end_read_removal()
261     -> handler returns the number of rows actually written
262   }
263 
264   @note This optimization in combination with batching may be used to
265         remove even more roundtrips.
266 */
267 #define HA_READ_BEFORE_WRITE_REMOVAL  (1ULL << 43)
268 
269 /*
270   Engine supports extended fulltext API
271  */
272 #define HA_CAN_FULLTEXT_EXT              (1ULL << 44)
273 
274 /*
275   Storage engine supports table export using the
276   FLUSH TABLE <table_list> FOR EXPORT statement
277   (meaning, after this statement one can copy table files out of the
278   datadir and later "import" (somehow) in another MariaDB instance)
279  */
280 #define HA_CAN_EXPORT                 (1ULL << 45)
281 
282 /*
283   Storage engine does not require an exclusive metadata lock
284   on the table during optimize. (TODO and repair?).
285   It can allow other connections to open the table.
286   (it does not necessarily mean that other connections can
287   read or modify the table - this is defined by THR locks and the
288   ::store_lock() method).
289 */
290 #define HA_CONCURRENT_OPTIMIZE          (1ULL << 46)
291 
292 /*
293   If the storage engine support tables that will not roll back on commit
294   In addition the table should not lock rows and support READ and WRITE
295   UNCOMMITTED.
296   This is useful for implementing things like SEQUENCE but can also in
297   the future be useful to do logging that should never roll back.
298 */
299 #define HA_CAN_TABLES_WITHOUT_ROLLBACK  (1ULL << 47)
300 
301 /*
302   Mainly for usage by SEQUENCE engine. Setting this flag means
303   that the table will never roll back and that all operations
304   for this table should stored in the non transactional log
305   space that will always be written, even on rollback.
306 */
307 
308 #define HA_PERSISTENT_TABLE              (1ULL << 48)
309 
310 /*
311   If storage engine uses another engine as a base
312   This flag is also needed if the table tries to open the .frm file
313   as part of drop table.
314 */
315 #define HA_REUSES_FILE_NAMES             (1ULL << 49)
316 
317 /*
318   Set of all binlog flags. Currently only contain the capabilities
319   flags.
320  */
321 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
322 
323 /* The following are used by Spider */
324 #define HA_CAN_FORCE_BULK_UPDATE (1ULL << 50)
325 #define HA_CAN_FORCE_BULK_DELETE (1ULL << 51)
326 #define HA_CAN_DIRECT_UPDATE_AND_DELETE (1ULL << 52)
327 
328 /* The following is for partition handler */
329 #define HA_CAN_MULTISTEP_MERGE (1LL << 53)
330 
331 /* calling cmp_ref() on the engine is expensive */
332 #define HA_SLOW_CMP_REF         (1ULL << 54)
333 #define HA_CMP_REF_IS_EXPENSIVE HA_SLOW_CMP_REF
334 
335 /**
336   Some engines are unable to provide an efficient implementation for rnd_pos().
337   Server will try to avoid it, if possible
338 
339   TODO better to do it with cost estimates, not with an explicit flag
340 */
341 #define HA_SLOW_RND_POS  (1ULL << 55)
342 
343 /* Safe for online backup */
344 #define HA_CAN_ONLINE_BACKUPS (1ULL << 56)
345 
346 /* Support native hash index */
347 #define HA_CAN_HASH_KEYS        (1ULL << 57)
348 #define HA_CRASH_SAFE           (1ULL << 58)
349 
350 /*
351   There is no need to evict the table from the table definition cache having
352   run ANALYZE TABLE on it
353  */
354 #define HA_ONLINE_ANALYZE             (1ULL << 59)
355 /*
356   Rowid's are not comparable. This is set if the rowid is unique to the
357   current open handler, like it is with federated where the rowid is a
358   pointer to a local result set buffer. The effect of having this set is
359   that the optimizer will not consirer the following optimizations for
360   the table:
361   ror scans or filtering
362 */
363 #define HA_NON_COMPARABLE_ROWID (1ULL << 60)
364 
365 #define HA_LAST_TABLE_FLAG HA_NON_COMPARABLE_ROWID
366 
367 
368 /* bits in index_flags(index_number) for what you can do with index */
369 #define HA_READ_NEXT            1       /* TODO really use this flag */
370 #define HA_READ_PREV            2       /* supports ::index_prev */
371 #define HA_READ_ORDER           4       /* index_next/prev follow sort order */
372 #define HA_READ_RANGE           8       /* can find all records in a range */
373 #define HA_ONLY_WHOLE_INDEX	16	/* Can't use part key searches */
374 #define HA_KEYREAD_ONLY         64	/* Support HA_EXTRA_KEYREAD */
375 
376 /*
377   Index scan will not return records in rowid order. Not guaranteed to be
378   set for unordered (e.g. HASH) indexes.
379 */
380 #define HA_KEY_SCAN_NOT_ROR     128
381 #define HA_DO_INDEX_COND_PUSHDOWN  256 /* Supports Index Condition Pushdown */
382 /*
383   Data is clustered on this key. This means that when you read the key
384   you also get the row data without any additional disk reads.
385 */
386 #define HA_CLUSTERED_INDEX      512
387 
388 #define HA_DO_RANGE_FILTER_PUSHDOWN  1024
389 
390 /*
391   bits in alter_table_flags:
392 */
393 /*
394   These bits are set if different kinds of indexes can be created or dropped
395   in-place without re-creating the table using a temporary table.
396   NO_READ_WRITE indicates that the handler needs concurrent reads and writes
397   of table data to be blocked.
398   Partitioning needs both ADD and DROP to be supported by its underlying
399   handlers, due to error handling, see bug#57778.
400 */
401 #define HA_INPLACE_ADD_INDEX_NO_READ_WRITE         (1UL << 0)
402 #define HA_INPLACE_DROP_INDEX_NO_READ_WRITE        (1UL << 1)
403 #define HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE  (1UL << 2)
404 #define HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE (1UL << 3)
405 #define HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE      (1UL << 4)
406 #define HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE     (1UL << 5)
407 /*
408   These are set if different kinds of indexes can be created or dropped
409   in-place while still allowing concurrent reads (but not writes) of table
410   data. If a handler is capable of one or more of these, it should also set
411   the corresponding *_NO_READ_WRITE bit(s).
412 */
413 #define HA_INPLACE_ADD_INDEX_NO_WRITE              (1UL << 6)
414 #define HA_INPLACE_DROP_INDEX_NO_WRITE             (1UL << 7)
415 #define HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE       (1UL << 8)
416 #define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE      (1UL << 9)
417 #define HA_INPLACE_ADD_PK_INDEX_NO_WRITE           (1UL << 10)
418 #define HA_INPLACE_DROP_PK_INDEX_NO_WRITE          (1UL << 11)
419 /*
420   HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
421   supported at all.
422   HA_FAST_CHANGE_PARTITION means that optimised variants of the changes
423   exists but they are not necessarily done online.
424 
425   HA_ONLINE_DOUBLE_WRITE means that the handler supports writing to both
426   the new partition and to the old partitions when updating through the
427   old partitioning schema while performing a change of the partitioning.
428   This means that we can support updating of the table while performing
429   the copy phase of the change. For no lock at all also a double write
430   from new to old must exist and this is not required when this flag is
431   set.
432   This is actually removed even before it was introduced the first time.
433   The new idea is that handlers will handle the lock level already in
434   store_lock for ALTER TABLE partitions.
435 
436   HA_PARTITION_ONE_PHASE is a flag that can be set by handlers that take
437   care of changing the partitions online and in one phase. Thus all phases
438   needed to handle the change are implemented inside the storage engine.
439   The storage engine must also support auto-discovery since the frm file
440   is changed as part of the change and this change must be controlled by
441   the storage engine. A typical engine to support this is NDB (through
442   WL #2498).
443 */
444 #define HA_PARTITION_FUNCTION_SUPPORTED         (1UL << 12)
445 #define HA_FAST_CHANGE_PARTITION                (1UL << 13)
446 #define HA_PARTITION_ONE_PHASE                  (1UL << 14)
447 
448 /* operations for disable/enable indexes */
449 #define HA_KEY_SWITCH_NONUNIQ      0
450 #define HA_KEY_SWITCH_ALL          1
451 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
452 #define HA_KEY_SWITCH_ALL_SAVE     3
453 
454 /*
455   Note: the following includes binlog and closing 0.
456   TODO remove the limit, use dynarrays
457 */
458 #define MAX_HA 64
459 
460 /*
461   Use this instead of 0 as the initial value for the slot number of
462   handlerton, so that we can distinguish uninitialized slot number
463   from slot 0.
464 */
465 #define HA_SLOT_UNDEF ((uint)-1)
466 
467 /*
468   Parameters for open() (in register form->filestat)
469   HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
470 */
471 
472 #define HA_OPEN_KEYFILE		1U
473 #define HA_READ_ONLY		16U	/* File opened as readonly */
474 /* Try readonly if can't open with read and write */
475 #define HA_TRY_READ_ONLY	32U
476 
477 	/* Some key definitions */
478 #define HA_KEY_NULL_LENGTH	1
479 #define HA_KEY_BLOB_LENGTH	2
480 
481 /* Maximum length of any index lookup key, in bytes */
482 
483 #define MAX_KEY_LENGTH (MAX_DATA_LENGTH_FOR_KEY \
484                          +(MAX_REF_PARTS \
485                           *(HA_KEY_NULL_LENGTH + HA_KEY_BLOB_LENGTH)))
486 
487 #define HA_LEX_CREATE_TMP_TABLE	1U
488 #define HA_CREATE_TMP_ALTER     8U
489 #define HA_LEX_CREATE_SEQUENCE  16U
490 #define HA_VERSIONED_TABLE      32U
491 #define HA_SKIP_KEY_SORT        64U
492 
493 #define HA_MAX_REC_LENGTH	65535
494 
495 /* Table caching type */
496 #define HA_CACHE_TBL_NONTRANSACT 0
497 #define HA_CACHE_TBL_NOCACHE     1U
498 #define HA_CACHE_TBL_ASKTRANSACT 2U
499 #define HA_CACHE_TBL_TRANSACT    4U
500 
501 /**
502   Options for the START TRANSACTION statement.
503 
504   Note that READ ONLY and READ WRITE are logically mutually exclusive.
505   This is enforced by the parser and depended upon by trans_begin().
506 
507   We need two flags instead of one in order to differentiate between
508   situation when no READ WRITE/ONLY clause were given and thus transaction
509   is implicitly READ WRITE and the case when READ WRITE clause was used
510   explicitly.
511 */
512 
513 // WITH CONSISTENT SNAPSHOT option
514 static const uint MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT = 1;
515 // READ ONLY option
516 static const uint MYSQL_START_TRANS_OPT_READ_ONLY          = 2;
517 // READ WRITE option
518 static const uint MYSQL_START_TRANS_OPT_READ_WRITE         = 4;
519 
520 /* Flags for method is_fatal_error */
521 #define HA_CHECK_DUP_KEY 1U
522 #define HA_CHECK_DUP_UNIQUE 2U
523 #define HA_CHECK_FK_ERROR 4U
524 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
525 #define HA_CHECK_ALL (~0U)
526 
527 /* Options for info_push() */
528 #define INFO_KIND_UPDATE_FIELDS       101
529 #define INFO_KIND_UPDATE_VALUES       102
530 #define INFO_KIND_FORCE_LIMIT_BEGIN   103
531 #define INFO_KIND_FORCE_LIMIT_END     104
532 
533 enum legacy_db_type
534 {
535   /* note these numerical values are fixed and can *not* be changed */
536   DB_TYPE_UNKNOWN=0,
537   DB_TYPE_HEAP=6,
538   DB_TYPE_MYISAM=9,
539   DB_TYPE_MRG_MYISAM=10,
540   DB_TYPE_INNODB=12,
541   DB_TYPE_EXAMPLE_DB=15,
542   DB_TYPE_ARCHIVE_DB=16,
543   DB_TYPE_CSV_DB=17,
544   DB_TYPE_FEDERATED_DB=18,
545   DB_TYPE_BLACKHOLE_DB=19,
546   DB_TYPE_PARTITION_DB=20,
547   DB_TYPE_BINLOG=21,
548   DB_TYPE_PBXT=23,
549   DB_TYPE_PERFORMANCE_SCHEMA=28,
550   DB_TYPE_S3=41,
551   DB_TYPE_ARIA=42,
552   DB_TYPE_TOKUDB=43,
553   DB_TYPE_SEQUENCE=44,
554   DB_TYPE_FIRST_DYNAMIC=45,
555   DB_TYPE_DEFAULT=127 // Must be last
556 };
557 /*
558   Better name for DB_TYPE_UNKNOWN. Should be used for engines that do not have
559   a hard-coded type value here.
560  */
561 #define DB_TYPE_AUTOASSIGN DB_TYPE_UNKNOWN
562 
563 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
564 		ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
565 		ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGE };
566 
567 /* not part of the enum, so that it shouldn't be in switch(row_type) */
568 #define ROW_TYPE_MAX ((uint)ROW_TYPE_PAGE + 1)
569 
570 /* Specifies data storage format for individual columns */
571 enum column_format_type {
572   COLUMN_FORMAT_TYPE_DEFAULT=   0, /* Not specified (use engine default) */
573   COLUMN_FORMAT_TYPE_FIXED=     1, /* FIXED format */
574   COLUMN_FORMAT_TYPE_DYNAMIC=   2  /* DYNAMIC format */
575 };
576 
577 enum enum_binlog_func {
578   BFN_RESET_LOGS=        1,
579   BFN_RESET_SLAVE=       2,
580   BFN_BINLOG_WAIT=       3,
581   BFN_BINLOG_END=        4,
582   BFN_BINLOG_PURGE_FILE= 5
583 };
584 
585 enum enum_binlog_command {
586   LOGCOM_CREATE_TABLE,
587   LOGCOM_ALTER_TABLE,
588   LOGCOM_RENAME_TABLE,
589   LOGCOM_DROP_TABLE,
590   LOGCOM_CREATE_DB,
591   LOGCOM_ALTER_DB,
592   LOGCOM_DROP_DB
593 };
594 
595 /* struct to hold information about the table that should be created */
596 
597 /* Bits in used_fields */
598 #define HA_CREATE_USED_AUTO             (1UL << 0)
599 #define HA_CREATE_USED_RAID             (1UL << 1) //RAID is no longer available
600 #define HA_CREATE_USED_UNION            (1UL << 2)
601 #define HA_CREATE_USED_INSERT_METHOD    (1UL << 3)
602 #define HA_CREATE_USED_MIN_ROWS         (1UL << 4)
603 #define HA_CREATE_USED_MAX_ROWS         (1UL << 5)
604 #define HA_CREATE_USED_AVG_ROW_LENGTH   (1UL << 6)
605 #define HA_CREATE_USED_PACK_KEYS        (1UL << 7)
606 #define HA_CREATE_USED_CHARSET          (1UL << 8)
607 #define HA_CREATE_USED_DEFAULT_CHARSET  (1UL << 9)
608 #define HA_CREATE_USED_DATADIR          (1UL << 10)
609 #define HA_CREATE_USED_INDEXDIR         (1UL << 11)
610 #define HA_CREATE_USED_ENGINE           (1UL << 12)
611 #define HA_CREATE_USED_CHECKSUM         (1UL << 13)
612 #define HA_CREATE_USED_DELAY_KEY_WRITE  (1UL << 14)
613 #define HA_CREATE_USED_ROW_FORMAT       (1UL << 15)
614 #define HA_CREATE_USED_COMMENT          (1UL << 16)
615 #define HA_CREATE_USED_PASSWORD         (1UL << 17)
616 #define HA_CREATE_USED_CONNECTION       (1UL << 18)
617 #define HA_CREATE_USED_KEY_BLOCK_SIZE   (1UL << 19)
618 /* The following two are used by Maria engine: */
619 #define HA_CREATE_USED_TRANSACTIONAL    (1UL << 20)
620 #define HA_CREATE_USED_PAGE_CHECKSUM    (1UL << 21)
621 /** This is set whenever STATS_PERSISTENT=0|1|default has been
622 specified in CREATE/ALTER TABLE. See also HA_OPTION_STATS_PERSISTENT in
623 include/my_base.h. It is possible to distinguish whether
624 STATS_PERSISTENT=default has been specified or no STATS_PERSISTENT= is
625 given at all. */
626 #define HA_CREATE_USED_STATS_PERSISTENT (1UL << 22)
627 /**
628    This is set whenever STATS_AUTO_RECALC=0|1|default has been
629    specified in CREATE/ALTER TABLE. See enum_stats_auto_recalc.
630    It is possible to distinguish whether STATS_AUTO_RECALC=default
631    has been specified or no STATS_AUTO_RECALC= is given at all.
632 */
633 #define HA_CREATE_USED_STATS_AUTO_RECALC (1UL << 23)
634 /**
635    This is set whenever STATS_SAMPLE_PAGES=N|default has been
636    specified in CREATE/ALTER TABLE. It is possible to distinguish whether
637    STATS_SAMPLE_PAGES=default has been specified or no STATS_SAMPLE_PAGES= is
638    given at all.
639 */
640 #define HA_CREATE_USED_STATS_SAMPLE_PAGES (1UL << 24)
641 
642 /* Create a sequence */
643 #define HA_CREATE_USED_SEQUENCE           (1UL << 25)
644 /* Tell binlog_show_create_table to print all engine options */
645 #define HA_CREATE_PRINT_ALL_OPTIONS       (1UL << 26)
646 
647 typedef ulonglong alter_table_operations;
648 typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
649 
650 /*
651   These flags are set by the parser and describes the type of
652   operation(s) specified by the ALTER TABLE statement.
653 */
654 
655 // Set by parser for ADD [COLUMN]
656 #define ALTER_PARSER_ADD_COLUMN     (1ULL <<  0)
657 // Set by parser for DROP [COLUMN]
658 #define ALTER_PARSER_DROP_COLUMN    (1ULL <<  1)
659 // Set for CHANGE [COLUMN] | MODIFY [CHANGE] & mysql_recreate_table
660 #define ALTER_CHANGE_COLUMN         (1ULL <<  2)
661 // Set for ADD INDEX | ADD KEY | ADD PRIMARY KEY | ADD UNIQUE KEY |
662 //         ADD UNIQUE INDEX | ALTER ADD [COLUMN]
663 #define ALTER_ADD_INDEX             (1ULL <<  3)
664 // Set for DROP PRIMARY KEY | DROP FOREIGN KEY | DROP KEY | DROP INDEX
665 #define ALTER_DROP_INDEX            (1ULL <<  4)
666 // Set for RENAME [TO]
667 #define ALTER_RENAME                (1ULL <<  5)
668 // Set for ORDER BY
669 #define ALTER_ORDER                 (1ULL <<  6)
670 // Set for table_options, like table comment
671 #define ALTER_OPTIONS               (1ULL <<  7)
672 // Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT
673 #define ALTER_CHANGE_COLUMN_DEFAULT (1ULL <<  8)
674 // Set for DISABLE KEYS | ENABLE KEYS
675 #define ALTER_KEYS_ONOFF            (1ULL <<  9)
676 // Set for FORCE, ENGINE(same engine), by mysql_recreate_table()
677 #define ALTER_RECREATE              (1ULL << 10)
678 // Set for CONVERT TO
679 #define ALTER_CONVERT_TO            (1ULL << 11)
680 // Set for DROP ... ADD some_index
681 #define ALTER_RENAME_INDEX          (1ULL << 12)
682 // Set for ADD FOREIGN KEY
683 #define ALTER_ADD_FOREIGN_KEY       (1ULL << 21)
684 // Set for DROP FOREIGN KEY
685 #define ALTER_DROP_FOREIGN_KEY      (1ULL << 22)
686 #define ALTER_CHANGE_INDEX_COMMENT  (1ULL << 23)
687 // Set for ADD [COLUMN] FIRST | AFTER
688 #define ALTER_COLUMN_ORDER          (1ULL << 25)
689 #define ALTER_ADD_CHECK_CONSTRAINT  (1ULL << 27)
690 #define ALTER_DROP_CHECK_CONSTRAINT (1ULL << 28)
691 #define ALTER_RENAME_COLUMN         (1ULL << 29)
692 #define ALTER_COLUMN_UNVERSIONED    (1ULL << 30)
693 #define ALTER_ADD_SYSTEM_VERSIONING (1ULL << 31)
694 #define ALTER_DROP_SYSTEM_VERSIONING (1ULL << 32)
695 #define ALTER_ADD_PERIOD             (1ULL << 33)
696 #define ALTER_DROP_PERIOD            (1ULL << 34)
697 
698 /*
699   Following defines are used by ALTER_INPLACE_TABLE
700 
701   They do describe in more detail the type operation(s) to be executed
702   by the storage engine. For example, which type of type of index to be
703   added/dropped.  These are set by fill_alter_inplace_info().
704 */
705 
706 #define ALTER_RECREATE_TABLE	     ALTER_RECREATE
707 #define ALTER_CHANGE_CREATE_OPTION   ALTER_OPTIONS
708 #define ALTER_ADD_COLUMN             (ALTER_ADD_VIRTUAL_COLUMN | \
709                                       ALTER_ADD_STORED_BASE_COLUMN | \
710                                       ALTER_ADD_STORED_GENERATED_COLUMN)
711 #define ALTER_DROP_COLUMN             (ALTER_DROP_VIRTUAL_COLUMN | \
712                                        ALTER_DROP_STORED_COLUMN)
713 #define ALTER_COLUMN_DEFAULT          ALTER_CHANGE_COLUMN_DEFAULT
714 
715 // Add non-unique, non-primary index
716 #define ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX  (1ULL << 35)
717 
718 // Drop non-unique, non-primary index
719 #define ALTER_DROP_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 36)
720 
721 // Add unique, non-primary index
722 #define ALTER_ADD_UNIQUE_INDEX               (1ULL << 37)
723 
724 // Drop unique, non-primary index
725 #define ALTER_DROP_UNIQUE_INDEX              (1ULL << 38)
726 
727 // Add primary index
728 #define ALTER_ADD_PK_INDEX                   (1ULL << 39)
729 
730 // Drop primary index
731 #define ALTER_DROP_PK_INDEX                  (1ULL << 40)
732 
733 // Virtual generated column
734 #define ALTER_ADD_VIRTUAL_COLUMN             (1ULL << 41)
735 // Stored base (non-generated) column
736 #define ALTER_ADD_STORED_BASE_COLUMN         (1ULL << 42)
737 // Stored generated column
738 #define ALTER_ADD_STORED_GENERATED_COLUMN    (1ULL << 43)
739 
740 // Drop column
741 #define ALTER_DROP_VIRTUAL_COLUMN            (1ULL << 44)
742 #define ALTER_DROP_STORED_COLUMN             (1ULL << 45)
743 
744 // Rename column (verified; ALTER_RENAME_COLUMN may use original name)
745 #define ALTER_COLUMN_NAME          	     (1ULL << 46)
746 
747 // Change column datatype
748 #define ALTER_VIRTUAL_COLUMN_TYPE            (1ULL << 47)
749 #define ALTER_STORED_COLUMN_TYPE             (1ULL << 48)
750 
751 
752 // Engine can handle type change by itself in ALGORITHM=INPLACE
753 #define ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE       (1ULL << 49)
754 
755 // Reorder column
756 #define ALTER_STORED_COLUMN_ORDER            (1ULL << 50)
757 
758 // Reorder column
759 #define ALTER_VIRTUAL_COLUMN_ORDER           (1ULL << 51)
760 
761 // Change column from NOT NULL to NULL
762 #define ALTER_COLUMN_NULLABLE                (1ULL << 52)
763 
764 // Change column from NULL to NOT NULL
765 #define ALTER_COLUMN_NOT_NULLABLE            (1ULL << 53)
766 
767 // Change column generation expression
768 #define ALTER_VIRTUAL_GCOL_EXPR              (1ULL << 54)
769 #define ALTER_STORED_GCOL_EXPR               (1ULL << 55)
770 
771 // column's engine options changed, something in field->option_struct
772 #define ALTER_COLUMN_OPTION                  (1ULL << 56)
773 
774 // MySQL alias for the same thing:
775 #define ALTER_COLUMN_STORAGE_TYPE            ALTER_COLUMN_OPTION
776 
777 // Change the column format of column
778 #define ALTER_COLUMN_COLUMN_FORMAT           (1ULL << 57)
779 
780 /**
781   Changes in generated columns that affect storage,
782   for example, when a vcol type or expression changes
783   and this vcol is indexed or used in a partitioning expression
784 */
785 #define ALTER_COLUMN_VCOL                    (1ULL << 58)
786 
787 /**
788   ALTER TABLE for a partitioned table. The engine needs to commit
789   online alter of all partitions atomically (using group_commit_ctx)
790 */
791 #define ALTER_PARTITIONED                    (1ULL << 59)
792 
793 /**
794    Change in index length such that it doesn't require index rebuild.
795 */
796 #define ALTER_COLUMN_INDEX_LENGTH            (1ULL << 60)
797 
798 /**
799   Indicate that index order might have been changed. Disables inplace algorithm
800   by default (not for InnoDB).
801 */
802 #define ALTER_INDEX_ORDER                    (1ULL << 61)
803 
804 
805 /*
806   Flags set in partition_flags when altering partitions
807 */
808 
809 // Set for ADD PARTITION
810 #define ALTER_PARTITION_ADD         (1ULL << 1)
811 // Set for DROP PARTITION
812 #define ALTER_PARTITION_DROP        (1ULL << 2)
813 // Set for COALESCE PARTITION
814 #define ALTER_PARTITION_COALESCE    (1ULL << 3)
815 // Set for REORGANIZE PARTITION ... INTO
816 #define ALTER_PARTITION_REORGANIZE  (1ULL << 4)
817 // Set for partition_options
818 #define ALTER_PARTITION_INFO        (1ULL << 5)
819 // Set for LOAD INDEX INTO CACHE ... PARTITION
820 // Set for CACHE INDEX ... PARTITION
821 #define ALTER_PARTITION_ADMIN       (1ULL << 6)
822 // Set for REBUILD PARTITION
823 #define ALTER_PARTITION_REBUILD     (1ULL << 7)
824 // Set for partitioning operations specifying ALL keyword
825 #define ALTER_PARTITION_ALL         (1ULL << 8)
826 // Set for REMOVE PARTITIONING
827 #define ALTER_PARTITION_REMOVE      (1ULL << 9)
828 // Set for EXCHANGE PARITION
829 #define ALTER_PARTITION_EXCHANGE    (1ULL << 10)
830 // Set by Sql_cmd_alter_table_truncate_partition::execute()
831 #define ALTER_PARTITION_TRUNCATE    (1ULL << 11)
832 // Set for REORGANIZE PARTITION
833 #define ALTER_PARTITION_TABLE_REORG           (1ULL << 12)
834 
835 /*
836   This is master database for most of system tables. However there
837   can be other databases which can hold system tables. Respective
838   storage engines define their own system database names.
839 */
840 extern const char *mysqld_system_database;
841 
842 /*
843   Structure to hold list of system_database.system_table.
844   This is used at both mysqld and storage engine layer.
845 */
846 struct st_system_tablename
847 {
848   const char *db;
849   const char *tablename;
850 };
851 
852 
853 typedef ulonglong my_xid; // this line is the same as in log_event.h
854 #define MYSQL_XID_PREFIX "MySQLXid"
855 #define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
856 #define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
857 #define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
858 
859 #define XIDDATASIZE MYSQL_XIDDATASIZE
860 #define MAXGTRIDSIZE 64
861 #define MAXBQUALSIZE 64
862 
863 #define COMPATIBLE_DATA_YES 0
864 #define COMPATIBLE_DATA_NO  1
865 
866 /**
867   struct xid_t is binary compatible with the XID structure as
868   in the X/Open CAE Specification, Distributed Transaction Processing:
869   The XA Specification, X/Open Company Ltd., 1991.
870   http://www.opengroup.org/bookstore/catalog/c193.htm
871 
872   @see MYSQL_XID in mysql/plugin.h
873 */
874 struct xid_t {
875   long formatID;
876   long gtrid_length;
877   long bqual_length;
878   char data[XIDDATASIZE];  // not \0-terminated !
879 
xid_txid_t880   xid_t() {}                                /* Remove gcc warning */
eqxid_t881   bool eq(struct xid_t *xid) const
882   { return !xid->is_null() && eq(xid->gtrid_length, xid->bqual_length, xid->data); }
eqxid_t883   bool eq(long g, long b, const char *d) const
884   { return !is_null() && g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
setxid_t885   void set(struct xid_t *xid)
886   { memcpy(this, xid, xid->length()); }
setxid_t887   void set(long f, const char *g, long gl, const char *b, long bl)
888   {
889     formatID= f;
890     if ((gtrid_length= gl))
891       memcpy(data, g, gl);
892     if ((bqual_length= bl))
893       memcpy(data+gl, b, bl);
894   }
setxid_t895   void set(ulonglong xid)
896   {
897     my_xid tmp;
898     formatID= 1;
899     set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
900     memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
901     tmp= xid;
902     memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
903     gtrid_length=MYSQL_XID_GTRID_LEN;
904   }
setxid_t905   void set(long g, long b, const char *d)
906   {
907     formatID= 1;
908     gtrid_length= g;
909     bqual_length= b;
910     memcpy(data, d, g+b);
911   }
is_nullxid_t912   bool is_null() const { return formatID == -1; }
nullxid_t913   void null() { formatID= -1; }
quick_get_my_xidxid_t914   my_xid quick_get_my_xid()
915   {
916     my_xid tmp;
917     memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp));
918     return tmp;
919   }
get_my_xidxid_t920   my_xid get_my_xid()
921   {
922     return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
923            !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
924            quick_get_my_xid() : 0;
925   }
lengthxid_t926   uint length()
927   {
928     return static_cast<uint>(sizeof(formatID)) + key_length();
929   }
keyxid_t930   uchar *key() const
931   {
932     return (uchar *)&gtrid_length;
933   }
key_lengthxid_t934   uint key_length() const
935   {
936     return static_cast<uint>(sizeof(gtrid_length)+sizeof(bqual_length)+
937                              gtrid_length+bqual_length);
938   }
939 };
940 typedef struct xid_t XID;
941 
942 /* for recover() handlerton call */
943 #define MIN_XID_LIST_SIZE  128
944 #define MAX_XID_LIST_SIZE  (1024*128)
945 
946 /*
947   These structures are used to pass information from a set of SQL commands
948   on add/drop/change tablespace definitions to the proper hton.
949 */
950 #define UNDEF_NODEGROUP 65535
951 enum ts_command_type
952 {
953   TS_CMD_NOT_DEFINED = -1,
954   CREATE_TABLESPACE = 0,
955   ALTER_TABLESPACE = 1,
956   CREATE_LOGFILE_GROUP = 2,
957   ALTER_LOGFILE_GROUP = 3,
958   DROP_TABLESPACE = 4,
959   DROP_LOGFILE_GROUP = 5,
960   CHANGE_FILE_TABLESPACE = 6,
961   ALTER_ACCESS_MODE_TABLESPACE = 7
962 };
963 
964 enum ts_alter_tablespace_type
965 {
966   TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
967   ALTER_TABLESPACE_ADD_FILE = 1,
968   ALTER_TABLESPACE_DROP_FILE = 2
969 };
970 
971 enum tablespace_access_mode
972 {
973   TS_NOT_DEFINED= -1,
974   TS_READ_ONLY = 0,
975   TS_READ_WRITE = 1,
976   TS_NOT_ACCESSIBLE = 2
977 };
978 
979 /* Statistics about batch operations like bulk_insert */
980 struct ha_copy_info
981 {
982   ha_rows records;        /* Used to check if rest of variables can be used */
983   ha_rows touched;
984   ha_rows copied;
985   ha_rows deleted;
986   ha_rows updated;
987 };
988 
989 struct handlerton;
990 class st_alter_tablespace : public Sql_alloc
991 {
992   public:
993   const char *tablespace_name;
994   const char *logfile_group_name;
995   enum ts_command_type ts_cmd_type;
996   enum ts_alter_tablespace_type ts_alter_tablespace_type;
997   const char *data_file_name;
998   const char *undo_file_name;
999   const char *redo_file_name;
1000   ulonglong extent_size;
1001   ulonglong undo_buffer_size;
1002   ulonglong redo_buffer_size;
1003   ulonglong initial_size;
1004   ulonglong autoextend_size;
1005   ulonglong max_size;
1006   uint nodegroup_id;
1007   handlerton *storage_engine;
1008   bool wait_until_completed;
1009   const char *ts_comment;
1010   enum tablespace_access_mode ts_access_mode;
st_alter_tablespace()1011   st_alter_tablespace()
1012   {
1013     tablespace_name= NULL;
1014     logfile_group_name= "DEFAULT_LG"; //Default log file group
1015     ts_cmd_type= TS_CMD_NOT_DEFINED;
1016     data_file_name= NULL;
1017     undo_file_name= NULL;
1018     redo_file_name= NULL;
1019     extent_size= 1024*1024;        //Default 1 MByte
1020     undo_buffer_size= 8*1024*1024; //Default 8 MByte
1021     redo_buffer_size= 8*1024*1024; //Default 8 MByte
1022     initial_size= 128*1024*1024;   //Default 128 MByte
1023     autoextend_size= 0;            //No autoextension as default
1024     max_size= 0;                   //Max size == initial size => no extension
1025     storage_engine= NULL;
1026     nodegroup_id= UNDEF_NODEGROUP;
1027     wait_until_completed= TRUE;
1028     ts_comment= NULL;
1029     ts_access_mode= TS_NOT_DEFINED;
1030   }
1031 };
1032 
1033 /* The handler for a table type.  Will be included in the TABLE structure */
1034 
1035 struct TABLE;
1036 
1037 /*
1038   Make sure that the order of schema_tables and enum_schema_tables are the same.
1039 */
1040 enum enum_schema_tables
1041 {
1042   SCH_ALL_PLUGINS,
1043   SCH_APPLICABLE_ROLES,
1044   SCH_CHARSETS,
1045   SCH_CHECK_CONSTRAINTS,
1046   SCH_COLLATIONS,
1047   SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
1048   SCH_COLUMNS,
1049   SCH_COLUMN_PRIVILEGES,
1050   SCH_ENABLED_ROLES,
1051   SCH_ENGINES,
1052   SCH_EVENTS,
1053   SCH_EXPLAIN,
1054   SCH_FILES,
1055   SCH_GLOBAL_STATUS,
1056   SCH_GLOBAL_VARIABLES,
1057   SCH_KEYWORDS,
1058   SCH_KEY_CACHES,
1059   SCH_KEY_COLUMN_USAGE,
1060   SCH_OPEN_TABLES,
1061   SCH_OPT_TRACE,
1062   SCH_PARAMETERS,
1063   SCH_PARTITIONS,
1064   SCH_PLUGINS,
1065   SCH_PROCESSLIST,
1066   SCH_PROFILES,
1067   SCH_REFERENTIAL_CONSTRAINTS,
1068   SCH_PROCEDURES,
1069   SCH_SCHEMATA,
1070   SCH_SCHEMA_PRIVILEGES,
1071   SCH_SESSION_STATUS,
1072   SCH_SESSION_VARIABLES,
1073   SCH_STATISTICS,
1074   SCH_SQL_FUNCTIONS,
1075   SCH_SYSTEM_VARIABLES,
1076   SCH_TABLES,
1077   SCH_TABLESPACES,
1078   SCH_TABLE_CONSTRAINTS,
1079   SCH_TABLE_NAMES,
1080   SCH_TABLE_PRIVILEGES,
1081   SCH_TRIGGERS,
1082   SCH_USER_PRIVILEGES,
1083   SCH_VIEWS
1084 };
1085 
1086 struct TABLE_SHARE;
1087 struct HA_CREATE_INFO;
1088 struct st_foreign_key_info;
1089 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
1090 typedef bool (stat_print_fn)(THD *thd, const char *type, size_t type_len,
1091                              const char *file, size_t file_len,
1092                              const char *status, size_t status_len);
1093 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
1094 extern MYSQL_PLUGIN_IMPORT st_plugin_int *hton2plugin[MAX_HA];
1095 
1096 /* Transaction log maintains type definitions */
1097 enum log_status
1098 {
1099   HA_LOG_STATUS_FREE= 0,      /* log is free and can be deleted */
1100   HA_LOG_STATUS_INUSE= 1,     /* log can't be deleted because it is in use */
1101   HA_LOG_STATUS_NOSUCHLOG= 2  /* no such log (can't be returned by
1102                                 the log iterator status) */
1103 };
1104 /*
1105   Function for signaling that the log file changed its state from
1106   LOG_STATUS_INUSE to LOG_STATUS_FREE
1107 
1108   Now it do nothing, will be implemented as part of new transaction
1109   log management for engines.
1110   TODO: implement the function.
1111 */
1112 void signal_log_not_needed(struct handlerton, char *log_file);
1113 /*
1114   Data of transaction log iterator.
1115 */
1116 struct handler_log_file_data {
1117   LEX_STRING filename;
1118   enum log_status status;
1119 };
1120 
1121 /*
1122   Definitions for engine-specific table/field/index options in the CREATE TABLE.
1123 
1124   Options are declared with HA_*OPTION_* macros (HA_TOPTION_NUMBER,
1125   HA_FOPTION_ENUM, HA_IOPTION_STRING, etc).
1126 
1127   Every macros takes the option name, and the name of the underlying field of
1128   the appropriate C structure. The "appropriate C structure" is
1129   ha_table_option_struct for table level options,
1130   ha_field_option_struct for field level options,
1131   ha_index_option_struct for key level options. The engine either
1132   defines a structure of this name, or uses #define's to map
1133   these "appropriate" names to the actual structure type name.
1134 
1135   ULL options use a ulonglong as the backing store.
1136   HA_*OPTION_NUMBER() takes the option name, the structure field name,
1137   the default value for the option, min, max, and blk_siz values.
1138 
1139   STRING options use a char* as a backing store.
1140   HA_*OPTION_STRING takes the option name and the structure field name.
1141   The default value will be 0.
1142 
1143   ENUM options use a uint as a backing store (not enum!!!).
1144   HA_*OPTION_ENUM takes the option name, the structure field name,
1145   the default value for the option as a number, and a string with the
1146   permitted values for this enum - one string with comma separated values,
1147   for example: "gzip,bzip2,lzma"
1148 
1149   BOOL options use a bool as a backing store.
1150   HA_*OPTION_BOOL takes the option name, the structure field name,
1151   and the default value for the option.
1152   From the SQL, BOOL options accept YES/NO, ON/OFF, and 1/0.
1153 
1154   The name of the option is limited to 255 bytes,
1155   the value (for string options) - to the 32767 bytes.
1156 
1157   See ha_example.cc for an example.
1158 */
1159 
1160 struct ha_table_option_struct;
1161 struct ha_field_option_struct;
1162 struct ha_index_option_struct;
1163 
1164 enum ha_option_type { HA_OPTION_TYPE_ULL,    /* unsigned long long */
1165                       HA_OPTION_TYPE_STRING, /* char * */
1166                       HA_OPTION_TYPE_ENUM,   /* uint */
1167                       HA_OPTION_TYPE_BOOL,   /* bool */
1168                       HA_OPTION_TYPE_SYSVAR};/* type of the sysval */
1169 
1170 #define HA_xOPTION_NUMBER(name, struc, field, def, min, max, blk_siz)   \
1171   { HA_OPTION_TYPE_ULL, name, sizeof(name)-1,                        \
1172     offsetof(struc, field), def, min, max, blk_siz, 0, 0 }
1173 #define HA_xOPTION_STRING(name, struc, field)                        \
1174   { HA_OPTION_TYPE_STRING, name, sizeof(name)-1,                     \
1175     offsetof(struc, field), 0, 0, 0, 0, 0, 0}
1176 #define HA_xOPTION_ENUM(name, struc, field, values, def)             \
1177   { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1,                       \
1178     offsetof(struc, field), def, 0,                                  \
1179     sizeof(values)-1, 0, values, 0 }
1180 #define HA_xOPTION_BOOL(name, struc, field, def)                     \
1181   { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1,                       \
1182     offsetof(struc, field), def, 0, 1, 0, 0, 0 }
1183 #define HA_xOPTION_SYSVAR(name, struc, field, sysvar)                \
1184   { HA_OPTION_TYPE_SYSVAR, name, sizeof(name)-1,                     \
1185     offsetof(struc, field), 0, 0, 0, 0, 0, MYSQL_SYSVAR(sysvar) }
1186 #define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
1187 
1188 #define HA_TOPTION_NUMBER(name, field, def, min, max, blk_siz)          \
1189   HA_xOPTION_NUMBER(name, ha_table_option_struct, field, def, min, max, blk_siz)
1190 #define HA_TOPTION_STRING(name, field)                               \
1191   HA_xOPTION_STRING(name, ha_table_option_struct, field)
1192 #define HA_TOPTION_ENUM(name, field, values, def)                    \
1193   HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
1194 #define HA_TOPTION_BOOL(name, field, def)                            \
1195   HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
1196 #define HA_TOPTION_SYSVAR(name, field, sysvar)                       \
1197   HA_xOPTION_SYSVAR(name, ha_table_option_struct, field, sysvar)
1198 #define HA_TOPTION_END HA_xOPTION_END
1199 
1200 #define HA_FOPTION_NUMBER(name, field, def, min, max, blk_siz)          \
1201   HA_xOPTION_NUMBER(name, ha_field_option_struct, field, def, min, max, blk_siz)
1202 #define HA_FOPTION_STRING(name, field)                               \
1203   HA_xOPTION_STRING(name, ha_field_option_struct, field)
1204 #define HA_FOPTION_ENUM(name, field, values, def)                    \
1205   HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
1206 #define HA_FOPTION_BOOL(name, field, def)                            \
1207   HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
1208 #define HA_FOPTION_SYSVAR(name, field, sysvar)                       \
1209   HA_xOPTION_SYSVAR(name, ha_field_option_struct, field, sysvar)
1210 #define HA_FOPTION_END HA_xOPTION_END
1211 
1212 #define HA_IOPTION_NUMBER(name, field, def, min, max, blk_siz)          \
1213   HA_xOPTION_NUMBER(name, ha_index_option_struct, field, def, min, max, blk_siz)
1214 #define HA_IOPTION_STRING(name, field)                               \
1215   HA_xOPTION_STRING(name, ha_index_option_struct, field)
1216 #define HA_IOPTION_ENUM(name, field, values, def)                    \
1217   HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def)
1218 #define HA_IOPTION_BOOL(name, field, def)                            \
1219   HA_xOPTION_BOOL(name, ha_index_option_struct, field, def)
1220 #define HA_IOPTION_SYSVAR(name, field, sysvar)                       \
1221   HA_xOPTION_SYSVAR(name, ha_index_option_struct, field, sysvar)
1222 #define HA_IOPTION_END HA_xOPTION_END
1223 
1224 typedef struct st_ha_create_table_option {
1225   enum ha_option_type type;
1226   const char *name;
1227   size_t name_length;
1228   ptrdiff_t offset;
1229   ulonglong def_value;
1230   ulonglong min_value, max_value, block_size;
1231   const char *values;
1232   struct st_mysql_sys_var *var;
1233 } ha_create_table_option;
1234 
1235 enum handler_iterator_type
1236 {
1237   /* request of transaction log iterator */
1238   HA_TRANSACTLOG_ITERATOR= 1
1239 };
1240 enum handler_create_iterator_result
1241 {
1242   HA_ITERATOR_OK,          /* iterator created */
1243   HA_ITERATOR_UNSUPPORTED, /* such type of iterator is not supported */
1244   HA_ITERATOR_ERROR        /* error during iterator creation */
1245 };
1246 
1247 /*
1248   Iterator structure. Can be used by handler/handlerton for different purposes.
1249 
1250   Iterator should be created in the way to point "before" the first object
1251   it iterate, so next() call move it to the first object or return !=0 if
1252   there is nothing to iterate through.
1253 */
1254 struct handler_iterator {
1255   /*
1256     Moves iterator to next record and return 0 or return !=0
1257     if there is no records.
1258     iterator_object will be filled by this function if next() returns 0.
1259     Content of the iterator_object depend on iterator type.
1260   */
1261   int (*next)(struct handler_iterator *, void *iterator_object);
1262   /*
1263     Free resources allocated by iterator, after this call iterator
1264     is not usable.
1265   */
1266   void (*destroy)(struct handler_iterator *);
1267   /*
1268     Pointer to buffer for the iterator to use.
1269     Should be allocated by function which created the iterator and
1270     destroyed by freed by above "destroy" call
1271   */
1272   void *buffer;
1273 };
1274 
1275 class handler;
1276 class group_by_handler;
1277 class derived_handler;
1278 class select_handler;
1279 struct Query;
1280 typedef class st_select_lex SELECT_LEX;
1281 typedef struct st_order ORDER;
1282 
1283 /*
1284   handlerton is a singleton structure - one instance per storage engine -
1285   to provide access to storage engine functionality that works on the
1286   "global" level (unlike handler class that works on a per-table basis)
1287 
1288   usually handlerton instance is defined statically in ha_xxx.cc as
1289 
1290   static handlerton { ... } xxx_hton;
1291 
1292   savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
1293 */
1294 struct handlerton
1295 {
1296   /*
1297     Historical number used for frm file to determine the correct
1298     storage engine.  This is going away and new engines will just use
1299     "name" for this.
1300   */
1301   enum legacy_db_type db_type;
1302   /*
1303     each storage engine has it's own memory area (actually a pointer)
1304     in the thd, for storing per-connection information.
1305     It is accessed as
1306 
1307       thd->ha_data[xxx_hton.slot]
1308 
1309    slot number is initialized by MySQL after xxx_init() is called.
1310    */
1311    uint slot;
1312    /*
1313      to store per-savepoint data storage engine is provided with an area
1314      of a requested size (0 is ok here).
1315      savepoint_offset must be initialized statically to the size of
1316      the needed memory to store per-savepoint information.
1317      After xxx_init it is changed to be an offset to savepoint storage
1318      area and need not be used by storage engine.
1319      see binlog_hton and binlog_savepoint_set/rollback for an example.
1320    */
1321    uint savepoint_offset;
1322    /*
1323      handlerton methods:
1324 
1325      close_connection is only called if
1326      thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
1327      this storage area - set it to something, so that MySQL would know
1328      this storage engine was accessed in this connection
1329    */
1330    int  (*close_connection)(handlerton *hton, THD *thd);
1331    /*
1332      Tell handler that query has been killed.
1333    */
1334    void (*kill_query)(handlerton *hton, THD *thd, enum thd_kill_levels level);
1335    /*
1336      sv points to an uninitialized storage area of requested size
1337      (see savepoint_offset description)
1338    */
1339    int  (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
1340    /*
1341      sv points to a storage area, that was earlier passed
1342      to the savepoint_set call
1343    */
1344    int  (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
1345    /**
1346      Check if storage engine allows to release metadata locks which were
1347      acquired after the savepoint if rollback to savepoint is done.
1348      @return true  - If it is safe to release MDL locks.
1349              false - If it is not.
1350    */
1351    bool (*savepoint_rollback_can_release_mdl)(handlerton *hton, THD *thd);
1352    int  (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
1353    /*
1354      'all' is true if it's a real commit, that makes persistent changes
1355      'all' is false if it's not in fact a commit but an end of the
1356      statement that is part of the transaction.
1357      NOTE 'all' is also false in auto-commit mode where 'end of statement'
1358      and 'real commit' mean the same event.
1359    */
1360    int (*commit)(handlerton *hton, THD *thd, bool all);
1361    /*
1362      The commit_ordered() method is called prior to the commit() method, after
1363      the transaction manager has decided to commit (not rollback) the
1364      transaction. Unlike commit(), commit_ordered() is called only when the
1365      full transaction is committed, not for each commit of statement
1366      transaction in a multi-statement transaction.
1367 
1368      Not that like prepare(), commit_ordered() is only called when 2-phase
1369      commit takes place. Ie. when no binary log and only a single engine
1370      participates in a transaction, one commit() is called, no
1371      commit_ordered(). So engines must be prepared for this.
1372 
1373      The calls to commit_ordered() in multiple parallel transactions is
1374      guaranteed to happen in the same order in every participating
1375      handler. This can be used to ensure the same commit order among multiple
1376      handlers (eg. in table handler and binlog). So if transaction T1 calls
1377      into commit_ordered() of handler A before T2, then T1 will also call
1378      commit_ordered() of handler B before T2.
1379 
1380      Engines that implement this method should during this call make the
1381      transaction visible to other transactions, thereby making the order of
1382      transaction commits be defined by the order of commit_ordered() calls.
1383 
1384      The intention is that commit_ordered() should do the minimal amount of
1385      work that needs to happen in consistent commit order among handlers. To
1386      preserve ordering, calls need to be serialised on a global mutex, so
1387      doing any time-consuming or blocking operations in commit_ordered() will
1388      limit scalability.
1389 
1390      Handlers can rely on commit_ordered() calls to be serialised (no two
1391      calls can run in parallel, so no extra locking on the handler part is
1392      required to ensure this).
1393 
1394      Note that commit_ordered() can be called from a different thread than the
1395      one handling the transaction! So it can not do anything that depends on
1396      thread local storage, in particular it can not call my_error() and
1397      friends (instead it can store the error code and delay the call of
1398      my_error() to the commit() method).
1399 
1400      Similarly, since commit_ordered() returns void, any return error code
1401      must be saved and returned from the commit() method instead.
1402 
1403      The commit_ordered method is optional, and can be left unset if not
1404      needed in a particular handler (then there will be no ordering guarantees
1405      wrt. other engines and binary log).
1406    */
1407    void (*commit_ordered)(handlerton *hton, THD *thd, bool all);
1408    int  (*rollback)(handlerton *hton, THD *thd, bool all);
1409    int  (*prepare)(handlerton *hton, THD *thd, bool all);
1410    /*
1411      The prepare_ordered method is optional. If set, it will be called after
1412      successful prepare() in all handlers participating in 2-phase
1413      commit. Like commit_ordered(), it is called only when the full
1414      transaction is committed, not for each commit of statement transaction.
1415 
1416      The calls to prepare_ordered() among multiple parallel transactions are
1417      ordered consistently with calls to commit_ordered(). This means that
1418      calls to prepare_ordered() effectively define the commit order, and that
1419      each handler will see the same sequence of transactions calling into
1420      prepare_ordered() and commit_ordered().
1421 
1422      Thus, prepare_ordered() can be used to define commit order for handlers
1423      that need to do this in the prepare step (like binlog). It can also be
1424      used to release transaction's locks early in an order consistent with the
1425      order transactions will be eventually committed.
1426 
1427      Like commit_ordered(), prepare_ordered() calls are serialised to maintain
1428      ordering, so the intention is that they should execute fast, with only
1429      the minimal amount of work needed to define commit order. Handlers can
1430      rely on this serialisation, and do not need to do any extra locking to
1431      avoid two prepare_ordered() calls running in parallel.
1432 
1433      Like commit_ordered(), prepare_ordered() is not guaranteed to be called
1434      in the context of the thread handling the rest of the transaction. So it
1435      cannot invoke code that relies on thread local storage, in particular it
1436      cannot call my_error().
1437 
1438      prepare_ordered() cannot cause a rollback by returning an error, all
1439      possible errors must be handled in prepare() (the prepare_ordered()
1440      method returns void). In case of some fatal error, a record of the error
1441      must be made internally by the engine and returned from commit() later.
1442 
1443      Note that for user-level XA SQL commands, no consistent ordering among
1444      prepare_ordered() and commit_ordered() is guaranteed (as that would
1445      require blocking all other commits for an indefinite time).
1446 
1447      When 2-phase commit is not used (eg. only one engine (and no binlog) in
1448      transaction), neither prepare() nor prepare_ordered() is called.
1449    */
1450    void (*prepare_ordered)(handlerton *hton, THD *thd, bool all);
1451    int  (*recover)(handlerton *hton, XID *xid_list, uint len);
1452    int  (*commit_by_xid)(handlerton *hton, XID *xid);
1453    int  (*rollback_by_xid)(handlerton *hton, XID *xid);
1454    /*
1455      The commit_checkpoint_request() handlerton method is used to checkpoint
1456      the XA recovery process for storage engines that support two-phase
1457      commit.
1458 
1459      The method is optional - an engine that does not implemented is expected
1460      to work the traditional way, where every commit() durably flushes the
1461      transaction to disk in the engine before completion, so XA recovery will
1462      no longer be needed for that transaction.
1463 
1464      An engine that does implement commit_checkpoint_request() is also
1465      expected to implement commit_ordered(), so that ordering of commits is
1466      consistent between 2pc participants. Such engine is no longer required to
1467      durably flush to disk transactions in commit(), provided that the
1468      transaction has been successfully prepare()d and commit_ordered(); thus
1469      potentionally saving one fsync() call. (Engine must still durably flush
1470      to disk in commit() when no prepare()/commit_ordered() steps took place,
1471      at least if durable commits are wanted; this happens eg. if binlog is
1472      disabled).
1473 
1474      The TC will periodically (eg. once per binlog rotation) call
1475      commit_checkpoint_request(). When this happens, the engine must arrange
1476      for all transaction that have completed commit_ordered() to be durably
1477      flushed to disk (this does not include transactions that might be in the
1478      middle of executing commit_ordered()). When such flush has completed, the
1479      engine must call commit_checkpoint_notify_ha(), passing back the opaque
1480      "cookie".
1481 
1482      The flush and call of commit_checkpoint_notify_ha() need not happen
1483      immediately - it can be scheduled and performed asynchronously (ie. as
1484      part of next prepare(), or sync every second, or whatever), but should
1485      not be postponed indefinitely. It is however also permissible to do it
1486      immediately, before returning from commit_checkpoint_request().
1487 
1488      When commit_checkpoint_notify_ha() is called, the TC will know that the
1489      transactions are durably committed, and thus no longer require XA
1490      recovery. It uses that to reduce the work needed for any subsequent XA
1491      recovery process.
1492    */
1493    void (*commit_checkpoint_request)(void *cookie);
1494   /*
1495     "Disable or enable checkpointing internal to the storage engine. This is
1496     used for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT to ensure that
1497     the engine will never start any recovery from a time between
1498     FLUSH TABLES ... ; UNLOCK TABLES.
1499 
1500     While checkpointing is disabled, the engine should pause any background
1501     write activity (such as tablespace checkpointing) that require consistency
1502     between different files (such as transaction log and tablespace files) for
1503     crash recovery to succeed. The idea is to use this to make safe
1504     multi-volume LVM snapshot backups.
1505   */
1506    int  (*checkpoint_state)(handlerton *hton, bool disabled);
1507    void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
1508    void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
1509    void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
1510    handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
1511    void (*drop_database)(handlerton *hton, char* path);
1512    /*
1513      return 0 if dropped successfully,
1514            -1 if nothing was done by design (as in e.g. blackhole)
1515            an error code (e.g. HA_ERR_NO_SUCH_TABLE) otherwise
1516    */
1517    int (*drop_table)(handlerton *hton, const char* path);
1518    int (*panic)(handlerton *hton, enum ha_panic_function flag);
1519    int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
1520    bool (*flush_logs)(handlerton *hton);
1521    bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
1522    uint (*partition_flags)();
1523    alter_table_operations (*alter_table_flags)(alter_table_operations flags);
1524    int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
1525    int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
1526                         class Item *cond,
1527                         enum enum_schema_tables);
1528    uint32 flags;                                /* global handler flags */
1529    /*
1530       Those handlerton functions below are properly initialized at handler
1531       init.
1532    */
1533    int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
1534    void (*binlog_log_query)(handlerton *hton, THD *thd,
1535                             enum_binlog_command binlog_command,
1536                             const char *query, uint query_length,
1537                             const char *db, const char *table_name);
1538 
1539    /*
1540      Get log status.
1541      If log_status is null then the handler do not support transaction
1542      log information (i.e. log iterator can't be created).
1543      (see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE)
1544 
1545    */
1546    enum log_status (*get_log_status)(handlerton *hton, char *log);
1547 
1548    /*
1549      Iterators creator.
1550      Presence of the pointer should be checked before using
1551    */
1552    enum handler_create_iterator_result
1553      (*create_iterator)(handlerton *hton, enum handler_iterator_type type,
1554                         struct handler_iterator *fill_this_in);
1555    void (*abort_transaction)(handlerton *hton, THD *bf_thd,
1556 			    THD *victim_thd, my_bool signal);
1557    int (*set_checkpoint)(handlerton *hton, const XID* xid);
1558    int (*get_checkpoint)(handlerton *hton, XID* xid);
1559    /*
1560      Optional clauses in the CREATE/ALTER TABLE
1561    */
1562    ha_create_table_option *table_options; // table level options
1563    ha_create_table_option *field_options; // these are specified per field
1564    ha_create_table_option *index_options; // these are specified per index
1565 
1566    /**
1567      The list of extensions of files created for a single table in the
1568      database directory (datadir/db_name/).
1569 
1570      Used by open_table_error(), by the default rename_table and delete_table
1571      handler methods, and by the default discovery implementation.
1572 
1573      For engines that have more than one file name extensions (separate
1574      metadata, index, and/or data files), the order of elements is relevant.
1575      First element of engine file name extensions array should be metadata
1576      file extention. This is implied by the open_table_error()
1577      and the default discovery implementation.
1578 
1579      Second element - data file extension. This is implied
1580      assumed by REPAIR TABLE ... USE_FRM implementation.
1581    */
1582    const char **tablefile_extensions; // by default - empty list
1583 
1584   /**********************************************************************
1585    Functions to intercept queries
1586   **********************************************************************/
1587 
1588   /*
1589     Create and return a group_by_handler, if the storage engine can execute
1590     the summary / group by query.
1591     If the storage engine can't do that, return NULL.
1592 
1593     The server guaranteeds that all tables in the list belong to this
1594     storage engine.
1595   */
1596   group_by_handler *(*create_group_by)(THD *thd, Query *query);
1597 
1598   /*
1599     Create and return a derived_handler if the storage engine can execute
1600     the derived table 'derived', otherwise return NULL.
1601     In a general case 'derived' may contain tables not from the engine.
1602     If the engine cannot handle or does not want to handle such pushed derived
1603     the function create_group_by has to return NULL.
1604   */
1605   derived_handler *(*create_derived)(THD *thd, TABLE_LIST *derived);
1606 
1607   /*
1608     Create and return a select_handler if the storage engine can execute
1609     the select statement 'select, otherwise return NULL
1610   */
1611   select_handler *(*create_select) (THD *thd, SELECT_LEX *select);
1612 
1613    /*********************************************************************
1614      Table discovery API.
1615      It allows the server to "discover" tables that exist in the storage
1616      engine, without user issuing an explicit CREATE TABLE statement.
1617    **********************************************************************/
1618 
1619    /*
1620      This method is required for any engine that supports automatic table
1621      discovery, there is no default implementation.
1622 
1623      Given a TABLE_SHARE discover_table() fills it in with a correct table
1624      structure using one of the TABLE_SHARE::init_from_* methods.
1625 
1626      Returns HA_ERR_NO_SUCH_TABLE if the table did not exist in the engine,
1627      zero if the table was discovered successfully, or any other
1628      HA_ERR_* error code as appropriate if the table existed, but the
1629      discovery failed.
1630    */
1631    int (*discover_table)(handlerton *hton, THD* thd, TABLE_SHARE *share);
1632 
1633    /*
1634      The discover_table_names method tells the server
1635      about all tables in the specified database that the engine
1636      knows about. Tables (or file names of tables) are added to
1637      the provided discovered_list collector object using
1638      add_table() or add_file() methods.
1639    */
1640    class discovered_list
1641    {
1642      public:
1643      virtual bool add_table(const char *tname, size_t tlen) = 0;
1644      virtual bool add_file(const char *fname) = 0;
~discovered_listhandlerton1645      protected: virtual ~discovered_list() {}
1646    };
1647 
1648    /*
1649      By default (if not implemented by the engine, but the discover_table() is
1650      implemented) it will perform a file-based discovery:
1651 
1652      - if tablefile_extensions[0] is not null, this will discovers all tables
1653        with the tablefile_extensions[0] extension.
1654 
1655      Returns 0 on success and 1 on error.
1656    */
1657    int (*discover_table_names)(handlerton *hton, LEX_CSTRING *db, MY_DIR *dir,
1658                                discovered_list *result);
1659 
1660    /*
1661      This is a method that allows to server to check if a table exists without
1662      an overhead of the complete discovery.
1663 
1664      By default (if not implemented by the engine, but the discovery_table() is
1665      implemented) it will try to perform a file-based discovery:
1666 
1667      - if tablefile_extensions[0] is not null this will look for a file name
1668        with the tablefile_extensions[0] extension.
1669 
1670      - if tablefile_extensions[0] is null, this will resort to discover_table().
1671 
1672      Note that resorting to discover_table() is slow and the engine
1673      should probably implement its own discover_table_existence() method,
1674      if its tablefile_extensions[0] is null.
1675 
1676      Returns 1 if the table exists and 0 if it does not.
1677    */
1678    int (*discover_table_existence)(handlerton *hton, const char *db,
1679                                    const char *table_name);
1680 
1681    /*
1682      This is the assisted table discovery method. Unlike the fully
1683      automatic discovery as above, here a user is expected to issue an
1684      explicit CREATE TABLE with the appropriate table attributes to
1685      "assist" the discovery of a table. But this "discovering" CREATE TABLE
1686      statement will not specify the table structure - the engine discovers
1687      it using this method. For example, FederatedX uses it in
1688 
1689       CREATE TABLE t1 ENGINE=FEDERATED CONNECTION="mysql://foo/bar/t1";
1690 
1691      Given a TABLE_SHARE discover_table_structure() fills it in with a correct
1692      table structure using one of the TABLE_SHARE::init_from_* methods.
1693 
1694      Assisted discovery works independently from the automatic discover.
1695      An engine is allowed to support only assisted discovery and not
1696      support automatic one. Or vice versa.
1697    */
1698    int (*discover_table_structure)(handlerton *hton, THD* thd,
1699                                    TABLE_SHARE *share, HA_CREATE_INFO *info);
1700 
1701   /*
1702     Notify the storage engine that the definition of the table (and the .frm
1703     file) has changed. Returns 0 if ok.
1704   */
1705   int (*notify_tabledef_changed)(handlerton *hton, LEX_CSTRING *db,
1706                                  LEX_CSTRING *table_name, LEX_CUSTRING *frm,
1707                                  LEX_CUSTRING *org_tabledef_version,
1708                                  handler *file);
1709 
1710    /*
1711      System Versioning
1712    */
1713    /** Determine if system-versioned data was modified by the transaction.
1714    @param[in,out] thd          current session
1715    @param[out]    trx_id       transaction start ID
1716    @return transaction commit ID
1717    @retval 0 if no system-versioned data was affected by the transaction */
1718    ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
1719 
1720   /* backup */
1721   void (*prepare_for_backup)(void);
1722   void (*end_backup)(void);
1723 
1724   /* Server shutdown early notification.*/
1725   void (*pre_shutdown)(void);
1726 
1727   /*
1728     Inform handler that partitioning engine has changed the .frm and the .par
1729     files
1730   */
1731   int (*create_partitioning_metadata)(const char *path,
1732                                       const char *old_path,
1733                                       chf_create_flags action_flag);
1734 };
1735 
1736 
hton_name(const handlerton * hton)1737 static inline LEX_CSTRING *hton_name(const handlerton *hton)
1738 {
1739   return &(hton2plugin[hton->slot]->name);
1740 }
1741 
plugin_hton(plugin_ref plugin)1742 static inline handlerton *plugin_hton(plugin_ref plugin)
1743 {
1744   return plugin_data(plugin, handlerton *);
1745 }
1746 
find_hton_sysvar(handlerton * hton,st_mysql_sys_var * var)1747 static inline sys_var *find_hton_sysvar(handlerton *hton, st_mysql_sys_var *var)
1748 {
1749   return find_plugin_sysvar(hton2plugin[hton->slot], var);
1750 }
1751 
1752 handlerton *ha_default_handlerton(THD *thd);
1753 handlerton *ha_default_tmp_handlerton(THD *thd);
1754 
1755 /* Possible flags of a handlerton (there can be 32 of them) */
1756 #define HTON_NO_FLAGS                 0
1757 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
1758 #define HTON_ALTER_NOT_SUPPORTED     (1 << 1) //Engine does not support alter
1759 #define HTON_CAN_RECREATE            (1 << 2) //Delete all is used for truncate
1760 #define HTON_HIDDEN                  (1 << 3) //Engine does not appear in lists
1761 #define HTON_NOT_USER_SELECTABLE     (1 << 5)
1762 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
1763 #define HTON_SUPPORT_LOG_TABLES      (1 << 7) //Engine supports log tables
1764 #define HTON_NO_PARTITION            (1 << 8) //Not partition of these tables
1765 
1766 /*
1767   This flag should be set when deciding that the engine does not allow
1768   row based binary logging (RBL) optimizations.
1769 
1770   Currently, setting this flag, means that table's read/write_set will
1771   be left untouched when logging changes to tables in this engine. In
1772   practice this means that the server will not mess around with
1773   table->write_set and/or table->read_set when using RBL and deciding
1774   whether to log full or minimal rows.
1775 
1776   It's valuable for instance for virtual tables, eg: Performance
1777   Schema which have no meaning for replication.
1778 */
1779 #define HTON_NO_BINLOG_ROW_OPT       (1 << 9)
1780 #define HTON_SUPPORTS_EXTENDED_KEYS  (1 <<10) //supports extended keys
1781 #define HTON_NATIVE_SYS_VERSIONING (1 << 11) //Engine supports System Versioning
1782 
1783 // MySQL compatibility. Unused.
1784 #define HTON_SUPPORTS_FOREIGN_KEYS   (1 << 0) //Foreign key constraint supported.
1785 
1786 #define HTON_CAN_MERGE               (1 <<11) //Merge type table
1787 // Engine needs to access the main connect string in partitions
1788 #define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 <<12)
1789 
1790 /* can be replicated by wsrep replication provider plugin */
1791 #define HTON_WSREP_REPLICATION (1 << 13)
1792 
1793 /*
1794   Set this on the *slave* that's connected to a shared with a master storage.
1795   The slave will ignore any CREATE TABLE, DROP or updates for this engine.
1796 */
1797 #define HTON_IGNORE_UPDATES (1 << 14)
1798 
1799 /*
1800   Set this on the *master* that's connected to a shared with a slave storage.
1801   The table may not exists on the slave. The effects of having this flag are:
1802   - ALTER TABLE that changes engine from this table to another engine will
1803     be replicated as CREATE + INSERT
1804   - CREATE ... LIKE shared_table will be replicated as a full CREATE TABLE
1805   - ALTER TABLE for this engine will have "IF EXISTS" added.
1806   - RENAME TABLE for this engine will have "IF EXISTS" added.
1807   - DROP TABLE for this engine will have "IF EXISTS" added.
1808 */
1809 #define HTON_TABLE_MAY_NOT_EXIST_ON_SLAVE (1 << 15)
1810 
1811 /*
1812   True if handler cannot rollback transactions. If not true, the transaction
1813   will be put in the transactional binlog cache.
1814   For some engines, like Aria, the rollback can happen in case of crash, but
1815   not trough a handler rollback call.
1816 */
1817 #define HTON_NO_ROLLBACK (1 << 16)
1818 
1819 /*
1820   This storage engine can support both transactional and non transactional
1821   tables
1822 */
1823 #define HTON_TRANSACTIONAL_AND_NON_TRANSACTIONAL (1 << 17)
1824 
1825 /*
1826   Table requires and close and reopen after truncate
1827   If the handler has HTON_CAN_RECREATE, this flag is not used
1828 */
1829 #define HTON_REQUIRES_CLOSE_AFTER_TRUNCATE (1 << 18)
1830 
1831 class Ha_trx_info;
1832 
1833 struct THD_TRANS
1834 {
1835   /* true is not all entries in the ht[] support 2pc */
1836   bool        no_2pc;
1837   /* storage engines that registered in this transaction */
1838   Ha_trx_info *ha_list;
1839   /*
1840     The purpose of this flag is to keep track of non-transactional
1841     tables that were modified in scope of:
1842     - transaction, when the variable is a member of
1843     THD::transaction.all
1844     - top-level statement or sub-statement, when the variable is a
1845     member of THD::transaction.stmt
1846     This member has the following life cycle:
1847     * stmt.modified_non_trans_table is used to keep track of
1848     modified non-transactional tables of top-level statements. At
1849     the end of the previous statement and at the beginning of the session,
1850     it is reset to FALSE.  If such functions
1851     as mysql_insert, mysql_update, mysql_delete etc modify a
1852     non-transactional table, they set this flag to TRUE.  At the
1853     end of the statement, the value of stmt.modified_non_trans_table
1854     is merged with all.modified_non_trans_table and gets reset.
1855     * all.modified_non_trans_table is reset at the end of transaction
1856 
1857     * Since we do not have a dedicated context for execution of a
1858     sub-statement, to keep track of non-transactional changes in a
1859     sub-statement, we re-use stmt.modified_non_trans_table.
1860     At entrance into a sub-statement, a copy of the value of
1861     stmt.modified_non_trans_table (containing the changes of the
1862     outer statement) is saved on stack. Then
1863     stmt.modified_non_trans_table is reset to FALSE and the
1864     substatement is executed. Then the new value is merged with the
1865     saved value.
1866   */
1867   bool modified_non_trans_table;
1868 
resetTHD_TRANS1869   void reset() {
1870     no_2pc= FALSE;
1871     modified_non_trans_table= FALSE;
1872     m_unsafe_rollback_flags= 0;
1873   }
is_emptyTHD_TRANS1874   bool is_empty() const { return ha_list == NULL; }
THD_TRANSTHD_TRANS1875   THD_TRANS() {}                        /* Remove gcc warning */
1876 
1877   unsigned int m_unsafe_rollback_flags;
1878  /*
1879     Define the type of statements which cannot be rolled back safely.
1880     Each type occupies one bit in m_unsafe_rollback_flags.
1881     MODIFIED_NON_TRANS_TABLE is limited to mark only the temporary
1882     non-transactional table *when* it's cached along with the transactional
1883     events; the regular table is covered by the "namesake" bool var.
1884   */
1885   enum unsafe_statement_types
1886   {
1887     MODIFIED_NON_TRANS_TABLE= 1,
1888     CREATED_TEMP_TABLE= 2,
1889     DROPPED_TEMP_TABLE= 4,
1890     DID_WAIT= 8,
1891     DID_DDL= 0x10,
1892     EXECUTED_TABLE_ADMIN_CMD= 0x20
1893   };
1894 
mark_modified_non_trans_temp_tableTHD_TRANS1895   void mark_modified_non_trans_temp_table()
1896   {
1897     m_unsafe_rollback_flags|= MODIFIED_NON_TRANS_TABLE;
1898   }
has_modified_non_trans_temp_tableTHD_TRANS1899   bool has_modified_non_trans_temp_table() const
1900   {
1901     return (m_unsafe_rollback_flags & MODIFIED_NON_TRANS_TABLE) != 0;
1902   }
mark_executed_table_admin_cmdTHD_TRANS1903   void mark_executed_table_admin_cmd()
1904   {
1905     DBUG_PRINT("debug", ("mark_executed_table_admin_cmd"));
1906     m_unsafe_rollback_flags|= EXECUTED_TABLE_ADMIN_CMD;
1907   }
trans_executed_admin_cmdTHD_TRANS1908   bool trans_executed_admin_cmd()
1909   {
1910     return (m_unsafe_rollback_flags & EXECUTED_TABLE_ADMIN_CMD) != 0;
1911   }
mark_created_temp_tableTHD_TRANS1912   void mark_created_temp_table()
1913   {
1914     DBUG_PRINT("debug", ("mark_created_temp_table"));
1915     m_unsafe_rollback_flags|= CREATED_TEMP_TABLE;
1916   }
mark_dropped_temp_tableTHD_TRANS1917   void mark_dropped_temp_table()
1918   {
1919     DBUG_PRINT("debug", ("mark_dropped_temp_table"));
1920     m_unsafe_rollback_flags|= DROPPED_TEMP_TABLE;
1921   }
has_created_dropped_temp_tableTHD_TRANS1922   bool has_created_dropped_temp_table() const {
1923     return
1924       (m_unsafe_rollback_flags & (CREATED_TEMP_TABLE|DROPPED_TEMP_TABLE)) != 0;
1925   }
mark_trans_did_waitTHD_TRANS1926   void mark_trans_did_wait() { m_unsafe_rollback_flags|= DID_WAIT; }
trans_did_waitTHD_TRANS1927   bool trans_did_wait() const {
1928     return (m_unsafe_rollback_flags & DID_WAIT) != 0;
1929   }
1930   bool is_trx_read_write() const;
mark_trans_did_ddlTHD_TRANS1931   void mark_trans_did_ddl() { m_unsafe_rollback_flags|= DID_DDL; }
trans_did_ddlTHD_TRANS1932   bool trans_did_ddl() const {
1933     return (m_unsafe_rollback_flags & DID_DDL) != 0;
1934   }
1935 
1936 };
1937 
1938 
1939 /**
1940   Either statement transaction or normal transaction - related
1941   thread-specific storage engine data.
1942 
1943   If a storage engine participates in a statement/transaction,
1944   an instance of this class is present in
1945   thd->transaction.{stmt|all}.ha_list. The addition to
1946   {stmt|all}.ha_list is made by trans_register_ha().
1947 
1948   When it's time to commit or rollback, each element of ha_list
1949   is used to access storage engine's prepare()/commit()/rollback()
1950   methods, and also to evaluate if a full two phase commit is
1951   necessary.
1952 
1953   @sa General description of transaction handling in handler.cc.
1954 */
1955 
1956 class Ha_trx_info
1957 {
1958 public:
1959   /** Register this storage engine in the given transaction context. */
register_ha(THD_TRANS * trans,handlerton * ht_arg)1960   void register_ha(THD_TRANS *trans, handlerton *ht_arg)
1961   {
1962     DBUG_ASSERT(m_flags == 0);
1963     DBUG_ASSERT(m_ht == NULL);
1964     DBUG_ASSERT(m_next == NULL);
1965 
1966     m_ht= ht_arg;
1967     m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */
1968 
1969     m_next= trans->ha_list;
1970     trans->ha_list= this;
1971   }
1972 
1973   /** Clear, prepare for reuse. */
reset()1974   void reset()
1975   {
1976     m_next= NULL;
1977     m_ht= NULL;
1978     m_flags= 0;
1979   }
1980 
Ha_trx_info()1981   Ha_trx_info() { reset(); }
1982 
set_trx_read_write()1983   void set_trx_read_write()
1984   {
1985     DBUG_ASSERT(is_started());
1986     m_flags|= (int) TRX_READ_WRITE;
1987   }
is_trx_read_write()1988   bool is_trx_read_write() const
1989   {
1990     DBUG_ASSERT(is_started());
1991     return m_flags & (int) TRX_READ_WRITE;
1992   }
is_started()1993   bool is_started() const { return m_ht != NULL; }
1994   /** Mark this transaction read-write if the argument is read-write. */
coalesce_trx_with(const Ha_trx_info * stmt_trx)1995   void coalesce_trx_with(const Ha_trx_info *stmt_trx)
1996   {
1997     /*
1998       Must be called only after the transaction has been started.
1999       Can be called many times, e.g. when we have many
2000       read-write statements in a transaction.
2001     */
2002     DBUG_ASSERT(is_started());
2003     if (stmt_trx->is_trx_read_write())
2004       set_trx_read_write();
2005   }
next()2006   Ha_trx_info *next() const
2007   {
2008     DBUG_ASSERT(is_started());
2009     return m_next;
2010   }
ht()2011   handlerton *ht() const
2012   {
2013     DBUG_ASSERT(is_started());
2014     return m_ht;
2015   }
2016 private:
2017   enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
2018   /** Auxiliary, used for ha_list management */
2019   Ha_trx_info *m_next;
2020   /**
2021     Although a given Ha_trx_info instance is currently always used
2022     for the same storage engine, 'ht' is not-NULL only when the
2023     corresponding storage is a part of a transaction.
2024   */
2025   handlerton *m_ht;
2026   /**
2027     Transaction flags related to this engine.
2028     Not-null only if this instance is a part of transaction.
2029     May assume a combination of enum values above.
2030   */
2031   uchar       m_flags;
2032 };
2033 
2034 
is_trx_read_write()2035 inline bool THD_TRANS::is_trx_read_write() const
2036 {
2037   Ha_trx_info *ha_info;
2038   for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
2039     if (ha_info->is_trx_read_write())
2040       return TRUE;
2041   return FALSE;
2042 }
2043 
2044 
2045 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
2046 			 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
2047 
2048 
2049 typedef struct {
2050   ulonglong data_file_length;
2051   ulonglong max_data_file_length;
2052   ulonglong index_file_length;
2053   ulonglong max_index_file_length;
2054   ulonglong delete_length;
2055   ha_rows records;
2056   ulong mean_rec_length;
2057   time_t create_time;
2058   time_t check_time;
2059   time_t update_time;
2060   ulonglong check_sum;
2061   bool check_sum_null;
2062 } PARTITION_STATS;
2063 
2064 #define UNDEF_NODEGROUP 65535
2065 class Item;
2066 struct st_table_log_memory_entry;
2067 
2068 class partition_info;
2069 
2070 struct st_partition_iter;
2071 
2072 enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES, HA_CHOICE_MAX };
2073 
2074 enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0,
2075                               HA_STATS_AUTO_RECALC_ON,
2076                               HA_STATS_AUTO_RECALC_OFF };
2077 
2078 /**
2079   A helper struct for schema DDL statements:
2080     CREATE SCHEMA [IF NOT EXISTS] name [ schema_specification... ]
2081     ALTER SCHEMA name [ schema_specification... ]
2082 
2083   It stores the "schema_specification" part of the CREATE/ALTER statements and
2084   is passed to mysql_create_db() and  mysql_alter_db().
2085   Currently consists of the schema default character set, collation
2086   and schema_comment.
2087 */
2088 struct Schema_specification_st
2089 {
2090   CHARSET_INFO *default_table_charset;
2091   LEX_CSTRING *schema_comment;
initSchema_specification_st2092   void init()
2093   {
2094     bzero(this, sizeof(*this));
2095   }
2096 };
2097 
2098 class Create_field;
2099 
2100 struct Table_period_info: Sql_alloc
2101 {
Table_period_infoTable_period_info2102   Table_period_info() :
2103     create_if_not_exists(false),
2104     constr(NULL),
2105     unique_keys(0) {}
Table_period_infoTable_period_info2106   Table_period_info(const char *name_arg, size_t size) :
2107     name(name_arg, size),
2108     create_if_not_exists(false),
2109     constr(NULL),
2110     unique_keys(0){}
2111 
2112   Lex_ident name;
2113 
2114   struct start_end_t
2115   {
start_end_tTable_period_info::start_end_t2116     start_end_t() {};
start_end_tTable_period_info::start_end_t2117     start_end_t(const LEX_CSTRING& _start, const LEX_CSTRING& _end) :
2118       start(_start),
2119       end(_end) {}
2120     Lex_ident start;
2121     Lex_ident end;
2122   };
2123   start_end_t period;
2124   bool create_if_not_exists;
2125   Virtual_column_info *constr;
2126   uint unique_keys;
2127 
is_setTable_period_info2128   bool is_set() const
2129   {
2130     DBUG_ASSERT(bool(period.start) == bool(period.end));
2131     return period.start;
2132   }
2133 
set_periodTable_period_info2134   void set_period(const Lex_ident& start, const Lex_ident& end)
2135   {
2136     period.start= start;
2137     period.end= end;
2138   }
2139   bool check_field(const Create_field* f, const Lex_ident& f_name) const;
2140 };
2141 
2142 struct Vers_parse_info: public Table_period_info
2143 {
Vers_parse_infoVers_parse_info2144   Vers_parse_info() :
2145     Table_period_info(STRING_WITH_LEN("SYSTEM_TIME")),
2146     versioned_fields(false),
2147     unversioned_fields(false)
2148   {}
2149 
2150   Table_period_info::start_end_t as_row;
2151 
2152 protected:
2153   friend struct Table_scope_and_contents_source_st;
set_startVers_parse_info2154   void set_start(const LEX_CSTRING field_name)
2155   {
2156     as_row.start= field_name;
2157     period.start= field_name;
2158   }
set_endVers_parse_info2159   void set_end(const LEX_CSTRING field_name)
2160   {
2161     as_row.end= field_name;
2162     period.end= field_name;
2163   }
2164   bool is_start(const char *name) const;
2165   bool is_end(const char *name) const;
2166   bool is_start(const Create_field &f) const;
2167   bool is_end(const Create_field &f) const;
2168   bool fix_implicit(THD *thd, Alter_info *alter_info);
2169   operator bool() const
2170   {
2171     return as_row.start || as_row.end || period.start || period.end;
2172   }
2173   bool need_check(const Alter_info *alter_info) const;
2174   bool check_conditions(const Lex_table_name &table_name,
2175                         const Lex_table_name &db) const;
2176 public:
2177   static const Lex_ident default_start;
2178   static const Lex_ident default_end;
2179 
2180   bool fix_alter_info(THD *thd, Alter_info *alter_info,
2181                        HA_CREATE_INFO *create_info, TABLE *table);
2182   bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
2183                        TABLE_LIST &src_table, TABLE_LIST &table);
2184   bool check_sys_fields(const Lex_table_name &table_name,
2185                         const Lex_table_name &db, Alter_info *alter_info) const;
2186 
2187   /**
2188      At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'.
2189      Useful for error handling.
2190   */
2191   bool versioned_fields : 1;
2192   bool unversioned_fields : 1;
2193 };
2194 
2195 /**
2196   A helper struct for table DDL statements, e.g.:
2197   CREATE [OR REPLACE] [TEMPORARY]
2198     TABLE [IF NOT EXISTS] tbl_name table_contents_source;
2199 
2200   Represents a combinations of:
2201   1. The scope, i.e. TEMPORARY or not TEMPORARY
2202   2. The "table_contents_source" part of the table DDL statements,
2203      which can be initialized from either of these:
2204      - table_element_list ...      // Explicit definition (column and key list)
2205      - LIKE another_table_name ... // Copy structure from another table
2206      - [AS] SELECT ...             // Copy structure from a subquery
2207 */
2208 
2209 struct Table_scope_and_contents_source_pod_st // For trivial members
2210 {
2211   CHARSET_INFO *alter_table_convert_to_charset;
2212   LEX_CUSTRING tabledef_version;
2213   LEX_CSTRING connect_string;
2214   LEX_CSTRING comment;
2215   LEX_CSTRING alias;
2216   const char *password, *tablespace;
2217   const char *data_file_name, *index_file_name;
2218   ulonglong max_rows,min_rows;
2219   ulonglong auto_increment_value;
2220   ulong table_options;                  ///< HA_OPTION_ values
2221   ulong avg_row_length;
2222   ulong used_fields;
2223   ulong key_block_size;
2224   ulong expression_length;
2225   ulong field_check_constraints;
2226   /*
2227     number of pages to sample during
2228     stats estimation, if used, otherwise 0.
2229   */
2230   uint stats_sample_pages;
2231   uint null_bits;                       /* NULL bits at start of record */
2232   uint options;				/* OR of HA_CREATE_ options */
2233   uint merge_insert_method;
2234   uint extra_size;                      /* length of extra data segment */
2235   handlerton *db_type;
2236   /**
2237     Row type of the table definition.
2238 
2239     Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
2240     For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
2241 
2242     Can be changed either explicitly by the parser.
2243     If nothing specified inherits the value of the original table (if present).
2244   */
2245   enum row_type row_type;
2246   enum ha_choice transactional;
2247   enum ha_storage_media storage_media;  ///< DEFAULT, DISK or MEMORY
2248   enum ha_choice page_checksum;         ///< If we have page_checksums
2249   engine_option_value *option_list;     ///< list of table create options
2250   enum_stats_auto_recalc stats_auto_recalc;
2251   bool varchar;                         ///< 1 if table has a VARCHAR
2252   bool sequence;                        // If SEQUENCE=1 was used
2253 
2254   List<Virtual_column_info> *check_constraint_list;
2255 
2256   /* the following three are only for ALTER TABLE, check_if_incompatible_data() */
2257   ha_table_option_struct *option_struct;           ///< structure with parsed table options
2258   ha_field_option_struct **fields_option_struct;   ///< array of field option structures
2259   ha_index_option_struct **indexes_option_struct;  ///< array of index option structures
2260 
2261   /* The following is used to remember the old state for CREATE OR REPLACE */
2262   TABLE *table;
2263   TABLE_LIST *pos_in_locked_tables;
2264   TABLE_LIST *merge_list;
2265   MDL_ticket *mdl_ticket;
2266   bool table_was_deleted;
2267   sequence_definition *seq_create_info;
2268 
initTable_scope_and_contents_source_pod_st2269   void init()
2270   {
2271     bzero(this, sizeof(*this));
2272   }
tmp_tableTable_scope_and_contents_source_pod_st2273   bool tmp_table() const { return options & HA_LEX_CREATE_TMP_TABLE; }
use_default_db_typeTable_scope_and_contents_source_pod_st2274   void use_default_db_type(THD *thd)
2275   {
2276     db_type= tmp_table() ? ha_default_tmp_handlerton(thd)
2277                          : ha_default_handlerton(thd);
2278   }
2279 
versionedTable_scope_and_contents_source_pod_st2280   bool versioned() const
2281   {
2282     return options & HA_VERSIONED_TABLE;
2283   }
2284 };
2285 
2286 
2287 struct Table_scope_and_contents_source_st:
2288          public Table_scope_and_contents_source_pod_st
2289 {
2290   Vers_parse_info vers_info;
2291   Table_period_info period_info;
2292 
initTable_scope_and_contents_source_st2293   void init()
2294   {
2295     Table_scope_and_contents_source_pod_st::init();
2296     vers_info= {};
2297     period_info= {};
2298   }
2299 
2300   bool fix_create_fields(THD *thd, Alter_info *alter_info,
2301                          const TABLE_LIST &create_table);
2302   bool fix_period_fields(THD *thd, Alter_info *alter_info);
2303   bool check_fields(THD *thd, Alter_info *alter_info,
2304                     const Lex_table_name &table_name,
2305                     const Lex_table_name &db,
2306                     int select_count= 0);
2307   bool check_period_fields(THD *thd, Alter_info *alter_info);
2308 
2309   bool vers_fix_system_fields(THD *thd, Alter_info *alter_info,
2310                               const TABLE_LIST &create_table);
2311 
2312   bool vers_check_system_fields(THD *thd, Alter_info *alter_info,
2313                                 const Lex_table_name &table_name,
2314                                 const Lex_table_name &db,
2315                                 int select_count= 0);
2316 
2317 };
2318 
2319 
2320 /**
2321   This struct is passed to handler table routines, e.g. ha_create().
2322   It does not include the "OR REPLACE" and "IF NOT EXISTS" parts, as these
2323   parts are handled on the SQL level and are not needed on the handler level.
2324 */
2325 struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
2326                        public Schema_specification_st
2327 {
2328   /* TODO: remove after MDEV-20865 */
2329   Alter_info *alter_info;
2330 
initHA_CREATE_INFO2331   void init()
2332   {
2333     Table_scope_and_contents_source_st::init();
2334     Schema_specification_st::init();
2335     alter_info= NULL;
2336   }
2337   bool check_conflicting_charset_declarations(CHARSET_INFO *cs);
add_table_option_default_charsetHA_CREATE_INFO2338   bool add_table_option_default_charset(CHARSET_INFO *cs)
2339   {
2340     // cs can be NULL, e.g.:  CREATE TABLE t1 (..) CHARACTER SET DEFAULT;
2341     if (check_conflicting_charset_declarations(cs))
2342       return true;
2343     default_table_charset= cs;
2344     used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
2345     return false;
2346   }
add_alter_list_item_convert_to_charsetHA_CREATE_INFO2347   bool add_alter_list_item_convert_to_charset(CHARSET_INFO *cs)
2348   {
2349     /*
2350       cs cannot be NULL, as sql_yacc.yy translates
2351          CONVERT TO CHARACTER SET DEFAULT
2352       to
2353          CONVERT TO CHARACTER SET <character-set-of-the-current-database>
2354       TODO: Shouldn't we postpone resolution of DEFAULT until the
2355       character set of the table owner database is loaded from its db.opt?
2356     */
2357     DBUG_ASSERT(cs);
2358     if (check_conflicting_charset_declarations(cs))
2359       return true;
2360     alter_table_convert_to_charset= default_table_charset= cs;
2361     used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
2362     return false;
2363   }
table_options_with_row_typeHA_CREATE_INFO2364   ulong table_options_with_row_type()
2365   {
2366     if (row_type == ROW_TYPE_DYNAMIC || row_type == ROW_TYPE_PAGE)
2367       return table_options | HA_OPTION_PACK_RECORD;
2368     else
2369       return table_options;
2370   }
2371 };
2372 
2373 
2374 /**
2375   This struct is passed to mysql_create_table() and similar creation functions,
2376   as well as to show_create_table().
2377 */
2378 struct Table_specification_st: public HA_CREATE_INFO,
2379                                public DDL_options_st
2380 {
2381   // Deep initialization
initTable_specification_st2382   void init()
2383   {
2384     HA_CREATE_INFO::init();
2385     DDL_options_st::init();
2386   }
initTable_specification_st2387   void init(DDL_options_st::Options options_arg)
2388   {
2389     HA_CREATE_INFO::init();
2390     DDL_options_st::init(options_arg);
2391   }
2392   /*
2393     Quick initialization, for parser.
2394     Most of the HA_CREATE_INFO is left uninitialized.
2395     It gets fully initialized in sql_yacc.yy, only when the parser
2396     scans a related keyword (e.g. CREATE, ALTER).
2397   */
lex_startTable_specification_st2398   void lex_start()
2399   {
2400     HA_CREATE_INFO::options= 0;
2401     DDL_options_st::init();
2402   }
2403 };
2404 
2405 
2406 /**
2407   In-place alter handler context.
2408 
2409   This is a superclass intended to be subclassed by individual handlers
2410   in order to store handler unique context between in-place alter API calls.
2411 
2412   The handler is responsible for creating the object. This can be done
2413   as early as during check_if_supported_inplace_alter().
2414 
2415   The SQL layer is responsible for destroying the object.
2416   The class extends Sql_alloc so the memory will be mem root allocated.
2417 
2418   @see Alter_inplace_info
2419 */
2420 
2421 class inplace_alter_handler_ctx : public Sql_alloc
2422 {
2423 public:
inplace_alter_handler_ctx()2424   inplace_alter_handler_ctx() {}
2425 
~inplace_alter_handler_ctx()2426   virtual ~inplace_alter_handler_ctx() {}
set_shared_data(const inplace_alter_handler_ctx & ctx)2427   virtual void set_shared_data(const inplace_alter_handler_ctx& ctx) {}
2428 };
2429 
2430 
2431 /**
2432   Class describing changes to be done by ALTER TABLE.
2433   Instance of this class is passed to storage engine in order
2434   to determine if this ALTER TABLE can be done using in-place
2435   algorithm. It is also used for executing the ALTER TABLE
2436   using in-place algorithm.
2437 */
2438 
2439 class Alter_inplace_info
2440 {
2441 public:
2442 
2443   /**
2444     Create options (like MAX_ROWS) for the new version of table.
2445 
2446     @note The referenced instance of HA_CREATE_INFO object was already
2447           used to create new .FRM file for table being altered. So it
2448           has been processed by mysql_prepare_create_table() already.
2449           For example, this means that it has HA_OPTION_PACK_RECORD
2450           flag in HA_CREATE_INFO::table_options member correctly set.
2451   */
2452   HA_CREATE_INFO *create_info;
2453 
2454   /**
2455     Alter options, fields and keys for the new version of table.
2456 
2457     @note The referenced instance of Alter_info object was already
2458           used to create new .FRM file for table being altered. So it
2459           has been processed by mysql_prepare_create_table() already.
2460           In particular, this means that in Create_field objects for
2461           fields which were present in some form in the old version
2462           of table, Create_field::field member points to corresponding
2463           Field instance for old version of table.
2464   */
2465   Alter_info *alter_info;
2466 
2467   /**
2468     Array of KEYs for new version of table - including KEYs to be added.
2469 
2470     @note Currently this array is produced as result of
2471           mysql_prepare_create_table() call.
2472           This means that it follows different convention for
2473           KEY_PART_INFO::fieldnr values than objects in TABLE::key_info
2474           array.
2475 
2476     @todo This is mainly due to the fact that we need to keep compatibility
2477           with removed handler::add_index() call. We plan to switch to
2478           TABLE::key_info numbering later.
2479 
2480     KEYs are sorted - see sort_keys().
2481   */
2482   KEY  *key_info_buffer;
2483 
2484   /** Size of key_info_buffer array. */
2485   uint key_count;
2486 
2487   /** Size of index_drop_buffer array. */
2488   uint index_drop_count;
2489 
2490   /**
2491      Array of pointers to KEYs to be dropped belonging to the TABLE instance
2492      for the old version of the table.
2493   */
2494   KEY  **index_drop_buffer;
2495 
2496   /** Size of index_add_buffer array. */
2497   uint index_add_count;
2498 
2499   /**
2500      Array of indexes into key_info_buffer for KEYs to be added,
2501      sorted in increasing order.
2502   */
2503   uint *index_add_buffer;
2504 
2505   /**
2506      Old and new index names. Used for index rename.
2507   */
2508   struct Rename_key_pair
2509   {
Rename_key_pairRename_key_pair2510     Rename_key_pair(const KEY *old_key, const KEY *new_key)
2511         : old_key(old_key), new_key(new_key)
2512     {
2513     }
2514     const KEY *old_key;
2515     const KEY *new_key;
2516   };
2517   /**
2518      Vector of key pairs from DROP/ADD index which can be renamed.
2519   */
2520   typedef Mem_root_array<Rename_key_pair, true> Rename_keys_vector;
2521 
2522   /**
2523      A list of indexes which should be renamed.
2524      Index definitions stays the same.
2525   */
2526   Rename_keys_vector rename_keys;
2527 
2528   /**
2529      Context information to allow handlers to keep context between in-place
2530      alter API calls.
2531 
2532      @see inplace_alter_handler_ctx for information about object lifecycle.
2533   */
2534   inplace_alter_handler_ctx *handler_ctx;
2535 
2536   /**
2537     If the table uses several handlers, like ha_partition uses one handler
2538     per partition, this contains a Null terminated array of ctx pointers
2539     that should all be committed together.
2540     Or NULL if only handler_ctx should be committed.
2541     Set to NULL if the low level handler::commit_inplace_alter_table uses it,
2542     to signal to the main handler that everything was committed as atomically.
2543 
2544     @see inplace_alter_handler_ctx for information about object lifecycle.
2545   */
2546   inplace_alter_handler_ctx **group_commit_ctx;
2547 
2548   /**
2549      Flags describing in detail which operations the storage engine is to
2550      execute. Flags are defined in sql_alter.h
2551   */
2552   alter_table_operations handler_flags;
2553 
2554   /* Alter operations involving parititons are strored here */
2555   ulong partition_flags;
2556 
2557   /**
2558      Partition_info taking into account the partition changes to be performed.
2559      Contains all partitions which are present in the old version of the table
2560      with partitions to be dropped or changed marked as such + all partitions
2561      to be added in the new version of table marked as such.
2562   */
2563   partition_info *modified_part_info;
2564 
2565   /** true for ALTER IGNORE TABLE ... */
2566   const bool ignore;
2567 
2568   /** true for online operation (LOCK=NONE) */
2569   bool online;
2570 
2571   /** which ALGORITHM and LOCK are supported by the storage engine */
2572   enum_alter_inplace_result inplace_supported;
2573 
2574   /**
2575      Can be set by handler to describe why a given operation cannot be done
2576      in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
2577      online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_COPY_NO_LOCK)
2578      If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
2579      results from handler::check_if_supported_inplace_alter() doesn't match
2580      requirements set by user. If not set, the more generic
2581      ER_ALTER_OPERATION_NOT_SUPPORTED will be used.
2582 
2583      Please set to a properly localized string, for example using
2584      my_get_err_msg(), so that the error message as a whole is localized.
2585   */
2586   const char *unsupported_reason;
2587 
2588   /** true when InnoDB should abort the alter when table is not empty */
2589   bool error_if_not_empty;
2590 
2591   /** True when DDL should avoid downgrading the MDL */
2592   bool mdl_exclusive_after_prepare= false;
2593 
2594   Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
2595                      Alter_info *alter_info_arg,
2596                      KEY *key_info_arg, uint key_count_arg,
2597                      partition_info *modified_part_info_arg,
2598                      bool ignore_arg, bool error_non_empty);
2599 
~Alter_inplace_info()2600   ~Alter_inplace_info()
2601   {
2602     delete handler_ctx;
2603   }
2604 
2605   /**
2606     Used after check_if_supported_inplace_alter() to report
2607     error if the result does not match the LOCK/ALGORITHM
2608     requirements set by the user.
2609 
2610     @param not_supported  Part of statement that was not supported.
2611     @param try_instead    Suggestion as to what the user should
2612                           replace not_supported with.
2613   */
2614   void report_unsupported_error(const char *not_supported,
2615                                 const char *try_instead) const;
2616 };
2617 
2618 
2619 typedef struct st_key_create_information
2620 {
2621   enum ha_key_alg algorithm;
2622   ulong block_size;
2623   uint flags;                                   /* HA_USE.. flags */
2624   LEX_CSTRING parser_name;
2625   LEX_CSTRING comment;
2626   /**
2627     A flag to determine if we will check for duplicate indexes.
2628     This typically means that the key information was specified
2629     directly by the user (set by the parser).
2630   */
2631   bool check_for_duplicate_indexes;
2632 } KEY_CREATE_INFO;
2633 
2634 
2635 /*
2636   Class for maintaining hooks used inside operations on tables such
2637   as: create table functions, delete table functions, and alter table
2638   functions.
2639 
2640   Class is using the Template Method pattern to separate the public
2641   usage interface from the private inheritance interface.  This
2642   imposes no overhead, since the public non-virtual function is small
2643   enough to be inlined.
2644 
2645   The hooks are usually used for functions that does several things,
2646   e.g., create_table_from_items(), which both create a table and lock
2647   it.
2648  */
2649 class TABLEOP_HOOKS
2650 {
2651 public:
TABLEOP_HOOKS()2652   TABLEOP_HOOKS() {}
~TABLEOP_HOOKS()2653   virtual ~TABLEOP_HOOKS() {}
2654 
prelock(TABLE ** tables,uint count)2655   inline void prelock(TABLE **tables, uint count)
2656   {
2657     do_prelock(tables, count);
2658   }
2659 
postlock(TABLE ** tables,uint count)2660   inline int postlock(TABLE **tables, uint count)
2661   {
2662     return do_postlock(tables, count);
2663   }
2664 private:
2665   /* Function primitive that is called prior to locking tables */
do_prelock(TABLE ** tables,uint count)2666   virtual void do_prelock(TABLE **tables, uint count)
2667   {
2668     /* Default is to do nothing */
2669   }
2670 
2671   /**
2672      Primitive called after tables are locked.
2673 
2674      If an error is returned, the tables will be unlocked and error
2675      handling start.
2676 
2677      @return Error code or zero.
2678    */
do_postlock(TABLE ** tables,uint count)2679   virtual int do_postlock(TABLE **tables, uint count)
2680   {
2681     return 0;                           /* Default is to do nothing */
2682   }
2683 };
2684 
2685 typedef struct st_savepoint SAVEPOINT;
2686 extern ulong savepoint_alloc_size;
2687 extern KEY_CREATE_INFO default_key_create_info;
2688 
2689 /* Forward declaration for condition pushdown to storage engine */
2690 typedef class Item COND;
2691 
2692 typedef struct st_ha_check_opt
2693 {
st_ha_check_optst_ha_check_opt2694   st_ha_check_opt() {}                        /* Remove gcc warning */
2695   uint flags;       /* isam layer flags (e.g. for myisamchk) */
2696   uint sql_flags;   /* sql layer flags - for something myisamchk cannot do */
2697   time_t start_time;   /* When check/repair starts */
2698   KEY_CACHE *key_cache; /* new key cache when changing key cache */
2699   void init();
2700 } HA_CHECK_OPT;
2701 
2702 
2703 /********************************************************************************
2704  * MRR
2705  ********************************************************************************/
2706 
2707 typedef void *range_seq_t;
2708 
2709 typedef struct st_range_seq_if
2710 {
2711   /*
2712     Get key information
2713 
2714     SYNOPSIS
2715       get_key_info()
2716         init_params  The seq_init_param parameter
2717         length       OUT length of the keys in this range sequence
2718         map          OUT key_part_map of the keys in this range sequence
2719 
2720     DESCRIPTION
2721       This function is set only when using HA_MRR_FIXED_KEY mode. In that mode,
2722       all ranges are single-point equality ranges that use the same set of key
2723       parts. This function allows the MRR implementation to get the length of
2724       a key, and which keyparts it uses.
2725   */
2726   void (*get_key_info)(void *init_params, uint *length, key_part_map *map);
2727 
2728   /*
2729     Initialize the traversal of range sequence
2730 
2731     SYNOPSIS
2732       init()
2733         init_params  The seq_init_param parameter
2734         n_ranges     The number of ranges obtained
2735         flags        A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
2736 
2737     RETURN
2738       An opaque value to be used as RANGE_SEQ_IF::next() parameter
2739   */
2740   range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
2741 
2742 
2743   /*
2744     Get the next range in the range sequence
2745 
2746     SYNOPSIS
2747       next()
2748         seq    The value returned by RANGE_SEQ_IF::init()
2749         range  OUT Information about the next range
2750 
2751     RETURN
2752       FALSE - Ok, the range structure filled with info about the next range
2753       TRUE  - No more ranges
2754   */
2755   bool (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
2756 
2757   /*
2758     Check whether range_info orders to skip the next record
2759 
2760     SYNOPSIS
2761       skip_record()
2762         seq         The value returned by RANGE_SEQ_IF::init()
2763         range_info  Information about the next range
2764                     (Ignored if MRR_NO_ASSOCIATION is set)
2765         rowid       Rowid of the record to be checked (ignored if set to 0)
2766 
2767     RETURN
2768       1 - Record with this range_info and/or this rowid shall be filtered
2769           out from the stream of records returned by multi_range_read_next()
2770       0 - The record shall be left in the stream
2771   */
2772   bool (*skip_record) (range_seq_t seq, range_id_t range_info, uchar *rowid);
2773 
2774   /*
2775     Check if the record combination matches the index condition
2776     SYNOPSIS
2777       skip_index_tuple()
2778         seq         The value returned by RANGE_SEQ_IF::init()
2779         range_info  Information about the next range
2780 
2781     RETURN
2782       0 - The record combination satisfies the index condition
2783       1 - Otherwise
2784   */
2785   bool (*skip_index_tuple) (range_seq_t seq, range_id_t range_info);
2786 } RANGE_SEQ_IF;
2787 
2788 typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, range_id_t range_info);
2789 
2790 class Cost_estimate
2791 {
2792 public:
2793   double io_count;        /* number of I/O to fetch records                */
2794   double avg_io_cost;     /* cost of an average I/O oper. to fetch records */
2795   double idx_io_count;    /* number of I/O to read keys                    */
2796   double idx_avg_io_cost; /* cost of an average I/O oper. to fetch records */
2797   double cpu_cost;        /* total cost of operations in CPU               */
2798   double idx_cpu_cost;    /* cost of operations in CPU for index           */
2799   double import_cost;     /* cost of remote operations     */
2800   double mem_cost;        /* cost of used memory           */
2801 
2802   static constexpr double IO_COEFF= 1;
2803   static constexpr double CPU_COEFF= 1;
2804   static constexpr double MEM_COEFF= 1;
2805   static constexpr double IMPORT_COEFF= 1;
2806 
Cost_estimate()2807   Cost_estimate()
2808   {
2809     reset();
2810   }
2811 
total_cost()2812   double total_cost() const
2813   {
2814     return IO_COEFF*io_count*avg_io_cost +
2815            IO_COEFF*idx_io_count*idx_avg_io_cost +
2816            CPU_COEFF*(cpu_cost + idx_cpu_cost) +
2817            MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost;
2818   }
2819 
index_only_cost()2820   double index_only_cost()
2821   {
2822     return IO_COEFF*idx_io_count*idx_avg_io_cost +
2823            CPU_COEFF*idx_cpu_cost;
2824   }
2825 
2826   /**
2827     Whether or not all costs in the object are zero
2828 
2829     @return true if all costs are zero, false otherwise
2830   */
is_zero()2831   bool is_zero() const
2832   {
2833     return io_count == 0.0 && idx_io_count == 0.0 && cpu_cost == 0.0 &&
2834       import_cost == 0.0 && mem_cost == 0.0;
2835   }
2836 
reset()2837   void reset()
2838   {
2839     avg_io_cost= 1.0;
2840     idx_avg_io_cost= 1.0;
2841     io_count= idx_io_count= cpu_cost= idx_cpu_cost= mem_cost= import_cost= 0.0;
2842   }
2843 
multiply(double m)2844   void multiply(double m)
2845   {
2846     io_count *= m;
2847     cpu_cost *= m;
2848     idx_io_count *= m;
2849     idx_cpu_cost *= m;
2850     import_cost *= m;
2851     /* Don't multiply mem_cost */
2852   }
2853 
add(const Cost_estimate * cost)2854   void add(const Cost_estimate* cost)
2855   {
2856     if (cost->io_count != 0.0)
2857     {
2858       double io_count_sum= io_count + cost->io_count;
2859       avg_io_cost= (io_count * avg_io_cost +
2860                     cost->io_count * cost->avg_io_cost)
2861 	            /io_count_sum;
2862       io_count= io_count_sum;
2863     }
2864     if (cost->idx_io_count != 0.0)
2865     {
2866       double idx_io_count_sum= idx_io_count + cost->idx_io_count;
2867       idx_avg_io_cost= (idx_io_count * idx_avg_io_cost +
2868                         cost->idx_io_count * cost->idx_avg_io_cost)
2869 	               /idx_io_count_sum;
2870       idx_io_count= idx_io_count_sum;
2871     }
2872     cpu_cost += cost->cpu_cost;
2873     idx_cpu_cost += cost->idx_cpu_cost;
2874     import_cost += cost->import_cost;
2875   }
2876 
add_io(double add_io_cnt,double add_avg_cost)2877   void add_io(double add_io_cnt, double add_avg_cost)
2878   {
2879     /* In edge cases add_io_cnt may be zero */
2880     if (add_io_cnt > 0)
2881     {
2882       double io_count_sum= io_count + add_io_cnt;
2883       avg_io_cost= (io_count * avg_io_cost +
2884                     add_io_cnt * add_avg_cost) / io_count_sum;
2885       io_count= io_count_sum;
2886     }
2887   }
2888 
2889   /// Add to CPU cost
add_cpu(double add_cpu_cost)2890   void add_cpu(double add_cpu_cost) { cpu_cost+= add_cpu_cost; }
2891 
2892   /// Add to import cost
add_import(double add_import_cost)2893   void add_import(double add_import_cost) { import_cost+= add_import_cost; }
2894 
2895   /// Add to memory cost
add_mem(double add_mem_cost)2896   void add_mem(double add_mem_cost) { mem_cost+= add_mem_cost; }
2897 
2898   /*
2899     To be used when we go from old single value-based cost calculations to
2900     the new Cost_estimate-based.
2901   */
convert_from_cost(double cost)2902   void convert_from_cost(double cost)
2903   {
2904     reset();
2905     io_count= cost;
2906   }
2907 };
2908 
2909 void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
2910                          Cost_estimate *cost);
2911 
2912 /*
2913   Indicates that all scanned ranges will be singlepoint (aka equality) ranges.
2914   The ranges may not use the full key but all of them will use the same number
2915   of key parts.
2916 */
2917 #define HA_MRR_SINGLE_POINT 1U
2918 #define HA_MRR_FIXED_KEY  2U
2919 
2920 /*
2921   Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
2922   'range' parameter.
2923 */
2924 #define HA_MRR_NO_ASSOCIATION 4U
2925 
2926 /*
2927   The MRR user will provide ranges in key order, and MRR implementation
2928   must return rows in key order.
2929 */
2930 #define HA_MRR_SORTED 8U
2931 
2932 /* MRR implementation doesn't have to retrieve full records */
2933 #define HA_MRR_INDEX_ONLY 16U
2934 
2935 /*
2936   The passed memory buffer is of maximum possible size, the caller can't
2937   assume larger buffer.
2938 */
2939 #define HA_MRR_LIMITS 32U
2940 
2941 
2942 /*
2943   Flag set <=> default MRR implementation is used
2944   (The choice is made by **_info[_const]() function which may set this
2945    flag. SQL layer remembers the flag value and then passes it to
2946    multi_read_range_init().
2947 */
2948 #define HA_MRR_USE_DEFAULT_IMPL 64U
2949 
2950 /*
2951   Used only as parameter to multi_range_read_info():
2952   Flag set <=> the caller guarantees that the bounds of the scanned ranges
2953   will not have NULL values.
2954 */
2955 #define HA_MRR_NO_NULL_ENDPOINTS 128U
2956 
2957 /*
2958   The MRR user has materialized range keys somewhere in the user's buffer.
2959   This can be used for optimization of the procedure that sorts these keys
2960   since in this case key values don't have to be copied into the MRR buffer.
2961 
2962   In other words, it is guaranteed that after RANGE_SEQ_IF::next() call the
2963   pointer in range->start_key.key will point to a key value that will remain
2964   there until the end of the MRR scan.
2965 */
2966 #define HA_MRR_MATERIALIZED_KEYS 256U
2967 
2968 /*
2969   The following bits are reserved for use by MRR implementation. The intended
2970   use scenario:
2971 
2972   * sql layer calls handler->multi_range_read_info[_const]()
2973     - MRR implementation figures out what kind of scan it will perform, saves
2974       the result in *mrr_mode parameter.
2975   * sql layer remembers what was returned in *mrr_mode
2976 
2977   * the optimizer picks the query plan (which may or may not include the MRR
2978     scan that was estimated by the multi_range_read_info[_const] call)
2979 
2980   * if the query is an EXPLAIN statement, sql layer will call
2981     handler->multi_range_read_explain_info(mrr_mode) to get a text description
2982     of the picked MRR scan; the description will be a part of EXPLAIN output.
2983 */
2984 #define HA_MRR_IMPLEMENTATION_FLAG1 512U
2985 #define HA_MRR_IMPLEMENTATION_FLAG2 1024U
2986 #define HA_MRR_IMPLEMENTATION_FLAG3 2048U
2987 #define HA_MRR_IMPLEMENTATION_FLAG4 4096U
2988 #define HA_MRR_IMPLEMENTATION_FLAG5 8192U
2989 #define HA_MRR_IMPLEMENTATION_FLAG6 16384U
2990 
2991 #define HA_MRR_IMPLEMENTATION_FLAGS \
2992   (512U | 1024U | 2048U | 4096U | 8192U | 16384U)
2993 
2994 /*
2995   This is a buffer area that the handler can use to store rows.
2996   'end_of_used_area' should be kept updated after calls to
2997   read-functions so that other parts of the code can use the
2998   remaining area (until next read calls is issued).
2999 */
3000 
3001 typedef struct st_handler_buffer
3002 {
3003   /* const? */uchar *buffer;         /* Buffer one can start using */
3004   /* const? */uchar *buffer_end;     /* End of buffer */
3005   uchar *end_of_used_area;     /* End of area that was used by handler */
3006 } HANDLER_BUFFER;
3007 
3008 typedef struct system_status_var SSV;
3009 
3010 class ha_statistics
3011 {
3012 public:
3013   ulonglong data_file_length;		/* Length off data file */
3014   ulonglong max_data_file_length;	/* Length off data file */
3015   ulonglong index_file_length;
3016   ulonglong max_index_file_length;
3017   ulonglong delete_length;		/* Free bytes */
3018   ulonglong auto_increment_value;
3019   /*
3020     The number of records in the table.
3021       0    - means the table has exactly 0 rows
3022     other  - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
3023                the value is the exact number of records in the table
3024              else
3025                it is an estimate
3026   */
3027   ha_rows records;
3028   ha_rows deleted;			/* Deleted records */
3029   ulong mean_rec_length;		/* physical reclength */
3030   time_t create_time;			/* When table was created */
3031   time_t check_time;
3032   time_t update_time;
3033   uint block_size;			/* index block size */
3034   ha_checksum checksum;
3035   bool checksum_null;
3036 
3037   /*
3038     number of buffer bytes that native mrr implementation needs,
3039   */
3040   uint mrr_length_per_rec;
3041 
ha_statistics()3042   ha_statistics():
3043     data_file_length(0), max_data_file_length(0),
3044     index_file_length(0), max_index_file_length(0), delete_length(0),
3045     auto_increment_value(0), records(0), deleted(0), mean_rec_length(0),
3046     create_time(0), check_time(0), update_time(0), block_size(8192),
3047     checksum(0), checksum_null(FALSE), mrr_length_per_rec(0)
3048   {}
3049 };
3050 
3051 extern "C" check_result_t handler_index_cond_check(void* h_arg);
3052 
3053 extern "C" check_result_t handler_rowid_filter_check(void* h_arg);
3054 extern "C" int handler_rowid_filter_is_active(void* h_arg);
3055 
3056 uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
3057 /*
3058   bitmap with first N+1 bits set
3059   (keypart_map for a key prefix of [0..N] keyparts)
3060 */
3061 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
3062 /*
3063   bitmap with first N bits set
3064   (keypart_map for a key prefix of [0..N-1] keyparts)
3065 */
3066 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
3067 
3068 
3069 /** Base class to be used by handlers different shares */
3070 class Handler_share
3071 {
3072 public:
Handler_share()3073   Handler_share() {}
~Handler_share()3074   virtual ~Handler_share() {}
3075 };
3076 
3077 enum class Compare_keys : uint32_t
3078 {
3079   Equal= 0,
3080   EqualButKeyPartLength,
3081   EqualButComment,
3082   NotEqual
3083 };
3084 
3085 /**
3086   The handler class is the interface for dynamically loadable
3087   storage engines. Do not add ifdefs and take care when adding or
3088   changing virtual functions to avoid vtable confusion
3089 
3090   Functions in this class accept and return table columns data. Two data
3091   representation formats are used:
3092   1. TableRecordFormat - Used to pass [partial] table records to/from
3093      storage engine
3094 
3095   2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
3096      storage engine. See opt_range.cc for description of this format.
3097 
3098   TableRecordFormat
3099   =================
3100   [Warning: this description is work in progress and may be incomplete]
3101   The table record is stored in a fixed-size buffer:
3102 
3103     record: null_bytes, column1_data, column2_data, ...
3104 
3105   The offsets of the parts of the buffer are also fixed: every column has
3106   an offset to its column{i}_data, and if it is nullable it also has its own
3107   bit in null_bytes.
3108 
3109   The record buffer only includes data about columns that are marked in the
3110   relevant column set (table->read_set and/or table->write_set, depending on
3111   the situation).
3112   <not-sure>It could be that it is required that null bits of non-present
3113   columns are set to 1</not-sure>
3114 
3115   VARIOUS EXCEPTIONS AND SPECIAL CASES
3116 
3117   If the table has no nullable columns, then null_bytes is still
3118   present, its length is one byte <not-sure> which must be set to 0xFF
3119   at all times. </not-sure>
3120 
3121   If the table has columns of type BIT, then certain bits from those columns
3122   may be stored in null_bytes as well. Grep around for Field_bit for
3123   details.
3124 
3125   For blob columns (see Field_blob), the record buffer stores length of the
3126   data, following by memory pointer to the blob data. The pointer is owned
3127   by the storage engine and is valid until the next operation.
3128 
3129   If a blob column has NULL value, then its length and blob data pointer
3130   must be set to 0.
3131 */
3132 
3133 class handler :public Sql_alloc
3134 {
3135 public:
3136   typedef ulonglong Table_flags;
3137 protected:
3138   TABLE_SHARE *table_share;   /* The table definition */
3139   TABLE *table;               /* The current open table */
3140   Table_flags cached_table_flags;       /* Set on init() and open() */
3141 
3142   ha_rows estimation_rows_to_insert;
3143   handler *lookup_handler;
3144 public:
3145   handlerton *ht;                 /* storage engine of this handler */
3146   uchar *ref;				/* Pointer to current row */
3147   uchar *dup_ref;			/* Pointer to duplicate row */
3148   uchar *lookup_buffer;
3149 
3150   ha_statistics stats;
3151 
3152   /** MultiRangeRead-related members: */
3153   range_seq_t mrr_iter;    /* Iterator to traverse the range sequence */
3154   RANGE_SEQ_IF mrr_funcs;  /* Range sequence traversal functions */
3155   HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
3156   uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
3157   /** Current range (the one we're now returning rows from) */
3158   KEY_MULTI_RANGE mrr_cur_range;
3159 
3160   /** The following are for read_range() */
3161   key_range save_end_range, *end_range;
3162   KEY_PART_INFO *range_key_part;
3163   int key_compare_result_on_equal;
3164 
3165   /* TRUE <=> source MRR ranges and the output are ordered */
3166   bool mrr_is_output_sorted;
3167   /** TRUE <=> we're currently traversing a range in mrr_cur_range. */
3168   bool mrr_have_range;
3169   bool eq_range;
3170   bool internal_tmp_table;                 /* If internal tmp table */
3171   bool implicit_emptied;                   /* Can be !=0 only if HEAP */
3172   bool mark_trx_read_write_done;           /* mark_trx_read_write was called */
3173   bool check_table_binlog_row_based_done; /* check_table_binlog.. was called */
3174   bool check_table_binlog_row_based_result; /* cached check_table_binlog... */
3175   /*
3176     TRUE <=> the engine guarantees that returned records are within the range
3177     being scanned.
3178   */
3179   bool in_range_check_pushed_down;
3180 
3181   uint lookup_errkey;
3182   uint errkey;                             /* Last dup key */
3183   uint key_used_on_scan;
3184   uint active_index, keyread;
3185 
3186   /** Length of ref (1-8 or the clustered key length) */
3187   uint ref_length;
3188   FT_INFO *ft_handler;
3189   enum init_stat { NONE=0, INDEX, RND };
3190   init_stat inited, pre_inited;
3191 
3192   const COND *pushed_cond;
3193   /**
3194     next_insert_id is the next value which should be inserted into the
3195     auto_increment column: in a inserting-multi-row statement (like INSERT
3196     SELECT), for the first row where the autoinc value is not specified by the
3197     statement, get_auto_increment() called and asked to generate a value,
3198     next_insert_id is set to the next value, then for all other rows
3199     next_insert_id is used (and increased each time) without calling
3200     get_auto_increment().
3201   */
3202   ulonglong next_insert_id;
3203   /**
3204     insert id for the current row (*autogenerated*; if not
3205     autogenerated, it's 0).
3206     At first successful insertion, this variable is stored into
3207     THD::first_successful_insert_id_in_cur_stmt.
3208   */
3209   ulonglong insert_id_for_cur_row;
3210   /**
3211     Interval returned by get_auto_increment() and being consumed by the
3212     inserter.
3213   */
3214   /* Statistics  variables */
3215   ulonglong rows_read;
3216   ulonglong rows_tmp_read;
3217   ulonglong rows_changed;
3218   /* One bigger than needed to avoid to test if key == MAX_KEY */
3219   ulonglong index_rows_read[MAX_KEY+1];
3220   ha_copy_info copy_info;
3221 
3222 private:
3223   /* ANALYZE time tracker, if present */
3224   Exec_time_tracker *tracker;
3225 public:
set_time_tracker(Exec_time_tracker * tracker_arg)3226   void set_time_tracker(Exec_time_tracker *tracker_arg) { tracker=tracker_arg;}
get_time_tracker()3227   Exec_time_tracker *get_time_tracker() { return tracker; }
3228 
3229   Item *pushed_idx_cond;
3230   uint pushed_idx_cond_keyno;  /* The index which the above condition is for */
3231 
3232   /* Rowid filter pushed into the engine */
3233   Rowid_filter *pushed_rowid_filter;
3234   /* true when the pushed rowid filter has been already filled */
3235   bool rowid_filter_is_active;
3236   /* Used for disabling/enabling pushed_rowid_filter */
3237   Rowid_filter *save_pushed_rowid_filter;
3238   bool save_rowid_filter_is_active;
3239 
3240   Discrete_interval auto_inc_interval_for_cur_row;
3241   /**
3242      Number of reserved auto-increment intervals. Serves as a heuristic
3243      when we have no estimation of how many records the statement will insert:
3244      the more intervals we have reserved, the bigger the next one. Reset in
3245      handler::ha_release_auto_increment().
3246   */
3247   uint auto_inc_intervals_count;
3248 
3249   /**
3250     Instrumented table associated with this handler.
3251     This member should be set to NULL when no instrumentation is in place,
3252     so that linking an instrumented/non instrumented server/plugin works.
3253     For example:
3254     - the server is compiled with the instrumentation.
3255     The server expects either NULL or valid pointers in m_psi.
3256     - an engine plugin is compiled without instrumentation.
3257     The plugin can not leave this pointer uninitialized,
3258     or can not leave a trash value on purpose in this pointer,
3259     as this would crash the server.
3260   */
3261   PSI_table *m_psi;
3262 
3263 private:
3264   /** Internal state of the batch instrumentation. */
3265   enum batch_mode_t
3266   {
3267     /** Batch mode not used. */
3268     PSI_BATCH_MODE_NONE,
3269     /** Batch mode used, before first table io. */
3270     PSI_BATCH_MODE_STARTING,
3271     /** Batch mode used, after first table io. */
3272     PSI_BATCH_MODE_STARTED
3273   };
3274   /**
3275     Batch mode state.
3276     @sa start_psi_batch_mode.
3277     @sa end_psi_batch_mode.
3278   */
3279   batch_mode_t m_psi_batch_mode;
3280   /**
3281     The number of rows in the batch.
3282     @sa start_psi_batch_mode.
3283     @sa end_psi_batch_mode.
3284   */
3285   ulonglong m_psi_numrows;
3286   /**
3287     The current event in a batch.
3288     @sa start_psi_batch_mode.
3289     @sa end_psi_batch_mode.
3290   */
3291   PSI_table_locker *m_psi_locker;
3292   /**
3293     Storage for the event in a batch.
3294     @sa start_psi_batch_mode.
3295     @sa end_psi_batch_mode.
3296   */
3297   PSI_table_locker_state m_psi_locker_state;
3298 
3299 public:
3300   virtual void unbind_psi();
3301   virtual void rebind_psi();
3302   /* Return error if definition doesn't match for already opened table */
discover_check_version()3303   virtual int discover_check_version() { return 0; }
3304 
3305   /**
3306     Put the handler in 'batch' mode when collecting
3307     table io instrumented events.
3308     When operating in batch mode:
3309     - a single start event is generated in the performance schema.
3310     - all table io performed between @c start_psi_batch_mode
3311       and @c end_psi_batch_mode is not instrumented:
3312       the number of rows affected is counted instead in @c m_psi_numrows.
3313     - a single end event is generated in the performance schema
3314       when the batch mode ends with @c end_psi_batch_mode.
3315   */
3316   void start_psi_batch_mode();
3317   /** End a batch started with @c start_psi_batch_mode. */
3318   void end_psi_batch_mode();
3319 
3320   /* If we have row logging enabled for this table */
3321   bool row_logging, row_logging_init;
3322   /* If the row logging should be done in transaction cache */
3323   bool row_logging_has_trans;
3324 
3325 private:
3326   /**
3327     The lock type set by when calling::ha_external_lock(). This is
3328     propagated down to the storage engine. The reason for also storing
3329     it here, is that when doing MRR we need to create/clone a second handler
3330     object. This cloned handler object needs to know about the lock_type used.
3331   */
3332   int m_lock_type;
3333   /**
3334     Pointer where to store/retrieve the Handler_share pointer.
3335     For non partitioned handlers this is &TABLE_SHARE::ha_share.
3336   */
3337   Handler_share **ha_share;
3338 
3339 public:
handler(handlerton * ht_arg,TABLE_SHARE * share_arg)3340   handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
3341     :table_share(share_arg), table(0),
3342     estimation_rows_to_insert(0),
3343     lookup_handler(this),
3344     ht(ht_arg), ref(0), lookup_buffer(NULL), end_range(NULL),
3345     implicit_emptied(0),
3346     mark_trx_read_write_done(0),
3347     check_table_binlog_row_based_done(0),
3348     check_table_binlog_row_based_result(0),
3349     in_range_check_pushed_down(FALSE), lookup_errkey(-1), errkey(-1),
3350     key_used_on_scan(MAX_KEY),
3351     active_index(MAX_KEY), keyread(MAX_KEY),
3352     ref_length(sizeof(my_off_t)),
3353     ft_handler(0), inited(NONE), pre_inited(NONE),
3354     pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
3355     tracker(NULL),
3356     pushed_idx_cond(NULL),
3357     pushed_idx_cond_keyno(MAX_KEY),
3358     pushed_rowid_filter(NULL),
3359     rowid_filter_is_active(0),
3360     save_pushed_rowid_filter(NULL),
3361     save_rowid_filter_is_active(false),
3362     auto_inc_intervals_count(0),
3363     m_psi(NULL),
3364     m_psi_batch_mode(PSI_BATCH_MODE_NONE),
3365     m_psi_numrows(0),
3366     m_psi_locker(NULL),
3367     row_logging(0), row_logging_init(0),
3368     m_lock_type(F_UNLCK), ha_share(NULL)
3369   {
3370     DBUG_PRINT("info",
3371                ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
3372                 F_UNLCK, F_RDLCK, F_WRLCK));
3373     reset_statistics();
3374   }
~handler(void)3375   virtual ~handler(void)
3376   {
3377     DBUG_ASSERT(m_lock_type == F_UNLCK);
3378     DBUG_ASSERT(inited == NONE);
3379   }
3380   /* To check if table has been properely opened */
is_open()3381   bool is_open()
3382   {
3383     return ref != 0;
3384   }
3385   virtual handler *clone(const char *name, MEM_ROOT *mem_root);
3386   /** This is called after create to allow us to set up cached variables */
init()3387   void init()
3388   {
3389     cached_table_flags= table_flags();
3390   }
3391   /* ha_ methods: public wrappers for private virtual API */
3392 
3393   int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
3394               MEM_ROOT *mem_root= 0, List<String> *partitions_to_open=NULL);
ha_index_init(uint idx,bool sorted)3395   int ha_index_init(uint idx, bool sorted)
3396   {
3397     DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
3398     int result;
3399     DBUG_ENTER("ha_index_init");
3400     DBUG_ASSERT(inited==NONE);
3401     if (!(result= index_init(idx, sorted)))
3402     {
3403       inited=       INDEX;
3404       active_index= idx;
3405       end_range= NULL;
3406     }
3407     DBUG_RETURN(result);
3408   }
ha_index_end()3409   int ha_index_end()
3410   {
3411     DBUG_ENTER("ha_index_end");
3412     DBUG_ASSERT(inited==INDEX);
3413     inited=       NONE;
3414     active_index= MAX_KEY;
3415     end_range=    NULL;
3416     DBUG_RETURN(index_end());
3417   }
3418   /* This is called after index_init() if we need to do a index scan */
prepare_index_scan()3419   virtual int prepare_index_scan() { return 0; }
prepare_index_key_scan_map(const uchar * key,key_part_map keypart_map)3420   virtual int prepare_index_key_scan_map(const uchar * key, key_part_map keypart_map)
3421   {
3422     uint key_len= calculate_key_len(table, active_index, key, keypart_map);
3423     return  prepare_index_key_scan(key, key_len);
3424   }
prepare_index_key_scan(const uchar * key,uint key_len)3425   virtual int prepare_index_key_scan( const uchar * key, uint key_len )
3426   { return 0; }
prepare_range_scan(const key_range * start_key,const key_range * end_key)3427   virtual int prepare_range_scan(const key_range *start_key, const key_range *end_key)
3428   { return 0; }
3429 
ha_rnd_init(bool scan)3430   int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result))
3431   {
3432     DBUG_EXECUTE_IF("ha_rnd_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
3433     int result;
3434     DBUG_ENTER("ha_rnd_init");
3435     DBUG_ASSERT(inited==NONE || (inited==RND && scan));
3436     inited= (result= rnd_init(scan)) ? NONE: RND;
3437     end_range= NULL;
3438     DBUG_RETURN(result);
3439   }
ha_rnd_end()3440   int ha_rnd_end()
3441   {
3442     DBUG_ENTER("ha_rnd_end");
3443     DBUG_ASSERT(inited==RND);
3444     inited=NONE;
3445     end_range= NULL;
3446     DBUG_RETURN(rnd_end());
3447   }
3448   int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result));
3449   int ha_reset();
3450   /* this is necessary in many places, e.g. in HANDLER command */
ha_index_or_rnd_end()3451   int ha_index_or_rnd_end()
3452   {
3453     return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
3454   }
3455   /**
3456     The cached_table_flags is set at ha_open and ha_external_lock
3457   */
ha_table_flags()3458   Table_flags ha_table_flags() const
3459   {
3460     DBUG_ASSERT(cached_table_flags < (HA_LAST_TABLE_FLAG << 1));
3461     return cached_table_flags;
3462   }
3463   /**
3464     These functions represent the public interface to *users* of the
3465     handler class, hence they are *not* virtual. For the inheritance
3466     interface, see the (private) functions write_row(), update_row(),
3467     and delete_row() below.
3468   */
3469   int ha_external_lock(THD *thd, int lock_type);
ha_external_unlock(THD * thd)3470   int ha_external_unlock(THD *thd) { return ha_external_lock(thd, F_UNLCK); }
3471   int ha_write_row(const uchar * buf);
3472   int ha_update_row(const uchar * old_data, const uchar * new_data);
3473   int ha_delete_row(const uchar * buf);
3474   void ha_release_auto_increment();
3475 
keyread_enabled()3476   bool keyread_enabled() { return keyread < MAX_KEY; }
ha_start_keyread(uint idx)3477   int ha_start_keyread(uint idx)
3478   {
3479     int res= keyread_enabled() ? 0 : extra_opt(HA_EXTRA_KEYREAD, idx);
3480     keyread= idx;
3481     return res;
3482   }
ha_end_keyread()3483   int ha_end_keyread()
3484   {
3485     if (!keyread_enabled())
3486       return 0;
3487     keyread= MAX_KEY;
3488     return extra(HA_EXTRA_NO_KEYREAD);
3489   }
3490 
3491   int check_collation_compatibility();
3492   int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
3493   /** to be actually called to get 'check()' functionality*/
3494   int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
3495   int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
3496   void ha_start_bulk_insert(ha_rows rows, uint flags= 0)
3497   {
3498     DBUG_ENTER("handler::ha_start_bulk_insert");
3499     estimation_rows_to_insert= rows;
3500     bzero(&copy_info,sizeof(copy_info));
3501     start_bulk_insert(rows, flags);
3502     DBUG_VOID_RETURN;
3503   }
3504   int ha_end_bulk_insert();
3505   int ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
3506                          ha_rows *dup_key_found);
3507   int ha_delete_all_rows();
3508   int ha_truncate();
3509   int ha_reset_auto_increment(ulonglong value);
3510   int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
3511   int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
3512   bool ha_check_and_repair(THD *thd);
3513   int ha_disable_indexes(uint mode);
3514   int ha_enable_indexes(uint mode);
3515   int ha_discard_or_import_tablespace(my_bool discard);
3516   int ha_rename_table(const char *from, const char *to);
3517   void ha_drop_table(const char *name);
3518 
3519   int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
3520 
3521   int ha_create_partitioning_metadata(const char *name, const char *old_name,
3522                                       chf_create_flags action_flag);
3523 
3524   int ha_change_partitions(HA_CREATE_INFO *create_info,
3525                            const char *path,
3526                            ulonglong * const copied,
3527                            ulonglong * const deleted,
3528                            const uchar *pack_frm_data,
3529                            size_t pack_frm_len);
3530   int ha_drop_partitions(const char *path);
3531   int ha_rename_partitions(const char *path);
3532 
3533   void adjust_next_insert_id_after_explicit_value(ulonglong nr);
3534   int update_auto_increment();
3535   virtual void print_error(int error, myf errflag);
3536   virtual bool get_error_message(int error, String *buf);
3537   uint get_dup_key(int error);
3538   /**
3539     Retrieves the names of the table and the key for which there was a
3540     duplicate entry in the case of HA_ERR_FOREIGN_DUPLICATE_KEY.
3541 
3542     If any of the table or key name is not available this method will return
3543     false and will not change any of child_table_name or child_key_name.
3544 
3545     @param child_table_name[out]    Table name
3546     @param child_table_name_len[in] Table name buffer size
3547     @param child_key_name[out]      Key name
3548     @param child_key_name_len[in]   Key name buffer size
3549 
3550     @retval  true                  table and key names were available
3551                                    and were written into the corresponding
3552                                    out parameters.
3553     @retval  false                 table and key names were not available,
3554                                    the out parameters were not touched.
3555   */
get_foreign_dup_key(char * child_table_name,uint child_table_name_len,char * child_key_name,uint child_key_name_len)3556   virtual bool get_foreign_dup_key(char *child_table_name,
3557                                    uint child_table_name_len,
3558                                    char *child_key_name,
3559                                    uint child_key_name_len)
3560   { DBUG_ASSERT(false); return(false); }
reset_statistics()3561   void reset_statistics()
3562   {
3563     rows_read= rows_changed= rows_tmp_read= 0;
3564     bzero(index_rows_read, sizeof(index_rows_read));
3565     bzero(&copy_info, sizeof(copy_info));
3566   }
reset_copy_info()3567   virtual void reset_copy_info() {}
ha_reset_copy_info()3568   void ha_reset_copy_info()
3569   {
3570     bzero(&copy_info, sizeof(copy_info));
3571     reset_copy_info();
3572   }
change_table_ptr(TABLE * table_arg,TABLE_SHARE * share)3573   virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
3574   {
3575     table= table_arg;
3576     table_share= share;
3577     reset_statistics();
3578   }
scan_time()3579   virtual double scan_time()
3580   {
3581     return ((ulonglong2double(stats.data_file_length) / stats.block_size + 2) *
3582             avg_io_cost());
3583   }
3584 
key_scan_time(uint index)3585   virtual double key_scan_time(uint index)
3586   {
3587     return keyread_time(index, 1, records());
3588   }
3589 
avg_io_cost()3590   virtual double avg_io_cost()
3591   {
3592    return 1.0;
3593   }
3594 
3595   /**
3596      The cost of reading a set of ranges from the table using an index
3597      to access it.
3598 
3599      @param index  The index number.
3600      @param ranges The number of ranges to be read. If 0, it means that
3601                    we calculate separately the cost of reading the key.
3602      @param rows   Total number of rows to be read.
3603 
3604      This method can be used to calculate the total cost of scanning a table
3605      using an index by calling it using read_time(index, 1, table_size).
3606   */
read_time(uint index,uint ranges,ha_rows rows)3607   virtual double read_time(uint index, uint ranges, ha_rows rows)
3608   { return rows2double(ranges+rows); }
3609 
3610   /**
3611     Calculate cost of 'keyread' scan for given index and number of records.
3612 
3613      @param index    index to read
3614      @param ranges   #of ranges to read
3615      @param rows     #of records to read
3616   */
3617   virtual double keyread_time(uint index, uint ranges, ha_rows rows);
3618 
keys_to_use_for_scanning()3619   virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
3620 
3621   /*
3622     True if changes to the table is persistent (if there are no rollback)
3623     This is used to decide:
3624     - If the table is stored in the transaction or non transactional binary
3625       log
3626     - How things are tracked in trx and in add_changed_table().
3627     - If we can combine several statements under one commit in the binary log.
3628   */
has_transactions()3629   bool has_transactions()
3630   {
3631     return ((ha_table_flags() & (HA_NO_TRANSACTIONS | HA_PERSISTENT_TABLE))
3632             == 0);
3633   }
3634   /*
3635     True if table has both transactions and rollback. This is used to decide
3636     if we should write the changes to the binary log.  If this is true,
3637     we don't have to write failed statements to the log as they can be
3638     rolled back.
3639   */
has_transactions_and_rollback()3640   bool has_transactions_and_rollback()
3641   {
3642     return has_transactions() && has_rollback();
3643   }
3644   /*
3645     True if the underlaying table support transactions and rollback
3646   */
has_transaction_manager()3647   bool has_transaction_manager()
3648   {
3649     return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0 && has_rollback());
3650   }
3651 
3652   /*
3653     True if table has rollback. Used to check if an update on the table
3654     can be killed fast.
3655   */
3656 
has_rollback()3657   bool has_rollback()
3658   {
3659     return ((ht->flags & HTON_NO_ROLLBACK) == 0);
3660   }
3661 
3662   /**
3663     This method is used to analyse the error to see whether the error
3664     is ignorable or not, certain handlers can have more error that are
3665     ignorable than others. E.g. the partition handler can get inserts
3666     into a range where there is no partition and this is an ignorable
3667     error.
3668     HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
3669     same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
3670     a slightly different error message.
3671   */
is_fatal_error(int error,uint flags)3672   virtual bool is_fatal_error(int error, uint flags)
3673   {
3674     if (!error ||
3675         ((flags & HA_CHECK_DUP_KEY) &&
3676          (error == HA_ERR_FOUND_DUPP_KEY ||
3677           error == HA_ERR_FOUND_DUPP_UNIQUE)) ||
3678         error == HA_ERR_AUTOINC_ERANGE ||
3679         ((flags & HA_CHECK_FK_ERROR) &&
3680          (error == HA_ERR_ROW_IS_REFERENCED ||
3681           error == HA_ERR_NO_REFERENCED_ROW)))
3682       return FALSE;
3683     return TRUE;
3684   }
3685 
3686   /**
3687     Number of rows in table. It will only be called if
3688     (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
3689   */
pre_records()3690   virtual int pre_records() { return 0; }
records()3691   virtual ha_rows records() { return stats.records; }
3692   /**
3693     Return upper bound of current number of records in the table
3694     (max. of how many records one will retrieve when doing a full table scan)
3695     If upper bound is not known, HA_POS_ERROR should be returned as a max
3696     possible upper bound.
3697   */
estimate_rows_upper_bound()3698   virtual ha_rows estimate_rows_upper_bound()
3699   { return stats.records+EXTRA_RECORDS; }
3700 
3701   /**
3702     Get the row type from the storage engine.  If this method returns
3703     ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
3704   */
get_row_type()3705   virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
3706 
index_type(uint key_number)3707   virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
3708 
3709 
3710   /**
3711     Signal that the table->read_set and table->write_set table maps changed
3712     The handler is allowed to set additional bits in the above map in this
3713     call. Normally the handler should ignore all calls until we have done
3714     a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
3715     as there may be several calls to this routine.
3716   */
3717   virtual void column_bitmaps_signal();
3718   /*
3719     We have to check for inited as some engines, like innodb, sets
3720     active_index during table scan.
3721   */
get_index(void)3722   uint get_index(void) const
3723   { return inited == INDEX ? active_index : MAX_KEY; }
3724   int ha_close(void);
3725 
3726   /**
3727     @retval  0   Bulk update used by handler
3728     @retval  1   Bulk update not used, normal operation used
3729   */
start_bulk_update()3730   virtual bool start_bulk_update() { return 1; }
3731   /**
3732     @retval  0   Bulk delete used by handler
3733     @retval  1   Bulk delete not used, normal operation used
3734   */
start_bulk_delete()3735   virtual bool start_bulk_delete() { return 1; }
3736   /**
3737     After this call all outstanding updates must be performed. The number
3738     of duplicate key errors are reported in the duplicate key parameter.
3739     It is allowed to continue to the batched update after this call, the
3740     handler has to wait until end_bulk_update with changing state.
3741 
3742     @param    dup_key_found       Number of duplicate keys found
3743 
3744     @retval  0           Success
3745     @retval  >0          Error code
3746   */
exec_bulk_update(ha_rows * dup_key_found)3747   virtual int exec_bulk_update(ha_rows *dup_key_found)
3748   {
3749     DBUG_ASSERT(FALSE);
3750     return HA_ERR_WRONG_COMMAND;
3751   }
3752   /**
3753     Perform any needed clean-up, no outstanding updates are there at the
3754     moment.
3755   */
end_bulk_update()3756   virtual int end_bulk_update() { return 0; }
3757   /**
3758     Execute all outstanding deletes and close down the bulk delete.
3759 
3760     @retval 0             Success
3761     @retval >0            Error code
3762   */
end_bulk_delete()3763   virtual int end_bulk_delete()
3764   {
3765     DBUG_ASSERT(FALSE);
3766     return HA_ERR_WRONG_COMMAND;
3767   }
pre_index_read_map(const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag,bool use_parallel)3768   virtual int pre_index_read_map(const uchar *key,
3769                                  key_part_map keypart_map,
3770                                  enum ha_rkey_function find_flag,
3771                                  bool use_parallel)
3772    { return 0; }
pre_index_first(bool use_parallel)3773   virtual int pre_index_first(bool use_parallel)
3774    { return 0; }
pre_index_last(bool use_parallel)3775   virtual int pre_index_last(bool use_parallel)
3776    { return 0; }
pre_index_read_last_map(const uchar * key,key_part_map keypart_map,bool use_parallel)3777   virtual int pre_index_read_last_map(const uchar *key,
3778                                       key_part_map keypart_map,
3779                                       bool use_parallel)
3780    { return 0; }
3781 /*
3782   virtual int pre_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
3783                                          KEY_MULTI_RANGE *ranges,
3784                                          uint range_count,
3785                                          bool sorted, HANDLER_BUFFER *buffer,
3786                                          bool use_parallel);
3787 */
pre_multi_range_read_next(bool use_parallel)3788   virtual int pre_multi_range_read_next(bool use_parallel)
3789   { return 0; }
pre_read_range_first(const key_range * start_key,const key_range * end_key,bool eq_range,bool sorted,bool use_parallel)3790   virtual int pre_read_range_first(const key_range *start_key,
3791                                    const key_range *end_key,
3792                                    bool eq_range, bool sorted,
3793                                    bool use_parallel)
3794    { return 0; }
pre_ft_read(bool use_parallel)3795   virtual int pre_ft_read(bool use_parallel)
3796    { return 0; }
pre_rnd_next(bool use_parallel)3797   virtual int pre_rnd_next(bool use_parallel)
3798    { return 0; }
ha_pre_rnd_init(bool scan)3799   int ha_pre_rnd_init(bool scan)
3800   {
3801     int result;
3802     DBUG_ENTER("ha_pre_rnd_init");
3803     DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan));
3804     pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND;
3805     DBUG_RETURN(result);
3806   }
ha_pre_rnd_end()3807   int ha_pre_rnd_end()
3808   {
3809     DBUG_ENTER("ha_pre_rnd_end");
3810     DBUG_ASSERT(pre_inited==RND);
3811     pre_inited=NONE;
3812     DBUG_RETURN(pre_rnd_end());
3813   }
pre_rnd_init(bool scan)3814   virtual int pre_rnd_init(bool scan) { return 0; }
pre_rnd_end()3815   virtual int pre_rnd_end() { return 0; }
pre_index_init(uint idx,bool sorted)3816   virtual int pre_index_init(uint idx, bool sorted) { return 0; }
pre_index_end()3817   virtual int pre_index_end() { return 0; }
ha_pre_index_init(uint idx,bool sorted)3818   int ha_pre_index_init(uint idx, bool sorted)
3819   {
3820     int result;
3821     DBUG_ENTER("ha_pre_index_init");
3822     DBUG_ASSERT(pre_inited==NONE);
3823     if (!(result= pre_index_init(idx, sorted)))
3824       pre_inited=INDEX;
3825     DBUG_RETURN(result);
3826   }
ha_pre_index_end()3827   int ha_pre_index_end()
3828   {
3829     DBUG_ENTER("ha_pre_index_end");
3830     DBUG_ASSERT(pre_inited==INDEX);
3831     pre_inited=NONE;
3832     DBUG_RETURN(pre_index_end());
3833   }
ha_pre_index_or_rnd_end()3834   int ha_pre_index_or_rnd_end()
3835   {
3836     return (pre_inited == INDEX ?
3837             ha_pre_index_end() :
3838             pre_inited == RND ? ha_pre_rnd_end() : 0 );
3839   }
vers_can_native(THD * thd)3840   virtual bool vers_can_native(THD *thd)
3841   {
3842     return ht->flags & HTON_NATIVE_SYS_VERSIONING;
3843   }
3844 
3845   /**
3846      @brief
3847      Positions an index cursor to the index specified in the
3848      handle. Fetches the row if available. If the key value is null,
3849      begin at the first key of the index.
3850   */
3851 protected:
index_read_map(uchar * buf,const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag)3852   virtual int index_read_map(uchar * buf, const uchar * key,
3853                              key_part_map keypart_map,
3854                              enum ha_rkey_function find_flag)
3855   {
3856     uint key_len= calculate_key_len(table, active_index, key, keypart_map);
3857     return index_read(buf, key, key_len, find_flag);
3858   }
3859   /**
3860      @brief
3861      Positions an index cursor to the index specified in the
3862      handle. Fetches the row if available. If the key value is null,
3863      begin at the first key of the index.
3864   */
3865   virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
3866                                  key_part_map keypart_map,
3867                                  enum ha_rkey_function find_flag);
index_next(uchar * buf)3868   virtual int index_next(uchar * buf)
3869    { return  HA_ERR_WRONG_COMMAND; }
index_prev(uchar * buf)3870   virtual int index_prev(uchar * buf)
3871    { return  HA_ERR_WRONG_COMMAND; }
index_first(uchar * buf)3872   virtual int index_first(uchar * buf)
3873    { return  HA_ERR_WRONG_COMMAND; }
index_last(uchar * buf)3874   virtual int index_last(uchar * buf)
3875    { return  HA_ERR_WRONG_COMMAND; }
3876   virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
3877   /**
3878      @brief
3879      The following functions works like index_read, but it find the last
3880      row with the current key value or prefix.
3881      @returns @see index_read_map().
3882   */
index_read_last_map(uchar * buf,const uchar * key,key_part_map keypart_map)3883   virtual int index_read_last_map(uchar * buf, const uchar * key,
3884                                   key_part_map keypart_map)
3885   {
3886     uint key_len= calculate_key_len(table, active_index, key, keypart_map);
3887     return index_read_last(buf, key, key_len);
3888   }
3889   virtual int close(void)=0;
update_rows_read()3890   inline void update_rows_read()
3891   {
3892     if (likely(!internal_tmp_table))
3893       rows_read++;
3894     else
3895       rows_tmp_read++;
3896   }
update_index_statistics()3897   inline void update_index_statistics()
3898   {
3899     index_rows_read[active_index]++;
3900     update_rows_read();
3901   }
3902 public:
3903 
3904   int ha_index_read_map(uchar * buf, const uchar * key,
3905                         key_part_map keypart_map,
3906                         enum ha_rkey_function find_flag);
3907   int ha_index_read_idx_map(uchar * buf, uint index, const uchar * key,
3908                             key_part_map keypart_map,
3909                             enum ha_rkey_function find_flag);
3910   int ha_index_next(uchar * buf);
3911   int ha_index_prev(uchar * buf);
3912   int ha_index_first(uchar * buf);
3913   int ha_index_last(uchar * buf);
3914   int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
3915   /*
3916     TODO: should we make for those functions non-virtual ha_func_name wrappers,
3917     too?
3918   */
3919   virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
3920                                               void *seq_init_param,
3921                                               uint n_ranges, uint *bufsz,
3922                                               uint *mrr_mode,
3923                                               Cost_estimate *cost);
3924   virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
3925                                         uint key_parts, uint *bufsz,
3926                                         uint *mrr_mode, Cost_estimate *cost);
3927   virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
3928                                     uint n_ranges, uint mrr_mode,
3929                                     HANDLER_BUFFER *buf);
3930   virtual int multi_range_read_next(range_id_t *range_info);
3931   /*
3932     Return string representation of the MRR plan.
3933 
3934     This is intended to be used for EXPLAIN, via the following scenario:
3935     1. SQL layer calls handler->multi_range_read_info().
3936     1.1. Storage engine figures out whether it will use some non-default
3937          MRR strategy, sets appropritate bits in *mrr_mode, and returns
3938          control to SQL layer
3939     2. SQL layer remembers the returned mrr_mode
3940     3. SQL layer compares various options and choses the final query plan. As
3941        a part of that, it makes a choice of whether to use the MRR strategy
3942        picked in 1.1
3943     4. EXPLAIN code converts the query plan to its text representation. If MRR
3944        strategy is part of the plan, it calls
3945        multi_range_read_explain_info(mrr_mode) to get a text representation of
3946        the picked MRR strategy.
3947 
3948     @param mrr_mode   Mode which was returned by multi_range_read_info[_const]
3949     @param str        INOUT string to be printed for EXPLAIN
3950     @param str_end    End of the string buffer. The function is free to put the
3951                       string into [str..str_end] memory range.
3952   */
multi_range_read_explain_info(uint mrr_mode,char * str,size_t size)3953   virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
3954                                             size_t size)
3955   { return 0; }
3956 
3957   virtual int read_range_first(const key_range *start_key,
3958                                const key_range *end_key,
3959                                bool eq_range, bool sorted);
3960   virtual int read_range_next();
3961   void set_end_range(const key_range *end_key);
3962   int compare_key(key_range *range);
3963   int compare_key2(key_range *range) const;
ft_init()3964   virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
pre_ft_init()3965   virtual int pre_ft_init() { return HA_ERR_WRONG_COMMAND; }
ft_end()3966   virtual void ft_end() {}
pre_ft_end()3967   virtual int pre_ft_end() { return 0; }
ft_init_ext(uint flags,uint inx,String * key)3968   virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
3969     { return NULL; }
3970 public:
ft_read(uchar * buf)3971   virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
3972   virtual int rnd_next(uchar *buf)=0;
3973   virtual int rnd_pos(uchar * buf, uchar *pos)=0;
3974   /**
3975     This function only works for handlers having
3976     HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
3977     It will return the row with the PK given in the record argument.
3978   */
rnd_pos_by_record(uchar * record)3979   virtual int rnd_pos_by_record(uchar *record)
3980   {
3981     int error;
3982     DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION);
3983 
3984     error = ha_rnd_init(false);
3985     if (error != 0)
3986       return error;
3987 
3988     position(record);
3989     error = ha_rnd_pos(record, ref);
3990     ha_rnd_end();
3991     return error;
3992   }
3993   virtual int read_first_row(uchar *buf, uint primary_key);
3994 public:
3995 
3996   /* Same as above, but with statistics */
3997   inline int ha_ft_read(uchar *buf);
ha_ft_end()3998   inline void ha_ft_end() { ft_end(); ft_handler=NULL; }
3999   int ha_rnd_next(uchar *buf);
4000   int ha_rnd_pos(uchar *buf, uchar *pos);
4001   inline int ha_rnd_pos_by_record(uchar *buf);
4002   inline int ha_read_first_row(uchar *buf, uint primary_key);
4003 
4004   /**
4005     The following 3 function is only needed for tables that may be
4006     internal temporary tables during joins.
4007   */
remember_rnd_pos()4008   virtual int remember_rnd_pos()
4009     { return HA_ERR_WRONG_COMMAND; }
restart_rnd_next(uchar * buf)4010   virtual int restart_rnd_next(uchar *buf)
4011     { return HA_ERR_WRONG_COMMAND; }
rnd_same(uchar * buf,uint inx)4012   virtual int rnd_same(uchar *buf, uint inx)
4013     { return HA_ERR_WRONG_COMMAND; }
4014 
records_in_range(uint inx,const key_range * min_key,const key_range * max_key,page_range * res)4015   virtual ha_rows records_in_range(uint inx, const key_range *min_key,
4016                                    const key_range *max_key,
4017                                    page_range *res)
4018     { return (ha_rows) 10; }
4019   /*
4020     If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
4021     (reference to the row, aka position, with the primary key given in
4022     the record).
4023     Otherwise it set ref to the current row.
4024   */
4025   virtual void position(const uchar *record)=0;
4026   virtual int info(uint)=0; // see my_base.h for full description
4027   virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
4028                                           uint part_id);
set_partitions_to_open(List<String> * partition_names)4029   virtual void set_partitions_to_open(List<String> *partition_names) {}
4030   virtual bool check_if_updates_are_ignored(const char *op) const;
change_partitions_to_open(List<String> * partition_names)4031   virtual int change_partitions_to_open(List<String> *partition_names)
4032   { return 0; }
extra(enum ha_extra_function operation)4033   virtual int extra(enum ha_extra_function operation)
4034   { return 0; }
extra_opt(enum ha_extra_function operation,ulong arg)4035   virtual int extra_opt(enum ha_extra_function operation, ulong arg)
4036   { return extra(operation); }
4037 
4038   /**
4039     In an UPDATE or DELETE, if the row under the cursor was locked by another
4040     transaction, and the engine used an optimistic read of the last
4041     committed row value under the cursor, then the engine returns 1 from this
4042     function. MySQL must NOT try to update this optimistic value. If the
4043     optimistic value does not match the WHERE condition, MySQL can decide to
4044     skip over this row. Currently only works for InnoDB. This can be used to
4045     avoid unnecessary lock waits.
4046 
4047     If this method returns nonzero, it will also signal the storage
4048     engine that the next read will be a locking re-read of the row.
4049   */
4050   bool ha_was_semi_consistent_read();
was_semi_consistent_read()4051   virtual bool was_semi_consistent_read() { return 0; }
4052   /**
4053     Tell the engine whether it should avoid unnecessary lock waits.
4054     If yes, in an UPDATE or DELETE, if the row under the cursor was locked
4055     by another transaction, the engine may try an optimistic read of
4056     the last committed row value under the cursor.
4057   */
try_semi_consistent_read(bool)4058   virtual void try_semi_consistent_read(bool) {}
unlock_row()4059   virtual void unlock_row() {}
start_stmt(THD * thd,thr_lock_type lock_type)4060   virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
need_info_for_auto_inc()4061   virtual bool need_info_for_auto_inc() { return 0; }
can_use_for_auto_inc_init()4062   virtual bool can_use_for_auto_inc_init() { return 1; }
4063   virtual void get_auto_increment(ulonglong offset, ulonglong increment,
4064                                   ulonglong nb_desired_values,
4065                                   ulonglong *first_value,
4066                                   ulonglong *nb_reserved_values);
set_next_insert_id(ulonglong id)4067   void set_next_insert_id(ulonglong id)
4068   {
4069     DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
4070     next_insert_id= id;
4071   }
restore_auto_increment(ulonglong prev_insert_id)4072   virtual void restore_auto_increment(ulonglong prev_insert_id)
4073   {
4074     /*
4075       Insertion of a row failed, re-use the lastly generated auto_increment
4076       id, for the next row. This is achieved by resetting next_insert_id to
4077       what it was before the failed insertion (that old value is provided by
4078       the caller). If that value was 0, it was the first row of the INSERT;
4079       then if insert_id_for_cur_row contains 0 it means no id was generated
4080       for this first row, so no id was generated since the INSERT started, so
4081       we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
4082       is the generated id of the first and failed row, so we use it.
4083     */
4084     next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
4085       insert_id_for_cur_row;
4086   }
4087 
update_create_info(HA_CREATE_INFO * create_info)4088   virtual void update_create_info(HA_CREATE_INFO *create_info) {}
4089   int check_old_types();
assign_to_keycache(THD * thd,HA_CHECK_OPT * check_opt)4090   virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
4091   { return HA_ADMIN_NOT_IMPLEMENTED; }
preload_keys(THD * thd,HA_CHECK_OPT * check_opt)4092   virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
4093   { return HA_ADMIN_NOT_IMPLEMENTED; }
4094   /* end of the list of admin commands */
4095 
indexes_are_disabled(void)4096   virtual int indexes_are_disabled(void) {return 0;}
append_create_info(String * packet)4097   virtual void append_create_info(String *packet) {}
4098   /**
4099     If index == MAX_KEY then a check for table is made and if index <
4100     MAX_KEY then a check is made if the table has foreign keys and if
4101     a foreign key uses this index (and thus the index cannot be dropped).
4102 
4103     @param  index            Index to check if foreign key uses it
4104 
4105     @retval   TRUE            Foreign key defined on table or index
4106     @retval   FALSE           No foreign key defined
4107   */
is_fk_defined_on_table_or_index(uint index)4108   virtual bool is_fk_defined_on_table_or_index(uint index)
4109   { return FALSE; }
get_foreign_key_create_info()4110   virtual char* get_foreign_key_create_info()
4111   { return(NULL);}  /* gets foreign key create string from InnoDB */
4112   /**
4113     Used in ALTER TABLE to check if changing storage engine is allowed.
4114 
4115     @note Called without holding thr_lock.c lock.
4116 
4117     @retval true   Changing storage engine is allowed.
4118     @retval false  Changing storage engine not allowed.
4119   */
can_switch_engines()4120   virtual bool can_switch_engines() { return true; }
can_continue_handler_scan()4121   virtual int can_continue_handler_scan() { return 0; }
4122   /**
4123     Get the list of foreign keys in this table.
4124 
4125     @remark Returns the set of foreign keys where this table is the
4126             dependent or child table.
4127 
4128     @param thd  The thread handle.
4129     @param f_key_list[out]  The list of foreign keys.
4130 
4131     @return The handler error code or zero for success.
4132   */
4133   virtual int
get_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)4134   get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
4135   { return 0; }
4136   /**
4137     Get the list of foreign keys referencing this table.
4138 
4139     @remark Returns the set of foreign keys where this table is the
4140             referenced or parent table.
4141 
4142     @param thd  The thread handle.
4143     @param f_key_list[out]  The list of foreign keys.
4144 
4145     @return The handler error code or zero for success.
4146   */
4147   virtual int
get_parent_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)4148   get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
4149   { return 0; }
referenced_by_foreign_key()4150   virtual uint referenced_by_foreign_key() { return 0;}
init_table_handle_for_HANDLER()4151   virtual void init_table_handle_for_HANDLER()
4152   { return; }       /* prepare InnoDB for HANDLER */
free_foreign_key_create_info(char * str)4153   virtual void free_foreign_key_create_info(char* str) {}
4154   /** The following can be called without an open handler */
table_type()4155   const char *table_type() const { return hton_name(ht)->str; }
bas_ext()4156   const char **bas_ext() const { return ht->tablefile_extensions; }
4157 
get_default_no_partitions(HA_CREATE_INFO * create_info)4158   virtual int get_default_no_partitions(HA_CREATE_INFO *create_info)
4159   { return 1;}
set_auto_partitions(partition_info * part_info)4160   virtual void set_auto_partitions(partition_info *part_info) { return; }
get_no_parts(const char * name,uint * no_parts)4161   virtual bool get_no_parts(const char *name,
4162                             uint *no_parts)
4163   {
4164     *no_parts= 0;
4165     return 0;
4166   }
set_part_info(partition_info * part_info)4167   virtual void set_part_info(partition_info *part_info) {return;}
return_record_by_parent()4168   virtual void return_record_by_parent() { return; }
4169 
4170   /* Information about index. Both index and part starts from 0 */
4171   virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
4172 
max_record_length()4173   uint max_record_length() const
4174   { return MY_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
max_keys()4175   uint max_keys() const
4176   { return MY_MIN(MAX_KEY, max_supported_keys()); }
max_key_parts()4177   uint max_key_parts() const
4178   { return MY_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
max_key_length()4179   uint max_key_length() const
4180   { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_length()); }
max_key_part_length()4181   uint max_key_part_length() const
4182   { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_part_length()); }
4183 
max_supported_record_length()4184   virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
max_supported_keys()4185   virtual uint max_supported_keys() const { return 0; }
max_supported_key_parts()4186   virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
max_supported_key_length()4187   virtual uint max_supported_key_length() const { return MAX_DATA_LENGTH_FOR_KEY; }
max_supported_key_part_length()4188   virtual uint max_supported_key_part_length() const { return 255; }
min_record_length(uint options)4189   virtual uint min_record_length(uint options) const { return 1; }
4190 
pre_calculate_checksum()4191   virtual int pre_calculate_checksum() { return 0; }
4192   virtual int calculate_checksum();
is_crashed()4193   virtual bool is_crashed() const  { return 0; }
auto_repair(int error)4194   virtual bool auto_repair(int error) const { return 0; }
4195 
4196   void update_global_table_stats();
4197   void update_global_index_stats();
4198 
4199   /**
4200     @note lock_count() can return > 1 if the table is MERGE or partitioned.
4201   */
lock_count(void)4202   virtual uint lock_count(void) const { return 1; }
4203   /**
4204     Is not invoked for non-transactional temporary tables.
4205 
4206     @note store_lock() can return more than one lock if the table is MERGE
4207     or partitioned.
4208 
4209     @note that one can NOT rely on table->in_use in store_lock().  It may
4210     refer to a different thread if called from mysql_lock_abort_for_thread().
4211 
4212     @note If the table is MERGE, store_lock() can return less locks
4213     than lock_count() claimed. This can happen when the MERGE children
4214     are not attached when this is called from another thread.
4215   */
4216   virtual THR_LOCK_DATA **store_lock(THD *thd,
4217 				     THR_LOCK_DATA **to,
4218 				     enum thr_lock_type lock_type)=0;
4219 
4220   /** Type of table for caching query */
table_cache_type()4221   virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
4222 
4223 
4224   /**
4225     @brief Register a named table with a call back function to the query cache.
4226 
4227     @param thd The thread handle
4228     @param table_key A pointer to the table name in the table cache
4229     @param key_length The length of the table name
4230     @param[out] engine_callback The pointer to the storage engine call back
4231       function
4232     @param[out] engine_data Storage engine specific data which could be
4233       anything
4234 
4235     This method offers the storage engine, the possibility to store a reference
4236     to a table name which is going to be used with query cache.
4237     The method is called each time a statement is written to the cache and can
4238     be used to verify if a specific statement is cacheable. It also offers
4239     the possibility to register a generic (but static) call back function which
4240     is called each time a statement is matched against the query cache.
4241 
4242     @note If engine_data supplied with this function is different from
4243       engine_data supplied with the callback function, and the callback returns
4244       FALSE, a table invalidation on the current table will occur.
4245 
4246     @return Upon success the engine_callback will point to the storage engine
4247       call back function, if any, and engine_data will point to any storage
4248       engine data used in the specific implementation.
4249       @retval TRUE Success
4250       @retval FALSE The specified table or current statement should not be
4251         cached
4252   */
4253 
register_query_cache_table(THD * thd,const char * table_key,uint key_length,qc_engine_callback * callback,ulonglong * engine_data)4254   virtual my_bool register_query_cache_table(THD *thd, const char *table_key,
4255                                              uint key_length,
4256                                              qc_engine_callback *callback,
4257                                              ulonglong *engine_data)
4258   {
4259     *callback= 0;
4260     return TRUE;
4261   }
4262 
4263   /*
4264     Count tables invisible from all tables list on which current one built
4265     (like myisammrg and partitioned tables)
4266 
4267     tables_type          mask for the tables should be added herdde
4268 
4269     returns number of such tables
4270   */
4271 
count_query_cache_dependant_tables(uint8 * tables_type)4272   virtual uint count_query_cache_dependant_tables(uint8 *tables_type
4273                                                   __attribute__((unused)))
4274   {
4275     return 0;
4276   }
4277 
4278   /*
4279     register tables invisible from all tables list on which current one built
4280     (like myisammrg and partitioned tables).
4281 
4282     @note they should be counted by method above
4283 
4284     cache                Query cache pointer
4285     block                Query cache block to write the table
4286     n                    Number of the table
4287 
4288     @retval FALSE - OK
4289     @retval TRUE  - Error
4290   */
4291 
4292   virtual my_bool
register_query_cache_dependant_tables(THD * thd,Query_cache * cache,Query_cache_block_table ** block,uint * n)4293     register_query_cache_dependant_tables(THD *thd
4294                                           __attribute__((unused)),
4295                                           Query_cache *cache
4296                                           __attribute__((unused)),
4297                                           Query_cache_block_table **block
4298                                           __attribute__((unused)),
4299                                           uint *n __attribute__((unused)))
4300   {
4301     return FALSE;
4302   }
4303 
4304  /*
4305    Check if the key is a clustering key
4306 
4307    - Data is stored together with the primary key (no secondary lookup
4308      needed to find the row data). The optimizer uses this to find out
4309      the cost of fetching data.
4310 
4311      Note that in many cases a clustered key is also a reference key.
4312      This means that:
4313 
4314    - The key is part of each secondary key and is used
4315      to find the row data in the primary index when reading trough
4316      secondary indexes.
4317    - When doing a HA_KEYREAD_ONLY we get also all the primary key parts
4318      into the row. This is critical property used by index_merge.
4319 
4320    All the above is usually true for engines that store the row
4321    data in the primary key index (e.g. in a b-tree), and use the key
4322    key value as a position().  InnoDB is an example of such an engine.
4323 
4324    For a clustered (primary) key, the following should also hold:
4325    index_flags() should contain HA_CLUSTERED_INDEX
4326    table_flags() should contain HA_TABLE_SCAN_ON_INDEX
4327 
4328    For a reference key the following should also hold:
4329    table_flags() should contain HA_PRIMARY_KEY_IS_READ_INDEX.
4330 
4331    @retval TRUE   yes
4332    @retval FALSE  No.
4333  */
4334 
4335  /* The following code is for primary keys */
pk_is_clustering_key(uint index)4336  bool pk_is_clustering_key(uint index) const
4337  {
4338    /*
4339      We have to check for MAX_INDEX as table->s->primary_key can be
4340      MAX_KEY in the case where there is no primary key.
4341    */
4342    return index != MAX_KEY && is_clustering_key(index);
4343  }
4344  /* Same as before but for other keys, in which case we can skip the check */
is_clustering_key(uint index)4345  bool is_clustering_key(uint index) const
4346  {
4347    DBUG_ASSERT(index != MAX_KEY);
4348    return (index_flags(index, 0, 1) & HA_CLUSTERED_INDEX);
4349  }
4350 
cmp_ref(const uchar * ref1,const uchar * ref2)4351  virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
4352  {
4353    return memcmp(ref1, ref2, ref_length);
4354  }
4355 
4356  /*
4357    Condition pushdown to storage engines
4358  */
4359 
4360  /**
4361    Push condition down to the table handler.
4362 
4363    @param  cond   Condition to be pushed. The condition tree must not be
4364                   modified by the by the caller.
4365 
4366    @return
4367      The 'remainder' condition that caller must use to filter out records.
4368      NULL means the handler will not return rows that do not match the
4369      passed condition.
4370 
4371    @note
4372    The pushed conditions form a stack (from which one can remove the
4373    last pushed condition using cond_pop).
4374    The table handler filters out rows using (pushed_cond1 AND pushed_cond2
4375    AND ... AND pushed_condN)
4376    or less restrictive condition, depending on handler's capabilities.
4377 
4378    handler->ha_reset() call empties the condition stack.
4379    Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
4380    condition stack.
4381  */
cond_push(const COND * cond)4382  virtual const COND *cond_push(const COND *cond) { return cond; };
4383  /**
4384    Pop the top condition from the condition stack of the handler instance.
4385 
4386    Pops the top if condition stack, if stack is not empty.
4387  */
cond_pop()4388  virtual void cond_pop() { return; };
4389 
4390  /**
4391    Push metadata for the current operation down to the table handler.
4392  */
info_push(uint info_type,void * info)4393  virtual int info_push(uint info_type, void *info) { return 0; };
4394 
4395  /**
4396    Push down an index condition to the handler.
4397 
4398    The server will use this method to push down a condition it wants
4399    the handler to evaluate when retrieving records using a specified
4400    index. The pushed index condition will only refer to fields from
4401    this handler that is contained in the index (but it may also refer
4402    to fields in other handlers). Before the handler evaluates the
4403    condition it must read the content of the index entry into the
4404    record buffer.
4405 
4406    The handler is free to decide if and how much of the condition it
4407    will take responsibility for evaluating. Based on this evaluation
4408    it should return the part of the condition it will not evaluate.
4409    If it decides to evaluate the entire condition it should return
4410    NULL. If it decides not to evaluate any part of the condition it
4411    should return a pointer to the same condition as given as argument.
4412 
4413    @param keyno    the index number to evaluate the condition on
4414    @param idx_cond the condition to be evaluated by the handler
4415 
4416    @return The part of the pushed condition that the handler decides
4417            not to evaluate
4418  */
idx_cond_push(uint keyno,Item * idx_cond)4419  virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
4420 
4421  /** Reset information about pushed index conditions */
cancel_pushed_idx_cond()4422  virtual void cancel_pushed_idx_cond()
4423  {
4424    pushed_idx_cond= NULL;
4425    pushed_idx_cond_keyno= MAX_KEY;
4426    in_range_check_pushed_down= false;
4427  }
4428 
cancel_pushed_rowid_filter()4429  virtual void cancel_pushed_rowid_filter()
4430  {
4431    pushed_rowid_filter= NULL;
4432    rowid_filter_is_active= false;
4433  }
4434 
disable_pushed_rowid_filter()4435  virtual void disable_pushed_rowid_filter()
4436  {
4437    DBUG_ASSERT(pushed_rowid_filter != NULL &&
4438                save_pushed_rowid_filter == NULL);
4439    save_pushed_rowid_filter= pushed_rowid_filter;
4440    if (rowid_filter_is_active)
4441      save_rowid_filter_is_active= rowid_filter_is_active;
4442    pushed_rowid_filter= NULL;
4443    rowid_filter_is_active= false;
4444  }
4445 
enable_pushed_rowid_filter()4446  virtual void enable_pushed_rowid_filter()
4447  {
4448    DBUG_ASSERT(save_pushed_rowid_filter != NULL &&
4449                pushed_rowid_filter == NULL);
4450    pushed_rowid_filter= save_pushed_rowid_filter;
4451    if (save_rowid_filter_is_active)
4452      rowid_filter_is_active= true;
4453    save_pushed_rowid_filter= NULL;
4454  }
4455 
rowid_filter_push(Rowid_filter * rowid_filter)4456  virtual bool rowid_filter_push(Rowid_filter *rowid_filter) { return true; }
4457 
4458  /* Needed for partition / spider */
get_next_global_for_child()4459   virtual TABLE_LIST *get_next_global_for_child() { return NULL; }
4460 
4461  /**
4462    Part of old, deprecated in-place ALTER API.
4463  */
check_if_incompatible_data(HA_CREATE_INFO * create_info,uint table_changes)4464  virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
4465 					 uint table_changes)
4466  { return COMPATIBLE_DATA_NO; }
4467 
4468  /* On-line/in-place ALTER TABLE interface. */
4469 
4470  /*
4471    Here is an outline of on-line/in-place ALTER TABLE execution through
4472    this interface.
4473 
4474    Phase 1 : Initialization
4475    ========================
4476    During this phase we determine which algorithm should be used
4477    for execution of ALTER TABLE and what level concurrency it will
4478    require.
4479 
4480    *) This phase starts by opening the table and preparing description
4481       of the new version of the table.
4482    *) Then we check if it is impossible even in theory to carry out
4483       this ALTER TABLE using the in-place algorithm. For example, because
4484       we need to change storage engine or the user has explicitly requested
4485       usage of the "copy" algorithm.
4486    *) If in-place ALTER TABLE is theoretically possible, we continue
4487       by compiling differences between old and new versions of the table
4488       in the form of HA_ALTER_FLAGS bitmap. We also build a few
4489       auxiliary structures describing requested changes and store
4490       all these data in the Alter_inplace_info object.
4491    *) Then the handler::check_if_supported_inplace_alter() method is called
4492       in order to find if the storage engine can carry out changes requested
4493       by this ALTER TABLE using the in-place algorithm. To determine this,
4494       the engine can rely on data in HA_ALTER_FLAGS/Alter_inplace_info
4495       passed to it as well as on its own checks. If the in-place algorithm
4496       can be used for this ALTER TABLE, the level of required concurrency for
4497       its execution is also returned.
4498       If any errors occur during the handler call, ALTER TABLE is aborted
4499       and no further handler functions are called.
4500    *) Locking requirements of the in-place algorithm are compared to any
4501       concurrency requirements specified by user. If there is a conflict
4502       between them, we either switch to the copy algorithm or emit an error.
4503 
4504    Phase 2 : Execution
4505    ===================
4506 
4507    In this phase the operations are executed.
4508 
4509    *) As the first step, we acquire a lock corresponding to the concurrency
4510       level which was returned by handler::check_if_supported_inplace_alter()
4511       and requested by the user. This lock is held for most of the
4512       duration of in-place ALTER (if HA_ALTER_INPLACE_COPY_LOCK
4513       or HA_ALTER_INPLACE_COPY_NO_LOCK were returned we acquire an
4514       exclusive lock for duration of the next step only).
4515    *) After that we call handler::ha_prepare_inplace_alter_table() to give the
4516       storage engine a chance to update its internal structures with a higher
4517       lock level than the one that will be used for the main step of algorithm.
4518       After that we downgrade the lock if it is necessary.
4519    *) After that, the main step of this phase and algorithm is executed.
4520       We call the handler::ha_inplace_alter_table() method, which carries out the
4521       changes requested by ALTER TABLE but does not makes them visible to other
4522       connections yet.
4523    *) We ensure that no other connection uses the table by upgrading our
4524       lock on it to exclusive.
4525    *) a) If the previous step succeeds, handler::ha_commit_inplace_alter_table() is
4526          called to allow the storage engine to do any final updates to its structures,
4527          to make all earlier changes durable and visible to other connections.
4528       b) If we have failed to upgrade lock or any errors have occurred during the
4529          handler functions calls (including commit), we call
4530          handler::ha_commit_inplace_alter_table()
4531          to rollback all changes which were done during previous steps.
4532 
4533   Phase 3 : Final
4534   ===============
4535 
4536   In this phase we:
4537 
4538   *) Update SQL-layer data-dictionary by installing .FRM file for the new version
4539      of the table.
4540   *) Inform the storage engine about this change by calling the
4541      hton::notify_table_changed()
4542   *) Destroy the Alter_inplace_info and handler_ctx objects.
4543 
4544  */
4545 
4546  /**
4547     Check if a storage engine supports a particular alter table in-place
4548 
4549     @param    altered_table     TABLE object for new version of table.
4550     @param    ha_alter_info     Structure describing changes to be done
4551                                 by ALTER TABLE and holding data used
4552                                 during in-place alter.
4553 
4554     @retval   HA_ALTER_ERROR                  Unexpected error.
4555     @retval   HA_ALTER_INPLACE_NOT_SUPPORTED  Not supported, must use copy.
4556     @retval   HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
4557     @retval   HA_ALTER_INPLACE_COPY_LOCK
4558                                               Supported, but requires SNW lock
4559                                               during main phase. Prepare phase
4560                                               requires X lock.
4561     @retval   HA_ALTER_INPLACE_SHARED_LOCK    Supported, but requires SNW lock.
4562     @retval   HA_ALTER_INPLACE_COPY_NO_LOCK
4563                                               Supported, concurrent reads/writes
4564                                               allowed. However, prepare phase
4565                                               requires X lock.
4566     @retval   HA_ALTER_INPLACE_NO_LOCK        Supported, concurrent
4567                                               reads/writes allowed.
4568 
4569     @note The default implementation uses the old in-place ALTER API
4570     to determine if the storage engine supports in-place ALTER or not.
4571 
4572     @note Called without holding thr_lock.c lock.
4573  */
4574  virtual enum_alter_inplace_result
4575  check_if_supported_inplace_alter(TABLE *altered_table,
4576                                   Alter_inplace_info *ha_alter_info);
4577 
4578 
4579  /**
4580     Public functions wrapping the actual handler call.
4581     @see prepare_inplace_alter_table()
4582  */
4583  bool ha_prepare_inplace_alter_table(TABLE *altered_table,
4584                                      Alter_inplace_info *ha_alter_info);
4585 
4586 
4587  /**
4588     Public function wrapping the actual handler call.
4589     @see inplace_alter_table()
4590  */
ha_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)4591  bool ha_inplace_alter_table(TABLE *altered_table,
4592                              Alter_inplace_info *ha_alter_info)
4593  {
4594    return inplace_alter_table(altered_table, ha_alter_info);
4595  }
4596 
4597 
4598  /**
4599     Public function wrapping the actual handler call.
4600     Allows us to enforce asserts regardless of handler implementation.
4601     @see commit_inplace_alter_table()
4602  */
4603  bool ha_commit_inplace_alter_table(TABLE *altered_table,
4604                                     Alter_inplace_info *ha_alter_info,
4605                                     bool commit);
4606 
4607 
4608 protected:
4609  /**
4610     Allows the storage engine to update internal structures with concurrent
4611     writes blocked. If check_if_supported_inplace_alter() returns
4612     HA_ALTER_INPLACE_COPY_NO_LOCK or HA_ALTER_INPLACE_COPY_LOCK,
4613     this function is called with exclusive lock otherwise the same level
4614     of locking as for inplace_alter_table() will be used.
4615 
4616     @note Storage engines are responsible for reporting any errors by
4617     calling my_error()/print_error()
4618 
4619     @note If this function reports error, commit_inplace_alter_table()
4620     will be called with commit= false.
4621 
4622     @note For partitioning, failing to prepare one partition, means that
4623     commit_inplace_alter_table() will be called to roll back changes for
4624     all partitions. This means that commit_inplace_alter_table() might be
4625     called without prepare_inplace_alter_table() having been called first
4626     for a given partition.
4627 
4628     @param    altered_table     TABLE object for new version of table.
4629     @param    ha_alter_info     Structure describing changes to be done
4630                                 by ALTER TABLE and holding data used
4631                                 during in-place alter.
4632 
4633     @retval   true              Error
4634     @retval   false             Success
4635  */
prepare_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)4636  virtual bool prepare_inplace_alter_table(TABLE *altered_table,
4637                                           Alter_inplace_info *ha_alter_info)
4638  { return false; }
4639 
4640 
4641  /**
4642     Alter the table structure in-place with operations specified using HA_ALTER_FLAGS
4643     and Alter_inplace_info. The level of concurrency allowed during this
4644     operation depends on the return value from check_if_supported_inplace_alter().
4645 
4646     @note Storage engines are responsible for reporting any errors by
4647     calling my_error()/print_error()
4648 
4649     @note If this function reports error, commit_inplace_alter_table()
4650     will be called with commit= false.
4651 
4652     @param    altered_table     TABLE object for new version of table.
4653     @param    ha_alter_info     Structure describing changes to be done
4654                                 by ALTER TABLE and holding data used
4655                                 during in-place alter.
4656 
4657     @retval   true              Error
4658     @retval   false             Success
4659  */
inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)4660  virtual bool inplace_alter_table(TABLE *altered_table,
4661                                   Alter_inplace_info *ha_alter_info)
4662  { return false; }
4663 
4664 
4665  /**
4666     Commit or rollback the changes made during prepare_inplace_alter_table()
4667     and inplace_alter_table() inside the storage engine.
4668     Note that in case of rollback the allowed level of concurrency during
4669     this operation will be the same as for inplace_alter_table() and thus
4670     might be higher than during prepare_inplace_alter_table(). (For example,
4671     concurrent writes were blocked during prepare, but might not be during
4672     rollback).
4673 
4674     @note Storage engines are responsible for reporting any errors by
4675     calling my_error()/print_error()
4676 
4677     @note If this function with commit= true reports error, it will be called
4678     again with commit= false.
4679 
4680     @note In case of partitioning, this function might be called for rollback
4681     without prepare_inplace_alter_table() having been called first.
4682     Also partitioned tables sets ha_alter_info->group_commit_ctx to a NULL
4683     terminated array of the partitions handlers and if all of them are
4684     committed as one, then group_commit_ctx should be set to NULL to indicate
4685     to the partitioning handler that all partitions handlers are committed.
4686     @see prepare_inplace_alter_table().
4687 
4688     @param    altered_table     TABLE object for new version of table.
4689     @param    ha_alter_info     Structure describing changes to be done
4690                                 by ALTER TABLE and holding data used
4691                                 during in-place alter.
4692     @param    commit            True => Commit, False => Rollback.
4693 
4694     @retval   true              Error
4695     @retval   false             Success
4696  */
commit_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info,bool commit)4697  virtual bool commit_inplace_alter_table(TABLE *altered_table,
4698                                          Alter_inplace_info *ha_alter_info,
4699                                          bool commit)
4700 {
4701   /* Nothing to commit/rollback, mark all handlers committed! */
4702   ha_alter_info->group_commit_ctx= NULL;
4703   return false;
4704 }
4705 
4706 public:
4707  /* End of On-line/in-place ALTER TABLE interface. */
4708 
4709 
4710   /**
4711     use_hidden_primary_key() is called in case of an update/delete when
4712     (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
4713     but we don't have a primary key
4714   */
4715   virtual void use_hidden_primary_key();
alter_table_flags(alter_table_operations flags)4716   virtual alter_table_operations alter_table_flags(alter_table_operations flags)
4717   {
4718     if (ht->alter_table_flags)
4719       return ht->alter_table_flags(flags);
4720     return 0;
4721   }
4722 
4723   virtual LEX_CSTRING *engine_name();
4724 
get_table()4725   TABLE* get_table() { return table; }
get_table_share()4726   TABLE_SHARE* get_table_share() { return table_share; }
4727 protected:
4728   /* Service methods for use by storage engines. */
4729   THD *ha_thd(void) const;
4730 
4731   /**
4732     Acquire the instrumented table information from a table share.
4733     @return an instrumented table share, or NULL.
4734   */
4735   PSI_table_share *ha_table_share_psi() const;
4736 
4737   /**
4738     Default rename_table() and delete_table() rename/delete files with a
4739     given name and extensions from bas_ext().
4740 
4741     These methods can be overridden, but their default implementation
4742     provide useful functionality.
4743   */
4744   virtual int rename_table(const char *from, const char *to);
4745 
4746 
4747 public:
4748   /**
4749     Delete a table in the engine. Called for base as well as temporary
4750     tables.
4751   */
4752   virtual int delete_table(const char *name);
4753   bool check_table_binlog_row_based();
4754   bool prepare_for_row_logging();
4755   int prepare_for_insert(bool do_create);
4756   int binlog_log_row(TABLE *table,
4757                      const uchar *before_record,
4758                      const uchar *after_record,
4759                      Log_func *log_func);
4760 
clear_cached_table_binlog_row_based_flag()4761   inline void clear_cached_table_binlog_row_based_flag()
4762   {
4763     check_table_binlog_row_based_done= 0;
4764   }
4765 private:
4766   /* Cache result to avoid extra calls */
mark_trx_read_write()4767   inline void mark_trx_read_write()
4768   {
4769     if (unlikely(!mark_trx_read_write_done))
4770     {
4771       mark_trx_read_write_done= 1;
4772       mark_trx_read_write_internal();
4773     }
4774   }
4775 
4776 private:
4777   void mark_trx_read_write_internal();
4778   bool check_table_binlog_row_based_internal();
4779 
4780   int create_lookup_handler();
4781   void alloc_lookup_buffer();
4782   int check_duplicate_long_entries(const uchar *new_rec);
4783   int check_duplicate_long_entries_update(const uchar *new_rec);
4784   int check_duplicate_long_entry_key(const uchar *new_rec, uint key_no);
4785   /** PRIMARY KEY/UNIQUE WITHOUT OVERLAPS check */
4786   int ha_check_overlaps(const uchar *old_data, const uchar* new_data);
4787 
4788 protected:
4789   /*
4790     These are intended to be used only by handler::ha_xxxx() functions
4791     However, engines that implement read_range_XXX() (like MariaRocks)
4792     or embed other engines (like ha_partition) may need to call these also
4793   */
4794   inline void increment_statistics(ulong SSV::*offset) const;
4795   inline void decrement_statistics(ulong SSV::*offset) const;
4796 
4797 private:
4798   /*
4799     Low-level primitives for storage engines.  These should be
4800     overridden by the storage engine class. To call these methods, use
4801     the corresponding 'ha_*' method above.
4802   */
4803 
4804   virtual int open(const char *name, int mode, uint test_if_locked)=0;
4805   /* Note: ha_index_read_idx_map() may bypass index_init() */
index_init(uint idx,bool sorted)4806   virtual int index_init(uint idx, bool sorted) { return 0; }
index_end()4807   virtual int index_end() { return 0; }
4808   /**
4809     rnd_init() can be called two times without rnd_end() in between
4810     (it only makes sense if scan=1).
4811     then the second call should prepare for the new table scan (e.g
4812     if rnd_init allocates the cursor, second call should position it
4813     to the start of the table, no need to deallocate and allocate it again
4814   */
4815   virtual int rnd_init(bool scan)= 0;
rnd_end()4816   virtual int rnd_end() { return 0; }
write_row(const uchar * buf)4817   virtual int write_row(const uchar *buf __attribute__((unused)))
4818   {
4819     return HA_ERR_WRONG_COMMAND;
4820   }
4821 
4822   /**
4823     Update a single row.
4824 
4825     Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
4826     all columns of the row so MySQL can create an error message. If
4827     the columns required for the error message are not read, the error
4828     message will contain garbage.
4829   */
update_row(const uchar * old_data,const uchar * new_data)4830   virtual int update_row(const uchar *old_data __attribute__((unused)),
4831                          const uchar *new_data __attribute__((unused)))
4832   {
4833     return HA_ERR_WRONG_COMMAND;
4834   }
4835 
4836   /*
4837     Optimized function for updating the first row. Only used by sequence
4838     tables
4839   */
4840   virtual int update_first_row(const uchar *new_data);
4841 
delete_row(const uchar * buf)4842   virtual int delete_row(const uchar *buf __attribute__((unused)))
4843   {
4844     return HA_ERR_WRONG_COMMAND;
4845   }
4846 
4847   /* Perform initialization for a direct update request */
4848 public:
4849   int ha_direct_update_rows(ha_rows *update_rows, ha_rows *found_rows);
direct_update_rows_init(List<Item> * update_fields)4850   virtual int direct_update_rows_init(List<Item> *update_fields)
4851   {
4852     return HA_ERR_WRONG_COMMAND;
4853   }
4854 private:
pre_direct_update_rows_init(List<Item> * update_fields)4855   virtual int pre_direct_update_rows_init(List<Item> *update_fields)
4856   {
4857     return HA_ERR_WRONG_COMMAND;
4858   }
direct_update_rows(ha_rows * update_rows,ha_rows * found_rows)4859   virtual int direct_update_rows(ha_rows *update_rows __attribute__((unused)),
4860                                  ha_rows *found_rows __attribute__((unused)))
4861   {
4862     return HA_ERR_WRONG_COMMAND;
4863   }
pre_direct_update_rows()4864   virtual int pre_direct_update_rows()
4865   {
4866     return HA_ERR_WRONG_COMMAND;
4867   }
4868 
4869   /* Perform initialization for a direct delete request */
4870 public:
4871   int ha_direct_delete_rows(ha_rows *delete_rows);
direct_delete_rows_init()4872   virtual int direct_delete_rows_init()
4873   {
4874     return HA_ERR_WRONG_COMMAND;
4875   }
4876 private:
pre_direct_delete_rows_init()4877   virtual int pre_direct_delete_rows_init()
4878   {
4879     return HA_ERR_WRONG_COMMAND;
4880   }
direct_delete_rows(ha_rows * delete_rows)4881   virtual int direct_delete_rows(ha_rows *delete_rows __attribute__((unused)))
4882   {
4883     return HA_ERR_WRONG_COMMAND;
4884   }
pre_direct_delete_rows()4885   virtual int pre_direct_delete_rows()
4886   {
4887     return HA_ERR_WRONG_COMMAND;
4888   }
4889 
4890   /**
4891     Reset state of file to after 'open'.
4892     This function is called after every statement for all tables used
4893     by that statement.
4894   */
reset()4895   virtual int reset() { return 0; }
4896   virtual Table_flags table_flags(void) const= 0;
4897   /**
4898     Is not invoked for non-transactional temporary tables.
4899 
4900     Tells the storage engine that we intend to read or write data
4901     from the table. This call is prefixed with a call to handler::store_lock()
4902     and is invoked only for those handler instances that stored the lock.
4903 
4904     Calls to rnd_init/index_init are prefixed with this call. When table
4905     IO is complete, we call external_lock(F_UNLCK).
4906     A storage engine writer should expect that each call to
4907     ::external_lock(F_[RD|WR]LOCK is followed by a call to
4908     ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
4909 
4910     The name and signature originate from the first implementation
4911     in MyISAM, which would call fcntl to set/clear an advisory
4912     lock on the data file in this method.
4913 
4914     @param   lock_type    F_RDLCK, F_WRLCK, F_UNLCK
4915 
4916     @return  non-0 in case of failure, 0 in case of success.
4917     When lock_type is F_UNLCK, the return value is ignored.
4918   */
external_lock(THD * thd,int lock_type)4919   virtual int external_lock(THD *thd __attribute__((unused)),
4920                             int lock_type __attribute__((unused)))
4921   {
4922     return 0;
4923   }
release_auto_increment()4924   virtual void release_auto_increment() { return; };
4925   /** admin commands - called from mysql_admin_table */
check_for_upgrade(HA_CHECK_OPT * check_opt)4926   virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
4927   { return 0; }
check(THD * thd,HA_CHECK_OPT * check_opt)4928   virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
4929   { return HA_ADMIN_NOT_IMPLEMENTED; }
4930 
4931   /**
4932      In this method check_opt can be modified
4933      to specify CHECK option to use to call check()
4934      upon the table.
4935   */
repair(THD * thd,HA_CHECK_OPT * check_opt)4936   virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
4937   {
4938     DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR));
4939     return HA_ADMIN_NOT_IMPLEMENTED;
4940   }
4941 protected:
start_bulk_insert(ha_rows rows,uint flags)4942   virtual void start_bulk_insert(ha_rows rows, uint flags) {}
end_bulk_insert()4943   virtual int end_bulk_insert() { return 0; }
index_read(uchar * buf,const uchar * key,uint key_len,enum ha_rkey_function find_flag)4944   virtual int index_read(uchar * buf, const uchar * key, uint key_len,
4945                          enum ha_rkey_function find_flag)
4946    { return  HA_ERR_WRONG_COMMAND; }
index_read_last(uchar * buf,const uchar * key,uint key_len)4947   virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
4948   {
4949     my_errno= HA_ERR_WRONG_COMMAND;
4950     return HA_ERR_WRONG_COMMAND;
4951   }
4952   friend class ha_partition;
4953   friend class ha_sequence;
4954 public:
4955   /**
4956     This method is similar to update_row, however the handler doesn't need
4957     to execute the updates at this point in time. The handler can be certain
4958     that another call to bulk_update_row will occur OR a call to
4959     exec_bulk_update before the set of updates in this query is concluded.
4960 
4961     @param    old_data       Old record
4962     @param    new_data       New record
4963     @param    dup_key_found  Number of duplicate keys found
4964 
4965     @retval  0   Bulk delete used by handler
4966     @retval  1   Bulk delete not used, normal operation used
4967   */
bulk_update_row(const uchar * old_data,const uchar * new_data,ha_rows * dup_key_found)4968   virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
4969                               ha_rows *dup_key_found)
4970   {
4971     DBUG_ASSERT(FALSE);
4972     return HA_ERR_WRONG_COMMAND;
4973   }
4974   /**
4975     This is called to delete all rows in a table
4976     If the handler don't support this, then this function will
4977     return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
4978     by one.
4979   */
delete_all_rows()4980   virtual int delete_all_rows()
4981   { return (my_errno=HA_ERR_WRONG_COMMAND); }
4982   /**
4983     Quickly remove all rows from a table.
4984 
4985     @remark This method is responsible for implementing MySQL's TRUNCATE
4986             TABLE statement, which is a DDL operation. As such, a engine
4987             can bypass certain integrity checks and in some cases avoid
4988             fine-grained locking (e.g. row locks) which would normally be
4989             required for a DELETE statement.
4990 
4991     @remark Typically, truncate is not used if it can result in integrity
4992             violation. For example, truncate is not used when a foreign
4993             key references the table, but it might be used if foreign key
4994             checks are disabled.
4995 
4996     @remark Engine is responsible for resetting the auto-increment counter.
4997 
4998     @remark The table is locked in exclusive mode.
4999   */
truncate()5000   virtual int truncate()
5001   {
5002     int error= delete_all_rows();
5003     return error ? error : reset_auto_increment(0);
5004   }
5005   /**
5006     Reset the auto-increment counter to the given value, i.e. the next row
5007     inserted will get the given value.
5008   */
reset_auto_increment(ulonglong value)5009   virtual int reset_auto_increment(ulonglong value)
5010   { return 0; }
optimize(THD * thd,HA_CHECK_OPT * check_opt)5011   virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
5012   { return HA_ADMIN_NOT_IMPLEMENTED; }
analyze(THD * thd,HA_CHECK_OPT * check_opt)5013   virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
5014   { return HA_ADMIN_NOT_IMPLEMENTED; }
check_and_repair(THD * thd)5015   virtual bool check_and_repair(THD *thd) { return TRUE; }
disable_indexes(uint mode)5016   virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
enable_indexes(uint mode)5017   virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
discard_or_import_tablespace(my_bool discard)5018   virtual int discard_or_import_tablespace(my_bool discard)
5019   { return (my_errno=HA_ERR_WRONG_COMMAND); }
5020   virtual void drop_table(const char *name);
5021   virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
5022 
create_partitioning_metadata(const char * name,const char * old_name,chf_create_flags action_flag)5023   virtual int create_partitioning_metadata(const char *name,
5024                                            const char *old_name,
5025                                            chf_create_flags action_flag)
5026   { return FALSE; }
5027 
change_partitions(HA_CREATE_INFO * create_info,const char * path,ulonglong * const copied,ulonglong * const deleted,const uchar * pack_frm_data,size_t pack_frm_len)5028   virtual int change_partitions(HA_CREATE_INFO *create_info,
5029                                 const char *path,
5030                                 ulonglong * const copied,
5031                                 ulonglong * const deleted,
5032                                 const uchar *pack_frm_data,
5033                                 size_t pack_frm_len)
5034   { return HA_ERR_WRONG_COMMAND; }
drop_partitions(const char * path)5035   virtual int drop_partitions(const char *path)
5036   { return HA_ERR_WRONG_COMMAND; }
rename_partitions(const char * path)5037   virtual int rename_partitions(const char *path)
5038   { return HA_ERR_WRONG_COMMAND; }
set_ha_share_ref(Handler_share ** arg_ha_share)5039   virtual bool set_ha_share_ref(Handler_share **arg_ha_share)
5040   {
5041     DBUG_ASSERT(!ha_share);
5042     DBUG_ASSERT(arg_ha_share);
5043     if (ha_share || !arg_ha_share)
5044       return true;
5045     ha_share= arg_ha_share;
5046     return false;
5047   }
set_table(TABLE * table_arg)5048   void set_table(TABLE* table_arg) { table= table_arg; }
get_lock_type()5049   int get_lock_type() const { return m_lock_type; }
5050 public:
5051   /* XXX to be removed, see ha_partition::partition_ht() */
partition_ht()5052   virtual handlerton *partition_ht() const
5053   { return ht; }
5054   inline int ha_write_tmp_row(uchar *buf);
5055   inline int ha_delete_tmp_row(uchar *buf);
5056   inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
5057 
5058   virtual void set_lock_type(enum thr_lock_type lock);
5059   friend check_result_t handler_index_cond_check(void* h_arg);
5060   friend check_result_t handler_rowid_filter_check(void *h_arg);
5061 
5062   /**
5063     Find unique record by index or unique constrain
5064 
5065     @param record        record to find (also will be fillded with
5066                          actual record fields)
5067     @param unique_ref    index or unique constraiun number (depends
5068                          on what used in the engine
5069 
5070     @retval -1 Error
5071     @retval  1 Not found
5072     @retval  0 Found
5073   */
find_unique_row(uchar * record,uint unique_ref)5074   virtual int find_unique_row(uchar *record, uint unique_ref)
5075   { return -1; /*unsupported */}
5076 
native_versioned()5077   bool native_versioned() const
5078   { DBUG_ASSERT(ht); return partition_ht()->flags & HTON_NATIVE_SYS_VERSIONING; }
update_partition(uint part_id)5079   virtual void update_partition(uint	part_id)
5080   {}
5081 
5082   /**
5083     Some engines can perform column type conversion with ALGORITHM=INPLACE.
5084     These functions check for such possibility.
5085     Implementation could be based on Field_xxx::is_equal()
5086    */
can_convert_string(const Field_string * field,const Column_definition & new_type)5087   virtual bool can_convert_string(const Field_string *field,
5088                                   const Column_definition &new_type) const
5089   {
5090     return false;
5091   }
can_convert_varstring(const Field_varstring * field,const Column_definition & new_type)5092   virtual bool can_convert_varstring(const Field_varstring *field,
5093                                      const Column_definition &new_type) const
5094   {
5095     return false;
5096   }
can_convert_blob(const Field_blob * field,const Column_definition & new_type)5097   virtual bool can_convert_blob(const Field_blob *field,
5098                                 const Column_definition &new_type) const
5099   {
5100     return false;
5101   }
5102   /* If the table is using sql level unique constraints on some column */
5103   inline bool has_long_unique();
5104 
5105   /* Used for ALTER TABLE.
5106   Some engines can handle some differences in indexes by themself. */
5107   virtual Compare_keys compare_key_parts(const Field &old_field,
5108                                          const Column_definition &new_field,
5109                                          const KEY_PART_INFO &old_part,
5110                                          const KEY_PART_INFO &new_part) const;
5111 
5112 protected:
5113   Handler_share *get_ha_share_ptr();
5114   void set_ha_share_ptr(Handler_share *arg_ha_share);
5115   void lock_shared_ha_data();
5116   void unlock_shared_ha_data();
5117 };
5118 
5119 #include "multi_range_read.h"
5120 #include "group_by_handler.h"
5121 
5122 bool key_uses_partial_cols(TABLE_SHARE *table, uint keyno);
5123 
5124 	/* Some extern variables used with handlers */
5125 
5126 extern const char *ha_row_type[];
5127 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
5128 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
5129 extern TYPELIB tx_isolation_typelib;
5130 extern const char *myisam_stats_method_names[];
5131 extern ulong total_ha, total_ha_2pc;
5132 
5133 /* lookups */
5134 plugin_ref ha_resolve_by_name(THD *thd, const LEX_CSTRING *name, bool tmp_table);
5135 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
5136 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
5137 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
5138                          handlerton *db_type);
5139 handlerton *ha_checktype(THD *thd, handlerton *hton, bool no_substitute);
5140 
5141 static inline handlerton *ha_checktype(THD *thd, enum legacy_db_type type,
5142                                        bool no_substitute = 0)
5143 {
5144   return ha_checktype(thd, ha_resolve_by_legacy_type(thd, type), no_substitute);
5145 }
5146 
ha_legacy_type(const handlerton * db_type)5147 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
5148 {
5149   return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
5150 }
5151 
ha_resolve_storage_engine_name(const handlerton * db_type)5152 static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
5153 {
5154   return db_type == NULL ? "UNKNOWN" : hton_name(db_type)->str;
5155 }
5156 
ha_check_storage_engine_flag(const handlerton * db_type,uint32 flag)5157 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
5158 {
5159   return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
5160 }
5161 
ha_storage_engine_is_enabled(const handlerton * db_type)5162 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
5163 {
5164   return db_type && db_type->create;
5165 }
5166 
5167 #define view_pseudo_hton ((handlerton *)1)
5168 
5169 /* basic stuff */
5170 int ha_init_errors(void);
5171 int ha_init(void);
5172 int ha_end(void);
5173 int ha_initialize_handlerton(st_plugin_int *plugin);
5174 int ha_finalize_handlerton(st_plugin_int *plugin);
5175 
5176 TYPELIB *ha_known_exts(void);
5177 int ha_panic(enum ha_panic_function flag);
5178 void ha_close_connection(THD* thd);
5179 void ha_kill_query(THD* thd, enum thd_kill_levels level);
5180 bool ha_flush_logs();
5181 void ha_drop_database(char* path);
5182 void ha_checkpoint_state(bool disable);
5183 void ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *));
5184 int ha_create_table(THD *thd, const char *path,
5185                     const char *db, const char *table_name,
5186                     HA_CREATE_INFO *create_info, LEX_CUSTRING *frm);
5187 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
5188                     const LEX_CSTRING *db, const LEX_CSTRING *alias,
5189                     bool generate_warning);
5190 int ha_delete_table_force(THD *thd, const char *path, const LEX_CSTRING *db,
5191                           const LEX_CSTRING *alias);
5192 
5193 void ha_prepare_for_backup();
5194 void ha_end_backup();
5195 void ha_pre_shutdown();
5196 
5197 /* statistics and info */
5198 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
5199 
5200 /* discovery */
5201 #ifdef MYSQL_SERVER
5202 class Discovered_table_list: public handlerton::discovered_list
5203 {
5204   THD *thd;
5205   const char *wild, *wend;
5206   bool with_temps; // whether to include temp tables in the result
5207 public:
5208   Dynamic_array<LEX_CSTRING*> *tables;
5209 
5210   Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_CSTRING*> *tables_arg,
5211                         const LEX_CSTRING *wild_arg);
Discovered_table_list(THD * thd_arg,Dynamic_array<LEX_CSTRING * > * tables_arg)5212   Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_CSTRING*> *tables_arg)
5213     : thd(thd_arg), wild(NULL), with_temps(true), tables(tables_arg) {}
~Discovered_table_list()5214   ~Discovered_table_list() {}
5215 
5216   bool add_table(const char *tname, size_t tlen);
5217   bool add_file(const char *fname);
5218 
5219   void sort();
5220   void remove_duplicates(); // assumes that the list is sorted
5221 #ifndef DBUG_OFF
5222   /*
5223      Used to find unstable mtr tests querying
5224      INFORMATION_SCHEMA.TABLES without ORDER BY.
5225   */
5226   void sort_desc();
5227 #endif /* DBUG_OFF */
5228 };
5229 
5230 int ha_discover_table(THD *thd, TABLE_SHARE *share);
5231 int ha_discover_table_names(THD *thd, LEX_CSTRING *db, MY_DIR *dirp,
5232                             Discovered_table_list *result, bool reusable);
5233 bool ha_table_exists(THD *thd, const LEX_CSTRING *db,
5234                      const LEX_CSTRING *table_name,
5235                      handlerton **hton= 0, bool *is_sequence= 0);
5236 bool ha_check_if_updates_are_ignored(THD *thd, handlerton *hton,
5237                                      const char *op);
5238 #endif /* MYSQL_SERVER */
5239 
5240 /* key cache */
5241 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache, void *);
5242 int ha_resize_key_cache(KEY_CACHE *key_cache);
5243 int ha_change_key_cache_param(KEY_CACHE *key_cache);
5244 int ha_repartition_key_cache(KEY_CACHE *key_cache);
5245 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
5246 
5247 /* transactions: interface to handlerton functions */
5248 int ha_start_consistent_snapshot(THD *thd);
5249 int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
5250 int ha_commit_one_phase(THD *thd, bool all);
5251 int ha_commit_trans(THD *thd, bool all);
5252 int ha_rollback_trans(THD *thd, bool all);
5253 int ha_prepare(THD *thd);
5254 int ha_recover(HASH *commit_list);
5255 
5256 /* transactions: these functions never call handlerton functions directly */
5257 int ha_enable_transaction(THD *thd, bool on);
5258 
5259 /* savepoints */
5260 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
5261 bool ha_rollback_to_savepoint_can_release_mdl(THD *thd);
5262 int ha_savepoint(THD *thd, SAVEPOINT *sv);
5263 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
5264 #ifdef WITH_WSREP
5265 int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal);
5266 #endif
5267 
5268 /* these are called by storage engines */
5269 void trans_register_ha(THD *thd, bool all, handlerton *ht,
5270                        ulonglong trxid);
5271 
5272 /*
5273   Storage engine has to assume the transaction will end up with 2pc if
5274    - there is more than one 2pc-capable storage engine available
5275    - in the current transaction 2pc was not disabled yet
5276 */
5277 #define trans_need_2pc(thd, all)                   ((total_ha_2pc > 1) && \
5278         !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
5279 
5280 const char *get_canonical_filename(handler *file, const char *path,
5281                                    char *tmp_path);
5282 void commit_checkpoint_notify_ha(void *cookie);
5283 
table_case_name(HA_CREATE_INFO * info,const LEX_CSTRING * name)5284 inline const LEX_CSTRING *table_case_name(HA_CREATE_INFO *info, const LEX_CSTRING *name)
5285 {
5286   return ((lower_case_table_names == 2 && info->alias.str) ? &info->alias : name);
5287 }
5288 
5289 typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
5290 int binlog_log_row(TABLE* table,
5291                    const uchar *before_record,
5292                    const uchar *after_record,
5293                    Log_func *log_func);
5294 
5295 /**
5296   @def MYSQL_TABLE_IO_WAIT
5297   Instrumentation helper for table io_waits.
5298   Note that this helper is intended to be used from
5299   within the handler class only, as it uses members
5300   from @c handler
5301   Performance schema events are instrumented as follows:
5302   - in non batch mode, one event is generated per call
5303   - in batch mode, the number of rows affected is saved
5304   in @c m_psi_numrows, so that @c end_psi_batch_mode()
5305   generates a single event for the batch.
5306   @param OP the table operation to be performed
5307   @param INDEX the table index used if any, or MAX_KEY.
5308   @param PAYLOAD instrumented code to execute
5309   @sa handler::end_psi_batch_mode.
5310 */
5311 #ifdef HAVE_PSI_TABLE_INTERFACE
5312   #define MYSQL_TABLE_IO_WAIT(OP, INDEX, RESULT, PAYLOAD)     \
5313     {                                                         \
5314       if (m_psi != NULL)                                      \
5315       {                                                       \
5316         switch (m_psi_batch_mode)                             \
5317         {                                                     \
5318           case PSI_BATCH_MODE_NONE:                           \
5319           {                                                   \
5320             PSI_table_locker *sub_locker= NULL;               \
5321             PSI_table_locker_state reentrant_safe_state;      \
5322             sub_locker= PSI_TABLE_CALL(start_table_io_wait)   \
5323               (& reentrant_safe_state, m_psi, OP, INDEX,      \
5324                __FILE__, __LINE__);                           \
5325             PAYLOAD                                           \
5326             if (sub_locker != NULL)                           \
5327               PSI_TABLE_CALL(end_table_io_wait)               \
5328                 (sub_locker, 1);                              \
5329             break;                                            \
5330           }                                                   \
5331           case PSI_BATCH_MODE_STARTING:                       \
5332           {                                                   \
5333             m_psi_locker= PSI_TABLE_CALL(start_table_io_wait) \
5334               (& m_psi_locker_state, m_psi, OP, INDEX,        \
5335                __FILE__, __LINE__);                           \
5336             PAYLOAD                                           \
5337             if (!RESULT)                                      \
5338               m_psi_numrows++;                                \
5339             m_psi_batch_mode= PSI_BATCH_MODE_STARTED;         \
5340             break;                                            \
5341           }                                                   \
5342           case PSI_BATCH_MODE_STARTED:                        \
5343           default:                                            \
5344           {                                                   \
5345             DBUG_ASSERT(m_psi_batch_mode                      \
5346                         == PSI_BATCH_MODE_STARTED);           \
5347             PAYLOAD                                           \
5348             if (!RESULT)                                      \
5349               m_psi_numrows++;                                \
5350             break;                                            \
5351           }                                                   \
5352         }                                                     \
5353       }                                                       \
5354       else                                                    \
5355       {                                                       \
5356         PAYLOAD                                               \
5357       }                                                       \
5358     }
5359 #else
5360   #define MYSQL_TABLE_IO_WAIT(OP, INDEX, RESULT, PAYLOAD) \
5361     PAYLOAD
5362 #endif
5363 
5364 #define TABLE_IO_WAIT(TRACKER, OP, INDEX, RESULT, PAYLOAD) \
5365   { \
5366     Exec_time_tracker *this_tracker; \
5367     if (unlikely((this_tracker= tracker))) \
5368       tracker->start_tracking(table->in_use); \
5369     \
5370     MYSQL_TABLE_IO_WAIT(OP, INDEX, RESULT, PAYLOAD); \
5371     \
5372     if (unlikely(this_tracker)) \
5373       tracker->stop_tracking(table->in_use); \
5374   }
5375 void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag);
5376 void print_keydup_error(TABLE *table, KEY *key, myf errflag);
5377 
5378 int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info);
5379 int del_global_table_stat(THD *thd, const  LEX_CSTRING *db, const LEX_CSTRING *table);
5380 uint ha_count_rw_all(THD *thd, Ha_trx_info **ptr_ha_info);
5381 bool non_existing_table_error(int error);
5382 #endif /* HANDLER_INCLUDED */
5383