MySQL 9.2.0
Source Code Documentation
handler.h
Go to the documentation of this file.
1#ifndef HANDLER_INCLUDED
2#define HANDLER_INCLUDED
3
4/*
5 Copyright (c) 2000, 2024, Oracle and/or its affiliates.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License, version 2.0,
9 as published by the Free Software Foundation.
10
11 This program is designed to work 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 either included with
17 the program or referenced in the documentation.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License, version 2.0, for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, write to the Free Software
26 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27*/
28
29/* Definitions for parameters to do with handler-routines */
30
31#include <fcntl.h>
32#include <float.h>
33#include <string.h>
34#include <sys/types.h>
35#include <time.h>
36#include <algorithm>
37#include <atomic>
38#include <bitset>
39#include <functional>
40#include <map>
41#include <memory>
42#include <optional>
43#include <random> // std::mt19937
44#include <set>
45#include <string>
46#include <string_view>
47
50#include "ft_global.h" // ft_hints
51#include "lex_string.h"
52#include "map_helpers.h"
53#include "my_alloc.h"
54#include "my_base.h"
55#include "my_bitmap.h"
56#include "my_checksum.h" // ha_checksum
57#include "my_compiler.h"
58#include "my_dbug.h"
59#include "my_double2ulonglong.h"
60#include "my_inttypes.h"
61#include "my_io.h"
62#include "my_sys.h"
63#include "my_table_map.h"
64#include "my_thread_local.h" // my_errno
67#include "sql/dd/object_id.h" // dd::Object_id
68#include "sql/dd/string_type.h"
69#include "sql/dd/types/object_table.h" // dd::Object_table
70#include "sql/discrete_interval.h" // Discrete_interval
71#include "sql/key.h"
72#include "sql/sql_const.h" // SHOW_COMP_OPTION
73#include "sql/sql_list.h" // SQL_I_List
74#include "sql/sql_plugin_ref.h" // plugin_ref
75#include "string_with_len.h" // STRING_WITH_LEN
76#include "thr_lock.h" // thr_lock_type
77#include "typelib.h"
78
79class Alter_info;
80class Create_field;
81class Field;
82class Item;
83class JOIN;
84class Json_dom;
86class Plugin_table;
88class Record_buffer;
89class SE_cost_constants; // see opt_costconstants.h
90class String;
91class THD;
92class handler;
93class partition_info;
95
96namespace dd {
97class Properties;
98} // namespace dd
99struct AccessPath;
100struct JoinHypergraph;
101struct KEY_CACHE;
102struct LEX;
103struct MY_BITMAP;
104struct SAVEPOINT;
105struct TABLE;
106class Table_ref;
107struct TABLE_SHARE;
108struct Tablespace_options;
109struct handlerton;
110
111typedef struct xid_t XID;
113struct MDL_key;
114
115namespace dd {
116enum class enum_column_types;
117class Table;
118class Tablespace;
119} // namespace dd
120
121constexpr const ha_rows EXTRA_RECORDS{10};
122
123/** Id for identifying Table SDIs */
124constexpr const uint32 SDI_TYPE_TABLE = 1;
125
126/** Id for identifying Tablespace SDIs */
127constexpr const uint32 SDI_TYPE_TABLESPACE = 2;
128
129/** Key to identify a dictionary object */
130struct sdi_key_t {
131 /** Type of Object, For ex: column, index, etc */
133
134 /** Object id which should be unique in tablespsace */
136};
137
138using sdi_container = std::vector<sdi_key_t>;
141};
142
143typedef bool (*qc_engine_callback)(THD *thd, const char *table_key,
144 uint key_length, ulonglong *engine_data);
145
146typedef bool(stat_print_fn)(THD *thd, const char *type, size_t type_len,
147 const char *file, size_t file_len,
148 const char *status, size_t status_len);
149
150class ha_statistics;
153class Unique_on_insert;
154
155extern ulong savepoint_alloc_size;
156
157/// Maps from slot to plugin. May return NULL if plugin has been unloaded.
158st_plugin_int *hton2plugin(uint slot);
159/// Returns the size of the array holding pointers to plugins.
160size_t num_hton2plugins();
161
162/**
163 For unit testing.
164 Insert plugin into arbitrary slot in array.
165 Remove plugin from arbitrary slot in array.
166*/
169
170extern const char *ha_row_type[];
171extern const char *tx_isolation_names[];
172extern const char *binlog_format_names[];
174extern ulong total_ha_2pc;
175
176// the following is for checking tables
177
178#define HA_ADMIN_ALREADY_DONE 1
179#define HA_ADMIN_OK 0
180#define HA_ADMIN_NOT_IMPLEMENTED -1
181#define HA_ADMIN_FAILED -2
182#define HA_ADMIN_CORRUPT -3
183#define HA_ADMIN_INTERNAL_ERROR -4
184#define HA_ADMIN_INVALID -5
185#define HA_ADMIN_REJECT -6
186#define HA_ADMIN_TRY_ALTER -7
187#define HA_ADMIN_WRONG_CHECKSUM -8
188#define HA_ADMIN_NOT_BASE_TABLE -9
189#define HA_ADMIN_NEEDS_UPGRADE -10
190#define HA_ADMIN_NEEDS_ALTER -11
191#define HA_ADMIN_NEEDS_CHECK -12
192#define HA_ADMIN_STATS_UPD_ERR -13
193/** User needs to dump and re-create table to fix pre 5.0 decimal types */
194#define HA_ADMIN_NEEDS_DUMP_UPGRADE -14
195
196/**
197 Return values for check_if_supported_inplace_alter().
198
199 @see check_if_supported_inplace_alter() for description of
200 the individual values.
201*/
212
213/**
214 * Used to identify which engine executed a SELECT query.
215 */
217
218/* Bits in table_flags() to show what database can do */
219
220#define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */
221#define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
222/*
223 Used to avoid scanning full tables on an index. If this flag is set then
224 the handler always has a primary key (hidden if not defined) and this
225 index is used for scanning rather than a full table scan in all
226 situations. No separate data/index file.
227*/
228#define HA_TABLE_SCAN_ON_INDEX (1 << 2)
229
230/// Not in use.
231#define HA_UNUSED3 (1 << 3)
232
233/*
234 Can the storage engine handle spatial data.
235 Used to check that no spatial attributes are declared unless
236 the storage engine is capable of handling it.
237*/
238#define HA_CAN_GEOMETRY (1 << 4)
239/*
240 Reading keys in random order is as fast as reading keys in sort order
241 (Used by filesort to decide if we should sort key + data or key +
242 pointer-to-row.)
243*/
244#define HA_FAST_KEY_READ (1 << 5)
245/*
246 Set the following flag if we on delete should force all key to be read
247 and on update read all keys that changes
248*/
249#define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
250/*
251 Is NULL values allowed in indexes.
252 If this is not allowed then it is not possible to use an index on a
253 NULLable field.
254*/
255#define HA_NULL_IN_KEY (1 << 7)
256/*
257 Tells that we can the position for the conflicting duplicate key
258 record is stored in table->file->dupp_ref. (insert uses rnd_pos() on
259 this to find the duplicated row)
260*/
261#define HA_DUPLICATE_POS (1 << 8)
262#define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
263/*
264 Is the storage engine capable of defining an index of a prefix on
265 a BLOB attribute.
266*/
267#define HA_CAN_INDEX_BLOBS (1 << 10)
268/*
269 Auto increment fields can be part of a multi-part key. For second part
270 auto-increment keys, the auto_incrementing is done in handler.cc
271*/
272#define HA_AUTO_PART_KEY (1 << 11)
273/*
274 Can't define a table without primary key (and cannot handle a table
275 with hidden primary key)
276*/
277#define HA_REQUIRE_PRIMARY_KEY (1 << 12)
278/*
279 Does the counter of records after the info call specify an exact
280 value or not. If it does this flag is set.
281*/
282#define HA_STATS_RECORDS_IS_EXACT (1 << 13)
283/// Not in use.
284#define HA_UNUSED14 (1 << 14)
285/*
286 This parameter is set when the handler will also return the primary key
287 when doing read-only-key on another index, i.e., if we get the primary
288 key columns for free when we do an index read (usually, it also implies
289 that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION flag is set).
290*/
291#define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
292/*
293 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
294 uses a primary key given by the record argument.
295 Without primary key, we can't call position().
296 If not set, the position is returned as the current rows position
297 regardless of what argument is given.
298*/
299#define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
300#define HA_CAN_RTREEKEYS (1 << 17)
301/// Not in use.
302#define HA_UNUSED18
303/*
304 The following is we need to a primary key to delete (and update) a row.
305 If there is no primary key, all columns needs to be read on update and delete
306*/
307#define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
308/*
309 Indexes on prefixes of character fields are not allowed.
310*/
311#define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
312/*
313 Does the storage engine support fulltext indexes.
314*/
315#define HA_CAN_FULLTEXT (1 << 21)
316/*
317 Can the HANDLER interface in the MySQL API be used towards this
318 storage engine.
319*/
320#define HA_CAN_SQL_HANDLER (1 << 22)
321/*
322 Set if the storage engine does not support auto increment fields.
323*/
324#define HA_NO_AUTO_INCREMENT (1 << 23)
325/*
326 Supports CHECKSUM option in CREATE TABLE (MyISAM feature).
327*/
328#define HA_HAS_CHECKSUM (1 << 24)
329/*
330 Table data are stored in separate files (for lower_case_table_names).
331 Should file names always be in lower case (used by engines that map
332 table names to file names.
333*/
334#define HA_FILE_BASED (1 << 26)
335#define HA_NO_VARCHAR (1 << 27)
336/*
337 Is the storage engine capable of handling bit fields.
338*/
339#define HA_CAN_BIT_FIELD (1 << 28)
340#define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
341#define HA_NO_COPY_ON_ALTER (1LL << 31)
342#define HA_COUNT_ROWS_INSTANT (1LL << 32) /* records() gives exact count*/
343/* Has it's own method of binlog logging */
344#define HA_HAS_OWN_BINLOGGING (1LL << 33)
345/*
346 Engine is capable of row-format and statement-format logging,
347 respectively
348*/
349#define HA_BINLOG_ROW_CAPABLE (1LL << 34)
350#define HA_BINLOG_STMT_CAPABLE (1LL << 35)
351/*
352 When a multiple key conflict happens in a REPLACE command mysql
353 expects the conflicts to be reported in the ascending order of
354 key names.
355
356 For e.g.
357
358 CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
359 NULL, INDEX(c));
360
361 REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
362
363 MySQL expects the conflict with 'a' to be reported before the conflict with
364 'b'.
365
366 If the underlying storage engine does not report the conflicting keys in
367 ascending order, it causes unexpected errors when the REPLACE command is
368 executed.
369
370 This flag helps the underlying SE to inform the server that the keys are not
371 ordered.
372*/
373#define HA_DUPLICATE_KEY_NOT_IN_ORDER (1LL << 36)
374/*
375 Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
376 incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
377 will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
378*/
379#define HA_CAN_REPAIR (1LL << 37)
380
381/*
382 Set of all binlog flags. Currently only contain the capabilities
383 flags.
384 */
385#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
386
387/**
388 The handler supports read before write removal optimization
389
390 Read before write removal may be used for storage engines which support
391 write without previous read of the row to be updated. Handler returning
392 this flag must implement start_read_removal() and end_read_removal().
393 The handler may return "fake" rows constructed from the key of the row
394 asked for. This is used to optimize UPDATE and DELETE by reducing the
395 number of round-trips between handler and storage engine.
396
397 Example:
398 UPDATE a=1 WHERE pk IN (@<keys@>)
399
400 @verbatim
401 mysql_update()
402 {
403 if (<conditions for starting read removal>)
404 start_read_removal()
405 -> handler returns true if read removal supported for this table/query
406
407 while(read_record("pk=<key>"))
408 -> handler returns fake row with column "pk" set to <key>
409
410 ha_update_row()
411 -> handler sends write "a=1" for row with "pk=<key>"
412
413 end_read_removal()
414 -> handler returns the number of rows actually written
415 }
416 @endverbatim
417
418 @note This optimization in combination with batching may be used to
419 remove even more round-trips.
420*/
421#define HA_READ_BEFORE_WRITE_REMOVAL (1LL << 38)
422
423/*
424 Engine supports extended fulltext API
425 */
426#define HA_CAN_FULLTEXT_EXT (1LL << 39)
427
428/*
429 Storage engine doesn't synchronize result set with expected table contents.
430 Used by replication slave to check if it is possible to retrieve rows from
431 the table when deciding whether to do a full table scan, index scan or hash
432 scan while applying a row event.
433 */
434#define HA_READ_OUT_OF_SYNC (1LL << 40)
435
436/*
437 Storage engine supports table export using the
438 FLUSH TABLE <table_list> FOR EXPORT statement.
439 */
440#define HA_CAN_EXPORT (1LL << 41)
441
442/*
443 The handler don't want accesses to this table to
444 be const-table optimized
445*/
446#define HA_BLOCK_CONST_TABLE (1LL << 42)
447
448/*
449 Handler supports FULLTEXT hints
450*/
451#define HA_CAN_FULLTEXT_HINTS (1LL << 43)
452
453/**
454 Storage engine doesn't support LOCK TABLE ... READ LOCAL locks
455 but doesn't want to use handler::store_lock() API for upgrading
456 them to LOCK TABLE ... READ locks, for example, because it doesn't
457 use THR_LOCK locks at all.
458*/
459#define HA_NO_READ_LOCAL_LOCK (1LL << 44)
460
461/**
462 A storage engine is compatible with the attachable transaction requirements
463 means that
464
465 - either SE detects the fact that THD::ha_data was reset and starts a new
466 attachable transaction, closes attachable transaction on close_connection
467 and resumes regular (outer) transaction when THD::ha_data is restored;
468
469 - or SE completely ignores THD::ha_data and close_connection like MyISAM
470 does.
471*/
472#define HA_ATTACHABLE_TRX_COMPATIBLE (1LL << 45)
473
474/**
475 Handler supports Generated Columns
476*/
477#define HA_GENERATED_COLUMNS (1LL << 46)
478
479/**
480 Supports index on virtual generated column
481*/
482#define HA_CAN_INDEX_VIRTUAL_GENERATED_COLUMN (1LL << 47)
483
484/**
485 Supports descending indexes
486*/
487#define HA_DESCENDING_INDEX (1LL << 48)
488
489/**
490 Supports partial update of BLOB columns.
491*/
492#define HA_BLOB_PARTIAL_UPDATE (1LL << 49)
493
494/**
495 If this isn't defined, only columns/indexes with Cartesian coordinate systems
496 (projected SRS or SRID 0) is supported. Columns/indexes without SRID
497 restriction is also supported if this isn't defined.
498*/
499#define HA_SUPPORTS_GEOGRAPHIC_GEOMETRY_COLUMN (1LL << 50)
500
501/**
502 Handler supports expressions as DEFAULT for a column.
503*/
504#define HA_SUPPORTS_DEFAULT_EXPRESSION (1LL << 51)
505
506/**
507 Handlers with this flag set do not support UPDATE operations.
508*/
509#define HA_UPDATE_NOT_SUPPORTED (1LL << 52)
510
511/**
512 Handlers with this flag set do not support DELETE operations.
513*/
514#define HA_DELETE_NOT_SUPPORTED (1LL << 53)
515
516/**
517 The storage engine does not support using indexes for access. Indexes can only
518 be used for estimating cost.
519*/
520#define HA_NO_INDEX_ACCESS (1LL << 54)
521
522/**
523 Supports multi-valued index
524*/
525#define HA_MULTI_VALUED_KEY_SUPPORT (1LL << 55)
526
527/*
528 Bits in index_flags(index_number) for what you can do with index.
529 If you do not implement indexes, just return zero here.
530*/
531/*
532 Does the index support read next, this is assumed in the server
533 code and never checked so all indexes must support this.
534 Note that the handler can be used even if it doesn't have any index.
535*/
536#define HA_READ_NEXT 1 /* TODO really use this flag */
537/*
538 Can the index be used to scan backwards (supports ::index_prev).
539*/
540#define HA_READ_PREV 2
541/*
542 Can the index deliver its record in index order. Typically true for
543 all ordered indexes and not true for hash indexes. Used to set keymap
544 part_of_sortkey.
545 This keymap is only used to find indexes usable for resolving an ORDER BY
546 in the query. Thus in most cases index_read will work just fine without
547 order in result production. When this flag is set it is however safe to
548 order all output started by index_read since most engines do this. With
549 read_multi_range calls there is a specific flag setting order or not
550 order so in those cases ordering of index output can be avoided.
551*/
552#define HA_READ_ORDER 4
553/*
554 Specify whether index can handle ranges, typically true for all
555 ordered indexes and not true for hash indexes.
556 Used by optimiser to check if ranges (as key >= 5) can be optimised
557 by index.
558*/
559#define HA_READ_RANGE 8
560/*
561 Can't use part key searches. This is typically true for hash indexes
562 and typically not true for ordered indexes.
563*/
564#define HA_ONLY_WHOLE_INDEX 16
565/*
566 Index does not store NULL values, even if the column is nullable.
567 (KEY::flags may still contain HA_NULL_PART_KEY)
568 If the key has a NULL-value, the handler need to do a full table scan
569 instead of using this key. This is typically true for NDB hash indexes.
570*/
571#define HA_TABLE_SCAN_ON_NULL 32
572/*
573 Does the storage engine support index-only scans on this index.
574 Enables use of HA_EXTRA_KEYREAD and HA_EXTRA_NO_KEYREAD
575 Used to set Key_map keys_for_keyread and to check in optimiser for
576 index-only scans. When doing a read under HA_EXTRA_KEYREAD the handler
577 only have to fill in the columns the key covers. If
578 HA_PRIMARY_KEY_IN_READ_INDEX is set then also the PRIMARY KEY columns
579 must be updated in the row.
580*/
581#define HA_KEYREAD_ONLY 64
582/*
583 Index scan will not return records in rowid order. Not guaranteed to be
584 set for unordered (e.g. HASH) indexes.
585*/
586#define HA_KEY_SCAN_NOT_ROR 128
587#define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */
588
589/* operations for disable/enable indexes */
590#define HA_KEY_SWITCH_NONUNIQ 0
591#define HA_KEY_SWITCH_ALL 1
592#define HA_KEY_SWITCH_NONUNIQ_SAVE 2
593#define HA_KEY_SWITCH_ALL_SAVE 3
594
595/*
596 Use this instead of 0 as the initial value for the slot number of
597 handlerton, so that we can distinguish uninitialized slot number
598 from slot 0.
599*/
600#define HA_SLOT_UNDEF ((uint)-1)
601
602/*
603 Parameters for open() (in register form->filestat)
604 HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
605*/
606
607#define HA_OPEN_KEYFILE 1
608#define HA_OPEN_RNDFILE 2
609#define HA_GET_INDEX 4
610#define HA_GET_INFO 8 /* do a handler::info() after open */
611#define HA_READ_ONLY 16 /* File opened as readonly */
612/* Try readonly if can't open with read and write */
613#define HA_TRY_READ_ONLY 32
614#define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */
615#define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
616#define HA_BLOCK_LOCK 256 /* unlock when reading some records */
617#define HA_OPEN_TEMPORARY 512
618
619/* Some key definitions */
620#define HA_KEY_NULL_LENGTH 1
621#define HA_KEY_BLOB_LENGTH 2
622
623#define HA_LEX_CREATE_TMP_TABLE 1
624#define HA_LEX_CREATE_IF_NOT_EXISTS 2
625#define HA_LEX_CREATE_TABLE_LIKE 4
626#define HA_LEX_CREATE_INTERNAL_TMP_TABLE 8
627#define HA_MAX_REC_LENGTH 65535U
628
629/**
630 Options for the START TRANSACTION statement.
631
632 Note that READ ONLY and READ WRITE are logically mutually exclusive.
633 This is enforced by the parser and depended upon by trans_begin().
634
635 We need two flags instead of one in order to differentiate between
636 situation when no READ WRITE/ONLY clause were given and thus transaction
637 is implicitly READ WRITE and the case when READ WRITE clause was used
638 explicitly.
639*/
640
641// WITH CONSISTENT SNAPSHOT option
643// READ ONLY option
645// READ WRITE option
647// HIGH PRIORITY option
649
671 DB_TYPE_PARTITION_DB, // No longer used.
676 DB_TYPE_MEMCACHE [[deprecated]],
679 /** Performance schema engine. */
683 DB_TYPE_DEFAULT = 127 // Must be last
685
686enum row_type : int {
694 /** Unused. Reserved for future versions. */
697
706
715};
716
718
719/* Bits in used_fields */
720#define HA_CREATE_USED_AUTO (1L << 0)
721#define HA_CREATE_USED_RAID (1L << 1) // RAID is no longer available
722#define HA_CREATE_USED_UNION (1L << 2)
723#define HA_CREATE_USED_INSERT_METHOD (1L << 3)
724#define HA_CREATE_USED_MIN_ROWS (1L << 4)
725#define HA_CREATE_USED_MAX_ROWS (1L << 5)
726#define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
727#define HA_CREATE_USED_PACK_KEYS (1L << 7)
728#define HA_CREATE_USED_CHARSET (1L << 8)
729#define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
730#define HA_CREATE_USED_DATADIR (1L << 10)
731#define HA_CREATE_USED_INDEXDIR (1L << 11)
732#define HA_CREATE_USED_ENGINE (1L << 12)
733#define HA_CREATE_USED_CHECKSUM (1L << 13)
734#define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
735#define HA_CREATE_USED_ROW_FORMAT (1L << 15)
736#define HA_CREATE_USED_COMMENT (1L << 16)
737#define HA_CREATE_USED_PASSWORD (1L << 17)
738#define HA_CREATE_USED_CONNECTION (1L << 18)
739#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
740/** Unused. Reserved for future versions. */
741#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
742/** Unused. Reserved for future versions. */
743#define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
744/** This is set whenever STATS_PERSISTENT=0|1|default has been
745specified in CREATE/ALTER TABLE. See also HA_OPTION_STATS_PERSISTENT in
746include/my_base.h. It is possible to distinguish whether
747STATS_PERSISTENT=default has been specified or no STATS_PERSISTENT= is
748given at all. */
749#define HA_CREATE_USED_STATS_PERSISTENT (1L << 22)
750/**
751 This is set whenever STATS_AUTO_RECALC=0|1|default has been
752 specified in CREATE/ALTER TABLE. See enum_stats_auto_recalc.
753 It is possible to distinguish whether STATS_AUTO_RECALC=default
754 has been specified or no STATS_AUTO_RECALC= is given at all.
755*/
756#define HA_CREATE_USED_STATS_AUTO_RECALC (1L << 23)
757/**
758 This is set whenever STATS_SAMPLE_PAGES=N|default has been
759 specified in CREATE/ALTER TABLE. It is possible to distinguish whether
760 STATS_SAMPLE_PAGES=default has been specified or no STATS_SAMPLE_PAGES= is
761 given at all.
762*/
763#define HA_CREATE_USED_STATS_SAMPLE_PAGES (1L << 24)
764
765/**
766 This is set whenever a 'TABLESPACE=...' phrase is used on CREATE TABLE
767*/
768#define HA_CREATE_USED_TABLESPACE (1L << 25)
769
770/** COMPRESSION="zlib|lz4|none" used during table create. */
771#define HA_CREATE_USED_COMPRESS (1L << 26)
772
773/** ENCRYPTION="Y" used during table create. */
774#define HA_CREATE_USED_ENCRYPT (1L << 27)
775
776/**
777 CREATE|ALTER SCHEMA|DATABASE|TABLE has an explicit COLLATE clause.
778
779 Implies HA_CREATE_USED_DEFAULT_CHARSET.
780*/
781#define HA_CREATE_USED_DEFAULT_COLLATE (1L << 28)
782
783/** SECONDARY_ENGINE used during table create. */
784#define HA_CREATE_USED_SECONDARY_ENGINE (1L << 29)
785
786/**
787 CREATE|ALTER SCHEMA|DATABASE has an explicit ENCRYPTION clause.
788
789 Implies HA_CREATE_USED_DEFAULT_ENCRYPTION.
790*/
791#define HA_CREATE_USED_DEFAULT_ENCRYPTION (1L << 30)
792
793/**
794 This option is used to convey that the create table should not
795 commit the operation and keep the transaction started.
796*/
797constexpr const uint64_t HA_CREATE_USED_START_TRANSACTION{1ULL << 31};
798
799constexpr const uint64_t HA_CREATE_USED_ENGINE_ATTRIBUTE{1ULL << 32};
800constexpr const uint64_t HA_CREATE_USED_SECONDARY_ENGINE_ATTRIBUTE{1ULL << 33};
801
802/**
803 ALTER SCHEMA|DATABASE has an explicit READ_ONLY clause.
804
805 Implies HA_CREATE_USED_READ_ONLY.
806*/
807constexpr const uint64_t HA_CREATE_USED_READ_ONLY{1ULL << 34};
808
809/**
810 These flags convey that the options AUTOEXTEND_SIZE has been
811 specified in the CREATE TABLE statement
812*/
813constexpr const uint64_t HA_CREATE_USED_AUTOEXTEND_SIZE{1ULL << 35};
814
815/*
816 End of bits used in used_fields
817*/
818
819/*
820 Structure to hold list of database_name.table_name.
821 This is used at both mysqld and storage engine layer.
822*/
824 const char *db;
825 const char *tablename;
826};
827
828#define MAXGTRIDSIZE 64
829#define MAXBQUALSIZE 64
830
831#define COMPATIBLE_DATA_YES 0
832#define COMPATIBLE_DATA_NO 1
833
834/*
835 These structures are used to pass information from a set of SQL commands
836 on add/drop/change tablespace definitions to the proper hton.
837*/
838#define UNDEF_NODEGROUP 65535
839
840// FUTURE: Combine these two enums into one enum class
855
865
866/**
867 Legacy struct for passing tablespace information to SEs.
868
869 FUTURE: Pass all info through dd objects
870 */
872 public:
873 const char *tablespace_name = nullptr;
874 const char *logfile_group_name = nullptr;
878 const char *data_file_name = nullptr;
879 const char *undo_file_name = nullptr;
880 ulonglong extent_size = 1024 * 1024; // Default 1 MByte
881 ulonglong undo_buffer_size = 8 * 1024 * 1024; // Default 8 MByte
882 ulonglong redo_buffer_size = 8 * 1024 * 1024; // Default 8 MByte
883 ulonglong initial_size = 128 * 1024 * 1024; // Default 128 MByte
884 std::optional<ulonglong> autoextend_size; // No autoextension as default
885 ulonglong max_size = 0; // Max size == initial size => no extension
886 ulonglong file_block_size = 0; // 0=default or must be a valid Page Size
889 const char *ts_comment = nullptr;
890 const char *encryption = nullptr;
891
893 return ts_cmd_type == CREATE_TABLESPACE ||
897 }
898
899 /**
900 Proper constructor even for all-public class simplifies initialization and
901 allows members to be const.
902
903 FUTURE: With constructor all members can be made const, and do not need
904 default initializers.
905
906 @param tablespace name of tabelspace (nullptr for logfile group statements)
907 @param logfile_group name of logfile group or nullptr
908 @param cmd main statement type
909 @param alter_tablespace_cmd subcommand type for ALTER TABLESPACE
910 @param datafile tablespace file for CREATE and ALTER ... ADD ...
911 @param undofile only applies to logfile group statements. nullptr otherwise.
912 @param opts options provided by parser
913 */
914 st_alter_tablespace(const char *tablespace, const char *logfile_group,
915 ts_command_type cmd,
916 enum ts_alter_tablespace_type alter_tablespace_cmd,
917 const char *datafile, const char *undofile,
918 const Tablespace_options &opts);
919};
920
921/*
922 Make sure that the order of schema_tables and enum_schema_tables are the same.
923*/
940
943enum ha_ddl_type : int {
949
950/** Clone start operation mode */
952 /** Start a new clone operation */
954
955 /** Re-start a clone operation after failure */
957
958 /** Add a new task to a running clone operation */
960
961 /** Get version for transfer data format */
963
964 /** Max value for clone mode */
967
968/** Clone operation types. */
969enum Ha_clone_type : size_t {
970 /** Caller must block all write operation to the SE. */
972
973 /** For transactional SE, archive redo to support concurrent dml */
975
976 /** For transactional SE, track page changes to support concurrent dml */
978
979 /** For transactional SE, use both page tracking and redo to optimize
980 clone with concurrent dml. Currently supported by Innodb. */
982
983 /** SE supports multiple threads for clone */
985
986 /** SE supports restarting clone after network failure */
988
989 /** Maximum value of clone type */
992
993using Ha_clone_flagset = std::bitset<HA_CLONE_TYPE_MAX>;
994
997
998/** File reference for clone */
1000 /** File reference type */
1001 enum {
1002 /** File handle */
1004
1005 /** File descriptor */
1006 FILE_DESC
1007
1009
1010 /** File reference */
1011 union {
1012 /** File descriptor */
1014
1015 /** File handle for windows */
1017 };
1018};
1019
1020/* Abstract callback interface to stream data back to the caller. */
1022 protected:
1023 /** Constructor to initialize members. */
1025 : m_hton(),
1026 m_loc_idx(),
1028 m_data_desc(),
1029 m_desc_len(),
1030 m_src_name(),
1031 m_dest_name(),
1033 m_flag() {}
1034
1035 public:
1036 /** Callback providing data from current position of a
1037 file descriptor of specific length.
1038 @param[in] from_file source file to read from
1039 @param[in] len data length
1040 @return error code */
1041 virtual int file_cbk(Ha_clone_file from_file, uint len) = 0;
1042
1043 /** Callback providing data in buffer of specific length.
1044 @param[in] from_buffer source buffer to read from
1045 @param[in] len data length
1046 @return error code */
1047 virtual int buffer_cbk(uchar *from_buffer, uint len) = 0;
1048
1049 /** Callback providing a file descriptor to write data starting
1050 from current position.
1051 @param[in] to_file destination file to write data
1052 @return error code */
1053 virtual int apply_file_cbk(Ha_clone_file to_file) = 0;
1054
1055 /** Callback to get data in buffer.
1056 @param[out] to_buffer data buffer
1057 @param[out] len data length
1058 @return error code */
1059 virtual int apply_buffer_cbk(uchar *&to_buffer, uint &len) = 0;
1060
1061 /** virtual destructor. */
1062 virtual ~Ha_clone_cbk() = default;
1063
1064 /** Set current storage engine handlerton.
1065 @param[in] hton SE handlerton */
1066 void set_hton(handlerton *hton) { m_hton = hton; }
1067
1068 /** Get current storage engine handlerton.
1069 @return SE handlerton */
1070 handlerton *get_hton() { return (m_hton); }
1071
1072 /** Set caller's transfer buffer size. SE can adjust the data chunk size
1073 based on this parameter.
1074 @param[in] size buffer size in bytes */
1076
1077 /** Get caller's transfer buffer size.
1078 @return buffer size in bytes */
1080
1081 /** Set current SE index.
1082 @param[in] idx SE index in locator array */
1083 void set_loc_index(uint idx) { m_loc_idx = idx; }
1084
1085 /** Get current SE index.
1086 @return SE index in locator array */
1087 uint get_loc_index() { return (m_loc_idx); }
1088
1089 /** Set data descriptor. SE specific descriptor for the
1090 data transferred by the callbacks.
1091 @param[in] desc serialized data descriptor
1092 @param[in] len length of the descriptor byte stream */
1093 void set_data_desc(const uchar *desc, uint len) {
1094 m_data_desc = desc;
1095 m_desc_len = len;
1096 }
1097
1098 /** Get data descriptor. SE specific descriptor for the
1099 data transferred by the callbacks.
1100 @param[out] lenp length of the descriptor byte stream
1101 @return pointer to the serialized data descriptor */
1102 const uchar *get_data_desc(uint *lenp) {
1103 if (lenp != nullptr) {
1104 *lenp = m_desc_len;
1105 }
1106
1107 return (m_data_desc);
1108 }
1109
1110 /** Get SE source file name. Used for debug printing and error message.
1111 @return null terminated string for source file name */
1112 const char *get_source_name() { return (m_src_name); }
1113
1114 /** Set SE source file name.
1115 @param[in] name null terminated string for source file name */
1116 void set_source_name(const char *name) { m_src_name = name; }
1117
1118 /** Get SE destination file name. Used for debug printing and error message.
1119 @return null terminated string for destination file name */
1120 const char *get_dest_name() { return (m_dest_name); }
1121
1122 /** Set SE destination file name.
1123 @param[in] name null terminated string for destination file name */
1124 void set_dest_name(const char *name) { m_dest_name = name; }
1125
1126 /** Clear all flags set by SE */
1127 void clear_flags() { m_flag = 0; }
1128
1129 /** Mark that ACK is needed for the data transfer before returning
1130 from callback. Set by SE. */
1132
1133 /** Check if ACK is needed for the data transfer
1134 @return true if ACK is needed */
1135 bool is_ack_needed() const { return (m_flag & HA_CLONE_ACK); }
1136
1137 /** Mark that the file descriptor is opened for read/write
1138 with OS buffer cache. For O_DIRECT, the flag is not set. */
1140
1141 /** Check if the file descriptor is opened for read/write with OS
1142 buffer cache. Currently clone avoids using zero copy (sendfile on linux),
1143 if SE is using O_DIRECT. This improves data copy performance.
1144 @return true if O_DIRECT is not used */
1145 bool is_os_buffer_cache() const { return (m_flag & HA_CLONE_FILE_CACHE); }
1146
1147 /** Mark that the file can be transferred with zero copy. */
1149
1150 /** Check if zero copy optimization is suggested. */
1151 bool is_zero_copy() const { return (m_flag & HA_CLONE_ZERO_COPY); }
1152
1153 /** Mark that data needs secure transfer. */
1155
1156 /** Check if data needs secure transfer. */
1157 bool is_secure() const { return (m_flag & HA_CLONE_SECURE); }
1158
1159 /** Set state information and notify state change.
1160 @param[in] estimate estimated bytes for current state. */
1161 void mark_state_change(uint64_t estimate) {
1163 m_state_estimate = estimate;
1164 }
1165
1166 /** Check if SE notified state change. */
1167 bool is_state_change(uint64_t &estimate) {
1168 estimate = m_state_estimate;
1169 return (m_flag & HA_CLONE_STATE_CHANGE);
1170 }
1171
1172 private:
1173 /** Handlerton for the SE */
1175
1176 /** SE index in caller's locator array */
1178
1179 /** Caller's transfer buffer size. */
1181
1182 /** SE's Serialized data descriptor */
1184
1185 /** SE's Serialized descriptor length. */
1187
1188 /** Current source file name */
1189 const char *m_src_name;
1190
1191 /** Current destination file name */
1192 const char *m_dest_name;
1193
1194 /** Estimated bytes to be transferred. */
1196
1197 /** Flag storing data related options */
1199
1200 /** Acknowledgement is needed for the data transfer. */
1201 const int HA_CLONE_ACK = 0x01;
1202
1203 /** Data file is opened for read/write with OS buffer cache. */
1204 const int HA_CLONE_FILE_CACHE = 0x02;
1205
1206 /** Data file can be transferred with zero copy. */
1207 const int HA_CLONE_ZERO_COPY = 0x04;
1208
1209 /** Data needs to be transferred securely over SSL connection. */
1210 const int HA_CLONE_SECURE = 0x08;
1211
1212 /** State change notification by SE. */
1213 const int HA_CLONE_STATE_CHANGE = 0x10;
1214};
1215
1216/**
1217 Column type description for foreign key columns compatibility check.
1218
1219 Contains subset of information from dd::Column class. It is inconvenient
1220 to use dd::Column class directly for such checks because it requires valid
1221 dd::Table object and in some cases we want to produce Ha_fk_column_type
1222 right from column description in Create_field format.
1223*/
1226 /*
1227 Note that both dd::Column::char_length() and length here are really
1228 in bytes.
1229 */
1235};
1236
1237typedef ulonglong my_xid; // this line is the same as in log_event.h
1238/**
1239 Enumeration of possible states for externally coordinated transactions (XA).
1240 */
1242 NOT_FOUND = -1, // Trnasaction not found
1243 PREPARED_IN_SE = 0, // Transaction is prepared in SEs
1244 PREPARED_IN_TC = 1, // Transaction is prepared in SEs and TC
1245 COMMITTED_WITH_ONEPHASE = 2, // Transaction was one-phase committed
1246 COMMITTED = 3, // Transaction was committed
1247 ROLLEDBACK = 4 // Transaction was rolled back
1248};
1249/**
1250 Single occurrence set of XIDs of internally coordinated transactions
1251 found as been committed in the transaction coordinator state.
1252 */
1254 std::unordered_set<my_xid, std::hash<my_xid>, std::equal_to<my_xid>,
1256
1257/**
1258 Class to maintain list of externally coordinated transactions and their
1259 current state at recovery.
1260 */
1262 public:
1263 using pair = std::pair<const XID, enum_ha_recover_xa_state>;
1265 using list = std::map<XID, enum_ha_recover_xa_state, std::less<XID>,
1267 using iterator = std::map<XID, enum_ha_recover_xa_state, std::less<XID>,
1269 using instantiation_tuple = std::tuple<
1270 std::unique_ptr<MEM_ROOT>, std::unique_ptr<Xa_state_list::allocator>,
1271 std::unique_ptr<Xa_state_list::list>, std::unique_ptr<Xa_state_list>>;
1272
1273 /**
1274 Class constructor.
1275
1276 @param populated_by_tc The underlying list of XIDs and transaction
1277 states, after being populated by the transaction
1278 coodinator.
1279 */
1280 Xa_state_list(Xa_state_list::list &populated_by_tc);
1281 virtual ~Xa_state_list() = default;
1282
1283 /**
1284 Searches the underlying map to find an key that corresponds to the
1285 parameter.
1286
1287 @param to_find The XID to find within the underlying map.
1288
1289 @return Ha_recover_states::NOT_FOUND if the transaction wasn't found,
1290 the state of the transaction, otherwise.
1291 */
1292 enum_ha_recover_xa_state find(XID const &to_find);
1293 /**
1294 Adds a transaction and state to the underlying map. If the given XID
1295 already exists in the underlying map, the associated state changes according
1296 to the following rules:
1297
1298 - If the parameter state is `PREPARED_IN_SE` it means that the
1299 transaction didn't reach PREPARED_IN_TC, COMMIT or ROLLBACK for
1300 sure. In that case:
1301 . If other participants state is `COMMITTED`/`ROLLEDBACK`, it would
1302 mean that it's a state inherited from a previous execution with the
1303 same XID and we should set the state to `PREPARED_IN_SE`.
1304 . If other participants state is `PREPARED_IN_TC`/
1305 `COMMITTED_WITH_ONEPHASE` it means that the current participant
1306 didn't reach it but some other did so, keep the state as
1307 `PREPARED_IN_TC`/`COMMITTED_WITH_ONEPHASE`.
1308
1309 - If the parameter state is `PREPARED_IN_TC`, it means that other
1310 participants must have persisted either the PREPARE, the COMMIT or
1311 the ROLLBACK. In that case, keep whatever state is already there and
1312 ensure that is not `PREPARED_IN_SE`.
1313
1314 - If the parameter state is `COMMITTED_WITH_ONEPHASE`, `COMMITTED` or
1315 `ROLLEDBACK`, do nothing, only the active transaction coordinator has
1316 the ability, for now, to set the transaction state to those values.
1317
1318 @param xid The XID to be added (the key).
1319 @param state The state to be added (the value).
1320
1321 @return The current value of the transaction state if the XID has
1322 already been added, Ha_recover_states::NOT_FOUND otherwise.
1323 */
1325 /**
1326 Factory like method to instantiate all the infra-structure needed to
1327 create an `Xa_state_list`. Since such infra-structuer is dependent on
1328 `MEM_ROOT` and `Mem_root_allocator`, the method returns a tuple
1329 containing unique pointers to all 4 objects needed: MEM_ROOT;
1330 Mem_root_allocator; Xa_state_list::list; Xa_state_list.
1331
1332 @return An std::tuple containing unique pointers to all 4 objects
1333 needed: MEM_ROOT; Mem_root_allocator; Xa_state_list::list;
1334 Xa_state_list.
1335 */
1337
1338 private:
1339 /** The underlying map holding the trx and states*/
1341};
1342
1343/* handlerton methods */
1344
1345/**
1346 close_connection is only called if
1347 thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
1348 this storage area - set it to something, so that MySQL would know
1349 this storage engine was accessed in this connection
1350*/
1351typedef int (*close_connection_t)(handlerton *hton, THD *thd);
1352
1353/** Terminate connection/statement notification. */
1354typedef void (*kill_connection_t)(handlerton *hton, THD *thd);
1355
1356/**
1357 Shut down all storage engine background tasks that might access
1358 the data dictionary, before the main shutdown.
1359*/
1360typedef void (*pre_dd_shutdown_t)(handlerton *hton);
1361
1362/**
1363 Some plugin session variables may require some special handling
1364 upon clean up. Reset appropriately these variables before
1365 ending the THD connection
1366*/
1367typedef void (*reset_plugin_vars_t)(THD *thd);
1368
1369/**
1370 sv points to a storage area, that was earlier passed
1371 to the savepoint_set call
1372*/
1373typedef int (*savepoint_rollback_t)(handlerton *hton, THD *thd, void *sv);
1374
1375/**
1376 sv points to an uninitialized storage area of requested size
1377 (see savepoint_offset description)
1378*/
1379typedef int (*savepoint_set_t)(handlerton *hton, THD *thd, void *sv);
1380
1381/**
1382 Check if storage engine allows to release metadata locks which were
1383 acquired after the savepoint if rollback to savepoint is done.
1384 @return true - If it is safe to release MDL locks.
1385 false - If it is not.
1386*/
1388 THD *thd);
1389
1390typedef int (*savepoint_release_t)(handlerton *hton, THD *thd, void *sv);
1391
1392/**
1393 'all' is true if it's a real commit, that makes persistent changes
1394 'all' is false if it's not in fact a commit but an end of the
1395 statement that is part of the transaction.
1396 NOTE 'all' is also false in auto-commit mode where 'end of statement'
1397 and 'real commit' mean the same event.
1398*/
1399typedef int (*commit_t)(handlerton *hton, THD *thd, bool all);
1400
1401typedef int (*rollback_t)(handlerton *hton, THD *thd, bool all);
1402
1403typedef int (*prepare_t)(handlerton *hton, THD *thd, bool all);
1404
1405typedef int (*recover_t)(handlerton *hton, XA_recover_txn *xid_list, uint len,
1407/**
1408 Retrieves information about externally coordinated transactions for which
1409 the two-phase prepare was finished and transactions were prepared in the
1410 server TC.
1411 */
1413 Xa_state_list &xa_list);
1414/**
1415 Instructs the storage engine to mark the externally coordinated
1416 transactions held by the THD parameters as prepared in the server TC.
1417 */
1418using set_prepared_in_tc_t = int (*)(handlerton *hton, THD *thd);
1419
1420/** X/Open XA distributed transaction status codes */
1422 /**
1423 normal execution
1424 */
1426
1427 /**
1428 asynchronous operation already outstanding
1429 */
1431
1432 /**
1433 a resource manager error occurred in the transaction branch
1434 */
1436
1437 /**
1438 the XID is not valid
1439 */
1441
1442 /**
1443 invalid arguments were given
1444 */
1446
1447 /**
1448 routine invoked in an improper context
1449 */
1451
1452 /**
1453 resource manager unavailable
1454 */
1456
1457 /**
1458 the XID already exists
1459 */
1461
1462 /**
1463 resource manager doing work outside transaction
1464 */
1465 XAER_OUTSIDE = -9
1467
1469
1471
1472/**
1473 Instructs the storage engine to mark the externally coordinated
1474 transactions identified by the XID parameters as prepared in the server
1475 TC.
1476 */
1478 XID *xid);
1479
1480/**
1481 Create handler object for the table in the storage engine.
1482
1483 @param hton Handlerton object for the storage engine.
1484 @param table TABLE_SHARE for the table, can be NULL if caller
1485 didn't perform full-blown open of table definition.
1486 @param partitioned Indicates whether table is partitioned.
1487 @param mem_root Memory root to be used for allocating handler
1488 object.
1489*/
1490typedef handler *(*create_t)(handlerton *hton, TABLE_SHARE *table,
1491 bool partitioned, MEM_ROOT *mem_root);
1492
1493typedef void (*drop_database_t)(handlerton *hton, char *path);
1494
1495typedef bool (*log_ddl_drop_schema_t)(handlerton *hton,
1496 const char *schema_name);
1497
1499 const char *schema_name);
1500
1501typedef int (*panic_t)(handlerton *hton, enum ha_panic_function flag);
1502
1503typedef int (*start_consistent_snapshot_t)(handlerton *hton, THD *thd);
1504
1505/**
1506 Flush the log(s) of storage engine(s).
1507
1508 @param hton Handlerton of storage engine.
1509 @param binlog_group_flush true if we got invoked by binlog group
1510 commit during flush stage, false in other cases.
1511 @retval false Succeed
1512 @retval true Error
1513*/
1514typedef bool (*flush_logs_t)(handlerton *hton, bool binlog_group_flush);
1515
1516typedef bool (*show_status_t)(handlerton *hton, THD *thd, stat_print_fn *print,
1517 enum ha_stat_type stat);
1518
1519/**
1520 The flag values are defined in sql_partition.h.
1521 If this function is set, then it implies that the handler supports
1522 partitioned tables.
1523 If this function exists, then handler::get_partition_handler must also be
1524 implemented.
1525*/
1526typedef uint (*partition_flags_t)();
1527
1528/**
1529 SE specific validation of the tablespace name.
1530
1531 This function will ask the relevant SE whether the submitted tablespace
1532 name is valid.
1533
1534 @param ts_cmd Purpose of usage - is this tablespace DDL?
1535 @param tablespace_name Name of the tablespace.
1536
1537 @return Tablespace name validity.
1538 @retval Whether the tablespace name is valid.
1539*/
1541 const char *tablespace_name);
1542
1543/**
1544 Get the tablespace name from the SE for the given schema and table.
1545
1546 @param thd Thread context.
1547 @param db_name Name of the relevant schema.
1548 @param table_name Name of the relevant table.
1549 @param [out] tablespace_name Name of the tablespace containing the table.
1550
1551 @return Operation status.
1552 @retval == 0 Success.
1553 @retval != 0 Error (handler error code returned).
1554*/
1557 LEX_CSTRING *tablespace_name);
1558
1559/**
1560 Create/drop or alter tablespace in the storage engine.
1561
1562 @param hton Hadlerton of the SE.
1563 @param thd Thread context.
1564 @param ts_info Description of tablespace and specific
1565 operation on it.
1566 @param old_ts_def dd::Tablespace object describing old version
1567 of tablespace.
1568 @param [in,out] new_ts_def dd::Tablespace object describing new version
1569 of tablespace. Engines which support atomic DDL
1570 can adjust this object. The updated information
1571 will be saved to the data-dictionary.
1572
1573 @return Operation status.
1574 @retval == 0 Success.
1575 @retval != 0 Error (handler error code returned).
1576*/
1577typedef int (*alter_tablespace_t)(handlerton *hton, THD *thd,
1578 st_alter_tablespace *ts_info,
1579 const dd::Tablespace *old_ts_def,
1580 dd::Tablespace *new_ts_def);
1581
1582/**
1583 SE interface for getting tablespace extension.
1584 @return Extension of tablespace datafile name.
1585*/
1586typedef const char *(*get_tablespace_filename_ext_t)();
1587
1588/**
1589 Get the tablespace data from SE and insert it into Data dictionary
1590
1591 @param thd Thread context
1592
1593 @return Operation status.
1594 @retval == 0 Success.
1595 @retval != 0 Error (handler error code returned)
1596*/
1597typedef int (*upgrade_tablespace_t)(THD *thd);
1598
1599/**
1600 Get the tablespace data from SE and insert it into Data dictionary
1601
1602 @param[in] tablespace tablespace object
1603
1604 @return Operation status.
1605 @retval == 0 Success.
1606 @retval != 0 Error (handler error code returned)
1607*/
1608typedef bool (*upgrade_space_version_t)(dd::Tablespace *tablespace);
1609
1610/**
1611 Finish upgrade process inside storage engines.
1612 This includes resetting flags to indicate upgrade process
1613 and cleanup after upgrade.
1614
1615 @param thd Thread context
1616 @param failed_upgrade True if the upgrade failed.
1617
1618 @return Operation status.
1619 @retval == 0 Success.
1620 @retval != 0 Error (handler error code returned)
1621*/
1622typedef int (*finish_upgrade_t)(THD *thd, bool failed_upgrade);
1623
1624/**
1625 Upgrade logs after the checkpoint from where upgrade
1626 process can only roll forward.
1627
1628 @param thd Thread context
1629
1630 @return Operation status.
1631 @retval == 0 Success.
1632 @retval != 0 Error (handler error code returned)
1633*/
1634typedef int (*upgrade_logs_t)(THD *thd);
1635
1643};
1644
1645/**
1646 Get the tablespace type from the SE.
1647
1648 @param[in] space tablespace object
1649 @param[out] space_type type of space
1650
1651 @return Operation status.
1652 @retval false on success and true for failure.
1653*/
1654typedef bool (*get_tablespace_type_t)(const dd::Tablespace &space,
1655 Tablespace_type *space_type);
1656
1657/**
1658 Get the tablespace type given the name, from the SE.
1659
1660 @param[in] tablespace_name tablespace name
1661 @param[out] space_type type of space
1662
1663 @return Operation status.
1664 @retval false on success and true for failure.
1665*/
1666typedef bool (*get_tablespace_type_by_name_t)(const char *tablespace_name,
1667 Tablespace_type *space_type);
1668
1669typedef int (*fill_is_table_t)(handlerton *hton, THD *thd, Table_ref *tables,
1670 class Item *cond, enum enum_schema_tables);
1671
1672typedef int (*binlog_func_t)(handlerton *hton, THD *thd, enum_binlog_func fn,
1673 void *arg);
1674
1675typedef void (*binlog_log_query_t)(handlerton *hton, THD *thd,
1676 enum_binlog_command binlog_command,
1677 const char *query, uint query_length,
1678 const char *db, const char *table_name);
1679
1680typedef void (*acl_notify_t)(THD *thd,
1681 const class Acl_change_notification *notice);
1682
1683typedef int (*discover_t)(handlerton *hton, THD *thd, const char *db,
1684 const char *name, uchar **frmblob, size_t *frmlen);
1685
1686typedef int (*find_files_t)(handlerton *hton, THD *thd, const char *db,
1687 const char *path, const char *wild, bool dir,
1688 List<LEX_STRING> *files);
1689
1690typedef int (*table_exists_in_engine_t)(handlerton *hton, THD *thd,
1691 const char *db, const char *name);
1692
1693/**
1694 Let storage engine inspect the query Accesspath and pick whatever
1695 it like for being pushed down to the engine. (Join, conditions, ..)
1696
1697 The handler implementation should itself keep track of what it 'pushed',
1698 such that later calls to the handlers access methods should
1699 activate the pushed parts of the execution plan on the storage
1700 engines.
1701
1702 @param thd Thread context
1703 @param query The AccessPath for the entire query.
1704 @param join The JOIN to be pushed
1705
1706 @returns
1707 0 on success
1708 error otherwise
1709*/
1710using push_to_engine_t = int (*)(THD *thd, AccessPath *query, JOIN *join);
1711
1712/**
1713 Check if the given db.tablename is a system table for this SE.
1714
1715 @param db Database name to check.
1716 @param table_name table name to check.
1717 @param is_sql_layer_system_table if the supplied db.table_name is a SQL
1718 layer system table.
1719
1720 @see example_is_supported_system_table in ha_example.cc
1721
1722 is_sql_layer_system_table is supplied to make more efficient
1723 checks possible for SEs that support all SQL layer tables.
1724
1725 This interface is optional, so every SE need not implement it.
1726*/
1727typedef bool (*is_supported_system_table_t)(const char *db,
1728 const char *table_name,
1729 bool is_sql_layer_system_table);
1730
1731/**
1732 Create SDI in a tablespace. This API should be used when upgrading
1733 a tablespace with no SDI or after invoking sdi_drop().
1734 @param[in] tablespace tablespace object
1735 @retval false success
1736 @retval true failure
1737*/
1738typedef bool (*sdi_create_t)(dd::Tablespace *tablespace);
1739
1740/**
1741 Drop SDI in a tablespace. This API should be used only when
1742 SDI is corrupted.
1743 @param[in] tablespace tablespace object
1744 @retval false success
1745 @retval true failure
1746*/
1747typedef bool (*sdi_drop_t)(dd::Tablespace *tablespace);
1748
1749/**
1750 Get the SDI keys in a tablespace into vector.
1751 @param[in] tablespace tablespace object
1752 @param[in,out] vector vector of SDI Keys
1753 @retval false success
1754 @retval true failure
1755*/
1756typedef bool (*sdi_get_keys_t)(const dd::Tablespace &tablespace,
1758
1759/**
1760 Retrieve SDI for a given SDI key.
1761
1762 Since the caller of this api will not know the SDI length, SDI retrieval
1763 should be done in the following way.
1764
1765 i. Allocate initial memory of some size (Lets say 64KB)
1766 ii. Pass the allocated memory to the below api.
1767 iii. If passed buffer is sufficient, sdi_get_by_id() copies the sdi
1768 to the buffer passed and returns success, else sdi_len is modified
1769 with the actual length of the SDI (and returns false on failure).
1770 For genuine errors, sdi_len is returned as UINT64_MAX
1771 iv. If sdi_len != UINT64_MAX, retry the call after allocating the memory
1772 of sdi_len
1773 v. Free the memory after using SDI (responsibility of caller)
1774
1775 @param[in] tablespace tablespace object
1776 @param[in] sdi_key SDI key to uniquely identify SDI obj
1777 @param[in,out] sdi SDI retrieved from tablespace
1778 A non-null pointer must be passed in
1779 @param[in,out] sdi_len in: length of the memory allocated
1780 out: actual length of SDI
1781 @retval false success
1782 @retval true failure
1783*/
1784typedef bool (*sdi_get_t)(const dd::Tablespace &tablespace,
1785 const sdi_key_t *sdi_key, void *sdi, uint64 *sdi_len);
1786
1787/**
1788 Insert/Update SDI for a given SDI key.
1789 @param[in] hton handlerton object
1790 @param[in] tablespace tablespace object
1791 @param[in] table table object
1792 @param[in] sdi_key SDI key to uniquely identify SDI obj
1793 @param[in] sdi SDI to write into the tablespace
1794 @param[in] sdi_len length of SDI BLOB returned
1795 @retval false success
1796 @retval true failure, my_error() should be called
1797 by SE
1798*/
1799typedef bool (*sdi_set_t)(handlerton *hton, const dd::Tablespace &tablespace,
1800 const dd::Table *table, const sdi_key_t *sdi_key,
1801 const void *sdi, uint64 sdi_len);
1802
1803/**
1804 Delete SDI for a given SDI key.
1805 @param[in] tablespace tablespace object
1806 @param[in] table table object
1807 @param[in] sdi_key SDI key to uniquely identify SDI obj
1808 @retval false success
1809 @retval true failure, my_error() should be called
1810 by SE
1811*/
1812typedef bool (*sdi_delete_t)(const dd::Tablespace &tablespace,
1813 const dd::Table *table, const sdi_key_t *sdi_key);
1814
1815/**
1816 Check if the DDSE is started in a way that leaves thd DD being read only.
1817
1818 @retval true The data dictionary can only be read.
1819 @retval false The data dictionary can be read and written.
1820 */
1821typedef bool (*is_dict_readonly_t)();
1822
1823/**
1824 Drop all temporary tables which have been left from previous server
1825 run belonging to this SE. Used on server start-up.
1826
1827 @param[in] hton Handlerton for storage engine.
1828 @param[in] thd Thread context.
1829 @param[in,out] files List of files in directories for temporary files
1830 which match tmp_file_prefix and thus can belong to
1831 temporary tables (but not necessarily in this SE).
1832 It is recommended to remove file from the list if
1833 SE recognizes it as belonging to temporary table
1834 in this SE and deletes it.
1835*/
1836typedef bool (*rm_tmp_tables_t)(handlerton *hton, THD *thd,
1837 List<LEX_STRING> *files);
1838
1839/**
1840 Retrieve cost constants to be used for this storage engine.
1841
1842 A storage engine that wants to provide its own cost constants to
1843 be used in the optimizer cost model, should implement this function.
1844 The server will call this function to get a cost constant object
1845 that will be used for tables stored in this storage engine instead
1846 of using the default cost constants.
1847
1848 Life cycle for the cost constant object: The storage engine must
1849 allocate the cost constant object on the heap. After the function
1850 returns, the server takes over the ownership of this object.
1851 The server will eventually delete the object by calling delete.
1852
1853 @note In the initial version the storage_category parameter will
1854 not be used. The only valid value this will have is DEFAULT_STORAGE_CLASS
1855 (see declaration in opt_costconstants.h).
1856
1857 @param storage_category the storage type that the cost constants will
1858 be used for
1859
1860 @return a pointer to the cost constant object, if NULL is returned
1861 the default cost constants will be used
1862*/
1863typedef SE_cost_constants *(*get_cost_constants_t)(uint storage_category);
1864
1865/**
1866 @param[in,out] thd pointer to THD
1867 @param[in] new_trx_arg pointer to replacement transaction
1868 @param[out] ptr_trx_arg double pointer to being replaced transaction
1869
1870 Associated with THD engine's native transaction is replaced
1871 with @c new_trx_arg. The old value is returned through a buffer if non-null
1872 pointer is provided with @c ptr_trx_arg.
1873 The method is adapted by XA start and XA prepare handlers to
1874 handle XA transaction that is logged as two parts by slave applier.
1875
1876 This interface concerns engines that are aware of XA transaction.
1877*/
1878typedef void (*replace_native_transaction_in_thd_t)(THD *thd, void *new_trx_arg,
1879 void **ptr_trx_arg);
1880
1881/** Mode for initializing the data dictionary. */
1883 DICT_INIT_CREATE_FILES, ///< Create all required SE files
1884 DICT_INIT_CHECK_FILES ///< Verify existence of expected files
1886
1887/**
1888 Initialize the SE for being used to store the DD tables. Create
1889 the required files according to the dict_init_mode. Create strings
1890 representing the required DDSE tables, i.e., tables that the DDSE
1891 expects to exist in the DD, and add them to the appropriate out
1892 parameter.
1893
1894 @note There are two variants of this function type, one is to be
1895 used by the DDSE, and has a different type of output parameters
1896 because the SQL layer needs more information about the DDSE tables
1897 in order to support upgrade.
1898
1899 @param dict_init_mode How to initialize files
1900 @param version Target DD version if a new
1901 server is being installed.
1902 0 if restarting an existing
1903 server.
1904 @param [out] DDSE_tables List of SQL DDL statements
1905 for creating DD tables that
1906 are needed by the DDSE.
1907 @param [out] DDSE_tablespaces List of meta data for predefined
1908 tablespaces created by the DDSE.
1909
1910 @retval true An error occurred.
1911 @retval false Success - no errors.
1912 */
1913
1914typedef bool (*dict_init_t)(dict_init_mode_t dict_init_mode, uint version,
1915 List<const Plugin_table> *DDSE_tables,
1916 List<const Plugin_tablespace> *DDSE_tablespaces);
1917
1918typedef bool (*ddse_dict_init_t)(
1919 dict_init_mode_t dict_init_mode, uint version,
1920 List<const dd::Object_table> *DDSE_tables,
1921 List<const Plugin_tablespace> *DDSE_tablespaces);
1922
1923/**
1924 Initialize the set of hard coded DD table ids.
1925*/
1926typedef void (*dict_register_dd_table_id_t)(dd::Object_id hard_coded_tables);
1927
1928/**
1929 Invalidate an entry in the local dictionary cache.
1930
1931 Needed during bootstrap to make sure the contents in the DDSE
1932 dictionary cache is in sync with the global DD.
1933
1934 @param schema_name Schema name.
1935 @param table_name Table name.
1936 */
1937
1938typedef void (*dict_cache_reset_t)(const char *schema_name,
1939 const char *table_name);
1940
1941/**
1942 Invalidate all table and tablespace entries in the local dictionary cache.
1943
1944 Needed for recovery during server restart.
1945 */
1946
1948
1949/** Mode for data dictionary recovery. */
1951 DICT_RECOVERY_INITIALIZE_SERVER, ///< First start of a new server
1952 DICT_RECOVERY_INITIALIZE_TABLESPACES, ///< First start, create tablespaces
1953 DICT_RECOVERY_RESTART_SERVER ///< Restart of an existing server
1955
1956/**
1957 Do recovery in the DDSE as part of initializing the data dictionary.
1958 The dict_recovery_mode indicates what kind of recovery should be
1959 done.
1960
1961 @param dict_recovery_mode How to do recovery
1962 @param version Target DD version if a new
1963 server is being installed.
1964 Actual DD version if restarting
1965 an existing server.
1966
1967 @retval true An error occurred.
1968 @retval false Success - no errors.
1969 */
1970
1971typedef bool (*dict_recover_t)(dict_recovery_mode_t dict_recovery_mode,
1972 uint version);
1973
1974/**
1975 Get the server version id stored in the header of the
1976 dictionary tablespace.
1977
1978 @param [out] version Version number from the DD
1979 tablespace header.
1980
1981 @retval Operation outcome, false if no error, otherwise true.
1982*/
1983typedef bool (*dict_get_server_version_t)(uint *version);
1984
1985/**
1986 Store the current server version number into the
1987 header of the dictionary tablespace.
1988
1989 @retval Operation outcome, false if no error, otherwise true.
1990*/
1992
1993/**
1994 Notify/get permission from storage engine before acquisition or after
1995 release of exclusive metadata lock on object represented by key.
1996
1997 @param thd Thread context.
1998 @param mdl_key MDL key identifying object on which exclusive
1999 lock is to be acquired/was released.
2000 @param notification_type Indicates whether this is pre-acquire or
2001 post-release notification.
2002 @param victimized 'true' if locking failed as we were selected
2003 as a victim in order to avoid possible deadlocks.
2004
2005 @note Notification is done only for objects from TABLESPACE, SCHEMA,
2006 TABLE, FUNCTION, PROCEDURE, TRIGGER and EVENT namespaces.
2007
2008 @note Problems during notification are to be reported as warnings, MDL
2009 subsystem will report generic error if pre-acquire notification
2010 fails/SE refuses lock acquisition.
2011 @note Return value is ignored/error is not reported in case of
2012 post-release notification.
2013
2014 @note In some cases post-release notification might happen even if
2015 there were no prior pre-acquire notification. For example,
2016 when SE was loaded after exclusive lock acquisition, or when
2017 we need notify SEs which permitted lock acquisition that it
2018 didn't happen because one of SEs didn't allow it (in such case
2019 we will do post-release notification for all SEs for simplicity).
2020
2021 @return False - if notification was successful/lock can be acquired,
2022 True - if it has failed/lock should not be acquired.
2023*/
2024typedef bool (*notify_exclusive_mdl_t)(THD *thd, const MDL_key *mdl_key,
2025 ha_notification_type notification_type,
2026 bool *victimized);
2027
2028/**
2029 Notify/get permission from storage engine before or after execution of
2030 ALTER TABLE operation on the table identified by the MDL key.
2031
2032 @param thd Thread context.
2033 @param mdl_key MDL key identifying table which is going to be
2034 or was ALTERed.
2035 @param notification_type Indicates whether this is pre-ALTER TABLE or
2036 post-ALTER TABLE notification.
2037
2038 @note This hook is necessary because for ALTER TABLE upgrade to X
2039 metadata lock happens fairly late during the execution process,
2040 so it can be expensive to abort ALTER TABLE operation at this
2041 stage by returning failure from notify_exclusive_mdl() hook.
2042
2043 @note This hook follows the same error reporting convention as
2044 @see notify_exclusive_mdl().
2045
2046 @note Similarly to notify_exclusive_mdl() in some cases post-ALTER
2047 notification might happen even if there were no prior pre-ALTER
2048 notification.
2049
2050 @note Post-ALTER notification can happen before post-release notification
2051 for exclusive metadata lock acquired by this ALTER TABLE.
2052
2053 @return False - if notification was successful/ALTER TABLE can proceed.
2054 True - if it has failed/ALTER TABLE should be aborted.
2055*/
2056typedef bool (*notify_alter_table_t)(THD *thd, const MDL_key *mdl_key,
2057 ha_notification_type notification_type);
2058
2059/**
2060 Notify/get permission from storage engine before or after execution of
2061 RENAME TABLE operation on the table identified by the MDL key.
2062
2063 @param thd Thread context.
2064 @param mdl_key MDL key identifying table which is going to be
2065 or was RENAMEd.
2066 @param notification_type Indicates whether this is pre-RENAME TABLE or
2067 post-RENAME TABLE notification.
2068 @param old_db_name old db name
2069 @param old_table_name old table name
2070 @param new_db_name new db name
2071 @param new_table_name new table name
2072*/
2073typedef bool (*notify_rename_table_t)(THD *thd, const MDL_key *mdl_key,
2074 ha_notification_type notification_type,
2075 const char *old_db_name,
2076 const char *old_table_name,
2077 const char *new_db_name,
2078 const char *new_table_name);
2079
2080/**
2081 Notify/get permission from storage engine before or after execution of
2082 TRUNCATE TABLE operation on the table identified by the MDL key.
2083
2084 @param thd Thread context.
2085 @param mdl_key MDL key identifying table which is going to be
2086 or was TRUNCATEd.
2087 @param notification_type Indicates whether this is pre-TRUNCATE TABLE or
2088 post-TRUNCATE TABLE notification.
2089*/
2090typedef bool (*notify_truncate_table_t)(THD *thd, const MDL_key *mdl_key,
2091 ha_notification_type notification_type);
2092
2093/**
2094 @brief
2095 Initiate master key rotation
2096
2097 @returns false on success,
2098 true on failure
2099*/
2101
2102/**
2103 @brief
2104 Enable or Disable SE write ahead logging.
2105
2106 @param[in] thd server thread handle
2107 @param[in] enable enable/disable redo logging
2108
2109 @return true iff failed.
2110*/
2111typedef bool (*redo_log_set_state_t)(THD *thd, bool enable);
2112
2113/**
2114 @brief
2115 Retrieve ha_statistics from SE.
2116
2117 @param db_name Name of schema
2118 @param table_name Name of table
2119 @param se_private_id SE private id of the table.
2120 @param ts_se_private_data Tablespace SE private data.
2121 @param tbl_se_private_data Table SE private data.
2122 @param flags Type of statistics to retrieve.
2123 @param[out] stats Contains statistics read from SE.
2124
2125 @note Handlers that implement this callback/API should adhere
2126 to servers expectation that, the implementation would invoke
2127 my_error() before returning 'true'/failure from this function.
2128
2129 @returns false on success,
2130 true on failure
2131*/
2133 const char *db_name, const char *table_name, dd::Object_id se_private_id,
2134 const dd::Properties &ts_se_private_data,
2135 const dd::Properties &tbl_se_private_data, uint flags,
2137
2138/**
2139 Retrieve column_statistics from SE.
2140
2141 @param db_name Name of schema
2142 @param table_name Name of table
2143 @param column_name Name of column
2144
2145 @returns The statistics if available, empty value otherwise.
2146*/
2147typedef std::optional<ha_column_statistics> (*get_column_statistics_t)(
2148 const char *db_name, const char *table_name, const char *column_name);
2149
2150/**
2151 @brief
2152 Retrieve index column cardinality from SE.
2153
2154 @param db_name Name of schema
2155 @param table_name Name of table
2156 @param index_name Name of index
2157 @param index_ordinal_position Position of index.
2158 @param column_ordinal_position Position of column in index.
2159 @param se_private_id SE private id of the table.
2160 @param[out] cardinality cardinality being returned by SE.
2161
2162 @note Handlers that implement this callback/API should adhere
2163 to servers expectation that, the implementation would invoke
2164 my_error() before returning 'true'/failure from this function.
2165
2166 @returns false on success,
2167 true on failure
2168*/
2170 const char *db_name, const char *table_name, const char *index_name,
2171 uint index_ordinal_position, uint column_ordinal_position,
2172 dd::Object_id se_private_id, ulonglong *cardinality);
2173
2174/**
2175 Retrieve ha_tablespace_statistics from SE.
2176
2177 @param tablespace_name Tablespace_name
2178 @param file_name Tablespace file name.
2179 @param ts_se_private_data Tablespace SE private data.
2180 @param[out] stats Contains tablespace
2181 statistics read from SE.
2182
2183 @note Handlers that implement this callback/API should adhere
2184 to servers expectation that, the implementation would invoke
2185 my_error() before returning 'true'/failure from this function.
2186
2187 @returns false on success, true on failure
2188*/
2190 const char *tablespace_name, const char *file_name,
2191 const dd::Properties &ts_se_private_data, ha_tablespace_statistics *stats);
2192
2193/* Database physical clone interfaces */
2194
2195/** Get capability flags for clone operation
2196@param[out] flags capability flag */
2198
2199/** Begin copy from source database
2200@param[in] hton handlerton for SE
2201@param[in] thd server thread handle
2202@param[in,out] loc locator
2203@param[in,out] loc_len locator length
2204@param[out] task_id task identifier
2205@param[in] type clone type
2206@param[in] mode mode for starting clone
2207@return error code */
2208using Clone_begin_t = int (*)(handlerton *hton, THD *thd, const uchar *&loc,
2209 uint &loc_len, uint &task_id, Ha_clone_type type,
2211
2212/** Copy data from source database in chunks via callback
2213@param[in] hton handlerton for SE
2214@param[in] thd server thread handle
2215@param[in] loc locator
2216@param[in] loc_len locator length in bytes
2217@param[in] task_id task identifier
2218@param[in] cbk callback interface for sending data
2219@return error code */
2220using Clone_copy_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2221 uint loc_len, uint task_id, Ha_clone_cbk *cbk);
2222
2223/** Acknowledge data transfer to source database
2224@param[in] hton handlerton for SE
2225@param[in] thd server thread handle
2226@param[in] loc locator
2227@param[in] loc_len locator length in bytes
2228@param[in] task_id task identifier
2229@param[in] in_err inform any error occurred
2230@param[in] cbk callback interface
2231@return error code */
2232using Clone_ack_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2233 uint loc_len, uint task_id, int in_err,
2234 Ha_clone_cbk *cbk);
2235
2236/** End copy from source database
2237@param[in] hton handlerton for SE
2238@param[in] thd server thread handle
2239@param[in] loc locator
2240@param[in] loc_len locator length in bytes
2241@param[in] task_id task identifier
2242@param[in] in_err error code when ending after error
2243@return error code */
2244using Clone_end_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2245 uint loc_len, uint task_id, int in_err);
2246
2247/** Begin apply to destination database
2248@param[in] hton handlerton for SE
2249@param[in] thd server thread handle
2250@param[in,out] loc locator
2251@param[in,out] loc_len locator length
2252@param[in] task_id task identifier
2253@param[in] mode mode for starting clone
2254@param[in] data_dir target data directory
2255@return error code */
2256using Clone_apply_begin_t = int (*)(handlerton *hton, THD *thd,
2257 const uchar *&loc, uint &loc_len,
2258 uint &task_id, Ha_clone_mode mode,
2259 const char *data_dir);
2260
2261/** Apply data to destination database in chunks via callback
2262@param[in] hton handlerton for SE
2263@param[in] thd server thread handle
2264@param[in] loc locator
2265@param[in] loc_len locator length in bytes
2266@param[in] task_id task identifier
2267@param[in] in_err inform any error occurred
2268@param[in] cbk callback interface for receiving data
2269@return error code */
2270using Clone_apply_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2271 uint loc_len, uint task_id, int in_err,
2272 Ha_clone_cbk *cbk);
2273
2274/** End apply to destination database
2275@param[in] hton handlerton for SE
2276@param[in] thd server thread handle
2277@param[in] loc locator
2278@param[in] loc_len locator length in bytes
2279@param[in] task_id task identifier
2280@param[in] in_err error code when ending after error
2281@return error code */
2282using Clone_apply_end_t = int (*)(handlerton *hton, THD *thd, const uchar *loc,
2283 uint loc_len, uint task_id, int in_err);
2284
2286 /* Get clone capabilities of an SE */
2288
2289 /* Interfaces to copy data. */
2294
2295 /* Interfaces to apply data. */
2299};
2300
2301/**
2302 Perform post-commit/rollback cleanup after DDL statement (e.g. in
2303 case of DROP TABLES really remove table files from disk).
2304
2305 @note This hook will be invoked after DDL commit or rollback only
2306 for storage engines supporting atomic DDL.
2307
2308 @note Problems during execution of this method should be reported to
2309 error log and as warnings/notes to user. Since this method is
2310 called after successful commit of the statement we can't fail
2311 statement with error.
2312*/
2313typedef void (*post_ddl_t)(THD *thd);
2314
2315/**
2316 Perform SE-specific cleanup after recovery of transactions.
2317
2318 @note Particularly SEs supporting atomic DDL can use this call
2319 to perform post-DDL actions for DDL statements which were
2320 committed or rolled back during recovery stage.
2321*/
2322typedef void (*post_recover_t)(void);
2323
2324/**
2325 Lock a handlerton (resource) log to collect log information.
2326*/
2327
2328typedef bool (*lock_hton_log_t)(handlerton *hton);
2329
2330/**
2331 Unlock a handlerton (resource) log after collecting log information.
2332*/
2333
2334typedef bool (*unlock_hton_log_t)(handlerton *hton);
2335
2336/**
2337 Collect a handlerton (resource) log information.
2338*/
2339
2340typedef bool (*collect_hton_log_info_t)(handlerton *hton, Json_dom *json);
2341
2342/**
2343 Check SE considers types of child and parent columns in foreign key
2344 to be compatible.
2345
2346 @param child_column_type Child column type description.
2347 @param parent_column_type Parent column type description.
2348 @param check_charsets Indicates whether we need to check
2349 that charsets of string columns
2350 match. Which is true in most cases.
2351
2352 @returns True if types are compatible, False if not.
2353*/
2354
2356 const Ha_fk_column_type *child_column_type,
2357 const Ha_fk_column_type *parent_column_type, bool check_charsets);
2358
2359typedef bool (*is_reserved_db_name_t)(handlerton *hton, const char *name);
2360
2361/**
2362 Prepare the secondary engine for executing a statement. This function is
2363 called right after the secondary engine TABLE objects have been opened by
2364 open_secondary_engine_tables(), before the statement is optimized and
2365 executed. Secondary engines will typically create a context object in this
2366 function, which they can use to store state that is needed during the
2367 optimization and execution phases.
2368
2369 @param thd thread context
2370 @param lex the statement to execute
2371 @return true on error, false on success
2372*/
2373using prepare_secondary_engine_t = bool (*)(THD *thd, LEX *lex);
2374
2375/**
2376 Optimize a statement for execution on a secondary storage engine. This
2377 function is called when the optimization of a statement has completed, just
2378 before the statement is executed. Secondary engines can use this function to
2379 apply engine-specific optimizations to the execution plan. They can also
2380 reject executing the query by raising an error, in which case the query will
2381 be reprepared and executed by the primary storage engine.
2382
2383 @param thd thread context
2384 @param lex the statement being optimized
2385 @return true on error, false on success
2386*/
2387using optimize_secondary_engine_t = bool (*)(THD *thd, LEX *lex);
2388
2389/**
2390 Compares the cost of two join plans in the secondary storage engine. The cost
2391 of the current candidate is compared with the cost of the best plan seen so
2392 far.
2393
2394 @param thd thread context
2395 @param join the candidate plan to evaluate
2396 @param optimizer_cost the cost estimate calculated by the optimizer
2397 @param[out] use_best_so_far true if the optimizer should stop searching for
2398 a better plan and use the best plan it has seen so far
2399 @param[out] cheaper true if the candidate is the best plan seen so far for
2400 this JOIN (must be true if it is the first plan seen),
2401 false otherwise
2402 @param[out] secondary_engine_cost the cost estimated by the secondary engine
2403
2404 @return false on success, or true if an error has been raised
2405*/
2406using compare_secondary_engine_cost_t = bool (*)(THD *thd, const JOIN &join,
2407 double optimizer_cost,
2408 bool *use_best_so_far,
2409 bool *cheaper,
2410 double *secondary_engine_cost);
2411
2412/**
2413 Evaluates/Views the cost of executing the given access path in the secondary
2414 storage engine, and potentially modifies the cost estimates that are in the
2415 access path when optimization is being done for secondary engine. For primary
2416 engine, the cost should be only viewed. This function is only called from the
2417 hypergraph join optimizer.
2418
2419 The function is called on every access path that the join optimizer might
2420 compare to an alternative access path. This includes both paths that represent
2421 complete execution plans and paths that represent partial plans. It is not
2422 guaranteed to be called on every child path. For example, if GROUP BY is done
2423 by sorting first and then aggregating the sorted results, the function will
2424 only be called on the aggregation path, and not on the sort path, because only
2425 the aggregation path will be compared to other paths.
2426
2427 The secondary engine is allowed to modify the estimates in the access path to
2428 better match the costs of the access path in the secondary engine. It can
2429 change any of the following AccessPath members:
2430
2431 - init_once_cost
2432 - init_cost
2433 - cost
2434 - cost_before_filter
2435 - num_output_rows
2436 - num_output_rows_before_filter
2437 - secondary_engine_data
2438
2439 Any other members should be left unchanged. The AccessPath must be in an
2440 internally consistent state when the function returns, and satisfy invariants
2441 expected by the hypergraph join optimizer, such as:
2442
2443 - init_cost <= cost_before_filter <= cost
2444 - num_output_rows <= num_output_rows_before_filter
2445
2446 The secondary engine can also reject an access path altogether, by returning
2447 true, in which case the join optimizer will not use that path in the final
2448 plan. Since the secondary engine can reject any partial or complete plan, it
2449 is possible that the join optimizer does not find any valid plan that is
2450 accepted. In this case, the join optimizer will raise an error.
2451
2452 If the secondary encounters an error when evaluating the cost of the path, it
2453 can signal an error by calling my_error() and return true, in which case the
2454 join optimizer will not suggest any plan for the query.
2455
2456 @param thd The thread context.
2457 @param hypergraph The hypergraph that represents the search space.
2458 @param[in,out] access_path The AccessPath to evaluate.
2459
2460 @retval false on success.
2461 @retval true if the plan is to be rejected, or if an error was raised.
2462*/
2464 THD *thd, const JoinHypergraph &hypergraph, AccessPath *access_path);
2465
2466/**
2467 Checks whether the tables used in an explain query are loaded in the secondary
2468 engine.
2469 @param thd thread context.
2470
2471 @retval true if there is a table not loaded to the secondary engine, false
2472 otherwise
2473*/
2475
2476/**
2477 Looks up and returns a specific secondary engine query offload or exec
2478 failure reason as a string given a thread context (representing the query)
2479 when the offloaded query fails in the secondary storage engine.
2480
2481 @param thd thread context.
2482
2483 @retval std::string_view as the offload failure reason.
2484 The memory pointed to is managed by the handlerton and may be freed
2485 when the statement completes.
2486*/
2488 std::string_view (*)(const THD *thd);
2489
2490/**
2491 Finds and returns a specific secondary engine query offload failure reason
2492 as a string given a thread context (representing the query) whenever
2493 get_secondary_engine_offload_or_exec_fail_reason_t returns an empty reason.
2494
2495 @param thd thread context.
2496
2497 @retval std::string_view as the offload failure reason.
2498*/
2500 std::string_view (*)(THD *thd);
2501
2502/**
2503 Sets a specific secondary engine offload failure reason for a query
2504 represented by the thread context when the offloaded query fails in
2505 the secondary storage engine.
2506
2507 @param thd thread context.
2508
2509 @param reason offload failure reason.
2510
2511 @retval bool to indicate if the setting succeeded or failed
2512*/
2514 bool (*)(const THD *thd, std::string_view reason);
2515
2517 /** Continue optimization phase with current hypergraph. */
2518 kContinue = 0,
2519 /** Trigger restart of hypergraph with provided number of subgraph pairs. */
2520 kRestart = 1,
2521};
2522
2524 /** Optimizer request from the secondary engine. */
2526 /** Subgraph pairs requested by the secondary engine. */
2528 /** Indicates if simplification is guided using secondary engine */
2530};
2531
2532/**
2533 Hook to evaluate the current hypergraph optimization state in optimization for
2534 all the engines, and returns the state that hypergraph should transition to.
2535 Usually invoked after secondary_engine_modify_view_ap_cost_t is invoked via
2536 the optimizer. The state is returned as object of type
2537 SecondaryEngineGraphSimplificationRequestParameters, and can lead to
2538 simplification of hypergraph search space, or resetting the graph and starting
2539 search afresh.
2540
2541 @param thd The thread context.
2542 @param hypergraph The hypergraph that represents the search space.
2543 @param access_path The AccessPath to evaluate.
2544 @param current_subgraph_pairs Count of subgraph pairs explored so far.
2545 @param current_subgraph_pairs_limit Limit for current hypergraph.
2546 @param is_root_access_path Indicating if access_path is root.
2547 @param trace Optimizer trace string.
2548
2549 @returns instance of SecondaryEngineGraphSimplificationRequestParameters which
2550 contains description of the state hypergraph optimizer should transition to.
2551*/
2554 THD *thd, const JoinHypergraph &hypergraph,
2555 const AccessPath *access_path, int current_subgraph_pairs,
2556 int current_subgraph_pairs_limit, bool is_root_access_path,
2557 std::string *trace);
2558
2559// Capabilities (bit flags) for secondary engines.
2560using SecondaryEngineFlags = uint64_t;
2564
2565 // If this flag is set, aggregation (GROUP BY and DISTINCT) do not require
2566 // ordered inputs and create unordered outputs. This is typically the case
2567 // if they are implemented using hash-based techniques.
2569
2570 /// This flag can be set to signal that a secondary storage engine will not
2571 /// use MySQL's executor (see JOIN::override_executor_func). In this case, it
2572 /// doesn't need MySQL's execution data structures, like internal temporary
2573 /// tables, filesort objects or iterators. If the flag is set,
2574 /// FinalizePlanForQueryBlock() will not make any changes to the plan, and
2575 /// CreateIteratorFromAccessPath() will not be called.
2577};
2578
2579/// Creates an empty bitmap of access path types. This is the base
2580/// case for the function template with the same name below.
2581inline constexpr SecondaryEngineFlags MakeSecondaryEngineFlags() { return 0; }
2582
2583/// Creates a bitmap representing a set of access path types.
2584template <typename... Args>
2586 SecondaryEngineFlag flag1, Args... rest) {
2587 return (uint64_t{1} << static_cast<int>(flag1)) |
2588 MakeSecondaryEngineFlags(rest...);
2589}
2590
2591/// Returns the handlerton of the secondary engine that is used in the session,
2592/// or nullptr if a secondary engine is not used.
2593const handlerton *SecondaryEngineHandlerton(const THD *thd);
2594
2595/// Returns the handlerton of the eligible secondary engine that is used in the
2596/// session, If found, also initialises the thd member which caches this
2597/// eligible secondary engine, or returns nullptr if a secondary engine is not
2598/// used.
2600 THD *thd, const LEX_CSTRING *secondary_engine_in_name);
2601
2602// FIXME: Temporary workaround to enable storage engine plugins to use the
2603// before_commit hook. Remove after WL#11320 has been completed.
2604using se_before_commit_t = void (*)(void *arg);
2605
2606// FIXME: Temporary workaround to enable storage engine plugins to use the
2607// after_commit hook. Remove after WL#11320 has been completed.
2608using se_after_commit_t = void (*)(void *arg);
2609
2610// FIXME: Temporary workaround to enable storage engine plugins to use the
2611// before_rollback hook. Remove after WL#11320 has been completed.
2612using se_before_rollback_t = void (*)(void *arg);
2613
2614/**
2615 Notify plugins when a SELECT query was executed. The plugins will be notified
2616 only if the query is not considered secondary engine relevant, i.e.:
2617 1. for a query with missing secondary_engine_statement_ctx, its estimated cost
2618 is greater than the currently configured 'secondary_engine_cost_threshold'
2619 2. for queries with secondary_engine_statement_ctx, wherever
2620 secondary_engine_statement_ctx::is_primary_engine_optimal() returns False
2621 indicating secondary engine relevance.
2622 */
2623using notify_after_select_t = void (*)(THD *thd, SelectExecutedIn executed_in);
2624
2625/**
2626 * Notify plugins when a table is created.
2627 */
2628using notify_create_table_t = void (*)(struct HA_CREATE_INFO *create_info,
2629 const char *db, const char *table_name);
2630
2631/**
2632 Secondary engine hook called after PRIMARY_TENTATIVELY optimization is
2633 complete, and decides if secondary engine optimization will be performed, and
2634 comparison of primary engine cost and secondary engine cost will determine
2635 which engine to use for execution.
2636 @param[in] thd current thd.
2637 @return :
2638 @retval true When secondary_engine's prepare hook is to be further called
2639 @retval false When secondary_engine's prepare hook is NOT to be further called
2640
2641 */
2643
2644/**
2645 Hook used to estimate the cardinality of table Node objects in the
2646 JoinHypergraph. For each Node, it attempts to estimate the cardinality,
2647 and if successful, stores it in the field `cardinality`.
2648
2649 @param thd The thread context.
2650 @param graph The JoinHypergraph where the estimates are to be made.
2651*/
2652using cardinality_estimation_hook_t = void (*)(THD *thd, JoinHypergraph *graph);
2653
2654/**
2655 * Notify plugins when a table is dropped.
2656 */
2657using notify_drop_table_t = void (*)(Table_ref *tab);
2658
2659/**
2660 * Store the name of default secondary engine, if any.
2661 */
2662extern std::atomic<const char *> default_secondary_engine_name;
2663/*
2664 Page Tracking : interfaces to handlerton functions which starts/stops page
2665 tracking, and purges/fetches page tracking information.
2666*/
2667
2668/**
2669 Start page tracking.
2670
2671 @param[out] start_id SE specific sequence number [LSN for InnoDB]
2672 indicating when the tracking was started
2673
2674 @return Operation status.
2675 @retval 0 Success
2676 @retval other ER_* mysql error. Get error details from THD.
2677*/
2678using page_track_start_t = int (*)(uint64_t *start_id);
2679
2680/**
2681 Stop page tracking.
2682
2683 @param[out] stop_id SE specific sequence number [LSN for InnoDB]
2684 indicating when the tracking was stopped
2685
2686 @return Operation status.
2687 @retval 0 Success
2688 @retval other ER_* mysql error. Get error details from THD.
2689*/
2690using page_track_stop_t = int (*)(uint64_t *stop_id);
2691
2692/**
2693 Purge page tracking data.
2694
2695 @param[in,out] purge_id SE specific sequence number [LSN for InnoDB]
2696 initially indicating till where the data needs to be purged and finally
2697 updated to until where it was actually purged
2698
2699 @return Operation status.
2700 @retval 0 Success
2701 @retval other ER_* mysql error. Get error details from THD.
2702*/
2703using page_track_purge_t = int (*)(uint64_t *purge_id);
2704
2705/**
2706 Fetch tracked pages.
2707
2708 @param[in] cbk_func callback function return page IDs
2709 @param[in] cbk_ctx caller's context for callback
2710 @param[in,out] start_id SE specific sequence number [LSN for InnoDB] from
2711 where the pages tracked would be returned.
2712 @note The range might get expanded and the actual start_id used for the
2713 querying will be updated.
2714 @param[in,out] stop_id SE specific sequence number [LSN for InnoDB]
2715 until where the pages tracked would be returned.
2716 @note The range might get expanded and the actual stop_id used for the
2717 querying will be updated.
2718 @param[out] buffer allocated buffer to copy page IDs
2719 @param[in] buffer_len length of buffer in bytes
2720
2721 @return Operation status.
2722 @retval 0 Success
2723 @retval other ER_* mysql error. Get error details from THD.
2724*/
2726 void *cbk_ctx, uint64_t *start_id,
2727 uint64_t *stop_id,
2728 unsigned char *buffer,
2729 size_t buffer_len);
2730
2731/**
2732 Fetch approximate number of tracked pages in the given range.
2733
2734 @param[in,out] start_id SE specific sequence number [LSN for InnoDB] from
2735 where the pages tracked would be returned.
2736 @note the range might get expanded and the actual start_id used for the
2737 querying will be updated.
2738 @param[in,out] stop_id SE specific sequence number [LSN for InnoDB]
2739 until where the pages tracked would be returned.
2740 @note the range might get expanded and the actual stop_id used for the
2741 querying will be updated.
2742 @param[out] num_pages number of pages tracked
2743
2744 @return Operation status.
2745 @retval 0 Success
2746 @retval other ER_* mysql error. Get error details from THD.
2747*/
2748using page_track_get_num_page_ids_t = int (*)(uint64_t *start_id,
2749 uint64_t *stop_id,
2750 uint64_t *num_pages);
2751
2752/** Fetch the status of the page tracking system.
2753@param[out] status vector of a pair of (ID, bool) where ID is the
2754start/stop point and bool is true if the ID is a start point else false */
2756 void (*)(std::vector<std::pair<uint64_t, bool>> &status);
2757
2758/** Page track interface */
2766};
2767
2768/**
2769 handlerton is a singleton structure - one instance per storage engine -
2770 to provide access to storage engine functionality that works on the
2771 "global" level (unlike handler class that works on a per-table basis).
2772
2773 usually handlerton instance is defined statically in ha_xxx.cc as
2774
2775 static handlerton { ... } xxx_hton;
2776
2777 savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
2778*/
2780 /**
2781 Historical marker for if the engine is available or not.
2782 */
2784
2785 /**
2786 Historical number used for frm file to determine the correct storage engine.
2787 This is going away and new engines will just use "name" for this.
2788 */
2790 /**
2791 Each storage engine has it's own memory area (actually a pointer)
2792 in the thd, for storing per-connection information.
2793 It is accessed as
2794
2795 thd->ha_data[xxx_hton.slot]
2796
2797 slot number is initialized by MySQL after xxx_init() is called.
2798 */
2799 uint slot;
2800 /**
2801 To store per-savepoint data storage engine is provided with an area
2802 of a requested size (0 is ok here).
2803 savepoint_offset must be initialized statically to the size of
2804 the needed memory to store per-savepoint information.
2805 After xxx_init it is changed to be an offset to savepoint storage
2806 area and need not be used by storage engine.
2807 see binlog_hton and binlog_savepoint_set/rollback for an example.
2808 */
2810
2811 /* handlerton methods */
2812
2860
2861 /** Global handler flags. */
2863
2864 /*
2865 Those handlerton functions below are properly initialized at handler
2866 init.
2867 */
2868
2877
2878 /*
2879 APIs for retrieving Serialized Dictionary Information by tablespace id
2880 */
2881
2888
2889 /**
2890 Null-ended array of file extensions that exist for the storage engine.
2891 Used by frm_error() and the default handler::rename_table and delete_table
2892 methods in handler.cc.
2893
2894 For engines that have two file name extensions (separate meta/index file
2895 and data file), the order of elements is relevant. First element of engine
2896 file name extensions array should be meta/index file extension. Second
2897 element - data file extension. This order is assumed by
2898 prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
2899
2900 For engines that don't have files, file_extensions is NULL.
2901
2902 Currently, the following alternatives are used:
2903 - file_extensions == NULL;
2904 - file_extensions[0] != NULL, file_extensions[1] == NULL;
2905 - file_extensions[0] != NULL, file_extensions[1] != NULL,
2906 file_extensions[2] == NULL;
2907 */
2908 const char **file_extensions;
2909
2920
2925
2928
2929 /** Clone data transfer interfaces */
2931
2932 /** Flag for Engine License. */
2934 /** Location for engines to keep personal structures. */
2935 void *data;
2936
2937 /*
2938 Log_resource functions that must be supported by storage engines
2939 with relevant log information to be collected.
2940 */
2944
2945 /** Flags describing details of foreign key support by storage engine. */
2947
2949
2950 /**
2951 Suffix for auto-generated foreign key names for tables using this storage
2952 engine. If such suffix is specified by SE then its generated foreign key
2953 names follow (table name)(SE-specific FK name suffix)(FK number) pattern.
2954 Length of such suffix should not exceed MAX_FK_NAME_SUFFIX_LENGTH bytes.
2955 If no suffix is specified then FK_NAME_DEFAULT_SUFFIX is used as
2956 default.
2957 */
2959
2960 /**
2961 Pointer to a function that prepares a secondary engine for executing a
2962 statement.
2963
2964 @see prepare_secondary_engine_t for function signature.
2965 */
2967
2968 /**
2969 Pointer to a function that optimizes the current statement for
2970 execution on the secondary storage engine represented by this
2971 handlerton.
2972
2973 @see optimize_secondary_engine_t for function signature.
2974 */
2976
2977 /**
2978 Pointer to a function that estimates the cost of executing a join in a
2979 secondary storage engine.
2980
2981 @see compare_secondary_engine_cost_t for function signature.
2982 */
2984
2985 /// Bitmap which contains the supported join types and other flags
2986 /// for a secondary storage engine when used with the hypergraph join
2987 /// optimizer. If it is empty, it means that the secondary engine
2988 /// does not support the hypergraph join optimizer.
2990
2991 /// Pointer to a function that checks if the table is loaded in the
2992 /// secondary engine in the case of an explain statement.
2993 ///
2994 /// @see external_engine_explain_check_t for function signature.
2996
2997 /// Pointer to a function that evaluates the cost of executing an access path
2998 /// in a secondary storage engine.
2999 ///
3000 /// @see secondary_engine_modify_view_ap_cost_t for function signature.
3002
3003 /// Pointer to a function that returns the query offload or exec failure
3004 /// reason as a string given a thread context (representing the query) when
3005 /// the offloaded query failed in a secondary storage engine.
3006 ///
3007 /// @see get_secondary_engine_offload_or_exec_fail_reason_t for function
3008 /// signature.
3011
3012 /// Pointer to a function that finds and returns the query offload failure
3013 /// reason as a string given a thread context (representing the query) when
3014 /// get_secondary_engine_offload_or_exec_fail_reason returns an empty reason.
3015 ///
3016 /// @see find_secondary_engine_offload_fail_reason_t for function
3017 /// signature.
3020
3021 /// Pointer to a function that sets the offload failure reason as a string
3022 /// for a thread context (representing the query) when the offloaded query
3023 /// failed in a secondary storage engine.
3024 ///
3025 /// @see set_secondary_engine_offload_fail_reason_t for function signature.
3028
3029 /// Pointer to function that checks secondary engine request for updating
3030 /// hypergraph join optimization.
3031 ///
3032 /// @see secondary_engine_check_optimizer_request_t for function signature.
3035
3036 /* Pointer to a function that is called at the end of the PRIMARY_TENTATIVELY
3037 * optimization stage, which also decides that the statement should be
3038 * attempted offloaded to a secondary storage engine. */
3040
3041 /* Pointer to a function to request table filter estimation to the
3042 * secondary_engine. */
3044
3048
3050
3053
3054 /** Page tracking interface */
3056};
3057
3058/* Possible flags of a handlerton (there can be 32 of them) */
3059#define HTON_NO_FLAGS 0
3060#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
3061#define HTON_ALTER_NOT_SUPPORTED (1 << 1) // Engine does not support alter
3062#define HTON_CAN_RECREATE (1 << 2) // Delete all is used for truncate
3063#define HTON_HIDDEN (1 << 3) // Engine does not appear in lists
3064/*
3065 Bit 4 was occupied by BDB-specific HTON_FLUSH_AFTER_RENAME flag and is no
3066 longer used.
3067*/
3068#define HTON_NOT_USER_SELECTABLE (1 << 5)
3069#define HTON_TEMPORARY_NOT_SUPPORTED \
3070 (1 << 6) // Having temporary tables not supported
3071#define HTON_SUPPORT_LOG_TABLES (1 << 7) // Engine supports log tables
3072#define HTON_NO_PARTITION (1 << 8) // You can not partition these tables
3073
3074/*
3075 This flag should be set when deciding that the engine does not allow row based
3076 binary logging (RBL) optimizations.
3077
3078 Currently, setting this flag, means that table's read/write_set will be left
3079 untouched when logging changes to tables in this engine. In practice this
3080 means that the server will not mess around with table->write_set and/or
3081 table->read_set when using RBL and deciding whether to log full or minimal
3082 rows.
3083
3084 It's valuable for instance for virtual tables, eg: Performance Schema which
3085 have no meaning for replication.
3086*/
3087#define HTON_NO_BINLOG_ROW_OPT (1 << 9)
3088
3089/**
3090 Engine supports extended keys. The flag allows to
3091 use 'extended key' feature if the engine is able to
3092 do it (has primary key values in the secondary key).
3093 Note that handler flag HA_PRIMARY_KEY_IN_READ_INDEX is
3094 actually partial case of HTON_SUPPORTS_EXTENDED_KEYS.
3095*/
3096
3097#define HTON_SUPPORTS_EXTENDED_KEYS (1 << 10)
3098
3099// Engine support foreign key constraint.
3100
3101#define HTON_SUPPORTS_FOREIGN_KEYS (1 << 11)
3102
3103/**
3104 Engine supports atomic DDL. That is rollback of transaction for DDL
3105 statement will also rollback all changes in SE, commit of transaction
3106 of DDL statement will make it durable.
3107*/
3108
3109#define HTON_SUPPORTS_ATOMIC_DDL (1 << 12)
3110
3111/* Engine supports packed keys. */
3112#define HTON_SUPPORTS_PACKED_KEYS (1 << 13)
3113
3114/** Engine is a secondary storage engine. */
3115#define HTON_IS_SECONDARY_ENGINE (1 << 14)
3116
3117/** Engine supports secondary storage engines. */
3118#define HTON_SUPPORTS_SECONDARY_ENGINE (1 << 15)
3119
3120/** Engine supports table or tablespace encryption . */
3121#define HTON_SUPPORTS_TABLE_ENCRYPTION (1 << 16)
3122
3124 1 << 17};
3125
3126/** Engine supports Generated invisible primary key. */
3127// clang-format off
3128constexpr const decltype(
3130// clang-format on
3131
3132/** Whether the secondary engine supports DDLs. No meaning if the engine is not
3133 * secondary. */
3134#define HTON_SECONDARY_ENGINE_SUPPORTS_DDL (1 << 19)
3135
3136/** Whether the engine does not support triggers. */
3137#define HTON_NO_TRIGGER_SUPPORT (1 << 20)
3138
3139/** Whether the primary engine supports external data sources. This case refers
3140 to having tables with data in object store and the engine does not store any
3141 of those data, only metadata. Table contents can be accessed only after
3142 loading the table in the secondary storage engine. The flag is used for
3143 a primary engine only.
3144 */
3145#define HTON_SUPPORTS_EXTERNAL_SOURCE (1 << 21)
3146
3147constexpr const decltype(handlerton::flags) HTON_SUPPORTS_BULK_LOAD{1 << 22};
3148
3149/** Engine supports index distance scan. */
3150inline constexpr const decltype(handlerton::flags) HTON_SUPPORTS_DISTANCE_SCAN{
3151 1 << 23};
3152
3153/* Whether the engine supports being specified as a default storage engine */
3154inline constexpr const decltype(handlerton::flags)
3156
3158 assert(hton->flags & HTON_IS_SECONDARY_ENGINE);
3159
3160 return (hton->flags & HTON_SECONDARY_ENGINE_SUPPORTS_DDL) != 0;
3161}
3162
3163inline bool ddl_is_atomic(const handlerton *hton) {
3164 return (hton->flags & HTON_SUPPORTS_ATOMIC_DDL) != 0;
3165}
3166
3167/* Bits for handlerton::foreign_keys_flags bitmap. */
3168
3169/**
3170 Engine supports both unique and non-unique parent keys for
3171 foreign keys which contain full foreign key as its prefix.
3172
3173 Storage engines which support foreign keys but do not have
3174 this flag set are assumed to support only parent keys which
3175 are primary/unique and contain exactly the same columns as
3176 the foreign key, possibly, in different order.
3177*/
3178
3180
3181/**
3182 Storage engine supports hash keys as supporting keys for foreign
3183 keys. Hash key should contain all foreign key columns and only
3184 them (although in any order).
3185
3186 Storage engines which support foreign keys but do not have this
3187 flag set are assumed to not allow hash keys as supporting keys.
3188*/
3189
3191
3192/**
3193 Storage engine supports non-hash keys which have common prefix
3194 with the foreign key as supporting keys for it. If there are
3195 several such keys, one which shares biggest prefix with FK is
3196 chosen.
3197
3198 Storage engines which support foreign keys but do not have this
3199 flag set are assumed to require that supporting key contains full
3200 foreign key as its prefix.
3201*/
3202
3204
3205/**
3206 Storage engine does not support using the same key for both parent
3207 and supporting key, but requires the two to be different.
3208*/
3209
3211 (1 << 3);
3212
3213/**
3214 Engine takes into account hidden part of key (coming from primary key)
3215 when determines if it can serve as parent key for a foreign key.
3216
3217 Implies HTON_FKS_WITH_PREFIX_PARENT_KEYS and is related to
3218 HTON_SUPPORTS_EXTENDED_KEYS.
3219*/
3220
3222
3223/**
3224 Maximum possible length of SE-specific suffixes for auto-generated
3225 foreign key names.
3226*/
3227static const size_t MAX_FK_NAME_SUFFIX_LENGTH = 16;
3228
3229/**
3230 Suffix for auto-generated foreign key names for tables in SE's which
3231 don't specify own suffix. I.e. for foreign keys on tables in such
3232 SE's generated names follow (table name)FK_NAME_DEFAULT_SUFFIX(FK number)
3233 pattern.
3234*/
3236
3243
3249
3250/**
3251 Struct to hold information about the table that should be created.
3252 */
3256 bool schema_read_only{false};
3258 const char *password{nullptr};
3259 const char *tablespace{nullptr};
3260 LEX_STRING comment{nullptr, 0};
3261
3262 /**
3263 Algorithm (and possible options) to be used for InnoDB's transparent
3264 page compression. If this attribute is set then it is hint to the
3265 storage engine to try and compress the data using the specified algorithm
3266 where possible. Note: this value is interpreted by the storage engine only.
3267 and ignored by the Server layer. */
3268
3270
3271 /**
3272 This attribute is used for InnoDB's transparent page encryption.
3273 If this attribute is set then it is hint to the storage engine to encrypt
3274 the data. Note: this value is interpreted by the storage engine only.
3275 and ignored by the Server layer. */
3276
3278
3279 /**
3280 * Secondary engine of the table.
3281 * Is nullptr if no secondary engine defined.
3282 */
3284 /** Secondary engine load status */
3285 bool secondary_load{false};
3286
3287 /** Part info in order to maintain in HA_CREATE_INFO the per-partition
3288 * secondary_load status*/
3290
3291 const char *data_file_name{nullptr};
3292 const char *index_file_name{nullptr};
3293 const char *alias{nullptr};
3299 uint64_t used_fields{0};
3300 // Can only be 1,2,4,8 or 16, but use uint32_t since that how it is
3301 // represented in InnoDB
3302 std::uint32_t key_block_size{0};
3303 uint stats_sample_pages{0}; /* number of pages to sample during
3304 stats estimation, if used, otherwise 0. */
3308 /**
3309 Row type of the table definition.
3310
3311 Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
3312 For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
3313
3314 Can be changed either explicitly by the parser.
3315 If nothing specified inherits the value of the original table (if present).
3316 */
3318 uint null_bits{0}; /* NULL bits at start of record */
3319 uint options{0}; /* OR of HA_CREATE_ options */
3321 ha_storage_media storage_media{HA_SM_DEFAULT}; /* DEFAULT, DISK or MEMORY */
3322
3323 /*
3324 A flag to indicate if this table should be marked as a hidden table in
3325 the data dictionary. One use case is to mark the temporary tables
3326 created by ALTER to be marked as hidden.
3327 */
3328 bool m_hidden{false};
3329
3330 /*
3331 A flag to indicate if this table should be created but not committed at
3332 the end of statement.
3333 */
3335
3338
3340
3342
3343 /**
3344 Fill HA_CREATE_INFO to be used by ALTER as well as upgrade code.
3345 This function separates code from mysql_prepare_alter_table() to be
3346 used by upgrade code as well to reduce code duplication.
3347 For ALTER code path, this lets new create options override the old
3348 ones.
3349
3350 @param[in] share TABLE_SHARE object
3351 @param[in] used_fields If a given create option is not flagged, old
3352 value be copied from the TABLE_SHARE.
3353 */
3354
3356 uint64_t used_fields);
3357};
3358
3359/**
3360 Structure describing changes to an index to be caused by ALTER TABLE.
3361*/
3362
3363struct KEY_PAIR {
3364 /**
3365 Pointer to KEY object describing old version of index in
3366 TABLE::key_info array for TABLE instance representing old
3367 version of table.
3368 */
3370 /**
3371 Pointer to KEY object describing new version of index in
3372 Alter_inplace_info::key_info_buffer array.
3373 */
3375};
3376
3377/**
3378 In-place alter handler context.
3379
3380 This is a superclass intended to be subclassed by individual handlers
3381 in order to store handler unique context between in-place alter API calls.
3382
3383 The handler is responsible for creating the object. This can be done
3384 as early as during check_if_supported_inplace_alter().
3385
3386 The SQL layer is responsible for destroying the object.
3387
3388 @see Alter_inplace_info
3389*/
3390
3392 public:
3394
3396 [[maybe_unused]]) {}
3397 virtual ~inplace_alter_handler_ctx() = default;
3398};
3399
3400/**
3401 Class describing changes to be done by ALTER TABLE.
3402 Instance of this class is passed to storage engine in order
3403 to determine if this ALTER TABLE can be done using in-place
3404 algorithm. It is also used for executing the ALTER TABLE
3405 using in-place algorithm.
3406*/
3407
3409 public:
3410 /**
3411 Bits to show in detail what operations the storage engine is
3412 to execute.
3413
3414 All these operations are supported as in-place operations by the
3415 SQL layer. This means that operations that by their nature must
3416 be performed by copying the table to a temporary table, will not
3417 have their own flags here (e.g. ALTER TABLE FORCE, ALTER TABLE
3418 ENGINE).
3419
3420 We generally try to specify handler flags only if there are real
3421 changes. But in cases when it is cumbersome to determine if some
3422 attribute has really changed we might choose to set flag
3423 pessimistically, for example, relying on parser output only.
3424 */
3426
3427 // Add non-unique, non-primary index
3428 static const HA_ALTER_FLAGS ADD_INDEX = 1ULL << 0;
3429
3430 // Drop non-unique, non-primary index
3431 static const HA_ALTER_FLAGS DROP_INDEX = 1ULL << 1;
3432
3433 // Add unique, non-primary index
3434 static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1ULL << 2;
3435
3436 // Drop unique, non-primary index
3437 static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1ULL << 3;
3438
3439 // Add primary index
3440 static const HA_ALTER_FLAGS ADD_PK_INDEX = 1ULL << 4;
3441
3442 // Drop primary index
3443 static const HA_ALTER_FLAGS DROP_PK_INDEX = 1ULL << 5;
3444
3445 // Add column
3446
3447 // Virtual generated column
3448 static const HA_ALTER_FLAGS ADD_VIRTUAL_COLUMN = 1ULL << 6;
3449 // Stored base (non-generated) column
3450 static const HA_ALTER_FLAGS ADD_STORED_BASE_COLUMN = 1ULL << 7;
3451 // Stored generated column
3453 // Add generic column (convenience constant).
3456
3457 // Drop column
3458 static const HA_ALTER_FLAGS DROP_VIRTUAL_COLUMN = 1ULL << 9;
3459 static const HA_ALTER_FLAGS DROP_STORED_COLUMN = 1ULL << 10;
3462
3463 // Rename column
3464 static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1ULL << 11;
3465
3466 // Change column datatype
3468 static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_TYPE = 1ULL << 13;
3469
3470 /**
3471 Change column datatype in such way that new type has compatible
3472 packed representation with old type, so it is theoretically
3473 possible to perform change by only updating data dictionary
3474 without changing table rows.
3475 */
3477
3478 /// A virtual column has changed its position
3480
3481 /// A stored column has changed its position (disregarding virtual columns)
3483
3484 // Change column from NOT NULL to NULL
3485 static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1ULL << 17;
3486
3487 // Change column from NULL to NOT NULL
3489
3490 // Set or remove default column value
3491 static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1ULL << 19;
3492
3493 // Change column generation expression
3494 static const HA_ALTER_FLAGS ALTER_VIRTUAL_GCOL_EXPR = 1ULL << 20;
3495 static const HA_ALTER_FLAGS ALTER_STORED_GCOL_EXPR = 1ULL << 21;
3496
3497 // Add foreign key
3498 static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1ULL << 22;
3499
3500 // Drop foreign key
3501 static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1ULL << 23;
3502
3503 // table_options changed, see HA_CREATE_INFO::used_fields for details.
3504 static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1ULL << 24;
3505
3506 // Table is renamed
3507 static const HA_ALTER_FLAGS ALTER_RENAME = 1ULL << 25;
3508
3509 // Change the storage type of column
3511
3512 // Change the column format of column
3514
3515 // Add partition
3516 static const HA_ALTER_FLAGS ADD_PARTITION = 1ULL << 28;
3517
3518 // Drop partition
3519 static const HA_ALTER_FLAGS DROP_PARTITION = 1ULL << 29;
3520
3521 // Changing partition options
3522 static const HA_ALTER_FLAGS ALTER_PARTITION = 1ULL << 30;
3523
3524 // Coalesce partition
3525 static const HA_ALTER_FLAGS COALESCE_PARTITION = 1ULL << 31;
3526
3527 // Reorganize partition ... into
3528 static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1ULL << 32;
3529
3530 // Reorganize partition
3531 static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1ULL << 33;
3532
3533 // Remove partitioning
3535
3536 // Partition operation with ALL keyword
3537 static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1ULL << 35;
3538
3539 /**
3540 Rename index. Note that we set this flag only if there are no other
3541 changes to the index being renamed. Also for simplicity we don't
3542 detect renaming of indexes which is done by dropping index and then
3543 re-creating index with identical definition under different name.
3544 */
3545 static const HA_ALTER_FLAGS RENAME_INDEX = 1ULL << 36;
3546
3547 /**
3548 Recreate the table for ALTER TABLE FORCE, ALTER TABLE ENGINE
3549 and OPTIMIZE TABLE operations.
3550 */
3551 static const HA_ALTER_FLAGS RECREATE_TABLE = 1ULL << 37;
3552
3553 // Add spatial index
3554 static const HA_ALTER_FLAGS ADD_SPATIAL_INDEX = 1ULL << 38;
3555
3556 // Alter index comment
3557 static const HA_ALTER_FLAGS ALTER_INDEX_COMMENT = 1ULL << 39;
3558
3559 // New/changed virtual generated column require validation
3560 static const HA_ALTER_FLAGS VALIDATE_VIRTUAL_COLUMN = 1ULL << 40;
3561
3562 /**
3563 Change index option in a way which is likely not to require index
3564 recreation. For example, change COMMENT or KEY::is_algorithm_explicit
3565 flag (without change of index algorithm itself).
3566 */
3567 static const HA_ALTER_FLAGS CHANGE_INDEX_OPTION = 1LL << 41;
3568
3569 // Rebuild partition
3570 static const HA_ALTER_FLAGS ALTER_REBUILD_PARTITION = 1ULL << 42;
3571
3572 /**
3573 Change in index length such that it does not require index rebuild.
3574 For example, change in index length due to column expansion like
3575 varchar(X) changed to varchar(X + N).
3576 */
3578
3579 /**
3580 Change to one of columns on which virtual generated column depends,
3581 so its values require re-evaluation.
3582 */
3583 static const HA_ALTER_FLAGS VIRTUAL_GCOL_REEVAL = 1ULL << 44;
3584
3585 /**
3586 Change to one of columns on which stored generated column depends,
3587 so its values require re-evaluation.
3588 */
3589 static const HA_ALTER_FLAGS STORED_GCOL_REEVAL = 1ULL << 45;
3590
3591 // Add check constraint.
3592 static const HA_ALTER_FLAGS ADD_CHECK_CONSTRAINT = 1ULL << 46;
3593
3594 // Drop check constraint.
3595 static const HA_ALTER_FLAGS DROP_CHECK_CONSTRAINT = 1ULL << 47;
3596
3597 // Suspend check constraint.
3598 static const HA_ALTER_FLAGS SUSPEND_CHECK_CONSTRAINT = 1ULL << 48;
3599
3600 // Alter column visibility.
3601 static const HA_ALTER_FLAGS ALTER_COLUMN_VISIBILITY = 1ULL << 49;
3602
3603 /**
3604 Create options (like MAX_ROWS) for the new version of table.
3605
3606 @note The referenced instance of HA_CREATE_INFO object was already
3607 used to create new .FRM file for table being altered. So it
3608 has been processed by mysql_prepare_create_table() already.
3609 For example, this means that it has HA_OPTION_PACK_RECORD
3610 flag in HA_CREATE_INFO::table_options member correctly set.
3611 */
3613
3614 /**
3615 Alter options, fields and keys for the new version of table.
3616
3617 @note The referenced instance of Alter_info object was already
3618 used to create new .FRM file for table being altered. So it
3619 has been processed by mysql_prepare_create_table() already.
3620 In particular, this means that in Create_field objects for
3621 fields which were present in some form in the old version
3622 of table, Create_field::field member points to corresponding
3623 Field instance for old version of table.
3624 */
3626
3627 /**
3628 Indicates whether operation should fail if table is non-empty.
3629 Storage engines should not suggest/allow execution of such operations
3630 using INSTANT algorithm since check whether table is empty done from
3631 SQL-layer is not "instant". Also SEs might choose different algorithm for
3632 ALTER TABLE execution knowing that it will be allowed to proceed only if
3633 table is empty.
3634
3635 Unlike for Alter_table_ctx::error_if_not_empty, we use bool for this flag
3636 and not bitmap, since SEs are really interested in the fact that ALTER
3637 will fail if table is not empty and not in exact reason behind this fact,
3638 and because we want to avoid extra dependency between Alter_table_ctx and
3639 Alter_inplace_info.
3640 */
3642
3643 /**
3644 Array of KEYs for new version of table - including KEYs to be added.
3645
3646 @note Currently this array is produced as result of
3647 mysql_prepare_create_table() call.
3648 This means that it follows different convention for
3649 KEY_PART_INFO::fieldnr values than objects in TABLE::key_info
3650 array.
3651
3652 @todo This is mainly due to the fact that we need to keep compatibility
3653 with removed handler::add_index() call. We plan to switch to
3654 TABLE::key_info numbering later.
3655
3656 KEYs are sorted - see sort_keys().
3657 */
3659
3660 /** Size of key_info_buffer array. */
3662
3663 /** Size of index_drop_buffer array. */
3665
3666 /**
3667 Array of pointers to KEYs to be dropped belonging to the TABLE instance
3668 for the old version of the table.
3669 */
3671
3672 /** Size of index_add_buffer array. */
3674
3675 /**
3676 Array of indexes into key_info_buffer for KEYs to be added,
3677 sorted in increasing order.
3678 */
3680
3681 /** Size of index_rename_buffer array. */
3683
3684 /** Size of index_rename_buffer array. */
3686
3687 /**
3688 Array of KEY_PAIR objects describing indexes being renamed.
3689 For each index renamed it contains object with KEY_PAIR::old_key
3690 pointing to KEY object belonging to the TABLE instance for old
3691 version of table representing old version of index and with
3692 KEY_PAIR::new_key pointing to KEY object for new version of
3693 index in key_info_buffer member.
3694 */
3697
3698 /** Number of virtual columns to be added. */
3700
3701 /** number of virtual columns to be dropped. */
3703
3704 /**
3705 Context information to allow handlers to keep context between in-place
3706 alter API calls.
3707
3708 @see inplace_alter_handler_ctx for information about object lifecycle.
3709 */
3711
3712 /**
3713 If the table uses several handlers, like ha_partition uses one handler
3714 per partition, this contains a Null terminated array of ctx pointers
3715 that should all be committed together.
3716 Or NULL if only handler_ctx should be committed.
3717 Set to NULL if the low level handler::commit_inplace_alter_table uses it,
3718 to signal to the main handler that everything was committed as atomically.
3719
3720 @see inplace_alter_handler_ctx for information about object lifecycle.
3721 */
3723
3724 /**
3725 Flags describing in detail which operations the storage engine is to
3726 execute.
3727 */
3729
3730 /**
3731 Partition_info taking into account the partition changes to be performed.
3732 Contains all partitions which are present in the old version of the table
3733 with partitions to be dropped or changed marked as such + all partitions
3734 to be added in the new version of table marked as such.
3735 */
3737
3738 /** true for online operation (LOCK=NONE) */
3740
3741 /**
3742 Can be set by handler along with handler_ctx. The difference is that
3743 this flag can be used to store SE-specific in-place ALTER context in cases
3744 when constructing full-blown inplace_alter_handler_ctx descendant is
3745 inconvenient.
3746 */
3748
3749 /**
3750 Can be set by handler to describe why a given operation cannot be done
3751 in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
3752 online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE)
3753 If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
3754 results from handler::check_if_supported_inplace_alter() doesn't match
3755 requirements set by user. If not set, the more generic
3756 ER_ALTER_OPERATION_NOT_SUPPORTED will be used.
3757
3758 Please set to a properly localized string, for example using
3759 my_get_err_msg(), so that the error message as a whole is localized.
3760 */
3762
3764 Alter_info *alter_info_arg, bool error_if_not_empty_arg,
3765 KEY *key_info_arg, uint key_count_arg,
3766 partition_info *modified_part_info_arg)
3767 : create_info(create_info_arg),
3768 alter_info(alter_info_arg),
3769 error_if_not_empty(error_if_not_empty_arg),
3770 key_info_buffer(key_info_arg),
3771 key_count(key_count_arg),
3774 index_add_count(0),
3783 handler_flags(0),
3784 modified_part_info(modified_part_info_arg),
3785 online(false),
3788
3790 if (handler_ctx != nullptr) ::destroy_at(handler_ctx);
3791 }
3792
3793 /**
3794 Used after check_if_supported_inplace_alter() to report
3795 error if the result does not match the LOCK/ALGORITHM
3796 requirements set by the user.
3797
3798 @param not_supported Part of statement that was not supported.
3799 @param try_instead Suggestion as to what the user should
3800 replace not_supported with.
3801 */
3802 void report_unsupported_error(const char *not_supported,
3803 const char *try_instead);
3804
3805 /** Add old and new version of key to array of indexes to be renamed. */
3806 void add_renamed_key(KEY *old_key, KEY *new_key) {
3808 key_pair->old_key = old_key;
3809 key_pair->new_key = new_key;
3810 DBUG_PRINT("info",
3811 ("index renamed: '%s' to '%s'", old_key->name, new_key->name));
3812 }
3813
3814 void add_altered_index_visibility(KEY *old_key, KEY *new_key) {
3815 KEY_PAIR *key_pair =
3817 key_pair->old_key = old_key;
3818 key_pair->new_key = new_key;
3819 DBUG_PRINT("info", ("index had visibility altered: %i to %i",
3820 old_key->is_visible, new_key->is_visible));
3821 }
3822
3823 /**
3824 Add old and new version of modified key to arrays of indexes to
3825 be dropped and added (correspondingly).
3826 */
3827 void add_modified_key(KEY *old_key, KEY *new_key) {
3829 index_add_buffer[index_add_count++] = (uint)(new_key - key_info_buffer);
3830 DBUG_PRINT("info", ("index changed: '%s'", old_key->name));
3831 }
3832
3833 /** Drop key to array of indexes to be dropped. */
3834 void add_dropped_key(KEY *old_key) {
3836 DBUG_PRINT("info", ("index dropped: '%s'", old_key->name));
3837 }
3838
3839 /** Add key to array of indexes to be added. */
3840 void add_added_key(KEY *new_key) {
3841 index_add_buffer[index_add_count++] = (uint)(new_key - key_info_buffer);
3842 DBUG_PRINT("info", ("index added: '%s'", new_key->name));
3843 }
3844};
3845
3847 uint flags{0}; /* isam layer flags (e.g. for myisamchk) */
3848 uint sql_flags{0}; /* sql layer flags - for something myisamchk cannot do */
3849 KEY_CACHE *key_cache; /* new key cache when changing key cache */
3850};
3851
3852/*
3853 This is a buffer area that the handler can use to store rows.
3854 'end_of_used_area' should be kept updated after calls to
3855 read-functions so that other parts of the code can use the
3856 remaining area (until next read calls is issued).
3857*/
3858
3860 uchar *buffer; /* Buffer one can start using */
3861 uchar *buffer_end; /* End of buffer */
3862 uchar *end_of_used_area; /* End of area that was used by handler */
3863};
3864
3865typedef void *range_seq_t;
3866
3868 /*
3869 Initialize the traversal of range sequence
3870
3871 SYNOPSIS
3872 init()
3873 init_params The seq_init_param parameter
3874 n_ranges The number of ranges obtained
3875 flags A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
3876
3877 RETURN
3878 An opaque value to be used as RANGE_SEQ_IF::next() parameter
3879 */
3880 range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
3881
3882 /*
3883 Get the next range in the range sequence
3884
3885 SYNOPSIS
3886 next()
3887 seq The value returned by RANGE_SEQ_IF::init()
3888 range OUT Information about the next range
3889
3890 RETURN
3891 0 - Ok, the range structure filled with info about the next range
3892 1 - No more ranges
3893 */
3895
3896 /*
3897 Check whether range_info orders to skip the next record
3898
3899 SYNOPSIS
3900 skip_record()
3901 seq The value returned by RANGE_SEQ_IF::init()
3902 range_info Information about the next range
3903 (Ignored if MRR_NO_ASSOCIATION is set)
3904 rowid Rowid of the record to be checked (ignored if set to 0)
3905
3906 RETURN
3907 1 - Record with this range_info and/or this rowid shall be filtered
3908 out from the stream of records returned by ha_multi_range_read_next()
3909 0 - The record shall be left in the stream
3910 */
3911 bool (*skip_record)(range_seq_t seq, char *range_info, uchar *rowid);
3912};
3913
3914/**
3915 Used to store optimizer cost estimates.
3916
3917 The class consists of PODs only: default operator=, copy constructor
3918 and destructor are used.
3919 */
3921 private:
3922 double io_cost; ///< cost of I/O operations
3923 double cpu_cost; ///< cost of CPU operations
3924 double import_cost; ///< cost of remote operations
3925 double mem_cost; ///< memory used (bytes)
3926
3927 public:
3929
3930 /// Returns sum of time-consuming costs, i.e., not counting memory cost
3931 double total_cost() const { return io_cost + cpu_cost + import_cost; }
3932 double get_io_cost() const { return io_cost; }
3933 double get_cpu_cost() const { return cpu_cost; }
3934 double get_import_cost() const { return import_cost; }
3935 double get_mem_cost() const { return mem_cost; }
3936
3937 /**
3938 Whether or not all costs in the object are zero
3939
3940 @return true if all costs are zero, false otherwise
3941 */
3942 bool is_zero() const {
3943 return !(io_cost || cpu_cost || import_cost || mem_cost);
3944 }
3945 /**
3946 Whether or not the total cost is the maximal double
3947
3948 @return true if total cost is the maximal double, false otherwise
3949 */
3950 bool is_max_cost() const { return io_cost == DBL_MAX; }
3951 /// Reset all costs to zero
3953 /// Set current cost to the maximal double
3955 reset();
3956 io_cost = DBL_MAX;
3957 }
3958
3959 /// Multiply io, cpu and import costs by parameter
3960 void multiply(double m) {
3961 assert(!is_max_cost());
3962
3963 io_cost *= m;
3964 cpu_cost *= m;
3965 import_cost *= m;
3966 /* Don't multiply mem_cost */
3967 }
3968
3970 assert(!is_max_cost() && !other.is_max_cost());
3971
3972 io_cost += other.io_cost;
3973 cpu_cost += other.cpu_cost;
3974 import_cost += other.import_cost;
3975 mem_cost += other.mem_cost;
3976
3977 return *this;
3978 }
3979
3981 Cost_estimate result = *this;
3982 result += other;
3983
3984 return result;
3985 }
3986
3989
3990 assert(!other.is_max_cost());
3991
3992 result.io_cost = io_cost - other.io_cost;
3993 result.cpu_cost = cpu_cost - other.cpu_cost;
3994 result.import_cost = import_cost - other.import_cost;
3995 result.mem_cost = mem_cost - other.mem_cost;
3996 return result;
3997 }
3998
3999 bool operator>(const Cost_estimate &other) const {
4000 return total_cost() > other.total_cost() ? true : false;
4001 }
4002
4003 bool operator<(const Cost_estimate &other) const {
4004 return other > *this ? true : false;
4005 }
4006
4007 /// Add to IO cost
4008 void add_io(double add_io_cost) {
4009 assert(!is_max_cost());
4010 io_cost += add_io_cost;
4011 }
4012
4013 /// Add to CPU cost
4014 void add_cpu(double add_cpu_cost) {
4015 assert(!is_max_cost());
4016 cpu_cost += add_cpu_cost;
4017 }
4018
4019 /// Add to import cost
4020 void add_import(double add_import_cost) {
4021 assert(!is_max_cost());
4022 import_cost += add_import_cost;
4023 }
4024
4025 /// Add to memory cost
4026 void add_mem(double add_mem_cost) {
4027 assert(!is_max_cost());
4028 mem_cost += add_mem_cost;
4029 }
4030};
4031
4033 Cost_estimate *cost);
4034
4035/*
4036 The below two are not used (and not handled) in this milestone of this WL
4037 entry because there seems to be no use for them at this stage of
4038 implementation.
4039*/
4040#define HA_MRR_SINGLE_POINT 1
4041#define HA_MRR_FIXED_KEY 2
4042
4043/*
4044 Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
4045 'range' parameter.
4046*/
4047#define HA_MRR_NO_ASSOCIATION 4
4048
4049/*
4050 The MRR user will provide ranges in key order, and MRR implementation
4051 must return rows in key order.
4052 Passing this flag to multi_read_range_init() may cause the
4053 default MRR handler to be used even if HA_MRR_USE_DEFAULT_IMPL
4054 was not specified.
4055 (If the native MRR impl. can not provide SORTED result)
4056*/
4057#define HA_MRR_SORTED 8
4058
4059/* MRR implementation doesn't have to retrieve full records */
4060#define HA_MRR_INDEX_ONLY 16
4061
4062/*
4063 The passed memory buffer is of maximum possible size, the caller can't
4064 assume larger buffer.
4065*/
4066#define HA_MRR_LIMITS 32
4067
4068/*
4069 Flag set <=> default MRR implementation is used
4070 (The choice is made by **_info[_const]() function which may set this
4071 flag. SQL layer remembers the flag value and then passes it to
4072 multi_read_range_init().
4073*/
4074#define HA_MRR_USE_DEFAULT_IMPL 64
4075
4076/*
4077 Used only as parameter to multi_range_read_info():
4078 Flag set <=> the caller guarantees that the bounds of the scanned ranges
4079 will not have NULL values.
4080*/
4081#define HA_MRR_NO_NULL_ENDPOINTS 128
4082
4083/*
4084 Set by the MRR implementation to signal that it will natively
4085 produced sorted result if multi_range_read_init() is called with
4086 the HA_MRR_SORTED flag - Else multi_range_read_init(HA_MRR_SORTED)
4087 will revert to use the default MRR implementation.
4088*/
4089#define HA_MRR_SUPPORT_SORTED 256
4090
4092 public:
4093 ulonglong data_file_length; /* Length off data file */
4094 ulonglong max_data_file_length; /* Length off data file */
4097 ulonglong delete_length; /* Free bytes */
4099 /*
4100 The number of records in the table.
4101 0 - means the table has exactly 0 rows
4102 other - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
4103 the value is the exact number of records in the table
4104 else
4105 it is an estimate
4106 */
4108 ha_rows deleted; /* Deleted records */
4109 ulong mean_rec_length; /* physical reclength */
4110 /* TODO: create_time should be retrieved from the new DD. Remove this. */
4111 time_t create_time; /* When table was created */
4114 uint block_size; /* index block size */
4115
4116 /*
4117 number of buffer bytes that native mrr implementation needs,
4118 */
4120
4121 /**
4122 Estimate for how much of the table that is available in a memory
4123 buffer. Valid range is [0..1]. If it has the special value
4124 IN_MEMORY_ESTIMATE_UNKNOWN (defined in structs.h), it means that
4125 the storage engine has not supplied any value for it.
4126 */
4128
4130 : data_file_length(0),
4133 delete_length(0),
4135 records(0),
4136 deleted(0),
4137 mean_rec_length(0),
4138 create_time(0),
4139 check_time(0),
4140 update_time(0),
4141 block_size(0),
4143};
4144
4146 public:
4148
4150};
4151
4152/**
4153 Calculates length of key.
4154
4155 Given a key index and a map of key parts return length of buffer used by key
4156 parts.
4157
4158 @param table Table containing the key
4159 @param key Key index
4160 @param keypart_map which key parts that is used
4161
4162 @return Length of used key parts.
4163*/
4164uint calculate_key_len(TABLE *table, uint key, key_part_map keypart_map);
4165/*
4166 bitmap with first N+1 bits set
4167 (keypart_map for a key prefix of [0..N] keyparts)
4168*/
4169#define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
4170/*
4171 bitmap with first N bits set
4172 (keypart_map for a key prefix of [0..N-1] keyparts)
4173*/
4174#define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
4175
4176/** Base class to be used by handlers different shares */
4178 public:
4179 Handler_share() = default;
4180 virtual ~Handler_share() = default;
4181};
4182
4183/**
4184 Wrapper for struct ft_hints.
4185*/
4186
4188 private:
4190
4191 public:
4192 explicit Ft_hints(uint ft_flags) {
4193 hints.flags = ft_flags;
4195 hints.op_value = 0.0;
4197 }
4198
4199 /**
4200 Set comparison operation type and and value for master MATCH function.
4201
4202 @param type comparison operation type
4203 @param value comparison operation value
4204 */
4205 void set_hint_op(enum ft_operation type, double value) {
4206 hints.op_type = type;
4207 hints.op_value = value;
4208 }
4209
4210 /**
4211 Set Ft_hints flag.
4212
4213 @param ft_flag Ft_hints flag
4214 */
4215 void set_hint_flag(uint ft_flag) { hints.flags |= ft_flag; }
4216
4217 /**
4218 Set Ft_hints limit.
4219
4220 @param ft_limit limit
4221 */
4222 void set_hint_limit(ha_rows ft_limit) { hints.limit = ft_limit; }
4223
4224 /**
4225 Get Ft_hints limit.
4226
4227 @return Ft_hints limit
4228 */
4229 ha_rows get_limit() const { return hints.limit; }
4230
4231 /**
4232 Get Ft_hints operation value.
4233
4234 @return operation value
4235 */
4236 double get_op_value() const { return hints.op_value; }
4237
4238 /**
4239 Get Ft_hints operation type.
4240
4241 @return operation type
4242 */
4243 enum ft_operation get_op_type() const { return hints.op_type; }
4244
4245 /**
4246 Get Ft_hints flags.
4247
4248 @return Ft_hints flags
4249 */
4250 uint get_flags() const { return hints.flags; }
4251
4252 /**
4253 Get ft_hints struct.
4254
4255 @return pointer to ft_hints struct
4256 */
4257 struct ft_hints *get_hints() { return &hints; }
4258};
4259
4260/**
4261 The handler class is the interface for dynamically loadable
4262 storage engines. Do not add ifdefs and take care when adding or
4263 changing virtual functions to avoid vtable confusion
4264
4265 Functions in this class accept and return table columns data. Two data
4266 representation formats are used:
4267 1. TableRecordFormat - Used to pass [partial] table records to/from
4268 storage engine
4269
4270 2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
4271 storage engine. See opt_range.cc for description of this format.
4272
4273 TableRecordFormat
4274 =================
4275 [Warning: this description is work in progress and may be incomplete]
4276 The table record is stored in a fixed-size buffer:
4277
4278 record: null_bytes, column1_data, column2_data, ...
4279
4280 The offsets of the parts of the buffer are also fixed: every column has
4281 an offset to its column{i}_data, and if it is nullable it also has its own
4282 bit in null_bytes.
4283
4284 The record buffer only includes data about columns that are marked in the
4285 relevant column set (table->read_set and/or table->write_set, depending on
4286 the situation).
4287 <not-sure>It could be that it is required that null bits of non-present
4288 columns are set to 1</not-sure>
4289
4290 VARIOUS EXCEPTIONS AND SPECIAL CASES
4291
4292 If the table has no nullable columns, then null_bytes is still
4293 present, its length is one byte <not-sure> which must be set to 0xFF
4294 at all times. </not-sure>
4295
4296 If the table has columns of type BIT, then certain bits from those columns
4297 may be stored in null_bytes as well. Grep around for Field_bit for
4298 details.
4299
4300 For blob columns (see Field_blob), the record buffer stores length of the
4301 data, following by memory pointer to the blob data. The pointer is owned
4302 by the storage engine and is valid until the next operation.
4303
4304 If a blob column has NULL value, then its length and blob data pointer
4305 must be set to 0.
4306
4307
4308 Overview of main modules of the handler API
4309 ===========================================
4310 The overview below was copied from the storage/partition/ha_partition.h when
4311 support for non-native partitioning was removed.
4312
4313 -------------------------------------------------------------------------
4314 MODULE create/delete handler object
4315 -------------------------------------------------------------------------
4316 Object create/delete method. Normally called when a table object
4317 exists.
4318
4319 -------------------------------------------------------------------------
4320 MODULE meta data changes
4321 -------------------------------------------------------------------------
4322 Meta data routines to CREATE, DROP, RENAME table are often used at
4323 ALTER TABLE (update_create_info used from ALTER TABLE and SHOW ..).
4324
4325 Methods:
4326 delete_table()
4327 rename_table()
4328 create()
4329 update_create_info()
4330
4331 -------------------------------------------------------------------------
4332 MODULE open/close object
4333 -------------------------------------------------------------------------
4334 Open and close handler object to ensure all underlying files and
4335 objects allocated and deallocated for query handling is handled
4336 properly.
4337
4338 A handler object is opened as part of its initialisation and before
4339 being used for normal queries (not before meta-data changes always.
4340 If the object was opened it will also be closed before being deleted.
4341
4342 Methods:
4343 open()
4344 close()
4345
4346 -------------------------------------------------------------------------
4347 MODULE start/end statement
4348 -------------------------------------------------------------------------
4349 This module contains methods that are used to understand start/end of
4350 statements, transaction boundaries, and aid for proper concurrency
4351 control.
4352
4353 Methods:
4354 store_lock()
4355 external_lock()
4356 start_stmt()
4357 lock_count()
4358 unlock_row()
4359 was_semi_consistent_read()
4360 try_semi_consistent_read()
4361
4362 -------------------------------------------------------------------------
4363 MODULE change record
4364 -------------------------------------------------------------------------
4365 This part of the handler interface is used to change the records
4366 after INSERT, DELETE, UPDATE, REPLACE method calls but also other
4367 special meta-data operations as ALTER TABLE, LOAD DATA, TRUNCATE.
4368
4369 These methods are used for insert (write_row), update (update_row)
4370 and delete (delete_row). All methods to change data always work on
4371 one row at a time. update_row and delete_row also contains the old
4372 row.
4373 delete_all_rows will delete all rows in the table in one call as a
4374 special optimization for DELETE from table;
4375
4376 Bulk inserts are supported if all underlying handlers support it.
4377 start_bulk_insert and end_bulk_insert is called before and after a
4378 number of calls to write_row.
4379
4380 Methods:
4381 write_row()
4382 update_row()
4383 delete_row()
4384 delete_all_rows()
4385 start_bulk_insert()
4386 end_bulk_insert()
4387
4388 -------------------------------------------------------------------------
4389 MODULE full table scan
4390 -------------------------------------------------------------------------
4391 This module is used for the most basic access method for any table
4392 handler. This is to fetch all data through a full table scan. No
4393 indexes are needed to implement this part.
4394 It contains one method to start the scan (rnd_init) that can also be
4395 called multiple times (typical in a nested loop join). Then proceeding
4396 to the next record (rnd_next) and closing the scan (rnd_end).
4397 To remember a record for later access there is a method (position)
4398 and there is a method used to retrieve the record based on the stored
4399 position.
4400 The position can be a file position, a primary key, a ROWID dependent
4401 on the handler below.
4402
4403 All functions that retrieve records and are callable through the
4404 handler interface must indicate whether a record is present after the call
4405 or not. Record found is indicated by returning 0 and setting table status
4406 to "has row". Record not found is indicated by returning a non-zero value
4407 and setting table status to "no row".
4408 @see TABLE::set_found_row() and TABLE::set_no_row().
4409 By enforcing these rules in the handler interface, storage handler functions
4410 need not set any status in struct TABLE. These notes also apply to module
4411 index scan, documented below.
4412
4413 Methods:
4414
4415 rnd_init()
4416 rnd_end()
4417 rnd_next()
4418 rnd_pos()
4419 rnd_pos_by_record()
4420 position()
4421
4422 -------------------------------------------------------------------------
4423 MODULE index scan
4424 -------------------------------------------------------------------------
4425 This part of the handler interface is used to perform access through
4426 indexes. The interface is defined as a scan interface but the handler
4427 can also use key lookup if the index is a unique index or a primary
4428 key index.
4429 Index scans are mostly useful for SELECT queries but are an important
4430 part also of UPDATE, DELETE, REPLACE and CREATE TABLE table AS SELECT
4431 and so forth.
4432 Naturally an index is needed for an index scan and indexes can either
4433 be ordered, hash based. Some ordered indexes can return data in order
4434 but not necessarily all of them.
4435 There are many flags that define the behavior of indexes in the
4436 various handlers. These methods are found in the optimizer module.
4437
4438 index_read is called to start a scan of an index. The find_flag defines
4439 the semantics of the scan. These flags are defined in
4440 include/my_base.h
4441 index_read_idx is the same but also initializes index before calling doing
4442 the same thing as index_read. Thus it is similar to index_init followed
4443 by index_read. This is also how we implement it.
4444
4445 index_read/index_read_idx does also return the first row. Thus for
4446 key lookups, the index_read will be the only call to the handler in
4447 the index scan.
4448
4449 index_init initializes an index before using it and index_end does
4450 any end processing needed.
4451
4452 Methods:
4453 index_read_map()
4454 index_init()
4455 index_end()
4456 index_read_idx_map()
4457 index_next()
4458 index_prev()
4459 index_first()
4460 index_last()
4461 index_next_same()
4462 index_read_last_map()
4463 read_range_first()
4464 read_range_next()
4465
4466 -------------------------------------------------------------------------
4467 MODULE information calls
4468 -------------------------------------------------------------------------
4469 This calls are used to inform the handler of specifics of the ongoing
4470 scans and other actions. Most of these are used for optimisation
4471 purposes.
4472
4473 Methods:
4474 info()
4475 get_dynamic_partition_info
4476 extra()
4477 extra_opt()
4478 reset()
4479
4480 -------------------------------------------------------------------------
4481 MODULE optimizer support
4482 -------------------------------------------------------------------------
4483 NOTE:
4484 One important part of the public handler interface that is not depicted in
4485 the methods is the attribute records which is defined in the base class.
4486 This is looked upon directly and is set by calling info(HA_STATUS_INFO) ?
4487
4488 Methods:
4489 min_rows_for_estimate()
4490 get_biggest_used_partition()
4491 scan_time()
4492 read_time()
4493 records_in_range()
4494 estimate_rows_upper_bound()
4495 records()
4496
4497 -------------------------------------------------------------------------
4498 MODULE print messages
4499 -------------------------------------------------------------------------
4500 This module contains various methods that returns text messages for
4501 table types, index type and error messages.
4502
4503 Methods:
4504 table_type()
4505 get_row_type()
4506 print_error()
4507 get_error_message()
4508
4509 -------------------------------------------------------------------------
4510 MODULE handler characteristics
4511 -------------------------------------------------------------------------
4512 This module contains a number of methods defining limitations and
4513 characteristics of the handler (see also documentation regarding the
4514 individual flags).
4515
4516 Methods:
4517 table_flags()
4518 index_flags()
4519 min_of_the_max_uint()
4520 max_supported_record_length()
4521 max_supported_keys()
4522 max_supported_key_parts()
4523 max_supported_key_length()
4524 max_supported_key_part_length()
4525 low_byte_first()
4526 extra_rec_buf_length()
4527 min_record_length(uint options)
4528 primary_key_is_clustered()
4529 ha_key_alg get_default_index_algorithm()
4530 is_index_algorithm_supported()
4531
4532 -------------------------------------------------------------------------
4533 MODULE compare records
4534 -------------------------------------------------------------------------
4535 cmp_ref checks if two references are the same. For most handlers this is
4536 a simple memcmp of the reference. However some handlers use primary key
4537 as reference and this can be the same even if memcmp says they are
4538 different. This is due to character sets and end spaces and so forth.
4539
4540 Methods:
4541 cmp_ref()
4542
4543 -------------------------------------------------------------------------
4544 MODULE auto increment
4545 -------------------------------------------------------------------------
4546 This module is used to handle the support of auto increments.
4547
4548 This variable in the handler is used as part of the handler interface
4549 It is maintained by the parent handler object and should not be
4550 touched by child handler objects (see handler.cc for its use).
4551
4552 Methods:
4553 get_auto_increment()
4554 release_auto_increment()
4555
4556 -------------------------------------------------------------------------
4557 MODULE initialize handler for HANDLER call
4558 -------------------------------------------------------------------------
4559 This method is a special InnoDB method called before a HANDLER query.
4560
4561 Methods:
4562 init_table_handle_for_HANDLER()
4563
4564 -------------------------------------------------------------------------
4565 MODULE fulltext index
4566 -------------------------------------------------------------------------
4567 Fulltext index support.
4568
4569 Methods:
4570 ft_init_ext_with_hints()
4571 ft_init()
4572 ft_init_ext()
4573 ft_read()
4574
4575 -------------------------------------------------------------------------
4576 MODULE in-place ALTER TABLE
4577 -------------------------------------------------------------------------
4578 Methods for in-place ALTER TABLE support (implemented by InnoDB and NDB).
4579
4580 Methods:
4581 check_if_supported_inplace_alter()
4582 prepare_inplace_alter_table()
4583 inplace_alter_table()
4584 commit_inplace_alter_table()
4585 notify_table_changed()
4586
4587 -------------------------------------------------------------------------
4588 MODULE tablespace support
4589 -------------------------------------------------------------------------
4590 Methods:
4591 discard_or_import_tablespace()
4592
4593 -------------------------------------------------------------------------
4594 MODULE administrative DDL
4595 -------------------------------------------------------------------------
4596 Methods:
4597 optimize()
4598 analyze()
4599 check()
4600 repair()
4601 check_and_repair()
4602 auto_repair()
4603 is_crashed()
4604 check_for_upgrade()
4605 checksum()
4606 assign_to_keycache()
4607
4608 -------------------------------------------------------------------------
4609 MODULE enable/disable indexes
4610 -------------------------------------------------------------------------
4611 Enable/Disable Indexes are only supported by HEAP and MyISAM.
4612
4613 Methods:
4614 disable_indexes()
4615 enable_indexes()
4616 indexes_are_disabled()
4617
4618 -------------------------------------------------------------------------
4619 MODULE append_create_info
4620 -------------------------------------------------------------------------
4621 Only used by MyISAM MERGE tables.
4622
4623 Methods:
4624 append_create_info()
4625
4626 -------------------------------------------------------------------------
4627 MODULE partitioning specific handler API
4628 -------------------------------------------------------------------------
4629 Methods:
4630 get_partition_handler()
4631*/
4632
4633class handler {
4634 friend class Partition_handler;
4635
4636 public:
4638 using Blob_context = void *;
4639
4640 protected:
4641 TABLE_SHARE *table_share; /* The table definition */
4642 TABLE *table; /* The current open table */
4643 Table_flags cached_table_flags{0}; /* Set on init() and open() */
4644
4646
4647 public:
4648 handlerton *ht; /* storage engine of this handler */
4649 /** Pointer to current row */
4651 /** Pointer to duplicate row */
4653
4655
4656 /* MultiRangeRead-related members: */
4657 range_seq_t mrr_iter; /* Iterator to traverse the range sequence */
4658 RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
4659 HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
4660 uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
4661 /* true <=> source MRR ranges and the output are ordered */
4663
4664 /* true <=> we're currently traversing a range in mrr_cur_range. */
4666 /* Current range (the one we're now returning rows from) */
4668
4669 /*
4670 The direction of the current range or index scan. This is used by
4671 the ICP implementation to determine if it has reached the end
4672 of the current range.
4673 */
4675
4676 private:
4677 Record_buffer *m_record_buffer = nullptr; ///< Buffer for multi-row reads.
4678 /*
4679 Storage space for the end range value. Should only be accessed using
4680 the end_range pointer. The content is invalid when end_range is NULL.
4681 */
4685
4686 /**
4687 Pointer to the handler of the table in the primary storage engine,
4688 if this handler represents a table in a secondary storage engine.
4689 */
4691
4692 protected:
4695 /*
4696 true <=> the engine guarantees that returned records are within the range
4697 being scanned.
4698 */
4700
4701 public:
4702 /**
4703 End value for a range scan. If this is NULL the range scan has no
4704 end value. Should also be NULL when there is no ongoing range scan.
4705 Used by the read_range() functions and also evaluated by pushed
4706 index conditions.
4707 */
4709 /**
4710 Flag which tells if #end_range contains a virtual generated column.
4711 The content is invalid when #end_range is @c nullptr.
4712 */
4714 uint errkey; /* Last dup key */
4717 /** Length of ref (1-8 or the clustered key length) */
4720 enum { NONE = 0, INDEX, RND, SAMPLING } inited;
4721 bool implicit_emptied; /* Can be !=0 only if HEAP */
4723
4725 uint pushed_idx_cond_keyno; /* The index which the above condition is for */
4726
4727 /**
4728 next_insert_id is the next value which should be inserted into the
4729 auto_increment column: in a inserting-multi-row statement (like INSERT
4730 SELECT), for the first row where the autoinc value is not specified by the
4731 statement, get_auto_increment() called and asked to generate a value,
4732 next_insert_id is set to the next value, then for all other rows
4733 next_insert_id is used (and increased each time) without calling
4734 get_auto_increment().
4735 */
4737 /**
4738 insert id for the current row (*autogenerated*; if not
4739 autogenerated, it's 0).
4740 At first successful insertion, this variable is stored into
4741 THD::first_successful_insert_id_in_cur_stmt.
4742 */
4744 /**
4745 Interval returned by get_auto_increment() and being consumed by the
4746 inserter.
4747 */
4749 /**
4750 Number of reserved auto-increment intervals. Serves as a heuristic
4751 when we have no estimation of how many records the statement will insert:
4752 the more intervals we have reserved, the bigger the next one. Reset in
4753 handler::ha_release_auto_increment().
4754 */
4756
4757 /**
4758 Instrumented table associated with this handler.
4759 */
4761
4762 std::mt19937 *m_random_number_engine{nullptr};
4764
4765 private:
4766 /** Internal state of the batch instrumentation. */
4768 /** Batch mode not used. */
4770 /** Batch mode used, before first table io. */
4772 /** Batch mode used, after first table io. */
4775 /**
4776 Batch mode state.
4777 @sa start_psi_batch_mode.
4778 @sa end_psi_batch_mode.
4779 */
4781 /**
4782 The number of rows in the batch.
4783 @sa start_psi_batch_mode.
4784 @sa end_psi_batch_mode.
4785 */
4787 /**
4788 The current event in a batch.
4789 @sa start_psi_batch_mode.
4790 @sa end_psi_batch_mode.
4791 */
4793 /**
4794 Storage for the event in a batch.
4795 @sa start_psi_batch_mode.
4796 @sa end_psi_batch_mode.
4797 */
4799
4800 public:
4801 void unbind_psi();
4802 void rebind_psi();
4803 /**
4804 Put the handler in 'batch' mode when collecting
4805 table io instrumented events.
4806 When operating in batch mode:
4807 - a single start event is generated in the performance schema.
4808 - all table io performed between @c start_psi_batch_mode
4809 and @c end_psi_batch_mode is not instrumented:
4810 the number of rows affected is counted instead in @c m_psi_numrows.
4811 - a single end event is generated in the performance schema
4812 when the batch mode ends with @c end_psi_batch_mode.
4813 */
4814 void start_psi_batch_mode();
4815 /** End a batch started with @c start_psi_batch_mode. */
4816 void end_psi_batch_mode();
4817 /**
4818 If a PSI batch was started, turn if off.
4819 @returns true if it was started.
4820 */
4822 const bool rc = m_psi_batch_mode;
4823 if (rc) end_psi_batch_mode();
4824 return rc;
4825 }
4826
4827 private:
4828 /**
4829 The lock type set by when calling::ha_external_lock(). This is
4830 propagated down to the storage engine. The reason for also storing
4831 it here, is that when doing MRR we need to create/clone a second handler
4832 object. This cloned handler object needs to know about the lock_type used.
4833 */
4835 /**
4836 Pointer where to store/retrieve the Handler_share pointer.
4837 For non partitioned handlers this is &TABLE_SHARE::ha_share.
4838 */
4840
4841 /**
4842 Some non-virtual ha_* functions, responsible for reading rows,
4843 like ha_rnd_pos(), must ensure that virtual generated columns are
4844 calculated before they return. For that, they should set this
4845 member to true at their start, and check it before they return: if
4846 the member is still true, it means they should calculate; if it's
4847 false, it means the calculation has been done by some called
4848 lower-level function and does not need to be re-done (which is why
4849 we need this status flag: to avoid redundant calculations, for
4850 performance).
4851
4852 Note that when updating generated fields, the NULL row status in
4853 the underlying TABLE objects matter, so be sure to reset them if needed!
4854 */
4856
4857 /* Filter row ids to weed out duplicates when multi-valued index is used */
4859
4860 public:
4861 handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
4862 : table_share(share_arg),
4863 table(nullptr),
4865 ht(ht_arg),
4866 ref(nullptr),
4872 ref_length(sizeof(my_off_t)),
4874 inited(NONE),
4875 implicit_emptied(false),
4879 next_insert_id(0),
4882 m_psi(nullptr),
4884 m_psi_numrows(0),
4886 m_lock_type(F_UNLCK),
4889 m_unique(nullptr) {
4890 DBUG_PRINT("info", ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
4891 F_UNLCK, F_RDLCK, F_WRLCK));
4892 }
4893
4894 virtual ~handler(void) {
4895 assert(m_psi == nullptr);
4897 assert(m_psi_locker == nullptr);
4898 assert(m_lock_type == F_UNLCK);
4899 assert(inited == NONE);
4900 }
4901
4902 /**
4903 Return extra handler specific text for EXPLAIN.
4904 */
4905 virtual std::string explain_extra() const { return ""; }
4906
4907 /*
4908 @todo reorganize functions, make proper public/protected/private qualifiers
4909 */
4910 virtual handler *clone(const char *name, MEM_ROOT *mem_root);
4911 /** This is called after create to allow us to set up cached variables */
4913 /* ha_ methods: public wrappers for private virtual API */
4914
4915 /**
4916 Set a record buffer that the storage engine can use for multi-row reads.
4917 The buffer has to be provided prior to the first read from an index or a
4918 table.
4919
4920 @param buffer the buffer to use for multi-row reads
4921 */
4923
4924 /**
4925 Get the record buffer that was set with ha_set_record_buffer().
4926
4927 @return the buffer to use for multi-row reads, or nullptr if there is none
4928 */
4930
4931 /**
4932 Does this handler want to get a Record_buffer for multi-row reads
4933 via the ha_set_record_buffer() function? And if so, what is the
4934 maximum number of records to allocate space for in the buffer?
4935
4936 Storage engines that support using a Record_buffer should override
4937 handler::is_record_buffer_wanted().
4938
4939 @param[out] max_rows gets set to the maximum number of records to
4940 allocate space for in the buffer if the function
4941 returns true
4942
4943 @retval true if the handler would like a Record_buffer
4944 @retval false if the handler does not want a Record_buffer
4945 */
4946 bool ha_is_record_buffer_wanted(ha_rows *const max_rows) const {
4947 return is_record_buffer_wanted(max_rows);
4948 }
4949
4950 int ha_open(TABLE *table, const char *name, int mode, int test_if_locked,
4951 const dd::Table *table_def);
4952 int ha_close(void);
4953 int ha_index_init(uint idx, bool sorted);
4954 int ha_index_end();
4955 int ha_rnd_init(bool scan);
4956 int ha_rnd_end();
4957 int ha_rnd_next(uchar *buf);
4958 // See the comment on m_update_generated_read_fields.
4959 int ha_rnd_pos(uchar *buf, uchar *pos);
4960 int ha_index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map,
4961 enum ha_rkey_function find_flag);
4963 key_part_map keypart_map);
4964 int ha_index_read_idx_map(uchar *buf, uint index, const uchar *key,
4965 key_part_map keypart_map,
4966 enum ha_rkey_function find_flag);
4967 int ha_index_next(uchar *buf);
4968 int ha_index_prev(uchar *buf);
4969 int ha_index_first(uchar *buf);
4970 int ha_index_last(uchar *buf);
4971 int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
4972 int ha_reset();
4973 /* this is necessary in many places, e.g. in HANDLER command */
4975 return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
4976 }
4977 /**
4978 The cached_table_flags is set at ha_open and ha_external_lock
4979 */
4981 /**
4982 These functions represent the public interface to *users* of the
4983 handler class, hence they are *not* virtual. For the inheritance
4984 interface, see the (private) functions write_row(), update_row(),
4985 and delete_row() below.
4986 */
4987 int ha_external_lock(THD *thd, int lock_type);
4988 int ha_write_row(uchar *buf);
4989 /**
4990 Update the current row.
4991
4992 @param old_data the old contents of the row
4993 @param new_data the new contents of the row
4994 @return error status (zero on success, HA_ERR_* error code on error)
4995 */
4996 int ha_update_row(const uchar *old_data, uchar *new_data);
4997 int ha_delete_row(const uchar *buf);
4999
5000 int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
5001 /** to be actually called to get 'check()' functionality*/
5002 int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
5003 int ha_repair(THD *thd, HA_CHECK_OPT *check_opt);
5004 void ha_start_bulk_insert(ha_rows rows);
5005 int ha_end_bulk_insert();
5006 int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
5007 uint *dup_key_found);
5008 int ha_delete_all_rows();
5010 int ha_optimize(THD *thd, HA_CHECK_OPT *check_opt);
5011 int ha_analyze(THD *thd, HA_CHECK_OPT *check_opt);
5012 bool ha_check_and_repair(THD *thd);
5013 int ha_disable_indexes(uint mode);
5014 int ha_enable_indexes(uint mode);
5016 int ha_rename_table(const char *from, const char *to,
5017 const dd::Table *from_table_def, dd::Table *to_table_def);
5018 int ha_delete_table(const char *name, const dd::Table *table_def);
5019 void ha_drop_table(const char *name);
5020
5021 int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info,
5023
5024 int ha_load_table(const TABLE &table, bool *skip_metadata_update);
5025
5026 int ha_unload_table(const char *db_name, const char *table_name,
5027 bool error_if_not_loaded);
5028
5029 /**
5030 Initializes a parallel scan. It creates a parallel_scan_ctx that has to
5031 be used across all parallel_scan methods. Also, gets the number of
5032 threads that would be spawned for parallel scan.
5033 @param[out] scan_ctx The parallel scan context.
5034 @param[out] num_threads Number of threads used for the scan.
5035 @param[in] use_reserved_threads true if reserved threads are to be used
5036 if we exhaust the max cap of number of
5037 parallel read threads that can be
5038 spawned at a time
5039 @param[in] max_desired_threads Maximum number of desired scan threads;
5040 passing 0 has no effect, it is