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