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