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