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 "my_global.h"
31 #include "ft_global.h" // ft_hints
32 #include "my_thread_local.h" // my_errno
33 #include "thr_lock.h" // thr_lock_type
34 #include "discrete_interval.h" // Discrete_interval
35 #include "key.h" // KEY
36 #include "mysqld.h" // lower_case_table_names
37 #include "sql_const.h" // SHOW_COMP_OPTION
38 #include "sql_list.h" // SQL_I_List
39 #include "sql_plugin_ref.h" // plugin_ref
40
41 #include "mysql/psi/psi.h"
42
43 #include <algorithm>
44 #include <string>
45
46 class Alter_info;
47 class SE_cost_constants; // see opt_costconstants.h
48 class String;
49 struct TABLE_LIST;
50 typedef struct st_bitmap MY_BITMAP;
51 typedef struct st_hash HASH;
52 typedef struct st_key_cache KEY_CACHE;
53 typedef struct xid_t XID;
54 class partition_info;
55 class Partition_handler;
56 typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
57 uint key_length,
58 ulonglong *engine_data);
59
60
61 // the following is for checking tables
62
63 #define HA_ADMIN_ALREADY_DONE 1
64 #define HA_ADMIN_OK 0
65 #define HA_ADMIN_NOT_IMPLEMENTED -1
66 #define HA_ADMIN_FAILED -2
67 #define HA_ADMIN_CORRUPT -3
68 #define HA_ADMIN_INTERNAL_ERROR -4
69 #define HA_ADMIN_INVALID -5
70 #define HA_ADMIN_REJECT -6
71 #define HA_ADMIN_TRY_ALTER -7
72 #define HA_ADMIN_WRONG_CHECKSUM -8
73 #define HA_ADMIN_NOT_BASE_TABLE -9
74 #define HA_ADMIN_NEEDS_UPGRADE -10
75 #define HA_ADMIN_NEEDS_ALTER -11
76 #define HA_ADMIN_NEEDS_CHECK -12
77 /** Needs ALTER TABLE t UPGRADE PARTITIONING. */
78 #define HA_ADMIN_NEEDS_UPG_PART -13
79 /** Needs to dump and re-create to fix pre 5.0 decimal types */
80 #define HA_ADMIN_NEEDS_DUMP_UPGRADE -14
81
82 /**
83 Return values for check_if_supported_inplace_alter().
84
85 @see check_if_supported_inplace_alter() for description of
86 the individual values.
87 */
88 enum enum_alter_inplace_result {
89 HA_ALTER_ERROR,
90 HA_ALTER_INPLACE_NOT_SUPPORTED,
91 HA_ALTER_INPLACE_EXCLUSIVE_LOCK,
92 HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE,
93 HA_ALTER_INPLACE_SHARED_LOCK,
94 HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE,
95 HA_ALTER_INPLACE_NO_LOCK
96 };
97
98 /* Bits in table_flags() to show what database can do */
99
100 #define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */
101 #define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */
102 #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */
103 /*
104 The following should be set if the following is not true when scanning
105 a table with rnd_next()
106 - We will see all rows (including deleted ones)
107 - Row positions are 'table->s->db_record_offset' apart
108 If this flag is not set, filesort will do a position() call for each matched
109 row to be able to find the row later.
110 */
111 #define HA_REC_NOT_IN_SEQ (1 << 3)
112 #define HA_CAN_GEOMETRY (1 << 4)
113 /*
114 Reading keys in random order is as fast as reading keys in sort order
115 (Used in records.cc to decide if we should use a record cache and by
116 filesort to decide if we should sort key + data or key + pointer-to-row
117 */
118 #define HA_FAST_KEY_READ (1 << 5)
119 /*
120 Set the following flag if we on delete should force all key to be read
121 and on update read all keys that changes
122 */
123 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6)
124 #define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */
125 #define HA_DUPLICATE_POS (1 << 8) /* position() gives dup row */
126 #define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */
127 #define HA_CAN_INDEX_BLOBS (1 << 10)
128 #define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */
129 #define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */
130 #define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */
131 /// Not in use.
132 #define HA_UNUSED (1 << 14)
133 /*
134 If we get the primary key columns for free when we do an index read
135 (usually, it also implies that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
136 flag is set).
137 */
138 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15)
139 /*
140 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
141 uses a primary key given by the record argument.
142 Without primary key, we can't call position().
143 If not set, the position is returned as the current rows position
144 regardless of what argument is given.
145 */
146 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16)
147 #define HA_CAN_RTREEKEYS (1 << 17)
148 #define HA_NOT_DELETE_WITH_CACHE (1 << 18)
149 /*
150 The following is we need to a primary key to delete (and update) a row.
151 If there is no primary key, all columns needs to be read on update and delete
152 */
153 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19)
154 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20)
155 #define HA_CAN_FULLTEXT (1 << 21)
156 #define HA_CAN_SQL_HANDLER (1 << 22)
157 #define HA_NO_AUTO_INCREMENT (1 << 23)
158 #define HA_HAS_CHECKSUM (1 << 24)
159 /* Table data are stored in separate files (for lower_case_table_names) */
160 #define HA_FILE_BASED (1 << 26)
161 #define HA_NO_VARCHAR (1 << 27)
162 #define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */
163 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30)
164 #define HA_NO_COPY_ON_ALTER (1LL << 31)
165 #define HA_HAS_RECORDS (1LL << 32) /* records() gives exact count*/
166 /* Has it's own method of binlog logging */
167 #define HA_HAS_OWN_BINLOGGING (1LL << 33)
168 /*
169 Engine is capable of row-format and statement-format logging,
170 respectively
171 */
172 #define HA_BINLOG_ROW_CAPABLE (1LL << 34)
173 #define HA_BINLOG_STMT_CAPABLE (1LL << 35)
174 /*
175 When a multiple key conflict happens in a REPLACE command mysql
176 expects the conflicts to be reported in the ascending order of
177 key names.
178
179 For e.g.
180
181 CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
182 NULL, INDEX(c));
183
184 REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
185
186 MySQL expects the conflict with 'a' to be reported before the conflict with
187 'b'.
188
189 If the underlying storage engine does not report the conflicting keys in
190 ascending order, it causes unexpected errors when the REPLACE command is
191 executed.
192
193 This flag helps the underlying SE to inform the server that the keys are not
194 ordered.
195 */
196 #define HA_DUPLICATE_KEY_NOT_IN_ORDER (1LL << 36)
197 /*
198 Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
199 incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
200 will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
201 */
202 #define HA_CAN_REPAIR (1LL << 37)
203
204 /*
205 Set of all binlog flags. Currently only contain the capabilities
206 flags.
207 */
208 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
209
210 /**
211 The handler supports read before write removal optimization
212
213 Read before write removal may be used for storage engines which support
214 write without previous read of the row to be updated. Handler returning
215 this flag must implement start_read_removal() and end_read_removal().
216 The handler may return "fake" rows constructed from the key of the row
217 asked for. This is used to optimize UPDATE and DELETE by reducing the
218 numer of roundtrips between handler and storage engine.
219
220 Example:
221 UPDATE a=1 WHERE pk IN (<keys>)
222
223 mysql_update()
224 {
225 if (<conditions for starting read removal>)
226 start_read_removal()
227 -> handler returns true if read removal supported for this table/query
228
229 while(read_record("pk=<key>"))
230 -> handler returns fake row with column "pk" set to <key>
231
232 ha_update_row()
233 -> handler sends write "a=1" for row with "pk=<key>"
234
235 end_read_removal()
236 -> handler returns the number of rows actually written
237 }
238
239 @note This optimization in combination with batching may be used to
240 remove even more roundtrips.
241 */
242 #define HA_READ_BEFORE_WRITE_REMOVAL (1LL << 38)
243
244 /*
245 Engine supports extended fulltext API
246 */
247 #define HA_CAN_FULLTEXT_EXT (1LL << 39)
248
249 /*
250 Storage engine doesn't synchronize result set with expected table contents.
251 Used by replication slave to check if it is possible to retrieve rows from
252 the table when deciding whether to do a full table scan, index scan or hash
253 scan while applying a row event.
254 */
255 #define HA_READ_OUT_OF_SYNC (1LL << 40)
256
257 /*
258 Storage engine supports table export using the
259 FLUSH TABLE <table_list> FOR EXPORT statement.
260 */
261 #define HA_CAN_EXPORT (1LL << 41)
262
263 /*
264 The handler don't want accesses to this table to
265 be const-table optimized
266 */
267 #define HA_BLOCK_CONST_TABLE (1LL << 42)
268
269 /*
270 Handler supports FULLTEXT hints
271 */
272 #define HA_CAN_FULLTEXT_HINTS (1LL << 43)
273
274 /**
275 Storage engine doesn't support LOCK TABLE ... READ LOCAL locks
276 but doesn't want to use handler::store_lock() API for upgrading
277 them to LOCK TABLE ... READ locks, for example, because it doesn't
278 use THR_LOCK locks at all.
279 */
280 #define HA_NO_READ_LOCAL_LOCK (1LL << 44)
281
282 /**
283 A storage engine is compatible with the attachable transaction requirements
284 means that
285
286 - either SE detects the fact that THD::ha_data was reset and starts a new
287 attachable transaction, closes attachable transaction on close_connection
288 and resumes regular (outer) transaction when THD::ha_data is restored;
289
290 - or SE completely ignores THD::ha_data and close_connection like MyISAM
291 does.
292 */
293 #define HA_ATTACHABLE_TRX_COMPATIBLE (1LL << 45)
294
295 /**
296 Handler supports Generated Columns
297 */
298 #define HA_GENERATED_COLUMNS (1LL << 46)
299
300 /**
301 Supports index on virtual generated column
302 */
303 #define HA_CAN_INDEX_VIRTUAL_GENERATED_COLUMN (1LL << 47)
304
305 /**
306 There is no need to evict the table from the table definition cache having
307 run ANALYZE TABLE on it
308 */
309 #define HA_ONLINE_ANALYZE (1LL << 48)
310
311 /* bits in index_flags(index_number) for what you can do with index */
312 #define HA_READ_NEXT 1 /* TODO really use this flag */
313 #define HA_READ_PREV 2 /* supports ::index_prev */
314 #define HA_READ_ORDER 4 /* index_next/prev follow sort order */
315 #define HA_READ_RANGE 8 /* can find all records in a range */
316 #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
317 #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
318 /*
319 Index scan will not return records in rowid order. Not guaranteed to be
320 set for unordered (e.g. HASH) indexes.
321 */
322 #define HA_KEY_SCAN_NOT_ROR 128
323 #define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */
324 #define HA_CLUSTERED_INDEX 512 /* Data is clustered on this key */
325
326 /* operations for disable/enable indexes */
327 #define HA_KEY_SWITCH_NONUNIQ 0
328 #define HA_KEY_SWITCH_ALL 1
329 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
330 #define HA_KEY_SWITCH_ALL_SAVE 3
331
332 /*
333 Note: the following includes binlog and closing 0.
334 so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive +
335 example + csv + heap + blackhole + federated + 0
336 (yes, the sum is deliberately inaccurate)
337 TODO remove the limit, use dynarrays
338 */
339 #define MAX_HA 15
340
341 /*
342 Use this instead of 0 as the initial value for the slot number of
343 handlerton, so that we can distinguish uninitialized slot number
344 from slot 0.
345 */
346 #define HA_SLOT_UNDEF ((uint)-1)
347
348 /*
349 Parameters for open() (in register form->filestat)
350 HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
351 */
352
353 #define HA_OPEN_KEYFILE 1
354 #define HA_OPEN_RNDFILE 2
355 #define HA_GET_INDEX 4
356 #define HA_GET_INFO 8 /* do a handler::info() after open */
357 #define HA_READ_ONLY 16 /* File opened as readonly */
358 /* Try readonly if can't open with read and write */
359 #define HA_TRY_READ_ONLY 32
360 #define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */
361 #define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/
362 #define HA_BLOCK_LOCK 256 /* unlock when reading some records */
363 #define HA_OPEN_TEMPORARY 512
364
365 /* Some key definitions */
366 #define HA_KEY_NULL_LENGTH 1
367 #define HA_KEY_BLOB_LENGTH 2
368
369 #define HA_LEX_CREATE_TMP_TABLE 1
370 #define HA_LEX_CREATE_IF_NOT_EXISTS 2
371 #define HA_LEX_CREATE_TABLE_LIKE 4
372 #define HA_LEX_CREATE_INTERNAL_TMP_TABLE 8
373 #define HA_OPTION_NO_CHECKSUM (1L << 17)
374 #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
375 #define HA_MAX_REC_LENGTH 65535U
376
377 /* Table caching type */
378 #define HA_CACHE_TBL_NONTRANSACT 0
379 #define HA_CACHE_TBL_NOCACHE 1
380 #define HA_CACHE_TBL_ASKTRANSACT 2
381 #define HA_CACHE_TBL_TRANSACT 4
382
383 /**
384 Options for the START TRANSACTION statement.
385
386 Note that READ ONLY and READ WRITE are logically mutually exclusive.
387 This is enforced by the parser and depended upon by trans_begin().
388
389 We need two flags instead of one in order to differentiate between
390 situation when no READ WRITE/ONLY clause were given and thus transaction
391 is implicitly READ WRITE and the case when READ WRITE clause was used
392 explicitly.
393 */
394
395 // WITH CONSISTENT SNAPSHOT option
396 static const uint MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT = 1;
397 // READ ONLY option
398 static const uint MYSQL_START_TRANS_OPT_READ_ONLY = 2;
399 // READ WRITE option
400 static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4;
401 // HIGH PRIORITY option
402 static const uint MYSQL_START_TRANS_OPT_HIGH_PRIORITY = 8;
403
404 enum legacy_db_type
405 {
406 DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
407 DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
408 DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
409 DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
410 DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
411 DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
412 DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
413 DB_TYPE_FEDERATED_DB,
414 DB_TYPE_BLACKHOLE_DB,
415 DB_TYPE_PARTITION_DB,
416 DB_TYPE_BINLOG,
417 DB_TYPE_SOLID,
418 DB_TYPE_PBXT,
419 DB_TYPE_TABLE_FUNCTION,
420 DB_TYPE_MEMCACHE,
421 DB_TYPE_FALCON,
422 DB_TYPE_MARIA,
423 /** Performance schema engine. */
424 DB_TYPE_PERFORMANCE_SCHEMA,
425 DB_TYPE_TOKUDB=41,
426 DB_TYPE_ROCKSDB=42,
427 DB_TYPE_FIRST_DYNAMIC=43,
428 DB_TYPE_DEFAULT=127 // Must be last
429 };
430
431 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
432 ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
433 ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT,
434 /** Unused. Reserved for future versions. */
435 ROW_TYPE_PAGE,
436 ROW_TYPE_TOKU_UNCOMPRESSED, ROW_TYPE_TOKU_ZLIB,
437 ROW_TYPE_TOKU_SNAPPY, ROW_TYPE_TOKU_QUICKLZ,
438 ROW_TYPE_TOKU_LZMA, ROW_TYPE_TOKU_FAST, ROW_TYPE_TOKU_SMALL,
439 ROW_TYPE_TOKU_DEFAULT };
440
441 /* Specifies data storage format for individual columns */
442 enum column_format_type {
443 COLUMN_FORMAT_TYPE_DEFAULT= 0, /* Not specified (use engine default) */
444 COLUMN_FORMAT_TYPE_FIXED= 1, /* FIXED format */
445 COLUMN_FORMAT_TYPE_DYNAMIC= 2, /* DYNAMIC format */
446 COLUMN_FORMAT_TYPE_COMPRESSED= 3 /* COMPRESSED format*/
447 };
448
449 enum enum_binlog_func {
450 BFN_RESET_LOGS= 1,
451 BFN_RESET_SLAVE= 2,
452 BFN_BINLOG_WAIT= 3,
453 BFN_BINLOG_END= 4,
454 BFN_BINLOG_PURGE_FILE= 5
455 };
456
457 enum enum_binlog_command {
458 LOGCOM_CREATE_TABLE,
459 LOGCOM_ALTER_TABLE,
460 LOGCOM_RENAME_TABLE,
461 LOGCOM_DROP_TABLE,
462 LOGCOM_CREATE_DB,
463 LOGCOM_ALTER_DB,
464 LOGCOM_DROP_DB,
465 LOGCOM_ACL_NOTIFY
466 };
467
468 /* struct to hold information about the table that should be created */
469
470 /* Bits in used_fields */
471 #define HA_CREATE_USED_AUTO (1L << 0)
472 #define HA_CREATE_USED_RAID (1L << 1) //RAID is no longer availble
473 #define HA_CREATE_USED_UNION (1L << 2)
474 #define HA_CREATE_USED_INSERT_METHOD (1L << 3)
475 #define HA_CREATE_USED_MIN_ROWS (1L << 4)
476 #define HA_CREATE_USED_MAX_ROWS (1L << 5)
477 #define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
478 #define HA_CREATE_USED_PACK_KEYS (1L << 7)
479 #define HA_CREATE_USED_CHARSET (1L << 8)
480 #define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
481 #define HA_CREATE_USED_DATADIR (1L << 10)
482 #define HA_CREATE_USED_INDEXDIR (1L << 11)
483 #define HA_CREATE_USED_ENGINE (1L << 12)
484 #define HA_CREATE_USED_CHECKSUM (1L << 13)
485 #define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
486 #define HA_CREATE_USED_ROW_FORMAT (1L << 15)
487 #define HA_CREATE_USED_COMMENT (1L << 16)
488 #define HA_CREATE_USED_PASSWORD (1L << 17)
489 #define HA_CREATE_USED_CONNECTION (1L << 18)
490 #define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
491 /** Unused. Reserved for future versions. */
492 #define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
493 /** Unused. Reserved for future versions. */
494 #define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
495 /** This is set whenever STATS_PERSISTENT=0|1|default has been
496 specified in CREATE/ALTER TABLE. See also HA_OPTION_STATS_PERSISTENT in
497 include/my_base.h. It is possible to distinguish whether
498 STATS_PERSISTENT=default has been specified or no STATS_PERSISTENT= is
499 given at all. */
500 #define HA_CREATE_USED_STATS_PERSISTENT (1L << 22)
501 /**
502 This is set whenever STATS_AUTO_RECALC=0|1|default has been
503 specified in CREATE/ALTER TABLE. See enum_stats_auto_recalc.
504 It is possible to distinguish whether STATS_AUTO_RECALC=default
505 has been specified or no STATS_AUTO_RECALC= is given at all.
506 */
507 #define HA_CREATE_USED_STATS_AUTO_RECALC (1L << 23)
508 /**
509 This is set whenever STATS_SAMPLE_PAGES=N|default has been
510 specified in CREATE/ALTER TABLE. It is possible to distinguish whether
511 STATS_SAMPLE_PAGES=default has been specified or no STATS_SAMPLE_PAGES= is
512 given at all.
513 */
514 #define HA_CREATE_USED_STATS_SAMPLE_PAGES (1L << 24)
515
516 /**
517 This is set whenever a 'TABLESPACE=...' phrase is used on CREATE TABLE
518 */
519 #define HA_CREATE_USED_TABLESPACE (1L << 25)
520
521 /** COMPRESSION="zlib|lz4|none" used during table create. */
522 #define HA_CREATE_USED_COMPRESS (1L << 26)
523
524 /*
525 This is master database for most of system tables. However there
526 can be other databases which can hold system tables. Respective
527 storage engines define their own system database names.
528 */
529 extern const char *mysqld_system_database;
530
531 /*
532 Structure to hold list of database_name.table_name.
533 This is used at both mysqld and storage engine layer.
534 */
535 struct st_handler_tablename
536 {
537 const char *db;
538 const char *tablename;
539 };
540
541 #define MAXGTRIDSIZE 64
542 #define MAXBQUALSIZE 64
543
544 #define COMPATIBLE_DATA_YES 0
545 #define COMPATIBLE_DATA_NO 1
546
547 namespace AQP {
548 class Join_plan;
549 };
550
551 /** ENCRYPTION="Y" used during table create. */
552 #define HA_CREATE_USED_ENCRYPT (1L << 27)
553
554 #define HA_CREATE_USED_ENCRYPTION_KEY_ID (1L << 28)
555
556 /*
557 These structures are used to pass information from a set of SQL commands
558 on add/drop/change tablespace definitions to the proper hton.
559 */
560 #define UNDEF_NODEGROUP 65535
561 enum ts_command_type
562 {
563 TS_CMD_NOT_DEFINED = -1,
564 CREATE_TABLESPACE = 0,
565 ALTER_TABLESPACE = 1,
566 CREATE_LOGFILE_GROUP = 2,
567 ALTER_LOGFILE_GROUP = 3,
568 DROP_TABLESPACE = 4,
569 DROP_LOGFILE_GROUP = 5,
570 CHANGE_FILE_TABLESPACE = 6,
571 ALTER_ACCESS_MODE_TABLESPACE = 7
572 };
573
574 enum ts_alter_tablespace_type
575 {
576 TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
577 ALTER_TABLESPACE_ADD_FILE = 1,
578 ALTER_TABLESPACE_DROP_FILE = 2
579 };
580
581 enum tablespace_access_mode
582 {
583 TS_NOT_DEFINED= -1,
584 TS_READ_ONLY = 0,
585 TS_READ_WRITE = 1,
586 TS_NOT_ACCESSIBLE = 2
587 };
588
589 struct handlerton;
590 class st_alter_tablespace : public Sql_alloc
591 {
592 public:
593 const char *tablespace_name;
594 const char *logfile_group_name;
595 enum ts_command_type ts_cmd_type;
596 enum ts_alter_tablespace_type ts_alter_tablespace_type;
597 const char *data_file_name;
598 const char *undo_file_name;
599 const char *redo_file_name;
600 ulonglong extent_size;
601 ulonglong undo_buffer_size;
602 ulonglong redo_buffer_size;
603 ulonglong initial_size;
604 ulonglong autoextend_size;
605 ulonglong max_size;
606 ulonglong file_block_size;
607 uint nodegroup_id;
608 handlerton *storage_engine;
609 bool wait_until_completed;
610 const char *ts_comment;
611 enum tablespace_access_mode ts_access_mode;
612 bool encrypt;
613 LEX_STRING encrypt_type;
is_tablespace_command()614 bool is_tablespace_command()
615 {
616 return ts_cmd_type == CREATE_TABLESPACE ||
617 ts_cmd_type == ALTER_TABLESPACE ||
618 ts_cmd_type == DROP_TABLESPACE ||
619 ts_cmd_type == CHANGE_FILE_TABLESPACE ||
620 ts_cmd_type == ALTER_ACCESS_MODE_TABLESPACE;
621 }
622
623 /** Default constructor */
st_alter_tablespace()624 st_alter_tablespace()
625 {
626 tablespace_name= NULL;
627 logfile_group_name= "DEFAULT_LG"; //Default log file group
628 ts_cmd_type= TS_CMD_NOT_DEFINED;
629 data_file_name= NULL;
630 undo_file_name= NULL;
631 redo_file_name= NULL;
632 extent_size= 1024*1024; // Default 1 MByte
633 undo_buffer_size= 8*1024*1024; // Default 8 MByte
634 redo_buffer_size= 8*1024*1024; // Default 8 MByte
635 initial_size= 128*1024*1024; // Default 128 MByte
636 autoextend_size= 0; // No autoextension as default
637 max_size= 0; // Max size == initial size => no extension
638 storage_engine= NULL;
639 file_block_size= 0; // 0=default or must be a valid Page Size
640 nodegroup_id= UNDEF_NODEGROUP;
641 wait_until_completed= TRUE;
642 ts_comment= NULL;
643 ts_access_mode= TS_NOT_DEFINED;
644 encrypt= false;
645 encrypt_type = LEX_STRING();
646 }
647 };
648
649 /* The handler for a table type. Will be included in the TABLE structure */
650
651 struct TABLE;
652
653 /*
654 Make sure that the order of schema_tables and enum_schema_tables are the same.
655 */
656 enum enum_schema_tables
657 {
658 SCH_CHARSETS= 0,
659 SCH_CLIENT_STATS,
660 SCH_COLLATIONS,
661 SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
662 SCH_COLUMNS,
663 SCH_COLUMN_PRIVILEGES,
664 SCH_INDEX_STATS,
665 SCH_ENGINES,
666 SCH_EVENTS,
667 SCH_FILES,
668 SCH_GLOBAL_STATUS,
669 SCH_GLOBAL_TEMPORARY_TABLES,
670 SCH_GLOBAL_VARIABLES,
671 SCH_KEY_COLUMN_USAGE,
672 SCH_OPEN_TABLES,
673 SCH_OPTIMIZER_TRACE,
674 SCH_PARAMETERS,
675 SCH_PARTITIONS,
676 SCH_PLUGINS,
677 SCH_PROCESSLIST,
678 SCH_PROFILES,
679 SCH_REFERENTIAL_CONSTRAINTS,
680 SCH_PROCEDURES,
681 SCH_SCHEMATA,
682 SCH_SCHEMA_PRIVILEGES,
683 SCH_SESSION_STATUS,
684 SCH_SESSION_VARIABLES,
685 SCH_STATISTICS,
686 SCH_STATUS,
687 SCH_TABLES,
688 SCH_TABLESPACES,
689 SCH_TABLE_CONSTRAINTS,
690 SCH_TABLE_NAMES,
691 SCH_TABLE_PRIVILEGES,
692 SCH_TABLE_STATS,
693 SCH_TEMPORARY_TABLES,
694 SCH_THREAD_STATS,
695 SCH_TRIGGERS,
696 SCH_USER_PRIVILEGES,
697 SCH_USER_STATS,
698 SCH_VARIABLES,
699 SCH_VIEWS
700 };
701
702 struct TABLE_SHARE;
703 struct st_foreign_key_info;
704 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
705 typedef bool (stat_print_fn)(THD *thd, const char *type, size_t type_len,
706 const char *file, size_t file_len,
707 const char *status, size_t status_len);
708 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
709 enum ha_notification_type { HA_NOTIFY_PRE_EVENT, HA_NOTIFY_POST_EVENT };
710
711 extern st_plugin_int *hton2plugin[MAX_HA];
712
713 /** Create compression dictionary result type. */
714 enum handler_create_zip_dict_result
715 {
716 HA_CREATE_ZIP_DICT_OK, /*!< zip_dict successfully created */
717 HA_CREATE_ZIP_DICT_ALREADY_EXISTS, /*!< zip dict with such name already
718 exists */
719 HA_CREATE_ZIP_DICT_NAME_TOO_LONG, /*!< zip dict name is too long */
720 HA_CREATE_ZIP_DICT_DATA_TOO_LONG, /*!< zip dict data is too long */
721 HA_CREATE_ZIP_DICT_READ_ONLY, /*!< cannot create in read-only mode */
722 HA_CREATE_ZIP_DICT_OUT_OF_MEMORY, /*!< out of memory */
723 HA_CREATE_ZIP_DICT_OUT_OF_FILE_SPACE,
724 /*!< out of disk space */
725 HA_CREATE_ZIP_DICT_TOO_MANY_CONCURRENT_TRXS,
726 /*!< too many concurrent transactions */
727 HA_CREATE_ZIP_DICT_UNKNOWN_ERROR /*!< unknown error during zip_dict
728 creation */
729 };
730
731 /** Drop compression dictionary result type. */
732 enum handler_drop_zip_dict_result
733 {
734 HA_DROP_ZIP_DICT_OK, /*!< zip_dict successfully dropped */
735 HA_DROP_ZIP_DICT_DOES_NOT_EXIST, /*!< zip dict with such name does not
736 exist */
737 HA_DROP_ZIP_DICT_IS_REFERENCED, /*!< zip dict is in use */
738 HA_DROP_ZIP_DICT_READ_ONLY, /*!< cannot drop in read-only mode */
739 HA_DROP_ZIP_DICT_OUT_OF_MEMORY, /*!< out of memory */
740 HA_DROP_ZIP_DICT_OUT_OF_FILE_SPACE,
741 /*!< out of disk space */
742 HA_DROP_ZIP_DICT_TOO_MANY_CONCURRENT_TRXS,
743 /*!< too many concurrent transactions */
744 HA_DROP_ZIP_DICT_UNKNOWN_ERROR /*!< unknown error during zip_dict
745 removal */
746 };
747
748 class handler;
749 /*
750 handlerton is a singleton structure - one instance per storage engine -
751 to provide access to storage engine functionality that works on the
752 "global" level (unlike handler class that works on a per-table basis)
753
754 usually handlerton instance is defined statically in ha_xxx.cc as
755
756 static handlerton { ... } xxx_hton;
757
758 savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
759 */
760 struct handlerton
761 {
762 /*
763 Historical marker for if the engine is available of not
764 */
765 SHOW_COMP_OPTION state;
766
767 /*
768 Historical number used for frm file to determine the correct storage engine.
769 This is going away and new engines will just use "name" for this.
770 */
771 enum legacy_db_type db_type;
772 /*
773 each storage engine has it's own memory area (actually a pointer)
774 in the thd, for storing per-connection information.
775 It is accessed as
776
777 thd->ha_data[xxx_hton.slot]
778
779 slot number is initialized by MySQL after xxx_init() is called.
780 */
781 uint slot;
782 /*
783 to store per-savepoint data storage engine is provided with an area
784 of a requested size (0 is ok here).
785 savepoint_offset must be initialized statically to the size of
786 the needed memory to store per-savepoint information.
787 After xxx_init it is changed to be an offset to savepoint storage
788 area and need not be used by storage engine.
789 see binlog_hton and binlog_savepoint_set/rollback for an example.
790 */
791 uint savepoint_offset;
792 /*
793 handlerton methods:
794
795 close_connection is only called if
796 thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
797 this storage area - set it to something, so that MySQL would know
798 this storage engine was accessed in this connection
799 */
800 int (*close_connection)(handlerton *hton, THD *thd);
801 /* Terminate connection/statement notification. */
802 void (*kill_connection)(handlerton *hton, THD *thd);
803 /*
804 sv points to an uninitialized storage area of requested size
805 (see savepoint_offset description)
806 */
807 int (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
808 /*
809 sv points to a storage area, that was earlier passed
810 to the savepoint_set call
811 */
812 int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
813 /**
814 Check if storage engine allows to release metadata locks which were
815 acquired after the savepoint if rollback to savepoint is done.
816 @return true - If it is safe to release MDL locks.
817 false - If it is not.
818 */
819 bool (*savepoint_rollback_can_release_mdl)(handlerton *hton, THD *thd);
820 int (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
821 /*
822 'all' is true if it's a real commit, that makes persistent changes
823 'all' is false if it's not in fact a commit but an end of the
824 statement that is part of the transaction.
825 NOTE 'all' is also false in auto-commit mode where 'end of statement'
826 and 'real commit' mean the same event.
827 */
828 int (*commit)(handlerton *hton, THD *thd, bool all);
829 int (*rollback)(handlerton *hton, THD *thd, bool all);
830 int (*prepare)(handlerton *hton, THD *thd, bool all);
831 int (*recover)(handlerton *hton, XID *xid_list, uint len);
832 int (*commit_by_xid)(handlerton *hton, XID *xid);
833 int (*rollback_by_xid)(handlerton *hton, XID *xid);
834 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
835 void (*drop_database)(handlerton *hton, char* path);
836 int (*panic)(handlerton *hton, enum ha_panic_function flag);
837 int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
838 int (*clone_consistent_snapshot)(handlerton *hton, THD *thd, THD *from_thd);
839 /**
840 Flush the log(s) of storage engine(s).
841
842 @param hton Handlerton of storage engine.
843 @param binlog_group_flush true if we got invoked by binlog group
844 commit during flush stage, false in other cases.
845 @retval false Succeed
846 @retval true Error
847 */
848 bool (*flush_logs)(handlerton *hton, bool binlog_group_flush);
849 int (*store_binlog_info)(handlerton *hton, THD *thd);
850 bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
851 /*
852 The flag values are defined in sql_partition.h.
853 If this function is set, then it implies that the handler supports
854 partitioned tables.
855 If this function exists, then handler::get_partition_handler must also be
856 implemented.
857 */
858 uint (*partition_flags)();
859
860
861 /**
862 Get the tablespace name from the SE for the given schema and table.
863
864 @param thd Thread context.
865 @param db_name Name of the relevant schema.
866 @param table_name Name of the relevant table.
867 @param [out] tablespace_name Name of the tablespace containing the table.
868
869 @return Operation status.
870 @retval == 0 Success.
871 @retval != 0 Error (handler error code returned).
872 */
873
874 int (*get_tablespace)(THD* thd, LEX_CSTRING db_name, LEX_CSTRING table_name,
875 LEX_CSTRING *tablespace_name);
876
877 int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
878 int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
879 class Item *cond,
880 enum enum_schema_tables);
881 my_bool (*flush_changed_page_bitmaps)(void);
882 my_bool (*purge_changed_page_bitmaps)(ulonglong lsn);
883
884 /**
885 Get the list of foreign keys referencing a specified table
886
887 @param thd The thread handle
888 @param path Path to the table
889 @param f_key_list[out] The list of foreign keys
890
891 @return error code or zero for success
892 */
893 int (*get_parent_fk_list)(THD *thd, const char *path,
894 List<FOREIGN_KEY_INFO>* f_key_list);
895 uint32 flags; /* global handler flags */
896 /*
897 Those handlerton functions below are properly initialized at handler
898 init.
899 */
900 int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
901 void (*binlog_log_query)(handlerton *hton, THD *thd,
902 enum_binlog_command binlog_command,
903 const char *query, uint query_length,
904 const char *db, const char *table_name);
905 int (*release_temporary_latches)(handlerton *hton, THD *thd);
906
907 int (*discover)(handlerton *hton, THD* thd, const char *db,
908 const char *name,
909 uchar **frmblob,
910 size_t *frmlen);
911 int (*find_files)(handlerton *hton, THD *thd,
912 const char *db,
913 const char *path,
914 const char *wild, bool dir, List<LEX_STRING> *files);
915 int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
916 const char *name);
917 int (*make_pushed_join)(handlerton *hton, THD* thd,
918 const AQP::Join_plan* plan);
919
920 /**
921 List of all system tables specific to the SE.
922 Array element would look like below,
923 { "<database_name>", "<system table name>" },
924 The last element MUST be,
925 { (const char*)NULL, (const char*)NULL }
926
927 @see ha_example_system_tables in ha_example.cc
928
929 This interface is optional, so every SE need not implement it.
930 */
931 const char* (*system_database)();
932
933 /**
934 Check if the given db.tablename is a system table for this SE.
935
936 @param db Database name to check.
937 @param table_name table name to check.
938 @param is_sql_layer_system_table if the supplied db.table_name is a SQL
939 layer system table.
940
941 @see example_is_supported_system_table in ha_example.cc
942
943 is_sql_layer_system_table is supplied to make more efficient
944 checks possible for SEs that support all SQL layer tables.
945
946 This interface is optional, so every SE need not implement it.
947 */
948 bool (*is_supported_system_table)(const char *db,
949 const char *table_name,
950 bool is_sql_layer_system_table);
951
952 /**
953 Retrieve cost constants to be used for this storage engine.
954
955 A storage engine that wants to provide its own cost constants to
956 be used in the optimizer cost model, should implement this function.
957 The server will call this function to get a cost constant object
958 that will be used for tables stored in this storage engine instead
959 of using the default cost constants.
960
961 Life cycle for the cost constant object: The storage engine must
962 allocate the cost constant object on the heap. After the function
963 returns, the server takes over the ownership of this object.
964 The server will eventually delete the object by calling delete.
965
966 @note In the initial version the storage_category parameter will
967 not be used. The only valid value this will have is DEFAULT_STORAGE_CLASS
968 (see declartion in opt_costconstants.h).
969
970 @param storage_category the storage type that the cost constants will
971 be used for
972
973 @return a pointer to the cost constant object, if NULL is returned
974 the default cost constants will be used
975 */
976
977 SE_cost_constants *(*get_cost_constants)(uint storage_category);
978
979 /**
980 @param[in,out] thd pointer to THD
981 @param[in] new_trx_arg pointer to replacement transaction
982 @param[out] ptr_trx_arg double pointer to being replaced transaction
983
984 Associated with THD engine's native transaction is replaced
985 with @c new_trx_arg. The old value is returned through a buffer if non-null
986 pointer is provided with @c ptr_trx_arg.
987 The method is adapted by XA start and XA prepare handlers to
988 handle XA transaction that is logged as two parts by slave applier.
989
990 This interface concerns engines that are aware of XA transaction.
991 */
992 void (*replace_native_transaction_in_thd)(THD *thd, void *new_trx_arg,
993 void **ptr_trx_arg);
994
995
996 /**
997 Notify/get permission from storage engine before acquisition or after
998 release of exclusive metadata lock on object represented by key.
999
1000 @param thd Thread context.
1001 @param mdl_key MDL key identifying object on which exclusive
1002 lock is to be acquired/was released.
1003 @param notification_type Indicates whether this is pre-acquire or
1004 post-release notification.
1005 @param victimized 'true' if locking failed as we were selected
1006 as a victim in order to avoid possible deadlocks.
1007
1008 @note Notification is done only for objects from TABLESPACE, SCHEMA,
1009 TABLE, FUNCTION, PROCEDURE, TRIGGER and EVENT namespaces.
1010
1011 @note Problems during notification are to be reported as warnings, MDL
1012 subsystem will report generic error if pre-acquire notification
1013 fails/SE refuses lock acquisition.
1014 @note Return value is ignored/error is not reported in case of
1015 post-release notification.
1016
1017 @note In some cases post-release notification might happen even if
1018 there were no prior pre-acquire notification. For example,
1019 when SE was loaded after exclusive lock acquisition, or when
1020 we need notify SEs which permitted lock acquisition that it
1021 didn't happen because one of SEs didn't allow it (in such case
1022 we will do post-release notification for all SEs for simplicity).
1023
1024 @return False - if notification was successful/lock can be acquired,
1025 True - if it has failed/lock should not be acquired.
1026 */
1027 bool (*notify_exclusive_mdl)(THD *thd, const MDL_key *mdl_key,
1028 ha_notification_type notification_type,
1029 bool *victimized);
1030
1031 /**
1032 Notify/get permission from storage engine before or after execution of
1033 ALTER TABLE operation on the table identified by the MDL key.
1034
1035 @param thd Thread context.
1036 @param mdl_key MDL key identifying table which is going to be
1037 or was ALTERed.
1038 @param notification_type Indicates whether this is pre-ALTER TABLE or
1039 post-ALTER TABLE notification.
1040
1041 @note This hook is necessary because for ALTER TABLE upgrade to X
1042 metadata lock happens fairly late during the execution process,
1043 so it can be expensive to abort ALTER TABLE operation at this
1044 stage by returning failure from notify_exclusive_mdl() hook.
1045
1046 @note This hook follows the same error reporting convention as
1047 @see notify_exclusive_mdl().
1048
1049 @note Similarly to notify_exclusive_mdl() in some cases post-ALTER
1050 notification might happen even if there were no prior pre-ALTER
1051 notification.
1052
1053 @note Post-ALTER notification can happen before post-release notification
1054 for exclusive metadata lock acquired by this ALTER TABLE.
1055
1056 @return False - if notification was successful/ALTER TABLE can proceed.
1057 True - if it has failed/ALTER TABLE should be aborted.
1058 */
1059 bool (*notify_alter_table)(THD *thd, const MDL_key *mdl_key,
1060 ha_notification_type notification_type);
1061
1062
1063 /**
1064 @brief
1065 Initiate master key rotation
1066
1067 @returns false on success,
1068 true on failure
1069 */
1070 bool (*rotate_encryption_master_key)(void);
1071 /**
1072 Check if the given database name is reserved.
1073
1074 @param hton Handlerton for SE.
1075 @param name Database name.
1076
1077 @retval true Database name is reserved by SE.
1078 @retval false Database name is not reserved.
1079 */
1080 bool (*is_reserved_db_name)(handlerton *hton, const char *name);
1081
1082 /**
1083 @brief
1084 Fix empty UUID of tablespaces of an engine. This is used when engine encrypts
1085 tablespaces as part of initialization. These tablespaces will have empty UUID
1086 because UUID is generated after all plugins are initialized. This API will be
1087 called by server only after UUID is available.
1088 @returns false on success,
1089 true on failure
1090 */
1091 bool (*fix_tablespaces_empty_uuid)(void);
1092
1093 /**
1094 Creates a new compression dictionary with the specified data for this SE.
1095
1096 @param hton handletron object.
1097 @param thd thread descriptor.
1098 @param name compression dictionary name
1099 @param name_len compression dictionary name length
1100 @param data compression dictionary data
1101 @param data_len compression dictionary data length
1102
1103 @return a valid #handler_create_zip_dict_result value.
1104
1105 This interface is optional, so not every SE needs to implement it.
1106 */
1107 handler_create_zip_dict_result (*create_zip_dict)(handlerton *hton,
1108 THD* thd, const char* name, ulong* name_len, const char* data,
1109 ulong* data_len);
1110 /**
1111 Deletes a compression dictionary for this SE.
1112
1113 @param hton handletron object.
1114 @param thd thread descriptor.
1115 @param name compression dictionary name
1116 @param name_len compression dictionary name length
1117
1118 @return a valid #handler_drop_zip_dict_result value.
1119
1120 This interface is optional, so not every SE needs to implement it.
1121 */
1122 handler_drop_zip_dict_result (*drop_zip_dict)(handlerton *hton, THD* thd,
1123 const char* name, ulong* name_len);
1124
1125 uint32 license; /* Flag for Engine License */
1126 void *data; /* Location for engines to keep personal structures */
1127 };
1128
1129
1130 /* Possible flags of a handlerton (there can be 32 of them) */
1131 #define HTON_NO_FLAGS 0
1132 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
1133 #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
1134 #define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
1135 #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
1136 #define HTON_FLUSH_AFTER_RENAME (1 << 4)
1137 #define HTON_NOT_USER_SELECTABLE (1 << 5)
1138 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
1139 #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
1140 #define HTON_NO_PARTITION (1 << 8) //You can not partition these tables
1141
1142 /*
1143 This flag should be set when deciding that the engine does not allow row based
1144 binary logging (RBL) optimizations.
1145
1146 Currently, setting this flag, means that table's read/write_set will be left
1147 untouched when logging changes to tables in this engine. In practice this
1148 means that the server will not mess around with table->write_set and/or
1149 table->read_set when using RBL and deciding whether to log full or minimal rows.
1150
1151 It's valuable for instance for virtual tables, eg: Performance Schema which have
1152 no meaning for replication.
1153 */
1154 #define HTON_NO_BINLOG_ROW_OPT (1 << 9)
1155
1156 /**
1157 Engine supports extended keys. The flag allows to
1158 use 'extended key' feature if the engine is able to
1159 do it (has primary key values in the secondary key).
1160 Note that handler flag HA_PRIMARY_KEY_IN_READ_INDEX is
1161 actually partial case of HTON_SUPPORTS_EXTENDED_KEYS.
1162 */
1163
1164 #define HTON_SUPPORTS_EXTENDED_KEYS (1 << 10)
1165
1166 /**
1167 Set if the storage engine supports 'online' backups. This means that there
1168 exists a way to create a consistent copy of its tables without blocking
1169 updates to them. If so, statements that update such tables will not be
1170 affected by an active LOCK TABLES FOR BACKUP.
1171 */
1172 #define HTON_SUPPORTS_ONLINE_BACKUPS (1 << 11)
1173
1174 /**
1175 Engine supports secondary clustered keys.
1176 */
1177 #define HTON_SUPPORTS_CLUSTERED_KEYS (1 << 12)
1178 // Engine support foreign key constraint.
1179
1180 #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 13)
1181
1182 /**
1183 Engine supports compressed columns.
1184 */
1185 #define HTON_SUPPORTS_COMPRESSED_COLUMNS (1 << 14)
1186
1187 // Engine supports packed keys.
1188 #define HTON_SUPPORTS_PACKED_KEYS (1 << 12)
1189
1190 // Engine supports table or tablespace encryption.
1191 #define HTON_SUPPORTS_TABLE_ENCRYPTION (1 << 13)
1192
1193 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
1194 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
1195
1196 typedef struct {
1197 ulonglong data_file_length;
1198 ulonglong max_data_file_length;
1199 ulonglong index_file_length;
1200 ulonglong delete_length;
1201 ha_rows records;
1202 ulong mean_rec_length;
1203 ulong create_time;
1204 ulong check_time;
1205 ulong update_time;
1206 ulonglong check_sum;
1207 } PARTITION_STATS;
1208
1209 typedef struct st_table_stats {
1210 char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0'
1211 size_t table_len;
1212 ulonglong rows_read, rows_changed;
1213 ulonglong rows_changed_x_indexes;
1214 /* Stores enum db_type, but forward declarations cannot be done */
1215 int engine_type;
1216 } TABLE_STATS;
1217
1218 typedef struct st_index_stats {
1219 char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0'
1220 size_t index_len;
1221 ulonglong rows_read;
1222 } INDEX_STATS;
1223
1224 #define UNDEF_NODEGROUP 65535
1225 class Item;
1226 struct st_table_log_memory_entry;
1227
1228 enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
1229
1230 enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0,
1231 HA_STATS_AUTO_RECALC_ON,
1232 HA_STATS_AUTO_RECALC_OFF };
1233
1234 typedef struct st_ha_create_information
1235 {
st_ha_create_informationst_ha_create_information1236 st_ha_create_information() { memset(this, 0, sizeof(*this)); }
1237
1238 const CHARSET_INFO *table_charset, *default_table_charset;
1239 LEX_STRING connect_string;
1240 const char *password, *tablespace;
1241 LEX_STRING comment;
1242
1243 /**
1244 Algorithm (and possible options) to be used for InnoDB's transparent
1245 page compression. If this attribute is set then it is hint to the
1246 storage engine to try and compress the data using the specified algorithm
1247 where possible. Note: this value is interpreted by the storage engine only.
1248 and ignored by the Server layer. */
1249
1250 LEX_STRING compress;
1251
1252 /**
1253 This attibute is used for InnoDB's transparent page encryption.
1254 If this attribute is set then it is hint to the storage engine to encrypt
1255 the data. Note: this value is interpreted by the storage engine only.
1256 and ignored by the Server layer. */
1257
1258 LEX_STRING encrypt_type;
1259 uint32_t encryption_key_id;
1260 bool was_encryption_key_id_set;
1261
1262 const char *data_file_name, *index_file_name;
1263 const char *alias;
1264 ulonglong max_rows,min_rows;
1265 ulonglong auto_increment_value;
1266 ulong table_options;
1267 ulong avg_row_length;
1268 ulong used_fields;
1269 ulong key_block_size;
1270 uint stats_sample_pages; /* number of pages to sample during
1271 stats estimation, if used, otherwise 0. */
1272 enum_stats_auto_recalc stats_auto_recalc;
1273 SQL_I_List<TABLE_LIST> merge_list;
1274 handlerton *db_type;
1275 /**
1276 Row type of the table definition.
1277
1278 Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
1279 For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
1280
1281 Can be changed either explicitly by the parser.
1282 If nothing specified inherits the value of the original table (if present).
1283 */
1284 enum row_type row_type;
1285 uint null_bits; /* NULL bits at start of record */
1286 uint options; /* OR of HA_CREATE_ options */
1287 uint merge_insert_method;
1288 uint extra_size; /* length of extra data segment */
1289 bool varchar; /* 1 if table has a VARCHAR */
1290 enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
1291 } HA_CREATE_INFO;
1292
1293
1294 /**
1295 Structure describing changes to an index to be caused by ALTER TABLE.
1296 */
1297
1298 struct KEY_PAIR
1299 {
1300 /**
1301 Pointer to KEY object describing old version of index in
1302 TABLE::key_info array for TABLE instance representing old
1303 version of table.
1304 */
1305 KEY *old_key;
1306 /**
1307 Pointer to KEY object describing new version of index in
1308 Alter_inplace_info::key_info_buffer array.
1309 */
1310 KEY *new_key;
1311 };
1312
1313
1314 /**
1315 In-place alter handler context.
1316
1317 This is a superclass intended to be subclassed by individual handlers
1318 in order to store handler unique context between in-place alter API calls.
1319
1320 The handler is responsible for creating the object. This can be done
1321 as early as during check_if_supported_inplace_alter().
1322
1323 The SQL layer is responsible for destroying the object.
1324 The class extends Sql_alloc so the memory will be mem root allocated.
1325
1326 @see Alter_inplace_info
1327 */
1328
1329 class inplace_alter_handler_ctx : public Sql_alloc
1330 {
1331 public:
inplace_alter_handler_ctx()1332 inplace_alter_handler_ctx() {}
1333
~inplace_alter_handler_ctx()1334 virtual ~inplace_alter_handler_ctx() {}
set_shared_data(const inplace_alter_handler_ctx * ctx)1335 virtual void set_shared_data(const inplace_alter_handler_ctx *ctx) {};
1336 };
1337
1338
1339 /**
1340 Class describing changes to be done by ALTER TABLE.
1341 Instance of this class is passed to storage engine in order
1342 to determine if this ALTER TABLE can be done using in-place
1343 algorithm. It is also used for executing the ALTER TABLE
1344 using in-place algorithm.
1345 */
1346
1347 class Alter_inplace_info
1348 {
1349 public:
1350 /**
1351 Bits to show in detail what operations the storage engine is
1352 to execute.
1353
1354 All these operations are supported as in-place operations by the
1355 SQL layer. This means that operations that by their nature must
1356 be performed by copying the table to a temporary table, will not
1357 have their own flags here (e.g. ALTER TABLE FORCE, ALTER TABLE
1358 ENGINE).
1359
1360 We generally try to specify handler flags only if there are real
1361 changes. But in cases when it is cumbersome to determine if some
1362 attribute has really changed we might choose to set flag
1363 pessimistically, for example, relying on parser output only.
1364 */
1365 typedef ulonglong HA_ALTER_FLAGS;
1366
1367 // Add non-unique, non-primary index
1368 static const HA_ALTER_FLAGS ADD_INDEX = 1ULL << 0;
1369
1370 // Drop non-unique, non-primary index
1371 static const HA_ALTER_FLAGS DROP_INDEX = 1ULL << 1;
1372
1373 // Add unique, non-primary index
1374 static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1ULL << 2;
1375
1376 // Drop unique, non-primary index
1377 static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1ULL << 3;
1378
1379 // Add primary index
1380 static const HA_ALTER_FLAGS ADD_PK_INDEX = 1ULL << 4;
1381
1382 // Drop primary index
1383 static const HA_ALTER_FLAGS DROP_PK_INDEX = 1ULL << 5;
1384
1385 // Add column
1386
1387 // Virtual generated column
1388 static const HA_ALTER_FLAGS ADD_VIRTUAL_COLUMN = 1ULL << 6;
1389 // Stored base (non-generated) column
1390 static const HA_ALTER_FLAGS ADD_STORED_BASE_COLUMN = 1ULL << 7;
1391 // Stored generated column
1392 static const HA_ALTER_FLAGS ADD_STORED_GENERATED_COLUMN= 1ULL << 8;
1393 // Add generic column (convience constant).
1394 static const HA_ALTER_FLAGS ADD_COLUMN= ADD_VIRTUAL_COLUMN |
1395 ADD_STORED_BASE_COLUMN |
1396 ADD_STORED_GENERATED_COLUMN;
1397
1398 // Drop column
1399 static const HA_ALTER_FLAGS DROP_VIRTUAL_COLUMN = 1ULL << 9;
1400 static const HA_ALTER_FLAGS DROP_STORED_COLUMN = 1ULL << 10;
1401 static const HA_ALTER_FLAGS DROP_COLUMN= DROP_VIRTUAL_COLUMN |
1402 DROP_STORED_COLUMN;
1403
1404 // Rename column
1405 static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1ULL << 11;
1406
1407 // Change column datatype
1408 static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_TYPE = 1ULL << 12;
1409 static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_TYPE = 1ULL << 13;
1410
1411 /**
1412 Change column datatype in such way that new type has compatible
1413 packed representation with old type, so it is theoretically
1414 possible to perform change by only updating data dictionary
1415 without changing table rows.
1416 */
1417 static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1ULL << 14;
1418
1419 /// A virtual column has changed its position
1420 static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_ORDER = 1ULL << 15;
1421
1422 /// A stored column has changed its position (disregarding virtual columns)
1423 static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_ORDER = 1ULL << 16;
1424
1425 // Change column from NOT NULL to NULL
1426 static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1ULL << 17;
1427
1428 // Change column from NULL to NOT NULL
1429 static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE = 1ULL << 18;
1430
1431 // Set or remove default column value
1432 static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1ULL << 19;
1433
1434 // Change column generation expression
1435 static const HA_ALTER_FLAGS ALTER_VIRTUAL_GCOL_EXPR = 1ULL << 20;
1436 static const HA_ALTER_FLAGS ALTER_STORED_GCOL_EXPR = 1ULL << 21;
1437
1438 // Add foreign key
1439 static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1ULL << 22;
1440
1441 // Drop foreign key
1442 static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1ULL << 23;
1443
1444 // table_options changed, see HA_CREATE_INFO::used_fields for details.
1445 static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1ULL << 24;
1446
1447 // Table is renamed
1448 static const HA_ALTER_FLAGS ALTER_RENAME = 1ULL << 25;
1449
1450 // Change the storage type of column
1451 static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1ULL << 26;
1452
1453 // Change the column format of column
1454 static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1ULL << 27;
1455
1456 // Add partition
1457 static const HA_ALTER_FLAGS ADD_PARTITION = 1ULL << 28;
1458
1459 // Drop partition
1460 static const HA_ALTER_FLAGS DROP_PARTITION = 1ULL << 29;
1461
1462 // Changing partition options
1463 static const HA_ALTER_FLAGS ALTER_PARTITION = 1ULL << 30;
1464
1465 // Coalesce partition
1466 static const HA_ALTER_FLAGS COALESCE_PARTITION = 1ULL << 31;
1467
1468 // Reorganize partition ... into
1469 static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1ULL << 32;
1470
1471 // Reorganize partition
1472 static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1ULL << 33;
1473
1474 // Remove partitioning
1475 static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING = 1ULL << 34;
1476
1477 // Partition operation with ALL keyword
1478 static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1ULL << 35;
1479
1480 /**
1481 Rename index. Note that we set this flag only if there are no other
1482 changes to the index being renamed. Also for simplicity we don't
1483 detect renaming of indexes which is done by dropping index and then
1484 re-creating index with identical definition under different name.
1485 */
1486 static const HA_ALTER_FLAGS RENAME_INDEX = 1ULL << 36;
1487
1488 /**
1489 Recreate the table for ALTER TABLE FORCE, ALTER TABLE ENGINE
1490 and OPTIMIZE TABLE operations.
1491 */
1492 static const HA_ALTER_FLAGS RECREATE_TABLE = 1ULL << 37;
1493
1494 // Add spatial index
1495 static const HA_ALTER_FLAGS ADD_SPATIAL_INDEX = 1ULL << 38;
1496
1497 // Alter index comment
1498 static const HA_ALTER_FLAGS ALTER_INDEX_COMMENT = 1ULL << 39;
1499
1500 // Upgrade partitioning
1501 static const HA_ALTER_FLAGS ALTER_UPGRADE_PARTITIONING = 1ULL << 40;
1502
1503 // New/changed virtual generated column require validation
1504 static const HA_ALTER_FLAGS VALIDATE_VIRTUAL_COLUMN = 1ULL << 41;
1505
1506 /**
1507 Change in index length such that it does not require index rebuild.
1508 For example, change in index length due to column expansion like
1509 varchar(X) changed to varchar(X + N).
1510 */
1511 static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH = 1ULL << 42;
1512
1513
1514 /**
1515 Create options (like MAX_ROWS) for the new version of table.
1516
1517 @note The referenced instance of HA_CREATE_INFO object was already
1518 used to create new .FRM file for table being altered. So it
1519 has been processed by mysql_prepare_create_table() already.
1520 For example, this means that it has HA_OPTION_PACK_RECORD
1521 flag in HA_CREATE_INFO::table_options member correctly set.
1522 */
1523 HA_CREATE_INFO *create_info;
1524
1525 /**
1526 Alter options, fields and keys for the new version of table.
1527
1528 @note The referenced instance of Alter_info object was already
1529 used to create new .FRM file for table being altered. So it
1530 has been processed by mysql_prepare_create_table() already.
1531 In particular, this means that in Create_field objects for
1532 fields which were present in some form in the old version
1533 of table, Create_field::field member points to corresponding
1534 Field instance for old version of table.
1535 */
1536 Alter_info *alter_info;
1537
1538 /**
1539 Array of KEYs for new version of table - including KEYs to be added.
1540
1541 @note Currently this array is produced as result of
1542 mysql_prepare_create_table() call.
1543 This means that it follows different convention for
1544 KEY_PART_INFO::fieldnr values than objects in TABLE::key_info
1545 array.
1546
1547 @todo This is mainly due to the fact that we need to keep compatibility
1548 with removed handler::add_index() call. We plan to switch to
1549 TABLE::key_info numbering later.
1550
1551 KEYs are sorted - see sort_keys().
1552 */
1553 KEY *key_info_buffer;
1554
1555 /** Size of key_info_buffer array. */
1556 uint key_count;
1557
1558 /** Size of index_drop_buffer array. */
1559 uint index_drop_count;
1560
1561 /**
1562 Array of pointers to KEYs to be dropped belonging to the TABLE instance
1563 for the old version of the table.
1564 */
1565 KEY **index_drop_buffer;
1566
1567 /** Size of index_add_buffer array. */
1568 uint index_add_count;
1569
1570 /**
1571 Array of indexes into key_info_buffer for KEYs to be added,
1572 sorted in increasing order.
1573 */
1574 uint *index_add_buffer;
1575
1576 /** Size of index_rename_buffer array. */
1577 uint index_rename_count;
1578
1579 /**
1580 Array of KEY_PAIR objects describing indexes being renamed.
1581 For each index renamed it contains object with KEY_PAIR::old_key
1582 pointing to KEY object belonging to the TABLE instance for old
1583 version of table representing old version of index and with
1584 KEY_PAIR::new_key pointing to KEY object for new version of
1585 index in key_info_buffer member.
1586 */
1587 KEY_PAIR *index_rename_buffer;
1588
1589 /**
1590 Context information to allow handlers to keep context between in-place
1591 alter API calls.
1592
1593 @see inplace_alter_handler_ctx for information about object lifecycle.
1594 */
1595 inplace_alter_handler_ctx *handler_ctx;
1596
1597 /**
1598 If the table uses several handlers, like ha_partition uses one handler
1599 per partition, this contains a Null terminated array of ctx pointers
1600 that should all be committed together.
1601 Or NULL if only handler_ctx should be committed.
1602 Set to NULL if the low level handler::commit_inplace_alter_table uses it,
1603 to signal to the main handler that everything was committed as atomically.
1604
1605 @see inplace_alter_handler_ctx for information about object lifecycle.
1606 */
1607 inplace_alter_handler_ctx **group_commit_ctx;
1608
1609 /**
1610 Flags describing in detail which operations the storage engine is to execute.
1611 */
1612 HA_ALTER_FLAGS handler_flags;
1613
1614 /**
1615 Partition_info taking into account the partition changes to be performed.
1616 Contains all partitions which are present in the old version of the table
1617 with partitions to be dropped or changed marked as such + all partitions
1618 to be added in the new version of table marked as such.
1619 */
1620 partition_info *modified_part_info;
1621
1622 /** true for online operation (LOCK=NONE) */
1623 bool online;
1624
1625 /**
1626 Can be set by handler to describe why a given operation cannot be done
1627 in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
1628 online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE)
1629 If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
1630 results from handler::check_if_supported_inplace_alter() doesn't match
1631 requirements set by user. If not set, the more generic
1632 ER_ALTER_OPERATION_NOT_SUPPORTED will be used.
1633
1634 Please set to a properly localized string, for example using
1635 my_get_err_msg(), so that the error message as a whole is localized.
1636 */
1637 const char *unsupported_reason;
1638
Alter_inplace_info(HA_CREATE_INFO * create_info_arg,Alter_info * alter_info_arg,KEY * key_info_arg,uint key_count_arg,partition_info * modified_part_info_arg)1639 Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
1640 Alter_info *alter_info_arg,
1641 KEY *key_info_arg, uint key_count_arg,
1642 partition_info *modified_part_info_arg)
1643 : create_info(create_info_arg),
1644 alter_info(alter_info_arg),
1645 key_info_buffer(key_info_arg),
1646 key_count(key_count_arg),
1647 index_drop_count(0),
1648 index_drop_buffer(NULL),
1649 index_add_count(0),
1650 index_add_buffer(NULL),
1651 index_rename_count(0),
1652 index_rename_buffer(NULL),
1653 handler_ctx(NULL),
1654 group_commit_ctx(NULL),
1655 handler_flags(0),
1656 modified_part_info(modified_part_info_arg),
1657 online(false),
1658 unsupported_reason(NULL)
1659 {}
1660
~Alter_inplace_info()1661 ~Alter_inplace_info()
1662 {
1663 delete handler_ctx;
1664 }
1665
1666 /**
1667 Used after check_if_supported_inplace_alter() to report
1668 error if the result does not match the LOCK/ALGORITHM
1669 requirements set by the user.
1670
1671 @param not_supported Part of statement that was not supported.
1672 @param try_instead Suggestion as to what the user should
1673 replace not_supported with.
1674 */
1675 void report_unsupported_error(const char *not_supported,
1676 const char *try_instead);
1677
1678 /** Add old and new version of key to array of indexes to be renamed. */
add_renamed_key(KEY * old_key,KEY * new_key)1679 void add_renamed_key(KEY *old_key, KEY *new_key)
1680 {
1681 KEY_PAIR *key_pair= index_rename_buffer + index_rename_count++;
1682 key_pair->old_key= old_key;
1683 key_pair->new_key= new_key;
1684 DBUG_PRINT("info", ("index renamed: '%s' to '%s'",
1685 old_key->name, new_key->name));
1686 }
1687
1688 /**
1689 Add old and new version of modified key to arrays of indexes to
1690 be dropped and added (correspondingly).
1691 */
add_modified_key(KEY * old_key,KEY * new_key)1692 void add_modified_key(KEY *old_key, KEY *new_key)
1693 {
1694 index_drop_buffer[index_drop_count++]= old_key;
1695 index_add_buffer[index_add_count++]= (uint) (new_key - key_info_buffer);
1696 DBUG_PRINT("info", ("index changed: '%s'", old_key->name));
1697 }
1698
1699 /** Drop key to array of indexes to be dropped. */
add_dropped_key(KEY * old_key)1700 void add_dropped_key(KEY *old_key)
1701 {
1702 index_drop_buffer[index_drop_count++]= old_key;
1703 DBUG_PRINT("info", ("index dropped: '%s'", old_key->name));
1704 }
1705
1706 /** Add key to array of indexes to be added. */
add_added_key(KEY * new_key)1707 void add_added_key(KEY *new_key)
1708 {
1709 index_add_buffer[index_add_count++]= (uint) (new_key - key_info_buffer);
1710 DBUG_PRINT("info", ("index added: '%s'", new_key->name));
1711 }
1712 };
1713
1714
1715 typedef struct st_key_create_information
1716 {
1717 enum ha_key_alg algorithm;
1718 ulong block_size;
1719 LEX_STRING parser_name;
1720 LEX_STRING comment;
1721 /**
1722 A flag to determine if we will check for duplicate indexes.
1723 This typically means that the key information was specified
1724 directly by the user (set by the parser) or a column
1725 associated with it was dropped.
1726 */
1727 bool check_for_duplicate_indexes;
1728 } KEY_CREATE_INFO;
1729
1730
1731 /*
1732 Class for maintaining hooks used inside operations on tables such
1733 as: create table functions, delete table functions, and alter table
1734 functions.
1735
1736 Class is using the Template Method pattern to separate the public
1737 usage interface from the private inheritance interface. This
1738 imposes no overhead, since the public non-virtual function is small
1739 enough to be inlined.
1740
1741 The hooks are usually used for functions that does several things,
1742 e.g., create_table_from_items(), which both create a table and lock
1743 it.
1744 */
1745 class TABLEOP_HOOKS
1746 {
1747 public:
TABLEOP_HOOKS()1748 TABLEOP_HOOKS() {}
~TABLEOP_HOOKS()1749 virtual ~TABLEOP_HOOKS() {}
1750
prelock(TABLE ** tables,uint count)1751 inline void prelock(TABLE **tables, uint count)
1752 {
1753 do_prelock(tables, count);
1754 }
1755
postlock(TABLE ** tables,uint count)1756 inline int postlock(TABLE **tables, uint count)
1757 {
1758 return do_postlock(tables, count);
1759 }
1760 private:
1761 /* Function primitive that is called prior to locking tables */
do_prelock(TABLE ** tables,uint count)1762 virtual void do_prelock(TABLE **tables, uint count)
1763 {
1764 /* Default is to do nothing */
1765 }
1766
1767 /**
1768 Primitive called after tables are locked.
1769
1770 If an error is returned, the tables will be unlocked and error
1771 handling start.
1772
1773 @return Error code or zero.
1774 */
do_postlock(TABLE ** tables,uint count)1775 virtual int do_postlock(TABLE **tables, uint count)
1776 {
1777 return 0; /* Default is to do nothing */
1778 }
1779 };
1780
1781 typedef struct st_savepoint SAVEPOINT;
1782 extern ulong savepoint_alloc_size;
1783 extern KEY_CREATE_INFO default_key_create_info;
1784
1785 typedef struct st_ha_check_opt
1786 {
st_ha_check_optst_ha_check_opt1787 st_ha_check_opt() {} /* Remove gcc warning */
1788 uint flags; /* isam layer flags (e.g. for myisamchk) */
1789 uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
1790 KEY_CACHE *key_cache; /* new key cache when changing key cache */
1791 void init();
1792 } HA_CHECK_OPT;
1793
1794
1795
1796 /*
1797 This is a buffer area that the handler can use to store rows.
1798 'end_of_used_area' should be kept updated after calls to
1799 read-functions so that other parts of the code can use the
1800 remaining area (until next read calls is issued).
1801 */
1802
1803 typedef struct st_handler_buffer
1804 {
1805 uchar *buffer; /* Buffer one can start using */
1806 uchar *buffer_end; /* End of buffer */
1807 uchar *end_of_used_area; /* End of area that was used by handler */
1808 } HANDLER_BUFFER;
1809
1810 typedef struct system_status_var SSV;
1811
1812
1813 typedef void *range_seq_t;
1814
1815 typedef struct st_range_seq_if
1816 {
1817 /*
1818 Initialize the traversal of range sequence
1819
1820 SYNOPSIS
1821 init()
1822 init_params The seq_init_param parameter
1823 n_ranges The number of ranges obtained
1824 flags A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
1825
1826 RETURN
1827 An opaque value to be used as RANGE_SEQ_IF::next() parameter
1828 */
1829 range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
1830
1831
1832 /*
1833 Get the next range in the range sequence
1834
1835 SYNOPSIS
1836 next()
1837 seq The value returned by RANGE_SEQ_IF::init()
1838 range OUT Information about the next range
1839
1840 RETURN
1841 0 - Ok, the range structure filled with info about the next range
1842 1 - No more ranges
1843 */
1844 uint (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
1845
1846 /*
1847 Check whether range_info orders to skip the next record
1848
1849 SYNOPSIS
1850 skip_record()
1851 seq The value returned by RANGE_SEQ_IF::init()
1852 range_info Information about the next range
1853 (Ignored if MRR_NO_ASSOCIATION is set)
1854 rowid Rowid of the record to be checked (ignored if set to 0)
1855
1856 RETURN
1857 1 - Record with this range_info and/or this rowid shall be filtered
1858 out from the stream of records returned by multi_range_read_next()
1859 0 - The record shall be left in the stream
1860 */
1861 bool (*skip_record) (range_seq_t seq, char *range_info, uchar *rowid);
1862
1863 /*
1864 Check if the record combination matches the index condition
1865 SYNOPSIS
1866 skip_index_tuple()
1867 seq The value returned by RANGE_SEQ_IF::init()
1868 range_info Information about the next range
1869
1870 RETURN
1871 0 - The record combination satisfies the index condition
1872 1 - Otherwise
1873 */
1874 bool (*skip_index_tuple) (range_seq_t seq, char *range_info);
1875 } RANGE_SEQ_IF;
1876
1877 uint16 &mrr_persistent_flag_storage(range_seq_t seq, uint idx);
1878 char* &mrr_get_ptr_by_idx(range_seq_t seq, uint idx);
1879
1880 /**
1881 Used to store optimizer cost estimates.
1882
1883 The class consists of PODs only: default operator=, copy constructor
1884 and destructor are used.
1885 */
1886 class Cost_estimate
1887 {
1888 private:
1889 double io_cost; ///< cost of I/O operations
1890 double cpu_cost; ///< cost of CPU operations
1891 double import_cost; ///< cost of remote operations
1892 double mem_cost; ///< memory used (bytes)
1893
1894 public:
Cost_estimate()1895 Cost_estimate() :
1896 io_cost(0),
1897 cpu_cost(0),
1898 import_cost(0),
1899 mem_cost(0)
1900 {}
1901
1902 /// Returns sum of time-consuming costs, i.e., not counting memory cost
total_cost()1903 double total_cost() const { return io_cost + cpu_cost + import_cost; }
get_io_cost()1904 double get_io_cost() const { return io_cost; }
get_cpu_cost()1905 double get_cpu_cost() const { return cpu_cost; }
get_import_cost()1906 double get_import_cost() const { return import_cost; }
get_mem_cost()1907 double get_mem_cost() const { return mem_cost; }
1908
1909 /**
1910 Whether or not all costs in the object are zero
1911
1912 @return true if all costs are zero, false otherwise
1913 */
is_zero()1914 bool is_zero() const
1915 {
1916 return !(io_cost || cpu_cost || import_cost || mem_cost);
1917 }
1918 /**
1919 Whether or not the total cost is the maximal double
1920
1921 @return true if total cost is the maximal double, false otherwise
1922 */
is_max_cost()1923 bool is_max_cost() const { return io_cost == DBL_MAX; }
1924 /// Reset all costs to zero
reset()1925 void reset()
1926 {
1927 io_cost= cpu_cost= import_cost= mem_cost= 0;
1928 }
1929 /// Set current cost to the maximal double
set_max_cost()1930 void set_max_cost()
1931 {
1932 reset();
1933 io_cost= DBL_MAX;
1934 }
1935
1936 /// Multiply io, cpu and import costs by parameter
multiply(double m)1937 void multiply(double m)
1938 {
1939 assert(!is_max_cost());
1940
1941 io_cost *= m;
1942 cpu_cost *= m;
1943 import_cost *= m;
1944 /* Don't multiply mem_cost */
1945 }
1946
1947 Cost_estimate& operator+= (const Cost_estimate &other)
1948 {
1949 assert(!is_max_cost() && !other.is_max_cost());
1950
1951 io_cost+= other.io_cost;
1952 cpu_cost+= other.cpu_cost;
1953 import_cost+= other.import_cost;
1954 mem_cost+= other.mem_cost;
1955
1956 return *this;
1957 }
1958
1959 Cost_estimate operator+ (const Cost_estimate &other)
1960 {
1961 Cost_estimate result= *this;
1962 result+= other;
1963
1964 return result;
1965 }
1966
1967 Cost_estimate operator- (const Cost_estimate &other)
1968 {
1969 Cost_estimate result;
1970
1971 assert(!other.is_max_cost());
1972
1973 result.io_cost= io_cost - other.io_cost;
1974 result.cpu_cost= cpu_cost - other.cpu_cost;
1975 result.import_cost= import_cost - other.import_cost;
1976 result.mem_cost= mem_cost - other.mem_cost;
1977 return result;
1978 }
1979
1980 bool operator> (const Cost_estimate &other) const
1981 {
1982 return total_cost() > other.total_cost() ? true : false;
1983 }
1984
1985 bool operator< (const Cost_estimate &other) const
1986 {
1987 return other > *this ? true : false;
1988 }
1989
1990 /// Add to IO cost
add_io(double add_io_cost)1991 void add_io(double add_io_cost)
1992 {
1993 assert(!is_max_cost());
1994 io_cost+= add_io_cost;
1995 }
1996
1997 /// Add to CPU cost
add_cpu(double add_cpu_cost)1998 void add_cpu(double add_cpu_cost)
1999 {
2000 assert(!is_max_cost());
2001 cpu_cost+= add_cpu_cost;
2002 }
2003
2004 /// Add to import cost
add_import(double add_import_cost)2005 void add_import(double add_import_cost)
2006 {
2007 assert(!is_max_cost());
2008 import_cost+= add_import_cost;
2009 }
2010
2011 /// Add to memory cost
add_mem(double add_mem_cost)2012 void add_mem(double add_mem_cost)
2013 {
2014 assert(!is_max_cost());
2015 mem_cost+= add_mem_cost;
2016 }
2017 };
2018
2019 void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
2020 Cost_estimate *cost);
2021
2022 /*
2023 The below two are not used (and not handled) in this milestone of this WL
2024 entry because there seems to be no use for them at this stage of
2025 implementation.
2026 */
2027 #define HA_MRR_SINGLE_POINT 1
2028 #define HA_MRR_FIXED_KEY 2
2029
2030 /*
2031 Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
2032 'range' parameter.
2033 */
2034 #define HA_MRR_NO_ASSOCIATION 4
2035
2036 /*
2037 The MRR user will provide ranges in key order, and MRR implementation
2038 must return rows in key order.
2039 Passing this flag to multi_read_range_init() may cause the
2040 default MRR handler to be used even if HA_MRR_USE_DEFAULT_IMPL
2041 was not specified.
2042 (If the native MRR impl. can not provide SORTED result)
2043 */
2044 #define HA_MRR_SORTED 8
2045
2046 /* MRR implementation doesn't have to retrieve full records */
2047 #define HA_MRR_INDEX_ONLY 16
2048
2049 /*
2050 The passed memory buffer is of maximum possible size, the caller can't
2051 assume larger buffer.
2052 */
2053 #define HA_MRR_LIMITS 32
2054
2055
2056 /*
2057 Flag set <=> default MRR implementation is used
2058 (The choice is made by **_info[_const]() function which may set this
2059 flag. SQL layer remembers the flag value and then passes it to
2060 multi_read_range_init().
2061 */
2062 #define HA_MRR_USE_DEFAULT_IMPL 64
2063
2064 /*
2065 Used only as parameter to multi_range_read_info():
2066 Flag set <=> the caller guarantees that the bounds of the scanned ranges
2067 will not have NULL values.
2068 */
2069 #define HA_MRR_NO_NULL_ENDPOINTS 128
2070
2071 /*
2072 Set by the MRR implementation to signal that it will natively
2073 produced sorted result if multi_range_read_init() is called with
2074 the HA_MRR_SORTED flag - Else multi_range_read_init(HA_MRR_SORTED)
2075 will revert to use the default MRR implementation.
2076 */
2077 #define HA_MRR_SUPPORT_SORTED 256
2078
2079
2080 class ha_statistics
2081 {
2082 public:
2083 ulonglong data_file_length; /* Length off data file */
2084 ulonglong max_data_file_length; /* Length off data file */
2085 ulonglong index_file_length;
2086 ulonglong max_index_file_length;
2087 ulonglong delete_length; /* Free bytes */
2088 ulonglong auto_increment_value;
2089 /*
2090 The number of records in the table.
2091 0 - means the table has exactly 0 rows
2092 other - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
2093 the value is the exact number of records in the table
2094 else
2095 it is an estimate
2096 */
2097 ha_rows records;
2098 ha_rows deleted; /* Deleted records */
2099 ulong mean_rec_length; /* physical reclength */
2100 time_t create_time; /* When table was created */
2101 ulong check_time;
2102 ulong update_time;
2103 uint block_size; /* index block size */
2104
2105 /*
2106 number of buffer bytes that native mrr implementation needs,
2107 */
2108 uint mrr_length_per_rec;
2109
2110 /**
2111 Estimate for how much of the table that is availabe in a memory
2112 buffer. Valid range is [0..1]. If it has the special value
2113 IN_MEMORY_ESTIMATE_UNKNOWN (defined in structs.h), it means that
2114 the storage engine has not supplied any value for it.
2115 */
2116 double table_in_mem_estimate;
2117
ha_statistics()2118 ha_statistics():
2119 data_file_length(0), max_data_file_length(0),
2120 index_file_length(0), delete_length(0), auto_increment_value(0),
2121 records(0), deleted(0), mean_rec_length(0), create_time(0),
2122 check_time(0), update_time(0), block_size(0),
2123 table_in_mem_estimate(IN_MEMORY_ESTIMATE_UNKNOWN)
2124 {}
2125 };
2126
2127 /**
2128 Calculates length of key.
2129
2130 Given a key index and a map of key parts return length of buffer used by key
2131 parts.
2132
2133 @param table Table containing the key
2134 @param key Key index
2135 @param keypart_map which key parts that is used
2136
2137 @return Length of used key parts.
2138 */
2139 uint calculate_key_len(TABLE *table, uint key,
2140 key_part_map keypart_map);
2141 /*
2142 bitmap with first N+1 bits set
2143 (keypart_map for a key prefix of [0..N] keyparts)
2144 */
2145 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
2146 /*
2147 bitmap with first N bits set
2148 (keypart_map for a key prefix of [0..N-1] keyparts)
2149 */
2150 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
2151
2152
2153 /** Base class to be used by handlers different shares */
2154 class Handler_share
2155 {
2156 public:
Handler_share()2157 Handler_share() {}
~Handler_share()2158 virtual ~Handler_share() {}
2159 };
2160
2161
2162 /**
2163 Wrapper for struct ft_hints.
2164 */
2165
2166 class Ft_hints: public Sql_alloc
2167 {
2168 private:
2169 struct ft_hints hints;
2170
2171 public:
Ft_hints(uint ft_flags)2172 Ft_hints(uint ft_flags)
2173 {
2174 hints.flags= ft_flags;
2175 hints.op_type= FT_OP_UNDEFINED;
2176 hints.op_value= 0.0;
2177 hints.limit= HA_POS_ERROR;
2178 }
2179
2180 /**
2181 Set comparison operation type and and value for master MATCH function.
2182
2183 @param type comparison operation type
2184 @param value comparison operation value
2185 */
set_hint_op(enum ft_operation type,double value)2186 void set_hint_op(enum ft_operation type, double value)
2187 {
2188 hints.op_type= type;
2189 hints.op_value= value;
2190 }
2191
2192 /**
2193 Set Ft_hints flag.
2194
2195 @param ft_flag Ft_hints flag
2196 */
set_hint_flag(uint ft_flag)2197 void set_hint_flag(uint ft_flag)
2198 {
2199 hints.flags|= ft_flag;
2200 }
2201
2202 /**
2203 Set Ft_hints limit.
2204
2205 @param Ft_hints limit
2206 */
set_hint_limit(ha_rows ft_limit)2207 void set_hint_limit(ha_rows ft_limit)
2208 {
2209 hints.limit= ft_limit;
2210 }
2211
2212 /**
2213 Get Ft_hints limit.
2214
2215 @return Ft_hints limit
2216 */
get_limit()2217 ha_rows get_limit()
2218 {
2219 return hints.limit;
2220 }
2221
2222 /**
2223 Get Ft_hints operation value.
2224
2225 @return operation value
2226 */
get_op_value()2227 double get_op_value()
2228 {
2229 return hints.op_value;
2230 }
2231
2232 /**
2233 Get Ft_hints operation type.
2234
2235 @return operation type
2236 */
get_op_type()2237 enum ft_operation get_op_type()
2238 {
2239 return hints.op_type;
2240 }
2241
2242 /**
2243 Get Ft_hints flags.
2244
2245 @return Ft_hints flags
2246 */
get_flags()2247 uint get_flags()
2248 {
2249 return hints.flags;
2250 }
2251
2252 /**
2253 Get ft_hints struct.
2254
2255 @return pointer to ft_hints struct
2256 */
get_hints()2257 struct ft_hints* get_hints()
2258 {
2259 return &hints;
2260 }
2261 };
2262
2263
2264 /**
2265 The handler class is the interface for dynamically loadable
2266 storage engines. Do not add ifdefs and take care when adding or
2267 changing virtual functions to avoid vtable confusion
2268
2269 Functions in this class accept and return table columns data. Two data
2270 representation formats are used:
2271 1. TableRecordFormat - Used to pass [partial] table records to/from
2272 storage engine
2273
2274 2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
2275 storage engine. See opt_range.cc for description of this format.
2276
2277 TableRecordFormat
2278 =================
2279 [Warning: this description is work in progress and may be incomplete]
2280 The table record is stored in a fixed-size buffer:
2281
2282 record: null_bytes, column1_data, column2_data, ...
2283
2284 The offsets of the parts of the buffer are also fixed: every column has
2285 an offset to its column{i}_data, and if it is nullable it also has its own
2286 bit in null_bytes.
2287
2288 The record buffer only includes data about columns that are marked in the
2289 relevant column set (table->read_set and/or table->write_set, depending on
2290 the situation).
2291 <not-sure>It could be that it is required that null bits of non-present
2292 columns are set to 1</not-sure>
2293
2294 VARIOUS EXCEPTIONS AND SPECIAL CASES
2295
2296 f the table has no nullable columns, then null_bytes is still
2297 present, its length is one byte <not-sure> which must be set to 0xFF
2298 at all times. </not-sure>
2299
2300 If the table has columns of type BIT, then certain bits from those columns
2301 may be stored in null_bytes as well. Grep around for Field_bit for
2302 details.
2303
2304 For blob columns (see Field_blob), the record buffer stores length of the
2305 data, following by memory pointer to the blob data. The pointer is owned
2306 by the storage engine and is valid until the next operation.
2307
2308 If a blob column has NULL value, then its length and blob data pointer
2309 must be set to 0.
2310 */
2311
2312 class handler :public Sql_alloc
2313 {
2314 friend class Partition_handler;
2315 public:
2316 typedef ulonglong Table_flags;
2317 protected:
2318 TABLE_SHARE *table_share; /* The table definition */
2319 TABLE *table; /* The current open table */
2320 mutable Table_flags cached_table_flags; /* Set on init() and open() */
2321
2322 ha_rows estimation_rows_to_insert;
2323 public:
2324 handlerton *ht; /* storage engine of this handler */
2325 uchar *ref; /* Pointer to current row */
2326 uchar *dup_ref; /* Pointer to duplicate row */
2327
2328 ha_statistics stats;
2329
2330 /* MultiRangeRead-related members: */
2331 range_seq_t mrr_iter; /* Interator to traverse the range sequence */
2332 RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
2333 HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
2334 uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
2335 /* TRUE <=> source MRR ranges and the output are ordered */
2336 bool mrr_is_output_sorted;
2337
2338 /* TRUE <=> we're currently traversing a range in mrr_cur_range. */
2339 bool mrr_have_range;
2340 /* Current range (the one we're now returning rows from) */
2341 KEY_MULTI_RANGE mrr_cur_range;
2342
2343 /*
2344 The direction of the current range or index scan. This is used by
2345 the ICP implementation to determine if it has reached the end
2346 of the current range.
2347 */
2348 enum enum_range_scan_direction {
2349 RANGE_SCAN_ASC,
2350 RANGE_SCAN_DESC
2351 };
2352 private:
2353 /*
2354 Storage space for the end range value. Should only be accessed using
2355 the end_range pointer. The content is invalid when end_range is NULL.
2356 */
2357 key_range save_end_range;
2358 enum_range_scan_direction range_scan_direction;
2359 int key_compare_result_on_equal;
2360
2361 protected:
2362 KEY_PART_INFO *range_key_part;
2363 bool eq_range;
2364 /*
2365 TRUE <=> the engine guarantees that returned records are within the range
2366 being scanned.
2367 */
2368 bool in_range_check_pushed_down;
2369
2370 public:
2371 /*
2372 End value for a range scan. If this is NULL the range scan has no
2373 end value. Should also be NULL when there is no ongoing range scan.
2374 Used by the read_range() functions and also evaluated by pushed
2375 index conditions.
2376 */
2377 key_range *end_range;
2378 /**
2379 Flag which tells if #end_range contains a virtual generated column.
2380 The content is invalid when #end_range is NULL.
2381 */
2382 bool m_virt_gcol_in_end_range;
2383 uint errkey; /* Last dup key */
2384 uint key_used_on_scan;
2385 uint active_index;
2386 /** Length of ref (1-8 or the clustered key length) */
2387 uint ref_length;
2388 FT_INFO *ft_handler;
2389 enum {NONE=0, INDEX, RND} inited;
2390 bool implicit_emptied; /* Can be !=0 only if HEAP */
2391 const Item *pushed_cond;
2392
2393 Item *pushed_idx_cond;
2394 uint pushed_idx_cond_keyno; /* The index which the above condition is for */
2395
2396 ulonglong rows_read;
2397 ulonglong rows_changed;
2398 ulonglong index_rows_read[MAX_KEY];
2399 /**
2400 next_insert_id is the next value which should be inserted into the
2401 auto_increment column: in a inserting-multi-row statement (like INSERT
2402 SELECT), for the first row where the autoinc value is not specified by the
2403 statement, get_auto_increment() called and asked to generate a value,
2404 next_insert_id is set to the next value, then for all other rows
2405 next_insert_id is used (and increased each time) without calling
2406 get_auto_increment().
2407 */
2408 ulonglong next_insert_id;
2409 /**
2410 insert id for the current row (*autogenerated*; if not
2411 autogenerated, it's 0).
2412 At first successful insertion, this variable is stored into
2413 THD::first_successful_insert_id_in_cur_stmt.
2414 */
2415 ulonglong insert_id_for_cur_row;
2416 /**
2417 Interval returned by get_auto_increment() and being consumed by the
2418 inserter.
2419 */
2420 Discrete_interval auto_inc_interval_for_cur_row;
2421 /**
2422 Number of reserved auto-increment intervals. Serves as a heuristic
2423 when we have no estimation of how many records the statement will insert:
2424 the more intervals we have reserved, the bigger the next one. Reset in
2425 handler::ha_release_auto_increment().
2426 */
2427 uint auto_inc_intervals_count;
2428
2429 /**
2430 Instrumented table associated with this handler.
2431 */
2432 PSI_table *m_psi;
2433
2434 private:
2435 /** Internal state of the batch instrumentation. */
2436 enum batch_mode_t
2437 {
2438 /** Batch mode not used. */
2439 PSI_BATCH_MODE_NONE,
2440 /** Batch mode used, before first table io. */
2441 PSI_BATCH_MODE_STARTING,
2442 /** Batch mode used, after first table io. */
2443 PSI_BATCH_MODE_STARTED
2444 };
2445 /**
2446 Batch mode state.
2447 @sa start_psi_batch_mode.
2448 @sa end_psi_batch_mode.
2449 */
2450 batch_mode_t m_psi_batch_mode;
2451 /**
2452 The number of rows in the batch.
2453 @sa start_psi_batch_mode.
2454 @sa end_psi_batch_mode.
2455 */
2456 ulonglong m_psi_numrows;
2457 /**
2458 The current event in a batch.
2459 @sa start_psi_batch_mode.
2460 @sa end_psi_batch_mode.
2461 */
2462 PSI_table_locker *m_psi_locker;
2463 /**
2464 Storage for the event in a batch.
2465 @sa start_psi_batch_mode.
2466 @sa end_psi_batch_mode.
2467 */
2468 PSI_table_locker_state m_psi_locker_state;
2469
2470 public:
2471 virtual void unbind_psi();
2472 virtual void rebind_psi();
2473 /**
2474 Put the handler in 'batch' mode when collecting
2475 table io instrumented events.
2476 When operating in batch mode:
2477 - a single start event is generated in the performance schema.
2478 - all table io performed between @c start_psi_batch_mode
2479 and @c end_psi_batch_mode is not instrumented:
2480 the number of rows affected is counted instead in @c m_psi_numrows.
2481 - a single end event is generated in the performance schema
2482 when the batch mode ends with @c end_psi_batch_mode.
2483 */
2484 void start_psi_batch_mode();
2485 /** End a batch started with @c start_psi_batch_mode. */
2486 void end_psi_batch_mode();
2487
2488 private:
2489 friend class DsMrr_impl;
2490 /**
2491 The lock type set by when calling::ha_external_lock(). This is
2492 propagated down to the storage engine. The reason for also storing
2493 it here, is that when doing MRR we need to create/clone a second handler
2494 object. This cloned handler object needs to know about the lock_type used.
2495 */
2496 int m_lock_type;
2497 /**
2498 Pointer where to store/retrieve the Handler_share pointer.
2499 For non partitioned handlers this is &TABLE_SHARE::ha_share.
2500 */
2501 Handler_share **ha_share;
2502
2503 /**
2504 Some non-virtual ha_* functions, responsible for reading rows,
2505 like ha_rnd_pos(), must ensure that virtual generated columns are
2506 calculated before they return. For that, they should set this
2507 member to true at their start, and check it before they return: if
2508 the member is still true, it means they should calculate; if it's
2509 false, it means the calculation has been done by some called
2510 lower-level function and does not need to be re-done (which is why
2511 we need this status flag: to avoid redundant calculations, for
2512 performance).
2513 */
2514 bool m_update_generated_read_fields;
2515
2516 public:
handler(handlerton * ht_arg,TABLE_SHARE * share_arg)2517 handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
2518 :table_share(share_arg), table(0),
2519 estimation_rows_to_insert(0), ht(ht_arg),
2520 ref(0), range_scan_direction(RANGE_SCAN_ASC),
2521 in_range_check_pushed_down(false), end_range(NULL),
2522 m_virt_gcol_in_end_range(false),
2523 key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
2524 ref_length(sizeof(my_off_t)),
2525 ft_handler(0), inited(NONE),
2526 implicit_emptied(0),
2527 pushed_cond(0), pushed_idx_cond(NULL),
2528 pushed_idx_cond_keyno(MAX_KEY), rows_read(0), rows_changed(0),
2529 next_insert_id(0), insert_id_for_cur_row(0),
2530 auto_inc_intervals_count(0),
2531 m_psi(NULL),
2532 m_psi_batch_mode(PSI_BATCH_MODE_NONE),
2533 m_psi_numrows(0),
2534 m_psi_locker(NULL),
2535 m_lock_type(F_UNLCK), ha_share(NULL),
2536 m_update_generated_read_fields(false), cloned(false)
2537 {
2538 DBUG_PRINT("info",
2539 ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
2540 F_UNLCK, F_RDLCK, F_WRLCK));
2541 memset(index_rows_read, 0, sizeof(index_rows_read));
2542 }
~handler(void)2543 virtual ~handler(void)
2544 {
2545 assert(m_psi == NULL);
2546 assert(m_psi_batch_mode == PSI_BATCH_MODE_NONE);
2547 assert(m_psi_locker == NULL);
2548 assert(m_lock_type == F_UNLCK);
2549 assert(inited == NONE);
2550 }
2551 /* TODO: reorganize the methods and have proper public/protected/private qualifiers!!! */
2552 virtual handler *clone(const char *name, MEM_ROOT *mem_root);
2553 /** This is called after create to allow us to set up cached variables */
init()2554 void init()
2555 {
2556 cached_table_flags= table_flags();
2557 }
2558 /**
2559 For MyRocks, secondary initialization that happens after frm is parsed into
2560 field information from within open_binary_frm. MyRocks uses this secondary
2561 init phase to analyze the key and field definitions to determine if
2562 HA_PRIMARY_KEY_IN_READ_INDEX flag is available for the table as it only
2563 supports that behavior for certain types of key combinations. The
2564 HA_PRIMARY_KEY_IN_READ_INDEX flag is enabled by default till this method
2565 invocation and can be disabled here in case it isn't supported.
2566 Return values: false success, true failure.
2567 */
init_with_fields()2568 virtual bool init_with_fields() { return false; }
2569 /* ha_ methods: public wrappers for private virtual API */
2570
2571 int ha_open(TABLE *table, const char *name, int mode, int test_if_locked);
2572 int ha_close(void);
2573 int ha_index_init(uint idx, bool sorted);
2574 int ha_index_end();
2575 int ha_rnd_init(bool scan);
2576 int ha_rnd_end();
2577 int ha_rnd_next(uchar *buf);
2578 int ha_rnd_pos(uchar * buf, uchar *pos);
2579 int ha_index_read_map(uchar *buf, const uchar *key,
2580 key_part_map keypart_map,
2581 enum ha_rkey_function find_flag);
2582 int ha_index_read_last_map(uchar * buf, const uchar * key,
2583 key_part_map keypart_map);
2584 int ha_index_read_idx_map(uchar *buf, uint index, const uchar *key,
2585 key_part_map keypart_map,
2586 enum ha_rkey_function find_flag);
2587 int ha_index_next(uchar * buf);
2588 int ha_index_prev(uchar * buf);
2589 int ha_index_first(uchar * buf);
2590 int ha_index_last(uchar * buf);
2591 int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
2592 int ha_reset();
2593 /* this is necessary in many places, e.g. in HANDLER command */
ha_index_or_rnd_end()2594 int ha_index_or_rnd_end()
2595 {
2596 return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
2597 }
2598 /**
2599 The cached_table_flags is set at ha_open and ha_external_lock
2600
2601 @param recalculate[in] Force flags recalculation instead of using cached
2602 value.
2603
2604 @retval table flags
2605 */
2606 Table_flags ha_table_flags(bool recalculate = false) const
2607 {
2608 if (recalculate)
2609 cached_table_flags= table_flags();
2610 return cached_table_flags;
2611 }
2612
2613 /**
2614 These functions represent the public interface to *users* of the
2615 handler class, hence they are *not* virtual. For the inheritance
2616 interface, see the (private) functions write_row(), update_row(),
2617 and delete_row() below.
2618 */
2619 int ha_external_lock(THD *thd, int lock_type);
2620 int ha_write_row(uchar * buf);
2621 int ha_update_row(const uchar * old_data, uchar * new_data);
2622 int ha_delete_row(const uchar * buf);
2623 void ha_release_auto_increment();
2624
2625 int check_collation_compatibility();
2626 int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
2627 /** to be actually called to get 'check()' functionality*/
2628 int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
2629 int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
2630 void ha_start_bulk_insert(ha_rows rows);
2631 int ha_end_bulk_insert();
2632 int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
2633 uint *dup_key_found);
2634 int ha_delete_all_rows();
2635 int ha_truncate();
2636 int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
2637 int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
2638 bool ha_check_and_repair(THD *thd);
2639 int ha_disable_indexes(uint mode);
2640 int ha_enable_indexes(uint mode);
2641 int ha_discard_or_import_tablespace(my_bool discard);
2642 int ha_rename_table(const char *from, const char *to);
2643 int ha_delete_table(const char *name);
2644 void ha_drop_table(const char *name);
2645
2646 int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
2647
2648 int ha_create_handler_files(const char *name, const char *old_name,
2649 int action_flag, HA_CREATE_INFO *info);
2650
2651 void adjust_next_insert_id_after_explicit_value(ulonglong nr);
2652 int update_auto_increment();
2653 virtual void print_error(int error, myf errflag);
2654 virtual bool get_error_message(int error, String *buf);
2655 uint get_dup_key(int error);
2656 /**
2657 Retrieves the names of the table and the key for which there was a
2658 duplicate entry in the case of HA_ERR_FOREIGN_DUPLICATE_KEY.
2659
2660 If any of the table or key name is not available this method will return
2661 false and will not change any of child_table_name or child_key_name.
2662
2663 @param child_table_name[out] Table name
2664 @param child_table_name_len[in] Table name buffer size
2665 @param child_key_name[out] Key name
2666 @param child_key_name_len[in] Key name buffer size
2667
2668 @retval true table and key names were available
2669 and were written into the corresponding
2670 out parameters.
2671 @retval false table and key names were not available,
2672 the out parameters were not touched.
2673 */
get_foreign_dup_key(char * child_table_name,uint child_table_name_len,char * child_key_name,uint child_key_name_len)2674 virtual bool get_foreign_dup_key(char *child_table_name,
2675 uint child_table_name_len,
2676 char *child_key_name,
2677 uint child_key_name_len)
2678 { assert(false); return(false); }
change_table_ptr(TABLE * table_arg,TABLE_SHARE * share)2679 virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
2680 {
2681 table= table_arg;
2682 table_share= share;
2683 rows_read= rows_changed= 0;
2684 memset(index_rows_read, 0, sizeof(index_rows_read));
2685 }
2686 /* Estimates calculation */
2687
2688 /**
2689 @deprecated This function is deprecated and will be removed in a future
2690 version. Use table_scan_cost() instead.
2691 */
2692
scan_time()2693 virtual double scan_time()
2694 { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
2695
2696 /**
2697 The cost of reading a set of ranges from the table using an index
2698 to access it.
2699
2700 @deprecated This function is deprecated and will be removed in a future
2701 version. Use read_cost() instead.
2702
2703 @param index The index number.
2704 @param ranges The number of ranges to be read.
2705 @param rows Total number of rows to be read.
2706
2707 This method can be used to calculate the total cost of scanning a table
2708 using an index by calling it using read_time(index, 1, table_size).
2709 */
2710
read_time(uint index,uint ranges,ha_rows rows)2711 virtual double read_time(uint index, uint ranges, ha_rows rows)
2712 { return rows2double(ranges+rows); }
2713
2714 /**
2715 @deprecated This function is deprecated and will be removed in a future
2716 version. Use index_scan_cost() instead.
2717 */
2718
2719 virtual double index_only_read_time(uint keynr, double records);
2720
2721 /**
2722 Cost estimate for doing a complete table scan.
2723
2724 @note For this version it is recommended that storage engines continue
2725 to override scan_time() instead of this function.
2726
2727 @returns the estimated cost
2728 */
2729
2730 virtual Cost_estimate table_scan_cost();
2731
2732 /**
2733 Cost estimate for reading a number of ranges from an index.
2734
2735 The cost estimate will only include the cost of reading data that
2736 is contained in the index. If the records need to be read, use
2737 read_cost() instead.
2738
2739 @note The ranges parameter is currently ignored and is not taken
2740 into account in the cost estimate.
2741
2742 @note For this version it is recommended that storage engines continue
2743 to override index_only_read_time() instead of this function.
2744
2745 @param index the index number
2746 @param ranges the number of ranges to be read
2747 @param rows total number of rows to be read
2748
2749 @returns the estimated cost
2750 */
2751
2752 virtual Cost_estimate index_scan_cost(uint index, double ranges, double rows);
2753
2754 /**
2755 Cost estimate for reading a set of ranges from the table using an index
2756 to access it.
2757
2758 @note For this version it is recommended that storage engines continue
2759 to override read_time() instead of this function.
2760
2761 @param index the index number
2762 @param ranges the number of ranges to be read
2763 @param rows total number of rows to be read
2764
2765 @returns the estimated cost
2766 */
2767
2768 virtual Cost_estimate read_cost(uint index, double ranges, double rows);
2769
2770 /**
2771 Return an estimate on the amount of memory the storage engine will
2772 use for caching data in memory. If this is unknown or the storage
2773 engine does not cache data in memory -1 is returned.
2774 */
get_memory_buffer_size()2775 virtual longlong get_memory_buffer_size() const { return -1; }
2776
2777 /**
2778 Return an estimate of how much of the table that is currently stored
2779 in main memory.
2780
2781 This estimate should be the fraction of the table that currently
2782 is available in a main memory buffer. The estimate should be in the
2783 range from 0.0 (nothing in memory) to 1.0 (entire table in memory).
2784
2785 @return The fraction of the table in main memory buffer
2786 */
2787
2788 double table_in_memory_estimate() const;
2789
2790 /**
2791 Return an estimate of how much of the index that is currently stored
2792 in main memory.
2793
2794 This estimate should be the fraction of the index that currently
2795 is available in a main memory buffer. The estimate should be in the
2796 range from 0.0 (nothing in memory) to 1.0 (entire index in memory).
2797
2798 @param keyno the index to get an estimate for
2799
2800 @return The fraction of the index in main memory buffer
2801 */
2802
2803 double index_in_memory_estimate(uint keyno) const;
2804
2805 private:
2806 /**
2807 Make a guestimate for how much of a table or index is in a memory
2808 buffer in the case where the storage engine has not provided any
2809 estimate for this.
2810
2811 @param table_index_size size of the table or index
2812
2813 @return The fraction of the table or index in main memory buffer
2814 */
2815
2816 double estimate_in_memory_buffer(ulonglong table_index_size) const;
2817
2818 public:
2819 virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
2820 void *seq_init_param,
2821 uint n_ranges, uint *bufsz,
2822 uint *flags,
2823 Cost_estimate *cost);
2824 virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
2825 uint *bufsz, uint *flags,
2826 Cost_estimate *cost);
2827 virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
2828 uint n_ranges, uint mode,
2829 HANDLER_BUFFER *buf);
2830 virtual int multi_range_read_next(char **range_info);
2831
2832
keys_to_use_for_scanning()2833 virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
has_transactions()2834 bool has_transactions() const
2835 { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
extra_rec_buf_length()2836 virtual uint extra_rec_buf_length() const { return 0; }
2837
2838 /**
2839 @brief Determine whether an error can be ignored or not.
2840
2841 @details This method is used to analyze the error to see whether the
2842 error is ignorable or not. Such errors will be reported as warnings
2843 instead of errors for IGNORE statements. This means that the statement
2844 will not abort, but instead continue to the next row.
2845
2846 HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
2847 same thing as HA_ERR_FOUND_DUP_KEY, but can in some cases lead to
2848 a slightly different error message.
2849
2850 @param error error code received from the handler interface (HA_ERR_...)
2851
2852 @return whether the error is ignorablel or not
2853 @retval true the error is ignorable
2854 @retval false the error is not ignorable
2855 */
2856
2857 virtual bool is_ignorable_error(int error);
2858
2859 /**
2860 @brief Determine whether an error is fatal or not.
2861
2862 @details This method is used to analyze the error to see whether the
2863 error is fatal or not. A fatal error is an error that will not be
2864 possible to handle with SP handlers and will not be subject to
2865 retry attempts on the slave.
2866
2867 @param error error code received from the handler interface (HA_ERR_...)
2868
2869 @return whether the error is fatal or not
2870 @retval true the error is fatal
2871 @retval false the error is not fatal
2872 */
2873
2874 virtual bool is_fatal_error(int error);
2875
2876 protected:
2877 /**
2878 Number of rows in table. It will only be called if
2879 (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
2880 @param[out] num_rows number of rows in table.
2881 @retval 0 for OK, one of the HA_xxx values in case of error.
2882 */
records(ha_rows * num_rows)2883 virtual int records(ha_rows *num_rows)
2884 {
2885 *num_rows= stats.records;
2886 return 0;
2887 }
2888
2889 public:
2890 /**
2891 Public function wrapping the actual handler call, and doing error checking.
2892 @param[out] num_rows number of rows in table.
2893 @retval 0 for OK, one of the HA_xxx values in case of error.
2894 */
ha_records(ha_rows * num_rows)2895 int ha_records(ha_rows *num_rows)
2896 {
2897 int error= records(num_rows);
2898 // A return value of HA_POS_ERROR was previously used to indicate error.
2899 if (error != 0)
2900 assert(*num_rows == HA_POS_ERROR);
2901 if (*num_rows == HA_POS_ERROR)
2902 assert(error != 0);
2903 if (error != 0)
2904 {
2905 /*
2906 ha_innobase::records may have rolled back internally.
2907 In this case, thd_mark_transaction_to_rollback() will have been called.
2908 For the errors below, we need to abort right away.
2909 */
2910 switch (error) {
2911 case HA_ERR_LOCK_DEADLOCK:
2912 case HA_ERR_LOCK_TABLE_FULL:
2913 case HA_ERR_LOCK_WAIT_TIMEOUT:
2914 case HA_ERR_QUERY_INTERRUPTED:
2915 print_error(error, MYF(0));
2916 return error;
2917 default:
2918 return error;
2919 }
2920 }
2921 return 0;
2922 }
2923
2924 /**
2925 Return upper bound of current number of records in the table
2926 (max. of how many records one will retrieve when doing a full table scan)
2927 If upper bound is not known, HA_POS_ERROR should be returned as a max
2928 possible upper bound.
2929 */
estimate_rows_upper_bound()2930 virtual ha_rows estimate_rows_upper_bound()
2931 { return stats.records+EXTRA_RECORDS; }
2932
2933 /**
2934 Get the row type from the storage engine. If this method returns
2935 ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
2936 */
get_row_type()2937 virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
2938
index_type(uint key_number)2939 virtual const char *index_type(uint key_number) { assert(0); return "";}
2940
2941
2942 /**
2943 Signal that the table->read_set and table->write_set table maps changed
2944 The handler is allowed to set additional bits in the above map in this
2945 call. Normally the handler should ignore all calls until we have done
2946 a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
2947 as there may be several calls to this routine.
2948 */
2949 virtual void column_bitmaps_signal();
get_index(void)2950 uint get_index(void) const { return active_index; }
2951
2952 /**
2953 @retval 0 Bulk update used by handler
2954 @retval 1 Bulk update not used, normal operation used
2955 */
start_bulk_update()2956 virtual bool start_bulk_update() { return 1; }
2957 /**
2958 @retval 0 Bulk delete used by handler
2959 @retval 1 Bulk delete not used, normal operation used
2960 */
start_bulk_delete()2961 virtual bool start_bulk_delete() { return 1; }
2962 /**
2963 After this call all outstanding updates must be performed. The number
2964 of duplicate key errors are reported in the duplicate key parameter.
2965 It is allowed to continue to the batched update after this call, the
2966 handler has to wait until end_bulk_update with changing state.
2967
2968 @param dup_key_found Number of duplicate keys found
2969
2970 @retval 0 Success
2971 @retval >0 Error code
2972 */
exec_bulk_update(uint * dup_key_found)2973 virtual int exec_bulk_update(uint *dup_key_found)
2974 {
2975 assert(FALSE);
2976 return HA_ERR_WRONG_COMMAND;
2977 }
2978 /**
2979 Perform any needed clean-up, no outstanding updates are there at the
2980 moment.
2981 */
end_bulk_update()2982 virtual void end_bulk_update() { return; }
2983 /**
2984 Execute all outstanding deletes and close down the bulk delete.
2985
2986 @retval 0 Success
2987 @retval >0 Error code
2988 */
end_bulk_delete()2989 virtual int end_bulk_delete()
2990 {
2991 assert(FALSE);
2992 return HA_ERR_WRONG_COMMAND;
2993 }
2994 protected:
2995 /**
2996 @brief
2997 Positions an index cursor to the index specified in the handle
2998 ('active_index'). Fetches the row if available. If the key value is null,
2999 begin at the first key of the index.
3000 @returns 0 if success (found a record, and function has set table->status
3001 to 0); non-zero if no record (function has set table->status to
3002 STATUS_NOT_FOUND).
3003 */
index_read_map(uchar * buf,const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag)3004 virtual int index_read_map(uchar * buf, const uchar * key,
3005 key_part_map keypart_map,
3006 enum ha_rkey_function find_flag)
3007 {
3008 uint key_len= calculate_key_len(table, active_index, keypart_map);
3009 return index_read(buf, key, key_len, find_flag);
3010 }
3011 /**
3012 @brief
3013 Positions an index cursor to the index specified in argument. Fetches
3014 the row if available. If the key value is null, begin at the first key of
3015 the index.
3016 @returns @see index_read_map().
3017 */
3018 virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
3019 key_part_map keypart_map,
3020 enum ha_rkey_function find_flag);
3021 /// @returns @see index_read_map().
index_next(uchar * buf)3022 virtual int index_next(uchar * buf)
3023 { return HA_ERR_WRONG_COMMAND; }
3024 /// @returns @see index_read_map().
index_prev(uchar * buf)3025 virtual int index_prev(uchar * buf)
3026 { return HA_ERR_WRONG_COMMAND; }
3027 /// @returns @see index_read_map().
index_first(uchar * buf)3028 virtual int index_first(uchar * buf)
3029 { return HA_ERR_WRONG_COMMAND; }
3030 /// @returns @see index_read_map().
index_last(uchar * buf)3031 virtual int index_last(uchar * buf)
3032 { return HA_ERR_WRONG_COMMAND; }
3033 /// @returns @see index_read_map().
3034 virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
3035 /**
3036 @brief
3037 The following functions works like index_read, but it find the last
3038 row with the current key value or prefix.
3039 @returns @see index_read_map().
3040 */
index_read_last_map(uchar * buf,const uchar * key,key_part_map keypart_map)3041 virtual int index_read_last_map(uchar * buf, const uchar * key,
3042 key_part_map keypart_map)
3043 {
3044 uint key_len= calculate_key_len(table, active_index, keypart_map);
3045 return index_read_last(buf, key, key_len);
3046 }
3047 public:
3048
3049 /**
3050 Notify storage engine about imminent index scan where a large number of
3051 rows is expected to be returned. Does not replace nor call index_init.
3052 */
prepare_index_scan(void)3053 virtual int prepare_index_scan(void) { return 0; }
3054
3055 /**
3056 Notify storage engine about imminent index range scan.
3057 */
prepare_range_scan(const key_range * start_key,const key_range * end_key)3058 virtual int prepare_range_scan(const key_range *start_key,
3059 const key_range *end_key)
3060 {
3061 return 0;
3062 }
3063
3064 /**
3065 Notify storage engine about imminent index read with a bitmap of used key
3066 parts.
3067 */
prepare_index_key_scan_map(const uchar * key,key_part_map keypart_map)3068 int prepare_index_key_scan_map(const uchar *key, key_part_map keypart_map)
3069 {
3070 uint key_len= calculate_key_len(table, active_index, keypart_map);
3071 return prepare_index_key_scan(key, key_len);
3072 }
3073
3074 /**
3075 Query storage engine to see if it supports gap locks on this table.
3076 */
has_gap_locks()3077 virtual bool has_gap_locks() const { return false; }
3078
3079 /**
3080 Query storage engine to see if it can support handling specific replication
3081 method in its current configuration.
3082 */
rpl_can_handle_stm_event()3083 virtual bool rpl_can_handle_stm_event() const
3084 {
3085 return true;
3086 }
3087
3088 protected:
3089 static bool is_using_full_key(key_part_map keypart_map, uint actual_key_parts);
3090 bool is_using_full_unique_key(uint active_index,
3091 key_part_map keypart_map,
3092 enum ha_rkey_function find_flag) const;
3093 bool is_using_prohibited_gap_locks(TABLE* table,
3094 bool using_full_primary_key) const;
3095
3096 /**
3097 Notify storage engine about imminent index read with key length.
3098 */
prepare_index_key_scan(const uchar * key,uint key_len)3099 virtual int prepare_index_key_scan(const uchar *key, uint key_len)
3100 {
3101 return 0;
3102 }
3103
3104 public:
3105
3106 virtual int read_range_first(const key_range *start_key,
3107 const key_range *end_key,
3108 bool eq_range, bool sorted);
3109 virtual int read_range_next();
3110
3111 /**
3112 Set the end position for a range scan. This is used for checking
3113 for when to end the range scan and by the ICP code to determine
3114 that the next record is within the current range.
3115
3116 @param range The end value for the range scan
3117 @param direction Direction of the range scan
3118 */
3119 void set_end_range(const key_range* range,
3120 enum_range_scan_direction direction);
3121 int compare_key(key_range *range);
3122 int compare_key_icp(const key_range *range) const;
3123 int compare_key_in_buffer(const uchar *buf) const;
ft_init()3124 virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
ft_end()3125 void ft_end() { ft_handler=NULL; }
ft_init_ext(uint flags,uint inx,String * key)3126 virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
3127 { return NULL; }
ft_init_ext_with_hints(uint inx,String * key,Ft_hints * hints)3128 virtual FT_INFO *ft_init_ext_with_hints(uint inx, String *key,
3129 Ft_hints *hints)
3130 {
3131 return ft_init_ext(hints->get_flags(), inx, key);
3132 }
ft_read(uchar * buf)3133 virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
3134 protected:
3135 /// @returns @see index_read_map().
3136 virtual int rnd_next(uchar *buf)=0;
3137 /// @returns @see index_read_map().
3138 virtual int rnd_pos(uchar * buf, uchar *pos)=0;
3139 public:
3140 /**
3141 This function only works for handlers having
3142 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
3143 It will return the row with the PK given in the record argument.
3144 */
rnd_pos_by_record(uchar * record)3145 virtual int rnd_pos_by_record(uchar *record)
3146 {
3147 int error;
3148 assert(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION);
3149
3150 error = ha_rnd_init(FALSE);
3151 if (error != 0)
3152 return error;
3153
3154 position(record);
3155 error = ha_rnd_pos(record, ref);
3156 ha_rnd_end();
3157 return error;
3158
3159 }
3160 virtual int read_first_row(uchar *buf, uint primary_key);
records_in_range(uint inx,key_range * min_key,key_range * max_key)3161 virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
3162 { return (ha_rows) 10; }
3163 /*
3164 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
3165 (reference to the row, aka position, with the primary key given in
3166 the record).
3167 Otherwise it set ref to the current row.
3168 */
3169 virtual void position(const uchar *record)=0;
3170 virtual int info(uint)=0; // see my_base.h for full description
calculate_key_hash_value(Field ** field_array)3171 virtual uint32 calculate_key_hash_value(Field **field_array)
3172 { assert(0); return 0; }
extra(enum ha_extra_function operation)3173 virtual int extra(enum ha_extra_function operation)
3174 { return 0; }
extra_opt(enum ha_extra_function operation,ulong cache_size)3175 virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
3176 { return extra(operation); }
3177
3178 /**
3179 Start read (before write) removal on the current table.
3180 @see HA_READ_BEFORE_WRITE_REMOVAL
3181 */
start_read_removal(void)3182 virtual bool start_read_removal(void)
3183 { assert(0); return false; }
3184
3185 /**
3186 End read (before write) removal and return the number of rows
3187 really written
3188 @see HA_READ_BEFORE_WRITE_REMOVAL
3189 */
end_read_removal(void)3190 virtual ha_rows end_read_removal(void)
3191 { assert(0); return (ha_rows) 0; }
3192
3193 /**
3194 In an UPDATE or DELETE, if the row under the cursor was locked by another
3195 transaction, and the engine used an optimistic read of the last
3196 committed row value under the cursor, then the engine returns 1 from this
3197 function. MySQL must NOT try to update this optimistic value. If the
3198 optimistic value does not match the WHERE condition, MySQL can decide to
3199 skip over this row. Currently only works for InnoDB. This can be used to
3200 avoid unnecessary lock waits.
3201
3202 If this method returns nonzero, it will also signal the storage
3203 engine that the next read will be a locking re-read of the row.
3204 */
was_semi_consistent_read()3205 virtual bool was_semi_consistent_read() { return 0; }
3206 /**
3207 Tell the engine whether it should avoid unnecessary lock waits.
3208 If yes, in an UPDATE or DELETE, if the row under the cursor was locked
3209 by another transaction, the engine may try an optimistic read of
3210 the last committed row value under the cursor.
3211 */
try_semi_consistent_read(bool)3212 virtual void try_semi_consistent_read(bool) {}
unlock_row()3213 virtual void unlock_row() {}
start_stmt(THD * thd,thr_lock_type lock_type)3214 virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
3215 virtual void get_auto_increment(ulonglong offset, ulonglong increment,
3216 ulonglong nb_desired_values,
3217 ulonglong *first_value,
3218 ulonglong *nb_reserved_values);
set_next_insert_id(ulonglong id)3219 void set_next_insert_id(ulonglong id)
3220 {
3221 DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
3222 next_insert_id= id;
3223 }
restore_auto_increment(ulonglong prev_insert_id)3224 void restore_auto_increment(ulonglong prev_insert_id)
3225 {
3226 /*
3227 Insertion of a row failed, re-use the lastly generated auto_increment
3228 id, for the next row. This is achieved by resetting next_insert_id to
3229 what it was before the failed insertion (that old value is provided by
3230 the caller). If that value was 0, it was the first row of the INSERT;
3231 then if insert_id_for_cur_row contains 0 it means no id was generated
3232 for this first row, so no id was generated since the INSERT started, so
3233 we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
3234 is the generated id of the first and failed row, so we use it.
3235 */
3236 next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
3237 insert_id_for_cur_row;
3238 }
3239
3240 /*
3241 This function allows the storage engine to adust the create_info before
3242 the frm is written based on it.
3243 This can be used for example to modify the create statement based on a
3244 storage engine specific setting.
3245 */
adjust_create_info_for_frm(HA_CREATE_INFO * create_info)3246 virtual void adjust_create_info_for_frm(HA_CREATE_INFO *create_info) {}
3247
update_create_info(HA_CREATE_INFO * create_info)3248 virtual void update_create_info(HA_CREATE_INFO *create_info) {}
3249
3250 int check_old_types();
assign_to_keycache(THD * thd,HA_CHECK_OPT * check_opt)3251 virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
3252 { return HA_ADMIN_NOT_IMPLEMENTED; }
preload_keys(THD * thd,HA_CHECK_OPT * check_opt)3253 virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
3254 { return HA_ADMIN_NOT_IMPLEMENTED; }
3255 /* end of the list of admin commands */
3256
indexes_are_disabled(void)3257 virtual int indexes_are_disabled(void) {return 0;}
append_create_info(String * packet)3258 virtual void append_create_info(String *packet) {}
3259 /**
3260 If index == MAX_KEY then a check for table is made and if index <
3261 MAX_KEY then a check is made if the table has foreign keys and if
3262 a foreign key uses this index (and thus the index cannot be dropped).
3263
3264 @param index Index to check if foreign key uses it
3265
3266 @retval TRUE Foreign key defined on table or index
3267 @retval FALSE No foreign key defined
3268 */
is_fk_defined_on_table_or_index(uint index)3269 virtual bool is_fk_defined_on_table_or_index(uint index)
3270 { return FALSE; }
get_foreign_key_create_info()3271 virtual char* get_foreign_key_create_info()
3272 { return(NULL);} /* gets foreign key create string from InnoDB */
3273 /**
3274 Used in ALTER TABLE to check if changing storage engine is allowed.
3275
3276 @note Called without holding thr_lock.c lock.
3277
3278 @retval true Changing storage engine is allowed.
3279 @retval false Changing storage engine not allowed.
3280 */
can_switch_engines()3281 virtual bool can_switch_engines() { return true; }
3282 /**
3283 Get the list of foreign keys in this table.
3284
3285 @remark Returns the set of foreign keys where this table is the
3286 dependent or child table.
3287
3288 @param thd The thread handle.
3289 @param f_key_list[out] The list of foreign keys.
3290
3291 @return The handler error code or zero for success.
3292 */
3293 virtual int
get_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)3294 get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
3295 { return 0; }
3296 /**
3297 Get the list of foreign keys referencing this table.
3298
3299 @remark Returns the set of foreign keys where this table is the
3300 referenced or parent table.
3301
3302 @param thd The thread handle.
3303 @param f_key_list[out] The list of foreign keys.
3304
3305 @return The handler error code or zero for success.
3306 */
3307 virtual int
get_parent_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)3308 get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
3309 { return 0; }
3310 /**
3311 Get the list of tables which are direct or indirect parents in foreign
3312 key with cascading actions for this table.
3313
3314 @remarks Returns the set of parent tables connected by FK clause that
3315 can modify the given table.
3316
3317 @param thd The thread handle.
3318 @param[out] fk_table_list List of parent tables (including indirect parents).
3319 Elements of the list as well as buffers for database
3320 and schema names are allocated from the current
3321 memory root.
3322
3323 @return The handler error code or zero for success
3324 */
3325 virtual int
get_cascade_foreign_key_table_list(THD * thd,List<st_handler_tablename> * fk_table_list)3326 get_cascade_foreign_key_table_list(THD *thd,
3327 List<st_handler_tablename> *fk_table_list)
3328 { return 0; }
referenced_by_foreign_key()3329 virtual uint referenced_by_foreign_key() { return 0;}
init_table_handle_for_HANDLER()3330 virtual void init_table_handle_for_HANDLER()
3331 { return; } /* prepare InnoDB for HANDLER */
free_foreign_key_create_info(char * str)3332 virtual void free_foreign_key_create_info(char* str) {}
3333 /** The following can be called without an open handler */
3334 virtual const char *table_type() const =0;
3335 /**
3336 If frm_error() is called then we will use this to find out what file
3337 extentions exist for the storage engine. This is also used by the default
3338 rename_table and delete_table method in handler.cc.
3339
3340 For engines that have two file name extentions (separate meta/index file
3341 and data file), the order of elements is relevant. First element of engine
3342 file name extentions array should be meta/index file extention. Second
3343 element - data file extention. This order is assumed by
3344 prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued.
3345 */
3346 virtual const char **bas_ext() const =0;
3347
3348 virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
3349
max_record_length()3350 uint max_record_length() const
3351 {
3352 return std::min(HA_MAX_REC_LENGTH, max_supported_record_length());
3353 }
max_keys()3354 uint max_keys() const
3355 {
3356 return std::min<uint>(MAX_KEY, max_supported_keys());
3357 }
max_key_parts()3358 uint max_key_parts() const
3359 {
3360 return std::min(MAX_REF_PARTS, max_supported_key_parts());
3361 }
max_key_length()3362 uint max_key_length() const
3363 {
3364 return std::min(MAX_KEY_LENGTH, max_supported_key_length());
3365 }
max_key_part_length(HA_CREATE_INFO * create_info)3366 uint max_key_part_length(HA_CREATE_INFO *create_info) const
3367 {
3368 return std::min(MAX_KEY_LENGTH, max_supported_key_part_length(create_info));
3369 }
3370
max_supported_record_length()3371 virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
max_supported_keys()3372 virtual uint max_supported_keys() const { return 0; }
max_supported_key_parts()3373 virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
max_supported_key_length()3374 virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
max_supported_key_part_length(HA_CREATE_INFO * create_info MY_ATTRIBUTE ((unused)))3375 virtual uint max_supported_key_part_length(HA_CREATE_INFO
3376 *create_info MY_ATTRIBUTE((unused))) const
3377 { return 255; }
min_record_length(uint options)3378 virtual uint min_record_length(uint options) const { return 1; }
3379
low_byte_first()3380 virtual bool low_byte_first() const { return 1; }
checksum()3381 virtual ha_checksum checksum() const { return 0; }
is_crashed()3382 virtual bool is_crashed() const { return 0; }
auto_repair()3383 virtual bool auto_repair() const { return 0; }
3384
3385 void update_global_table_stats();
3386 void update_global_index_stats();
update_index_stats(uint current_index)3387 void update_index_stats(uint current_index)
3388 {
3389 rows_read++;
3390 if (current_index < MAX_KEY)
3391 index_rows_read[current_index]++;
3392 else
3393 index_rows_read[0]++;
3394 }
3395
3396 #define CHF_CREATE_FLAG 0
3397 #define CHF_DELETE_FLAG 1
3398 #define CHF_RENAME_FLAG 2
3399 #define CHF_INDEX_FLAG 3
3400
3401
3402 /**
3403 @note lock_count() can return > 1 if the table is MERGE or partitioned.
3404 */
lock_count(void)3405 virtual uint lock_count(void) const { return 1; }
3406 /**
3407 Is not invoked for non-transactional temporary tables.
3408
3409 @note store_lock() can return more than one lock if the table is MERGE
3410 or partitioned.
3411
3412 @note that one can NOT rely on table->in_use in store_lock(). It may
3413 refer to a different thread if called from mysql_lock_abort_for_thread().
3414
3415 @note If the table is MERGE, store_lock() can return less locks
3416 than lock_count() claimed. This can happen when the MERGE children
3417 are not attached when this is called from another thread.
3418 */
3419 virtual THR_LOCK_DATA **store_lock(THD *thd,
3420 THR_LOCK_DATA **to,
3421 enum thr_lock_type lock_type)=0;
3422
3423 /** Type of table for caching query */
table_cache_type()3424 virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
3425
3426
3427 /**
3428 @brief Register a named table with a call back function to the query cache.
3429
3430 @param thd The thread handle
3431 @param table_key A pointer to the table name in the table cache
3432 @param key_length The length of the table name
3433 @param[out] engine_callback The pointer to the storage engine call back
3434 function
3435 @param[out] engine_data Storage engine specific data which could be
3436 anything
3437
3438 This method offers the storage engine, the possibility to store a reference
3439 to a table name which is going to be used with query cache.
3440 The method is called each time a statement is written to the cache and can
3441 be used to verify if a specific statement is cachable. It also offers
3442 the possibility to register a generic (but static) call back function which
3443 is called each time a statement is matched against the query cache.
3444
3445 @note If engine_data supplied with this function is different from
3446 engine_data supplied with the callback function, and the callback returns
3447 FALSE, a table invalidation on the current table will occur.
3448
3449 @return Upon success the engine_callback will point to the storage engine
3450 call back function, if any, and engine_data will point to any storage
3451 engine data used in the specific implementation.
3452 @retval TRUE Success
3453 @retval FALSE The specified table or current statement should not be
3454 cached
3455 */
3456
register_query_cache_table(THD * thd,char * table_key,size_t key_length,qc_engine_callback * engine_callback,ulonglong * engine_data)3457 virtual my_bool register_query_cache_table(THD *thd, char *table_key,
3458 size_t key_length,
3459 qc_engine_callback
3460 *engine_callback,
3461 ulonglong *engine_data)
3462 {
3463 *engine_callback= 0;
3464 return TRUE;
3465 }
3466
3467
3468 /**
3469 Check if the primary key is clustered or not.
3470
3471 @retval true Primary key (if there is one) is a clustered
3472 key covering all fields
3473 @retval false otherwise
3474 */
3475
primary_key_is_clustered()3476 virtual bool primary_key_is_clustered() const { return false; }
cmp_ref(const uchar * ref1,const uchar * ref2)3477 virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
3478 {
3479 return memcmp(ref1, ref2, ref_length);
3480 }
3481
3482 /*
3483 Condition pushdown to storage engines
3484 */
3485
3486 /**
3487 Push condition down to the table handler.
3488
3489 @param cond Condition to be pushed. The condition tree must not be
3490 modified by the by the caller.
3491
3492 @return
3493 The 'remainder' condition that caller must use to filter out records.
3494 NULL means the handler will not return rows that do not match the
3495 passed condition.
3496
3497 @note
3498 The pushed conditions form a stack (from which one can remove the
3499 last pushed condition using cond_pop).
3500 The table handler filters out rows using (pushed_cond1 AND pushed_cond2
3501 AND ... AND pushed_condN)
3502 or less restrictive condition, depending on handler's capabilities.
3503
3504 handler->ha_reset() call empties the condition stack.
3505 Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
3506 condition stack.
3507 */
cond_push(const Item * cond)3508 virtual const Item *cond_push(const Item *cond) { return cond; };
3509 /**
3510 Pop the top condition from the condition stack of the handler instance.
3511
3512 Pops the top if condition stack, if stack is not empty.
3513 */
cond_pop()3514 virtual void cond_pop() { return; }
3515
3516 /**
3517 Push down an index condition to the handler.
3518
3519 The server will use this method to push down a condition it wants
3520 the handler to evaluate when retrieving records using a specified
3521 index. The pushed index condition will only refer to fields from
3522 this handler that is contained in the index (but it may also refer
3523 to fields in other handlers). Before the handler evaluates the
3524 condition it must read the content of the index entry into the
3525 record buffer.
3526
3527 The handler is free to decide if and how much of the condition it
3528 will take responsibility for evaluating. Based on this evaluation
3529 it should return the part of the condition it will not evaluate.
3530 If it decides to evaluate the entire condition it should return
3531 NULL. If it decides not to evaluate any part of the condition it
3532 should return a pointer to the same condition as given as argument.
3533
3534 @param keyno the index number to evaluate the condition on
3535 @param idx_cond the condition to be evaluated by the handler
3536
3537 @return The part of the pushed condition that the handler decides
3538 not to evaluate
3539 */
3540
idx_cond_push(uint keyno,Item * idx_cond)3541 virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
3542
3543 /** Reset information about pushed index conditions */
cancel_pushed_idx_cond()3544 virtual void cancel_pushed_idx_cond()
3545 {
3546 pushed_idx_cond= NULL;
3547 pushed_idx_cond_keyno= MAX_KEY;
3548 in_range_check_pushed_down= false;
3549 }
3550
3551 /**
3552 Reports #tables included in pushed join which this
3553 handler instance is part of. ==0 -> Not pushed
3554 */
number_of_pushed_joins()3555 virtual uint number_of_pushed_joins() const
3556 { return 0; }
3557
3558 /**
3559 If this handler instance is part of a pushed join sequence
3560 returned TABLE instance being root of the pushed query?
3561 */
root_of_pushed_join()3562 virtual const TABLE* root_of_pushed_join() const
3563 { return NULL; }
3564
3565 /**
3566 If this handler instance is a child in a pushed join sequence
3567 returned TABLE instance being my parent?
3568 */
parent_of_pushed_join()3569 virtual const TABLE* parent_of_pushed_join() const
3570 { return NULL; }
3571
index_read_pushed(uchar * buf,const uchar * key,key_part_map keypart_map)3572 virtual int index_read_pushed(uchar * buf, const uchar * key,
3573 key_part_map keypart_map)
3574 { return HA_ERR_WRONG_COMMAND; }
3575
index_next_pushed(uchar * buf)3576 virtual int index_next_pushed(uchar * buf)
3577 { return HA_ERR_WRONG_COMMAND; }
3578
3579 /**
3580 Part of old, deprecated in-place ALTER API.
3581 */
check_if_incompatible_data(HA_CREATE_INFO * create_info,uint table_changes)3582 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
3583 uint table_changes)
3584 { return COMPATIBLE_DATA_NO; }
3585
3586 /* On-line/in-place ALTER TABLE interface. */
3587
3588 /*
3589 Here is an outline of on-line/in-place ALTER TABLE execution through
3590 this interface.
3591
3592 Phase 1 : Initialization
3593 ========================
3594 During this phase we determine which algorithm should be used
3595 for execution of ALTER TABLE and what level concurrency it will
3596 require.
3597
3598 *) This phase starts by opening the table and preparing description
3599 of the new version of the table.
3600 *) Then we check if it is impossible even in theory to carry out
3601 this ALTER TABLE using the in-place algorithm. For example, because
3602 we need to change storage engine or the user has explicitly requested
3603 usage of the "copy" algorithm.
3604 *) If in-place ALTER TABLE is theoretically possible, we continue
3605 by compiling differences between old and new versions of the table
3606 in the form of HA_ALTER_FLAGS bitmap. We also build a few
3607 auxiliary structures describing requested changes and store
3608 all these data in the Alter_inplace_info object.
3609 *) Then the handler::check_if_supported_inplace_alter() method is called
3610 in order to find if the storage engine can carry out changes requested
3611 by this ALTER TABLE using the in-place algorithm. To determine this,
3612 the engine can rely on data in HA_ALTER_FLAGS/Alter_inplace_info
3613 passed to it as well as on its own checks. If the in-place algorithm
3614 can be used for this ALTER TABLE, the level of required concurrency for
3615 its execution is also returned.
3616 If any errors occur during the handler call, ALTER TABLE is aborted
3617 and no further handler functions are called.
3618 *) Locking requirements of the in-place algorithm are compared to any
3619 concurrency requirements specified by user. If there is a conflict
3620 between them, we either switch to the copy algorithm or emit an error.
3621
3622 Phase 2 : Execution
3623 ===================
3624
3625 In this phase the operations are executed.
3626
3627 *) As the first step, we acquire a lock corresponding to the concurrency
3628 level which was returned by handler::check_if_supported_inplace_alter()
3629 and requested by the user. This lock is held for most of the
3630 duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
3631 or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an
3632 exclusive lock for duration of the next step only).
3633 *) After that we call handler::ha_prepare_inplace_alter_table() to give the
3634 storage engine a chance to update its internal structures with a higher
3635 lock level than the one that will be used for the main step of algorithm.
3636 After that we downgrade the lock if it is necessary.
3637 *) After that, the main step of this phase and algorithm is executed.
3638 We call the handler::ha_inplace_alter_table() method, which carries out the
3639 changes requested by ALTER TABLE but does not makes them visible to other
3640 connections yet.
3641 *) We ensure that no other connection uses the table by upgrading our
3642 lock on it to exclusive.
3643 *) a) If the previous step succeeds, handler::ha_commit_inplace_alter_table() is
3644 called to allow the storage engine to do any final updates to its structures,
3645 to make all earlier changes durable and visible to other connections.
3646 b) If we have failed to upgrade lock or any errors have occured during the
3647 handler functions calls (including commit), we call
3648 handler::ha_commit_inplace_alter_table()
3649 to rollback all changes which were done during previous steps.
3650
3651 Phase 3 : Final
3652 ===============
3653
3654 In this phase we:
3655
3656 *) Update SQL-layer data-dictionary by installing .FRM file for the new version
3657 of the table.
3658 *) Inform the storage engine about this change by calling the
3659 handler::ha_notify_table_changed() method.
3660 *) Destroy the Alter_inplace_info and handler_ctx objects.
3661
3662 */
3663
3664 /**
3665 Check if a storage engine supports a particular alter table in-place
3666
3667 @param altered_table TABLE object for new version of table.
3668 @param ha_alter_info Structure describing changes to be done
3669 by ALTER TABLE and holding data used
3670 during in-place alter.
3671
3672 @retval HA_ALTER_ERROR Unexpected error.
3673 @retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported, must use copy.
3674 @retval HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
3675 @retval HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
3676 Supported, but requires SNW lock
3677 during main phase. Prepare phase
3678 requires X lock.
3679 @retval HA_ALTER_INPLACE_SHARED_LOCK Supported, but requires SNW lock.
3680 @retval HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
3681 Supported, concurrent reads/writes
3682 allowed. However, prepare phase
3683 requires X lock.
3684 @retval HA_ALTER_INPLACE_NO_LOCK Supported, concurrent
3685 reads/writes allowed.
3686
3687 @note The default implementation uses the old in-place ALTER API
3688 to determine if the storage engine supports in-place ALTER or not.
3689
3690 @note Called without holding thr_lock.c lock.
3691 */
3692 virtual enum_alter_inplace_result
3693 check_if_supported_inplace_alter(TABLE *altered_table,
3694 Alter_inplace_info *ha_alter_info);
3695
3696
3697 /**
3698 Public functions wrapping the actual handler call.
3699 @see prepare_inplace_alter_table()
3700 */
3701 bool ha_prepare_inplace_alter_table(TABLE *altered_table,
3702 Alter_inplace_info *ha_alter_info);
3703
3704
3705 /**
3706 Public function wrapping the actual handler call.
3707 @see inplace_alter_table()
3708 */
ha_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)3709 bool ha_inplace_alter_table(TABLE *altered_table,
3710 Alter_inplace_info *ha_alter_info)
3711 {
3712 return inplace_alter_table(altered_table, ha_alter_info);
3713 }
3714
3715
3716 /**
3717 Public function wrapping the actual handler call.
3718 Allows us to enforce asserts regardless of handler implementation.
3719 @see commit_inplace_alter_table()
3720 */
3721 bool ha_commit_inplace_alter_table(TABLE *altered_table,
3722 Alter_inplace_info *ha_alter_info,
3723 bool commit);
3724
3725
3726 /**
3727 Public function wrapping the actual handler call.
3728 @see notify_table_changed()
3729 */
ha_notify_table_changed()3730 void ha_notify_table_changed()
3731 {
3732 notify_table_changed();
3733 }
3734
3735
3736 protected:
3737 /**
3738 Allows the storage engine to update internal structures with concurrent
3739 writes blocked. If check_if_supported_inplace_alter() returns
3740 HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE or
3741 HA_ALTER_INPLACE_SHARED_AFTER_PREPARE, this function is called with
3742 exclusive lock otherwise the same level of locking as for
3743 inplace_alter_table() will be used.
3744
3745 @note Storage engines are responsible for reporting any errors by
3746 calling my_error()/print_error()
3747
3748 @note If this function reports error, commit_inplace_alter_table()
3749 will be called with commit= false.
3750
3751 @note For partitioning, failing to prepare one partition, means that
3752 commit_inplace_alter_table() will be called to roll back changes for
3753 all partitions. This means that commit_inplace_alter_table() might be
3754 called without prepare_inplace_alter_table() having been called first
3755 for a given partition.
3756
3757 @param altered_table TABLE object for new version of table.
3758 @param ha_alter_info Structure describing changes to be done
3759 by ALTER TABLE and holding data used
3760 during in-place alter.
3761
3762 @retval true Error
3763 @retval false Success
3764 */
prepare_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)3765 virtual bool prepare_inplace_alter_table(TABLE *altered_table,
3766 Alter_inplace_info *ha_alter_info)
3767 { return false; }
3768
3769
3770 /**
3771 Alter the table structure in-place with operations specified using HA_ALTER_FLAGS
3772 and Alter_inplace_info. The level of concurrency allowed during this
3773 operation depends on the return value from check_if_supported_inplace_alter().
3774
3775 @note Storage engines are responsible for reporting any errors by
3776 calling my_error()/print_error()
3777
3778 @note If this function reports error, commit_inplace_alter_table()
3779 will be called with commit= false.
3780
3781 @param altered_table TABLE object for new version of table.
3782 @param ha_alter_info Structure describing changes to be done
3783 by ALTER TABLE and holding data used
3784 during in-place alter.
3785
3786 @retval true Error
3787 @retval false Success
3788 */
inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)3789 virtual bool inplace_alter_table(TABLE *altered_table,
3790 Alter_inplace_info *ha_alter_info)
3791 { return false; }
3792
3793
3794 /**
3795 Commit or rollback the changes made during prepare_inplace_alter_table()
3796 and inplace_alter_table() inside the storage engine.
3797 Note that in case of rollback the allowed level of concurrency during
3798 this operation will be the same as for inplace_alter_table() and thus
3799 might be higher than during prepare_inplace_alter_table(). (For example,
3800 concurrent writes were blocked during prepare, but might not be during
3801 rollback).
3802
3803 @note Storage engines are responsible for reporting any errors by
3804 calling my_error()/print_error()
3805
3806 @note If this function with commit= true reports error, it will be called
3807 again with commit= false.
3808
3809 @note In case of partitioning, this function might be called for rollback
3810 without prepare_inplace_alter_table() having been called first.
3811 Also partitioned tables sets ha_alter_info->group_commit_ctx to a NULL
3812 terminated array of the partitions handlers and if all of them are
3813 committed as one, then group_commit_ctx should be set to NULL to indicate
3814 to the partitioning handler that all partitions handlers are committed.
3815 @see prepare_inplace_alter_table().
3816
3817 @param altered_table TABLE object for new version of table.
3818 @param ha_alter_info Structure describing changes to be done
3819 by ALTER TABLE and holding data used
3820 during in-place alter.
3821 @param commit True => Commit, False => Rollback.
3822
3823 @retval true Error
3824 @retval false Success
3825 */
commit_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info,bool commit)3826 virtual bool commit_inplace_alter_table(TABLE *altered_table,
3827 Alter_inplace_info *ha_alter_info,
3828 bool commit)
3829 {
3830 /* Nothing to commit/rollback, mark all handlers committed! */
3831 ha_alter_info->group_commit_ctx= NULL;
3832 return false;
3833 }
3834
3835
3836 /**
3837 Notify the storage engine that the table structure (.FRM) has been updated.
3838
3839 @note No errors are allowed during notify_table_changed().
3840 */
3841 virtual void notify_table_changed();
3842
3843 public:
3844 /* End of On-line/in-place ALTER TABLE interface. */
3845
3846 /**
3847 @brief Offload an update to the storage engine. See handler::fast_update()
3848 for details.
3849 */
3850 MY_NODISCARD int ha_fast_update(THD *thd,
3851 List<Item> &update_fields,
3852 List<Item> &update_values,
3853 Item *conds);
3854
3855 /**
3856 @brief Offload an upsert to the storage engine. See handler::upsert()
3857 for details.
3858 */
3859 MY_NODISCARD int ha_upsert(THD *thd,
3860 List<Item> &update_fields,
3861 List<Item> &update_values);
3862 private:
3863 /**
3864 Offload an update to the storage engine implementation.
3865
3866 @param thd The thread handle.
3867 @param update_fields The list of fields to update.
3868 @param update_values The list of new values for the fields
3869 in update_fields.
3870 @param conds Conditions tree.
3871
3872 @retval 0 if the storage engine handled the update.
3873 @retval ENOTSUP if the storage engine can not handle the
3874 update and the slow update code path should
3875 continue executing the update.
3876
3877 @return an error if the update should be terminated.
3878
3879 @note HA_READ_BEFORE_WRITE_REMOVAL flag doesn not fit there because
3880 handler::ha_update_row(...) does not accept conditions.
3881 */
fast_update(THD * thd,List<Item> & update_fields,List<Item> & update_values,Item * conds)3882 MY_NODISCARD virtual int fast_update(THD *thd,
3883 List<Item> &update_fields,
3884 List<Item> &update_values,
3885 Item *conds)
3886 { return ENOTSUP; }
3887
3888 /**
3889 Offload an upsert to the storage engine implementation. Expects the row
3890 to be stored in record[0].
3891
3892 @param thd The thread handle.
3893 @param update_fields The list of fields to update.
3894 @param update_values The list of new values for the fields
3895 in update_fields.
3896
3897 @retval 0 if the storage engine handled the upsert.
3898 @retval ENOTSUP if the storage engine can not handle the upsert
3899 and the slow insert code path should continue
3900 executing the insert.
3901
3902 @return an error if the insert should be terminated.
3903 */
upsert(THD * thd,List<Item> & update_fields,List<Item> & update_values)3904 MY_NODISCARD virtual int upsert(THD *thd,
3905 List<Item> &update_fields,
3906 List<Item> &update_values)
3907 { return ENOTSUP; }
3908
3909 public:
3910 /**
3911 use_hidden_primary_key() is called in case of an update/delete when
3912 (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
3913 but we don't have a primary key
3914 */
3915 virtual void use_hidden_primary_key();
3916
3917 /**
3918 A helper function to mark a transaction as noop_read_write if it is started.
3919 */
3920 void mark_trx_noop_dml();
3921
3922 protected:
3923 /* Service methods for use by storage engines. */
3924 void ha_statistic_increment(ulonglong SSV::*offset) const;
3925 THD *ha_thd(void) const;
3926
3927 /**
3928 Acquire the instrumented table information from a table share.
3929 @param share a table share
3930 @return an instrumented table share, or NULL.
3931 */
3932 PSI_table_share *ha_table_share_psi(const TABLE_SHARE *share) const;
3933
3934 /**
3935 Default rename_table() and delete_table() rename/delete files with a
3936 given name and extensions from bas_ext().
3937
3938 These methods can be overridden, but their default implementation
3939 provide useful functionality.
3940 */
3941 virtual int rename_table(const char *from, const char *to);
3942 /**
3943 Delete a table in the engine. Called for base as well as temporary
3944 tables.
3945 */
3946 virtual int delete_table(const char *name);
3947 private:
3948 /* Private helpers */
3949 void mark_trx_read_write();
3950 /*
3951 Low-level primitives for storage engines. These should be
3952 overridden by the storage engine class. To call these methods, use
3953 the corresponding 'ha_*' method above.
3954 */
3955
3956 virtual int open(const char *name, int mode, uint test_if_locked)=0;
3957 virtual int close(void)=0;
index_init(uint idx,bool sorted)3958 virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; }
index_end()3959 virtual int index_end() { active_index= MAX_KEY; return 0; }
3960 /**
3961 rnd_init() can be called two times without rnd_end() in between
3962 (it only makes sense if scan=1).
3963 then the second call should prepare for the new table scan (e.g
3964 if rnd_init allocates the cursor, second call should position it
3965 to the start of the table, no need to deallocate and allocate it again
3966 */
3967 virtual int rnd_init(bool scan)= 0;
rnd_end()3968 virtual int rnd_end() { return 0; }
3969 /**
3970 Write a row.
3971
3972 write_row() inserts a row. buf is a byte array of data, normally
3973 record[0].
3974
3975 You can use the field information to extract the data from the native byte
3976 array type.
3977
3978 Example of this would be:
3979 for (Field **field=table->field ; *field ; field++)
3980 {
3981 ...
3982 }
3983
3984 @param buf Buffer to write from.
3985
3986 @return Operation status.
3987 @retval 0 Success.
3988 @retval != 0 Error code.
3989 */
write_row(uchar * buf MY_ATTRIBUTE ((unused)))3990 virtual int write_row(uchar *buf MY_ATTRIBUTE((unused)))
3991 {
3992 return HA_ERR_WRONG_COMMAND;
3993 }
3994
3995 /**
3996 Update a single row.
3997
3998 Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
3999 all columns of the row so MySQL can create an error message. If
4000 the columns required for the error message are not read, the error
4001 message will contain garbage.
4002 */
update_row(const uchar * old_data MY_ATTRIBUTE ((unused)),uchar * new_data MY_ATTRIBUTE ((unused)))4003 virtual int update_row(const uchar *old_data MY_ATTRIBUTE((unused)),
4004 uchar *new_data MY_ATTRIBUTE((unused)))
4005 {
4006 return HA_ERR_WRONG_COMMAND;
4007 }
4008
delete_row(const uchar * buf MY_ATTRIBUTE ((unused)))4009 virtual int delete_row(const uchar *buf MY_ATTRIBUTE((unused)))
4010 {
4011 return HA_ERR_WRONG_COMMAND;
4012 }
4013 /**
4014 Reset state of file to after 'open'.
4015 This function is called after every statement for all tables used
4016 by that statement.
4017 */
reset()4018 virtual int reset() { return 0; }
4019 virtual Table_flags table_flags(void) const= 0;
4020 /**
4021 Is not invoked for non-transactional temporary tables.
4022
4023 Tells the storage engine that we intend to read or write data
4024 from the table. This call is prefixed with a call to handler::store_lock()
4025 and is invoked only for those handler instances that stored the lock.
4026
4027 Calls to rnd_init/index_init are prefixed with this call. When table
4028 IO is complete, we call external_lock(F_UNLCK).
4029 A storage engine writer should expect that each call to
4030 ::external_lock(F_[RD|WR]LOCK is followed by a call to
4031 ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
4032
4033 The name and signature originate from the first implementation
4034 in MyISAM, which would call fcntl to set/clear an advisory
4035 lock on the data file in this method.
4036
4037 @param lock_type F_RDLCK, F_WRLCK, F_UNLCK
4038
4039 @return non-0 in case of failure, 0 in case of success.
4040 When lock_type is F_UNLCK, the return value is ignored.
4041 */
external_lock(THD * thd MY_ATTRIBUTE ((unused)),int lock_type MY_ATTRIBUTE ((unused)))4042 virtual int external_lock(THD *thd MY_ATTRIBUTE((unused)),
4043 int lock_type MY_ATTRIBUTE((unused)))
4044 {
4045 return 0;
4046 }
release_auto_increment()4047 virtual void release_auto_increment() { return; };
4048 /** admin commands - called from mysql_admin_table */
check_for_upgrade(HA_CHECK_OPT * check_opt)4049 virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
4050 { return 0; }
check(THD * thd,HA_CHECK_OPT * check_opt)4051 virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
4052 { return HA_ADMIN_NOT_IMPLEMENTED; }
4053
4054 /**
4055 In this method check_opt can be modified
4056 to specify CHECK option to use to call check()
4057 upon the table.
4058 */
repair(THD * thd,HA_CHECK_OPT * check_opt)4059 virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
4060 {
4061 assert(!(ha_table_flags() & HA_CAN_REPAIR));
4062 return HA_ADMIN_NOT_IMPLEMENTED;
4063 }
start_bulk_insert(ha_rows rows)4064 virtual void start_bulk_insert(ha_rows rows) {}
end_bulk_insert()4065 virtual int end_bulk_insert() { return 0; }
4066 protected:
index_read(uchar * buf,const uchar * key,uint key_len,enum ha_rkey_function find_flag)4067 virtual int index_read(uchar * buf, const uchar * key, uint key_len,
4068 enum ha_rkey_function find_flag)
4069 { return HA_ERR_WRONG_COMMAND; }
index_read_last(uchar * buf,const uchar * key,uint key_len)4070 virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
4071 {
4072 set_my_errno(HA_ERR_WRONG_COMMAND);
4073 return HA_ERR_WRONG_COMMAND;
4074 }
4075 public:
4076 /**
4077 This method is similar to update_row, however the handler doesn't need
4078 to execute the updates at this point in time. The handler can be certain
4079 that another call to bulk_update_row will occur OR a call to
4080 exec_bulk_update before the set of updates in this query is concluded.
4081
4082 Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
4083 all columns of the row so MySQL can create an error message. If
4084 the columns required for the error message are not read, the error
4085 message will contain garbage.
4086
4087 @param old_data Old record
4088 @param new_data New record
4089 @param dup_key_found Number of duplicate keys found
4090
4091 */
bulk_update_row(const uchar * old_data,uchar * new_data,uint * dup_key_found)4092 virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
4093 uint *dup_key_found)
4094 {
4095 assert(FALSE);
4096 return HA_ERR_WRONG_COMMAND;
4097 }
4098 /**
4099 This is called to delete all rows in a table
4100 If the handler don't support this, then this function will
4101 return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
4102 by one.
4103 */
delete_all_rows()4104 virtual int delete_all_rows()
4105 {
4106 set_my_errno(HA_ERR_WRONG_COMMAND);
4107 return HA_ERR_WRONG_COMMAND;
4108 }
4109 /**
4110 Quickly remove all rows from a table.
4111
4112 @remark This method is responsible for implementing MySQL's TRUNCATE
4113 TABLE statement, which is a DDL operation. As such, a engine
4114 can bypass certain integrity checks and in some cases avoid
4115 fine-grained locking (e.g. row locks) which would normally be
4116 required for a DELETE statement.
4117
4118 @remark Typically, truncate is not used if it can result in integrity
4119 violation. For example, truncate is not used when a foreign
4120 key references the table, but it might be used if foreign key
4121 checks are disabled.
4122
4123 @remark Engine is responsible for resetting the auto-increment counter.
4124
4125 @remark The table is locked in exclusive mode.
4126 */
truncate()4127 virtual int truncate()
4128 { return HA_ERR_WRONG_COMMAND; }
optimize(THD * thd,HA_CHECK_OPT * check_opt)4129 virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
4130 { return HA_ADMIN_NOT_IMPLEMENTED; }
analyze(THD * thd,HA_CHECK_OPT * check_opt)4131 virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
4132 { return HA_ADMIN_NOT_IMPLEMENTED; }
check_and_repair(THD * thd)4133 virtual bool check_and_repair(THD *thd) { return TRUE; }
disable_indexes(uint mode)4134 virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
enable_indexes(uint mode)4135 virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
discard_or_import_tablespace(my_bool discard)4136 virtual int discard_or_import_tablespace(my_bool discard)
4137 {
4138 set_my_errno(HA_ERR_WRONG_COMMAND);
4139 return HA_ERR_WRONG_COMMAND;
4140 }
4141 virtual void drop_table(const char *name);
4142 virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
4143
create_handler_files(const char * name,const char * old_name,int action_flag,HA_CREATE_INFO * info)4144 virtual int create_handler_files(const char *name, const char *old_name,
4145 int action_flag, HA_CREATE_INFO *info)
4146 { return FALSE; }
4147
set_ha_share_ref(Handler_share ** arg_ha_share)4148 virtual bool set_ha_share_ref(Handler_share **arg_ha_share)
4149 {
4150 assert(!ha_share);
4151 assert(arg_ha_share);
4152 if (ha_share || !arg_ha_share)
4153 return true;
4154 ha_share= arg_ha_share;
4155 return false;
4156 }
get_lock_type()4157 int get_lock_type() const { return m_lock_type; }
4158 /**
4159 This method is supposed to fill field definition objects with
4160 compression dictionary info (name and data).
4161 If the handler does not support compression dictionaries
4162 this method should be left empty (not overloaded).
4163
4164 @param thd Thread handle
4165 @param part_name Full table name (including partition part).
4166 Optional.
4167 */
update_field_defs_with_zip_dict_info(THD * thd,const char * part_name)4168 virtual void update_field_defs_with_zip_dict_info(THD* thd,
4169 const char* part_name) {}
4170
4171 public:
4172 /* Read-free replication interface */
4173
4174 /**
4175 Determine whether the storage engine asks for row-based replication that
4176 may skip the lookup of the old row image.
4177
4178 @return true if old rows should be read (the default)
4179 false if old rows should not be read
4180 */
rpl_lookup_rows()4181 virtual bool rpl_lookup_rows() { return true; }
4182 /*
4183 Storage engine hooks to be called before and after row write, delete, and
4184 update events
4185 */
rpl_before_write_rows()4186 virtual void rpl_before_write_rows() { }
rpl_after_write_rows()4187 virtual void rpl_after_write_rows() { }
rpl_before_delete_rows()4188 virtual void rpl_before_delete_rows() { }
rpl_after_delete_rows()4189 virtual void rpl_after_delete_rows() { }
rpl_before_update_rows()4190 virtual void rpl_before_update_rows() { }
rpl_after_update_rows()4191 virtual void rpl_after_update_rows() { }
4192
4193 /**
4194 Callback function that will be called by my_prepare_gcolumn_template
4195 once the table has been opened.
4196 */
4197 typedef void (*my_gcolumn_template_callback_t)(const TABLE*, void*);
4198 static bool my_prepare_gcolumn_template(THD *thd,
4199 const char *db_name,
4200 const char *table_name,
4201 my_gcolumn_template_callback_t myc,
4202 void *ib_table);
4203 static bool my_eval_gcolumn_expr_with_open(THD *thd,
4204 const char *db_name,
4205 const char *table_name,
4206 const MY_BITMAP *const fields,
4207 uchar *record);
4208
4209 /**
4210 Callback for computing generated column values.
4211
4212 Storage engines that need to have virtual column values for a row
4213 can use this function to get the values computed. The storage
4214 engine must have filled in the values for the base columns that
4215 the virutal columns depend on.
4216
4217 @param thd thread handle
4218 @param table table object
4219 @param fields bitmap of field index of evaluated generated
4220 column
4221 @param record buff of base columns generated column depends.
4222 After calling this function, it will be
4223 used to return the value of the generated
4224 columns.
4225
4226 @retval true in case of error
4227 @retval false on success.
4228 */
4229 static bool my_eval_gcolumn_expr(THD *thd, TABLE *table,
4230 const MY_BITMAP *const fields,
4231 uchar *record);
4232
4233 /* This must be implemented if the handlerton's partition_flags() is set. */
get_partition_handler()4234 virtual Partition_handler *get_partition_handler()
4235 { return NULL; }
4236
4237 protected:
4238 Handler_share *get_ha_share_ptr();
4239 void set_ha_share_ptr(Handler_share *arg_ha_share);
4240 void lock_shared_ha_data();
4241 void unlock_shared_ha_data();
4242
4243 private:
4244 /**
4245 If true, the current handler is a clone. In that case certain invariants
4246 such as table->in_use == current_thd are relaxed to support cloning a
4247 handler belonging to a different thread. */
4248 bool cloned;
4249 };
4250
4251
4252 bool key_uses_partial_cols(TABLE *table, uint keyno);
4253
4254 /*
4255 A Disk-Sweep MRR interface implementation
4256
4257 This implementation makes range (and, in the future, 'ref') scans to read
4258 table rows in disk sweeps.
4259
4260 Currently it is used by MyISAM and InnoDB. Potentially it can be used with
4261 any table handler that has non-clustered indexes and on-disk rows.
4262 */
4263
4264 class DsMrr_impl
4265 {
4266 public:
4267 typedef void (handler::*range_check_toggle_func_t)(bool on);
4268
DsMrr_impl()4269 DsMrr_impl() : h2(NULL) {}
4270
~DsMrr_impl()4271 ~DsMrr_impl()
4272 {
4273 /*
4274 If ha_reset() has not been called then the h2 dialog might still
4275 exist. This must be closed and deleted (this is the case for
4276 internally created temporary tables).
4277 */
4278 if (h2)
4279 reset();
4280 assert(h2 == NULL);
4281 }
4282
4283 /*
4284 The "owner" handler object (the one that calls dsmrr_XXX functions.
4285 It is used to retrieve full table rows by calling rnd_pos().
4286 */
4287 handler *h;
4288 TABLE *table; /* Always equal to h->table */
4289 private:
4290 /* Secondary handler object. It is used for scanning the index */
4291 handler *h2;
4292
4293 /* Buffer to store rowids, or (rowid, range_id) pairs */
4294 uchar *rowids_buf;
4295 uchar *rowids_buf_cur; /* Current position when reading/writing */
4296 uchar *rowids_buf_last; /* When reading: end of used buffer space */
4297 uchar *rowids_buf_end; /* End of the buffer */
4298
4299 bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */
4300
4301 /* TRUE <=> need range association, buffer holds {rowid, range_id} pairs */
4302 bool is_mrr_assoc;
4303
4304 bool use_default_impl; /* TRUE <=> shortcut all calls to default MRR impl */
4305 public:
4306 /**
4307 Initialize the DsMrr_impl object.
4308
4309 This object is used for both doing default MRR scans and DS-MRR scans.
4310 This function just initializes the object. To do a DS-MRR scan,
4311 this must also be initialized by calling dsmrr_init().
4312
4313 @param h_arg pointer to the handler that owns this object
4314 @param table_arg pointer to the TABLE that owns the handler
4315 */
4316
init(handler * h_arg,TABLE * table_arg)4317 void init(handler *h_arg, TABLE *table_arg)
4318 {
4319 assert(h_arg != NULL);
4320 assert(table_arg != NULL);
4321 h= h_arg;
4322 table= table_arg;
4323 }
4324
4325 int dsmrr_init(handler *h, RANGE_SEQ_IF *seq_funcs, void *seq_init_param,
4326 uint n_ranges, uint mode, HANDLER_BUFFER *buf);
4327 void dsmrr_close();
4328
4329 /**
4330 Resets the DS-MRR object to the state it had after being intialized.
4331
4332 If there is an open scan then this will be closed.
4333
4334 This function should be called by handler::ha_reset() which is called
4335 when a statement is completed in order to make the handler object ready
4336 for re-use by a different statement.
4337 */
4338
4339 void reset();
4340 int dsmrr_fill_buffer();
4341 int dsmrr_next(char **range_info);
4342
4343 ha_rows dsmrr_info(uint keyno, uint n_ranges, uint keys, uint *bufsz,
4344 uint *flags, Cost_estimate *cost);
4345
4346 ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq,
4347 void *seq_init_param, uint n_ranges, uint *bufsz,
4348 uint *flags, Cost_estimate *cost);
4349 private:
4350 bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz,
4351 Cost_estimate *cost);
4352 bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags,
4353 uint *buffer_size, Cost_estimate *cost);
4354 };
4355 /* Some extern variables used with handlers */
4356
4357 extern const char *ha_row_type[];
4358 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
4359 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
4360 extern TYPELIB tx_isolation_typelib;
4361 extern const char *myisam_stats_method_names[];
4362 extern ulong total_ha, total_ha_2pc;
4363
4364 /* lookups */
4365 handlerton *ha_default_handlerton(THD *thd);
4366 handlerton *ha_default_temp_handlerton(THD *thd);
4367 handlerton *ha_enforce_handlerton(THD *thd);
4368 /**
4369 Resolve handlerton plugin by name, without checking for "DEFAULT" or
4370 HTON_NOT_USER_SELECTABLE.
4371
4372 @param thd Thread context.
4373 @param name Plugin name.
4374
4375 @return plugin or NULL if not found.
4376 */
4377 plugin_ref ha_resolve_by_name_raw(THD *thd, const LEX_CSTRING &name);
4378 plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name,
4379 bool is_temp_table);
4380 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
4381 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
4382 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
4383 handlerton *db_type);
4384 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type,
4385 bool no_substitute, bool report_error);
4386
4387
ha_legacy_type(const handlerton * db_type)4388 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
4389 {
4390 return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
4391 }
4392
4393 const char *ha_resolve_storage_engine_name(const handlerton *db_type);
4394
ha_check_storage_engine_flag(const handlerton * db_type,uint32 flag)4395 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
4396 {
4397 return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
4398 }
4399
ha_storage_engine_is_enabled(const handlerton * db_type)4400 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
4401 {
4402 return (db_type && db_type->create) ?
4403 (db_type->state == SHOW_OPTION_YES) : FALSE;
4404 }
4405
is_ha_partition_handlerton(const handlerton * db_type)4406 static inline bool is_ha_partition_handlerton(const handlerton *db_type)
4407 {
4408 return (db_type->db_type == DB_TYPE_PARTITION_DB);
4409 }
4410
4411 /* basic stuff */
4412 int ha_init_errors(void);
4413 int ha_init(void);
4414 void ha_end();
4415 int ha_initialize_handlerton(st_plugin_int *plugin);
4416 int ha_finalize_handlerton(st_plugin_int *plugin);
4417
4418 TYPELIB* ha_known_exts();
4419 int ha_panic(enum ha_panic_function flag);
4420 void ha_close_connection(THD* thd);
4421 void ha_kill_connection(THD *thd);
4422 /**
4423 Flush the log(s) of storage engine(s).
4424
4425 @param hton Handlerton of storage engine.
4426 @param binlog_group_flush true if we got invoked by binlog group
4427 commit during flush stage, false in other cases.
4428 @retval false Succeed
4429 @retval true Error
4430 */
4431 bool ha_flush_logs(handlerton *db_type, bool binlog_group_flush= false);
4432 void ha_drop_database(char* path);
4433
4434 class Create_field;
4435 int ha_create_table(THD *thd, const char *path,
4436 const char *db, const char *table_name,
4437 HA_CREATE_INFO *create_info,
4438 const List<Create_field> *create_fields,
4439 bool update_create_info,
4440 bool is_temp_table= false);
4441
4442 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
4443 const char *db, const char *alias, bool generate_warning);
4444
4445 /* statistics and info */
4446 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
4447
4448 /* discovery */
4449 int ha_create_table_from_engine(THD* thd, const char *db, const char *name);
4450 bool ha_check_if_table_exists(THD* thd, const char *db, const char *name,
4451 bool *exists);
4452 int ha_discover(THD* thd, const char* dbname, const char* name,
4453 uchar** frmblob, size_t* frmlen);
4454 int ha_find_files(THD *thd,const char *db,const char *path,
4455 const char *wild, bool dir, List<LEX_STRING>* files);
4456 int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
4457 bool ha_is_supported_system_table(handlerton *hton, const char *db,
4458 const char *table_name);
4459 bool ha_is_valid_system_or_user_table(handlerton *hton, const char *db,
4460 const char *table_name);
4461
4462 /* key cache */
4463 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
4464 int ha_resize_key_cache(KEY_CACHE *key_cache);
4465 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
4466
4467 /* report to InnoDB that control passes to the client */
4468 int ha_release_temporary_latches(THD *thd);
4469
4470 /* transactions: interface to handlerton functions */
4471 int ha_start_consistent_snapshot(THD *thd);
4472 int ha_store_binlog_info(THD *thd);
4473 int ha_commit_trans(THD *thd, bool all, bool ignore_global_read_lock= false);
4474 int ha_commit_attachable(THD *thd);
4475 int ha_rollback_trans(THD *thd, bool all);
4476 int ha_prepare(THD *thd);
4477
4478
4479 /**
4480 recover() step of xa.
4481
4482 @note
4483 there are three modes of operation:
4484 - automatic recover after a crash
4485 in this case commit_list != 0, tc_heuristic_recover==TC_HEURISTIC_NOT_USED
4486 all xids from commit_list are committed, others are rolled back
4487 - manual (heuristic) recover
4488 in this case commit_list==0, tc_heuristic_recover != TC_HEURISTIC_NOT_USED
4489 DBA has explicitly specified that all prepared transactions should
4490 be committed (or rolled back).
4491 - no recovery (MySQL did not detect a crash)
4492 in this case commit_list==0, tc_heuristic_recover == TC_HEURISTIC_NOT_USED
4493 there should be no prepared transactions in this case.
4494 */
4495
4496 int ha_recover(HASH *commit_list);
4497
4498 /*
4499 transactions: interface to low-level handlerton functions. These are
4500 intended to be used by the transaction coordinators to
4501 commit/prepare/rollback transactions in the engines.
4502 */
4503 int ha_commit_low(THD *thd, bool all, bool run_after_commit= true);
4504 int ha_prepare_low(THD *thd, bool all);
4505 int ha_rollback_low(THD *thd, bool all);
4506
4507 bool ha_flush_changed_page_bitmaps();
4508 bool ha_purge_changed_page_bitmaps(ulonglong lsn);
4509
4510 /* transactions: these functions never call handlerton functions directly */
4511 int ha_enable_transaction(THD *thd, bool on);
4512
4513 /* savepoints */
4514 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
4515 bool ha_rollback_to_savepoint_can_release_mdl(THD *thd);
4516 int ha_savepoint(THD *thd, SAVEPOINT *sv);
4517 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
4518
4519 /* Build pushed joins in handlers implementing this feature */
4520 int ha_make_pushed_joins(THD *thd, const AQP::Join_plan* plan);
4521
4522 /* these are called by storage engines */
4523 void trans_register_ha(THD *thd, bool all, handlerton *ht,
4524 const ulonglong *trxid);
4525 /*
4526 Storage engine has to assume the transaction will end up with 2pc if
4527 - there is more than one 2pc-capable storage engine available
4528 - in the current transaction 2pc was not disabled yet
4529 */
4530 #define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \
4531 !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
4532
4533 int ha_reset_logs(THD *thd);
4534 int ha_binlog_index_purge_file(THD *thd, const char *file);
4535 void ha_reset_slave(THD *thd);
4536 void ha_binlog_log_query(THD *thd, handlerton *db_type,
4537 enum_binlog_command binlog_command,
4538 const char *query, size_t query_length,
4539 const char *db, const char *table_name);
4540 void ha_binlog_wait(THD *thd);
4541
4542 /* It is required by basic binlog features on both MySQL server and libmysqld */
4543 int ha_binlog_end(THD *thd);
4544
4545 const char *ha_legacy_type_name(legacy_db_type legacy_type);
4546 const char *get_canonical_filename(handler *file, const char *path,
4547 char *tmp_path);
4548
table_case_name(HA_CREATE_INFO * info,const char * name)4549 inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
4550 {
4551 return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
4552 }
4553
4554 void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag);
4555 void print_keydup_error(TABLE *table, KEY *key, myf errflag);
4556
4557 void ha_set_normalized_disabled_se_str(const std::string &disabled_se_str);
4558 bool ha_is_storage_engine_disabled(handlerton *se_engine);
4559
4560 bool ha_notify_exclusive_mdl(THD *thd, const MDL_key *mdl_key,
4561 ha_notification_type notification_type,
4562 bool *victimized);
4563 bool ha_notify_alter_table(THD *thd, const MDL_key *mdl_key,
4564 ha_notification_type notification_type);
4565
4566 int commit_owned_gtids(THD *thd, bool all, bool *need_clear_ptr);
4567 int commit_owned_gtid_by_partial_command(THD *thd);
4568 bool set_tx_isolation(THD *thd,
4569 enum_tx_isolation tx_isolation,
4570 bool one_shot);
4571 bool ha_check_reserved_db_name(const char *name);
4572
4573 #endif /* HANDLER_INCLUDED */
4574