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