1 #ifndef HANDLER_INCLUDED
2 #define HANDLER_INCLUDED
3 /*
4 Copyright (c) 2000, 2019, Oracle and/or its affiliates.
5 Copyright (c) 2009, 2021, MariaDB
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; version 2 of
10 the License.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA
20 */
21
22 /* Definitions for parameters to do with handler-routines */
23
24 #ifdef USE_PRAGMA_INTERFACE
25 #pragma interface /* gcc class implementation */
26 #endif
27
28 #include "sql_const.h"
29 #include "sql_basic_types.h"
30 #include "mysqld.h" /* server_id */
31 #include "sql_plugin.h" /* plugin_ref, st_plugin_int, plugin */
32 #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA */
33 #include "sql_cache.h"
34 #include "structs.h" /* SHOW_COMP_OPTION */
35 #include "sql_array.h" /* Dynamic_array<> */
36 #include "mdl.h"
37 #include "vers_string.h"
38
39 #include "sql_analyze_stmt.h" // for Exec_time_tracker
40
41 #include <my_compare.h>
42 #include <ft_global.h>
43 #include <keycache.h>
44 #include <mysql/psi/mysql_table.h>
45 #include "sql_sequence.h"
46 #include "mem_root_array.h"
47
48 class Alter_info;
49 class Virtual_column_info;
50 class sequence_definition;
51 class Rowid_filter;
52 class Field_string;
53 class Field_varstring;
54 class Field_blob;
55 class Column_definition;
56
57 // the following is for checking tables
58
59 #define HA_ADMIN_ALREADY_DONE 1
60 #define HA_ADMIN_OK 0
61 #define HA_ADMIN_NOT_IMPLEMENTED -1
62 #define HA_ADMIN_FAILED -2
63 #define HA_ADMIN_CORRUPT -3
64 #define HA_ADMIN_INTERNAL_ERROR -4
65 #define HA_ADMIN_INVALID -5
66 #define HA_ADMIN_REJECT -6
67 #define HA_ADMIN_TRY_ALTER -7
68 #define HA_ADMIN_WRONG_CHECKSUM -8
69 #define HA_ADMIN_NOT_BASE_TABLE -9
70 #define HA_ADMIN_NEEDS_UPGRADE -10
71 #define HA_ADMIN_NEEDS_ALTER -11
72 #define HA_ADMIN_NEEDS_CHECK -12
73 #define HA_ADMIN_COMMIT_ERROR -13
74
75 /**
76 Return values for check_if_supported_inplace_alter().
77
78 @see check_if_supported_inplace_alter() for description of
79 the individual values.
80 */
81 enum enum_alter_inplace_result {
82 HA_ALTER_ERROR,
83 HA_ALTER_INPLACE_COPY_NO_LOCK,
84 HA_ALTER_INPLACE_COPY_LOCK,
85 HA_ALTER_INPLACE_NOCOPY_LOCK,
86 HA_ALTER_INPLACE_NOCOPY_NO_LOCK,
87 HA_ALTER_INPLACE_INSTANT,
88 HA_ALTER_INPLACE_NOT_SUPPORTED,
89 HA_ALTER_INPLACE_EXCLUSIVE_LOCK,
90 HA_ALTER_INPLACE_SHARED_LOCK,
91 HA_ALTER_INPLACE_NO_LOCK
92 };
93
94 /* Flags for create_partitioning_metadata() */
95
96 enum chf_create_flags {
97 CHF_CREATE_FLAG,
98 CHF_DELETE_FLAG,
99 CHF_RENAME_FLAG,
100 CHF_INDEX_FLAG
101 };
102
103 /* Bits in table_flags() to show what database can do */
104
105 #define HA_NO_TRANSACTIONS (1ULL << 0) /* Doesn't support transactions */
106 #define HA_PARTIAL_COLUMN_READ (1ULL << 1) /* read may not return all columns */
107 #define HA_TABLE_SCAN_ON_INDEX (1ULL << 2) /* No separate data/index file */
108 /*
109 The following should be set if the following is not true when scanning
110 a table with rnd_next()
111 - We will see all rows (including deleted ones)
112 - Row positions are 'table->s->db_record_offset' apart
113 If this flag is not set, filesort will do a position() call for each matched
114 row to be able to find the row later.
115 */
116 #define HA_REC_NOT_IN_SEQ (1ULL << 3)
117 #define HA_CAN_GEOMETRY (1ULL << 4)
118 /*
119 Reading keys in random order is as fast as reading keys in sort order
120 (Used in records.cc to decide if we should use a record cache and by
121 filesort to decide if we should sort key + data or key + pointer-to-row
122 */
123 #define HA_FAST_KEY_READ (1ULL << 5)
124 /*
125 Set the following flag if we on delete should force all key to be read
126 and on update read all keys that changes
127 */
128 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1ULL << 6)
129 #define HA_NULL_IN_KEY (1ULL << 7) /* One can have keys with NULL */
130 #define HA_DUPLICATE_POS (1ULL << 8) /* ha_position() gives dup row */
131 #define HA_NO_BLOBS (1ULL << 9) /* Doesn't support blobs */
132 #define HA_CAN_INDEX_BLOBS (1ULL << 10)
133 #define HA_AUTO_PART_KEY (1ULL << 11) /* auto-increment in multi-part key */
134 /*
135 The engine requires every table to have a user-specified PRIMARY KEY.
136 Do not set the flag if the engine can generate a hidden primary key internally.
137 This flag is ignored if a SEQUENCE is created (which, in turn, needs
138 HA_CAN_TABLES_WITHOUT_ROLLBACK flag)
139 */
140 #define HA_REQUIRE_PRIMARY_KEY (1ULL << 12)
141 #define HA_STATS_RECORDS_IS_EXACT (1ULL << 13) /* stats.records is exact */
142 /*
143 INSERT_DELAYED only works with handlers that uses MySQL internal table
144 level locks
145 */
146 #define HA_CAN_INSERT_DELAYED (1ULL << 14)
147 /*
148 If we get the primary key columns for free when we do an index read
149 (usually, it also implies that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION
150 flag is set).
151 */
152 #define HA_PRIMARY_KEY_IN_READ_INDEX (1ULL << 15)
153 /*
154 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position()
155 uses a primary key given by the record argument.
156 Without primary key, we can't call position().
157 If not set, the position is returned as the current rows position
158 regardless of what argument is given.
159 */
160 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1ULL << 16)
161 #define HA_CAN_RTREEKEYS (1ULL << 17)
162 #define HA_NOT_DELETE_WITH_CACHE (1ULL << 18) /* unused */
163 /*
164 The following is we need to a primary key to delete (and update) a row.
165 If there is no primary key, all columns needs to be read on update and delete
166 */
167 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1ULL << 19)
168 #define HA_NO_PREFIX_CHAR_KEYS (1ULL << 20)
169 #define HA_CAN_FULLTEXT (1ULL << 21)
170 #define HA_CAN_SQL_HANDLER (1ULL << 22)
171 #define HA_NO_AUTO_INCREMENT (1ULL << 23)
172 /* Has automatic checksums and uses the old checksum format */
173 #define HA_HAS_OLD_CHECKSUM (1ULL << 24)
174 /* Table data are stored in separate files (for lower_case_table_names) */
175 #define HA_FILE_BASED (1ULL << 26)
176 #define HA_CAN_BIT_FIELD (1ULL << 28) /* supports bit fields */
177 #define HA_NEED_READ_RANGE_BUFFER (1ULL << 29) /* for read_multi_range */
178 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1ULL << 30)
179 #define HA_NO_COPY_ON_ALTER (1ULL << 31)
180 #define HA_HAS_RECORDS (1ULL << 32) /* records() gives exact count*/
181 /* Has it's own method of binlog logging */
182 #define HA_HAS_OWN_BINLOGGING (1ULL << 33)
183 /*
184 Engine is capable of row-format and statement-format logging,
185 respectively
186 */
187 #define HA_BINLOG_ROW_CAPABLE (1ULL << 34)
188 #define HA_BINLOG_STMT_CAPABLE (1ULL << 35)
189
190 /*
191 When a multiple key conflict happens in a REPLACE command mysql
192 expects the conflicts to be reported in the ascending order of
193 key names.
194
195 For e.g.
196
197 CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT
198 NULL, INDEX(c));
199
200 REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3);
201
202 MySQL expects the conflict with 'a' to be reported before the conflict with
203 'b'.
204
205 If the underlying storage engine does not report the conflicting keys in
206 ascending order, it causes unexpected errors when the REPLACE command is
207 executed.
208
209 This flag helps the underlying SE to inform the server that the keys are not
210 ordered.
211 */
212 #define HA_DUPLICATE_KEY_NOT_IN_ORDER (1ULL << 36)
213
214 /*
215 Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an
216 incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE
217 will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD.
218 */
219 #define HA_CAN_REPAIR (1ULL << 37)
220
221 /* Has automatic checksums and uses the new checksum format */
222 #define HA_HAS_NEW_CHECKSUM (1ULL << 38)
223 #define HA_CAN_VIRTUAL_COLUMNS (1ULL << 39)
224 #define HA_MRR_CANT_SORT (1ULL << 40)
225 /* All of VARCHAR is stored, including bytes after real varchar data */
226 #define HA_RECORD_MUST_BE_CLEAN_ON_WRITE (1ULL << 41)
227
228 /*
229 This storage engine supports condition pushdown
230 */
231 #define HA_CAN_TABLE_CONDITION_PUSHDOWN (1ULL << 42)
232 /* old name for the same flag */
233 #define HA_MUST_USE_TABLE_CONDITION_PUSHDOWN HA_CAN_TABLE_CONDITION_PUSHDOWN
234
235 /**
236 The handler supports read before write removal optimization
237
238 Read before write removal may be used for storage engines which support
239 write without previous read of the row to be updated. Handler returning
240 this flag must implement start_read_removal() and end_read_removal().
241 The handler may return "fake" rows constructed from the key of the row
242 asked for. This is used to optimize UPDATE and DELETE by reducing the
243 number of roundtrips between handler and storage engine.
244
245 Example:
246 UPDATE a=1 WHERE pk IN (<keys>)
247
248 mysql_update()
249 {
250 if (<conditions for starting read removal>)
251 start_read_removal()
252 -> handler returns true if read removal supported for this table/query
253
254 while(read_record("pk=<key>"))
255 -> handler returns fake row with column "pk" set to <key>
256
257 ha_update_row()
258 -> handler sends write "a=1" for row with "pk=<key>"
259
260 end_read_removal()
261 -> handler returns the number of rows actually written
262 }
263
264 @note This optimization in combination with batching may be used to
265 remove even more roundtrips.
266 */
267 #define HA_READ_BEFORE_WRITE_REMOVAL (1ULL << 43)
268
269 /*
270 Engine supports extended fulltext API
271 */
272 #define HA_CAN_FULLTEXT_EXT (1ULL << 44)
273
274 /*
275 Storage engine supports table export using the
276 FLUSH TABLE <table_list> FOR EXPORT statement
277 (meaning, after this statement one can copy table files out of the
278 datadir and later "import" (somehow) in another MariaDB instance)
279 */
280 #define HA_CAN_EXPORT (1ULL << 45)
281
282 /*
283 Storage engine does not require an exclusive metadata lock
284 on the table during optimize. (TODO and repair?).
285 It can allow other connections to open the table.
286 (it does not necessarily mean that other connections can
287 read or modify the table - this is defined by THR locks and the
288 ::store_lock() method).
289 */
290 #define HA_CONCURRENT_OPTIMIZE (1ULL << 46)
291
292 /*
293 If the storage engine support tables that will not roll back on commit
294 In addition the table should not lock rows and support READ and WRITE
295 UNCOMMITTED.
296 This is useful for implementing things like SEQUENCE but can also in
297 the future be useful to do logging that should never roll back.
298 */
299 #define HA_CAN_TABLES_WITHOUT_ROLLBACK (1ULL << 47)
300
301 /*
302 Mainly for usage by SEQUENCE engine. Setting this flag means
303 that the table will never roll back and that all operations
304 for this table should stored in the non transactional log
305 space that will always be written, even on rollback.
306 */
307
308 #define HA_PERSISTENT_TABLE (1ULL << 48)
309
310 /*
311 If storage engine uses another engine as a base
312 This flag is also needed if the table tries to open the .frm file
313 as part of drop table.
314 */
315 #define HA_REUSES_FILE_NAMES (1ULL << 49)
316
317 /*
318 Set of all binlog flags. Currently only contain the capabilities
319 flags.
320 */
321 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
322
323 /* The following are used by Spider */
324 #define HA_CAN_FORCE_BULK_UPDATE (1ULL << 50)
325 #define HA_CAN_FORCE_BULK_DELETE (1ULL << 51)
326 #define HA_CAN_DIRECT_UPDATE_AND_DELETE (1ULL << 52)
327
328 /* The following is for partition handler */
329 #define HA_CAN_MULTISTEP_MERGE (1LL << 53)
330
331 /* calling cmp_ref() on the engine is expensive */
332 #define HA_SLOW_CMP_REF (1ULL << 54)
333 #define HA_CMP_REF_IS_EXPENSIVE HA_SLOW_CMP_REF
334
335 /**
336 Some engines are unable to provide an efficient implementation for rnd_pos().
337 Server will try to avoid it, if possible
338
339 TODO better to do it with cost estimates, not with an explicit flag
340 */
341 #define HA_SLOW_RND_POS (1ULL << 55)
342
343 /* Safe for online backup */
344 #define HA_CAN_ONLINE_BACKUPS (1ULL << 56)
345
346 /* Support native hash index */
347 #define HA_CAN_HASH_KEYS (1ULL << 57)
348 #define HA_CRASH_SAFE (1ULL << 58)
349
350 /*
351 There is no need to evict the table from the table definition cache having
352 run ANALYZE TABLE on it
353 */
354 #define HA_ONLINE_ANALYZE (1ULL << 59)
355 /*
356 Rowid's are not comparable. This is set if the rowid is unique to the
357 current open handler, like it is with federated where the rowid is a
358 pointer to a local result set buffer. The effect of having this set is
359 that the optimizer will not consirer the following optimizations for
360 the table:
361 ror scans or filtering
362 */
363 #define HA_NON_COMPARABLE_ROWID (1ULL << 60)
364
365 #define HA_LAST_TABLE_FLAG HA_NON_COMPARABLE_ROWID
366
367
368 /* bits in index_flags(index_number) for what you can do with index */
369 #define HA_READ_NEXT 1 /* TODO really use this flag */
370 #define HA_READ_PREV 2 /* supports ::index_prev */
371 #define HA_READ_ORDER 4 /* index_next/prev follow sort order */
372 #define HA_READ_RANGE 8 /* can find all records in a range */
373 #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
374 #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
375
376 /*
377 Index scan will not return records in rowid order. Not guaranteed to be
378 set for unordered (e.g. HASH) indexes.
379 */
380 #define HA_KEY_SCAN_NOT_ROR 128
381 #define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */
382 /*
383 Data is clustered on this key. This means that when you read the key
384 you also get the row data without any additional disk reads.
385 */
386 #define HA_CLUSTERED_INDEX 512
387
388 #define HA_DO_RANGE_FILTER_PUSHDOWN 1024
389
390 /*
391 bits in alter_table_flags:
392 */
393 /*
394 These bits are set if different kinds of indexes can be created or dropped
395 in-place without re-creating the table using a temporary table.
396 NO_READ_WRITE indicates that the handler needs concurrent reads and writes
397 of table data to be blocked.
398 Partitioning needs both ADD and DROP to be supported by its underlying
399 handlers, due to error handling, see bug#57778.
400 */
401 #define HA_INPLACE_ADD_INDEX_NO_READ_WRITE (1UL << 0)
402 #define HA_INPLACE_DROP_INDEX_NO_READ_WRITE (1UL << 1)
403 #define HA_INPLACE_ADD_UNIQUE_INDEX_NO_READ_WRITE (1UL << 2)
404 #define HA_INPLACE_DROP_UNIQUE_INDEX_NO_READ_WRITE (1UL << 3)
405 #define HA_INPLACE_ADD_PK_INDEX_NO_READ_WRITE (1UL << 4)
406 #define HA_INPLACE_DROP_PK_INDEX_NO_READ_WRITE (1UL << 5)
407 /*
408 These are set if different kinds of indexes can be created or dropped
409 in-place while still allowing concurrent reads (but not writes) of table
410 data. If a handler is capable of one or more of these, it should also set
411 the corresponding *_NO_READ_WRITE bit(s).
412 */
413 #define HA_INPLACE_ADD_INDEX_NO_WRITE (1UL << 6)
414 #define HA_INPLACE_DROP_INDEX_NO_WRITE (1UL << 7)
415 #define HA_INPLACE_ADD_UNIQUE_INDEX_NO_WRITE (1UL << 8)
416 #define HA_INPLACE_DROP_UNIQUE_INDEX_NO_WRITE (1UL << 9)
417 #define HA_INPLACE_ADD_PK_INDEX_NO_WRITE (1UL << 10)
418 #define HA_INPLACE_DROP_PK_INDEX_NO_WRITE (1UL << 11)
419 /*
420 HA_PARTITION_FUNCTION_SUPPORTED indicates that the function is
421 supported at all.
422 HA_FAST_CHANGE_PARTITION means that optimised variants of the changes
423 exists but they are not necessarily done online.
424
425 HA_ONLINE_DOUBLE_WRITE means that the handler supports writing to both
426 the new partition and to the old partitions when updating through the
427 old partitioning schema while performing a change of the partitioning.
428 This means that we can support updating of the table while performing
429 the copy phase of the change. For no lock at all also a double write
430 from new to old must exist and this is not required when this flag is
431 set.
432 This is actually removed even before it was introduced the first time.
433 The new idea is that handlers will handle the lock level already in
434 store_lock for ALTER TABLE partitions.
435
436 HA_PARTITION_ONE_PHASE is a flag that can be set by handlers that take
437 care of changing the partitions online and in one phase. Thus all phases
438 needed to handle the change are implemented inside the storage engine.
439 The storage engine must also support auto-discovery since the frm file
440 is changed as part of the change and this change must be controlled by
441 the storage engine. A typical engine to support this is NDB (through
442 WL #2498).
443 */
444 #define HA_PARTITION_FUNCTION_SUPPORTED (1UL << 12)
445 #define HA_FAST_CHANGE_PARTITION (1UL << 13)
446 #define HA_PARTITION_ONE_PHASE (1UL << 14)
447
448 /* operations for disable/enable indexes */
449 #define HA_KEY_SWITCH_NONUNIQ 0
450 #define HA_KEY_SWITCH_ALL 1
451 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2
452 #define HA_KEY_SWITCH_ALL_SAVE 3
453
454 /*
455 Note: the following includes binlog and closing 0.
456 TODO remove the limit, use dynarrays
457 */
458 #define MAX_HA 64
459
460 /*
461 Use this instead of 0 as the initial value for the slot number of
462 handlerton, so that we can distinguish uninitialized slot number
463 from slot 0.
464 */
465 #define HA_SLOT_UNDEF ((uint)-1)
466
467 /*
468 Parameters for open() (in register form->filestat)
469 HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
470 */
471
472 #define HA_OPEN_KEYFILE 1U
473 #define HA_READ_ONLY 16U /* File opened as readonly */
474 /* Try readonly if can't open with read and write */
475 #define HA_TRY_READ_ONLY 32U
476
477 /* Some key definitions */
478 #define HA_KEY_NULL_LENGTH 1
479 #define HA_KEY_BLOB_LENGTH 2
480
481 /* Maximum length of any index lookup key, in bytes */
482
483 #define MAX_KEY_LENGTH (MAX_DATA_LENGTH_FOR_KEY \
484 +(MAX_REF_PARTS \
485 *(HA_KEY_NULL_LENGTH + HA_KEY_BLOB_LENGTH)))
486
487 #define HA_LEX_CREATE_TMP_TABLE 1U
488 #define HA_CREATE_TMP_ALTER 8U
489 #define HA_LEX_CREATE_SEQUENCE 16U
490 #define HA_VERSIONED_TABLE 32U
491 #define HA_SKIP_KEY_SORT 64U
492
493 #define HA_MAX_REC_LENGTH 65535
494
495 /* Table caching type */
496 #define HA_CACHE_TBL_NONTRANSACT 0
497 #define HA_CACHE_TBL_NOCACHE 1U
498 #define HA_CACHE_TBL_ASKTRANSACT 2U
499 #define HA_CACHE_TBL_TRANSACT 4U
500
501 /**
502 Options for the START TRANSACTION statement.
503
504 Note that READ ONLY and READ WRITE are logically mutually exclusive.
505 This is enforced by the parser and depended upon by trans_begin().
506
507 We need two flags instead of one in order to differentiate between
508 situation when no READ WRITE/ONLY clause were given and thus transaction
509 is implicitly READ WRITE and the case when READ WRITE clause was used
510 explicitly.
511 */
512
513 // WITH CONSISTENT SNAPSHOT option
514 static const uint MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT = 1;
515 // READ ONLY option
516 static const uint MYSQL_START_TRANS_OPT_READ_ONLY = 2;
517 // READ WRITE option
518 static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4;
519
520 /* Flags for method is_fatal_error */
521 #define HA_CHECK_DUP_KEY 1U
522 #define HA_CHECK_DUP_UNIQUE 2U
523 #define HA_CHECK_FK_ERROR 4U
524 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
525 #define HA_CHECK_ALL (~0U)
526
527 /* Options for info_push() */
528 #define INFO_KIND_UPDATE_FIELDS 101
529 #define INFO_KIND_UPDATE_VALUES 102
530 #define INFO_KIND_FORCE_LIMIT_BEGIN 103
531 #define INFO_KIND_FORCE_LIMIT_END 104
532
533 enum legacy_db_type
534 {
535 /* note these numerical values are fixed and can *not* be changed */
536 DB_TYPE_UNKNOWN=0,
537 DB_TYPE_HEAP=6,
538 DB_TYPE_MYISAM=9,
539 DB_TYPE_MRG_MYISAM=10,
540 DB_TYPE_INNODB=12,
541 DB_TYPE_EXAMPLE_DB=15,
542 DB_TYPE_ARCHIVE_DB=16,
543 DB_TYPE_CSV_DB=17,
544 DB_TYPE_FEDERATED_DB=18,
545 DB_TYPE_BLACKHOLE_DB=19,
546 DB_TYPE_PARTITION_DB=20,
547 DB_TYPE_BINLOG=21,
548 DB_TYPE_PBXT=23,
549 DB_TYPE_PERFORMANCE_SCHEMA=28,
550 DB_TYPE_S3=41,
551 DB_TYPE_ARIA=42,
552 DB_TYPE_TOKUDB=43,
553 DB_TYPE_SEQUENCE=44,
554 DB_TYPE_FIRST_DYNAMIC=45,
555 DB_TYPE_DEFAULT=127 // Must be last
556 };
557 /*
558 Better name for DB_TYPE_UNKNOWN. Should be used for engines that do not have
559 a hard-coded type value here.
560 */
561 #define DB_TYPE_AUTOASSIGN DB_TYPE_UNKNOWN
562
563 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
564 ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
565 ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, ROW_TYPE_PAGE };
566
567 /* not part of the enum, so that it shouldn't be in switch(row_type) */
568 #define ROW_TYPE_MAX ((uint)ROW_TYPE_PAGE + 1)
569
570 /* Specifies data storage format for individual columns */
571 enum column_format_type {
572 COLUMN_FORMAT_TYPE_DEFAULT= 0, /* Not specified (use engine default) */
573 COLUMN_FORMAT_TYPE_FIXED= 1, /* FIXED format */
574 COLUMN_FORMAT_TYPE_DYNAMIC= 2 /* DYNAMIC format */
575 };
576
577 enum enum_binlog_func {
578 BFN_RESET_LOGS= 1,
579 BFN_RESET_SLAVE= 2,
580 BFN_BINLOG_WAIT= 3,
581 BFN_BINLOG_END= 4,
582 BFN_BINLOG_PURGE_FILE= 5
583 };
584
585 enum enum_binlog_command {
586 LOGCOM_CREATE_TABLE,
587 LOGCOM_ALTER_TABLE,
588 LOGCOM_RENAME_TABLE,
589 LOGCOM_DROP_TABLE,
590 LOGCOM_CREATE_DB,
591 LOGCOM_ALTER_DB,
592 LOGCOM_DROP_DB
593 };
594
595 /* struct to hold information about the table that should be created */
596
597 /* Bits in used_fields */
598 #define HA_CREATE_USED_AUTO (1UL << 0)
599 #define HA_CREATE_USED_RAID (1UL << 1) //RAID is no longer available
600 #define HA_CREATE_USED_UNION (1UL << 2)
601 #define HA_CREATE_USED_INSERT_METHOD (1UL << 3)
602 #define HA_CREATE_USED_MIN_ROWS (1UL << 4)
603 #define HA_CREATE_USED_MAX_ROWS (1UL << 5)
604 #define HA_CREATE_USED_AVG_ROW_LENGTH (1UL << 6)
605 #define HA_CREATE_USED_PACK_KEYS (1UL << 7)
606 #define HA_CREATE_USED_CHARSET (1UL << 8)
607 #define HA_CREATE_USED_DEFAULT_CHARSET (1UL << 9)
608 #define HA_CREATE_USED_DATADIR (1UL << 10)
609 #define HA_CREATE_USED_INDEXDIR (1UL << 11)
610 #define HA_CREATE_USED_ENGINE (1UL << 12)
611 #define HA_CREATE_USED_CHECKSUM (1UL << 13)
612 #define HA_CREATE_USED_DELAY_KEY_WRITE (1UL << 14)
613 #define HA_CREATE_USED_ROW_FORMAT (1UL << 15)
614 #define HA_CREATE_USED_COMMENT (1UL << 16)
615 #define HA_CREATE_USED_PASSWORD (1UL << 17)
616 #define HA_CREATE_USED_CONNECTION (1UL << 18)
617 #define HA_CREATE_USED_KEY_BLOCK_SIZE (1UL << 19)
618 /* The following two are used by Maria engine: */
619 #define HA_CREATE_USED_TRANSACTIONAL (1UL << 20)
620 #define HA_CREATE_USED_PAGE_CHECKSUM (1UL << 21)
621 /** This is set whenever STATS_PERSISTENT=0|1|default has been
622 specified in CREATE/ALTER TABLE. See also HA_OPTION_STATS_PERSISTENT in
623 include/my_base.h. It is possible to distinguish whether
624 STATS_PERSISTENT=default has been specified or no STATS_PERSISTENT= is
625 given at all. */
626 #define HA_CREATE_USED_STATS_PERSISTENT (1UL << 22)
627 /**
628 This is set whenever STATS_AUTO_RECALC=0|1|default has been
629 specified in CREATE/ALTER TABLE. See enum_stats_auto_recalc.
630 It is possible to distinguish whether STATS_AUTO_RECALC=default
631 has been specified or no STATS_AUTO_RECALC= is given at all.
632 */
633 #define HA_CREATE_USED_STATS_AUTO_RECALC (1UL << 23)
634 /**
635 This is set whenever STATS_SAMPLE_PAGES=N|default has been
636 specified in CREATE/ALTER TABLE. It is possible to distinguish whether
637 STATS_SAMPLE_PAGES=default has been specified or no STATS_SAMPLE_PAGES= is
638 given at all.
639 */
640 #define HA_CREATE_USED_STATS_SAMPLE_PAGES (1UL << 24)
641
642 /* Create a sequence */
643 #define HA_CREATE_USED_SEQUENCE (1UL << 25)
644 /* Tell binlog_show_create_table to print all engine options */
645 #define HA_CREATE_PRINT_ALL_OPTIONS (1UL << 26)
646
647 typedef ulonglong alter_table_operations;
648 typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
649
650 /*
651 These flags are set by the parser and describes the type of
652 operation(s) specified by the ALTER TABLE statement.
653 */
654
655 // Set by parser for ADD [COLUMN]
656 #define ALTER_PARSER_ADD_COLUMN (1ULL << 0)
657 // Set by parser for DROP [COLUMN]
658 #define ALTER_PARSER_DROP_COLUMN (1ULL << 1)
659 // Set for CHANGE [COLUMN] | MODIFY [CHANGE] & mysql_recreate_table
660 #define ALTER_CHANGE_COLUMN (1ULL << 2)
661 // Set for ADD INDEX | ADD KEY | ADD PRIMARY KEY | ADD UNIQUE KEY |
662 // ADD UNIQUE INDEX | ALTER ADD [COLUMN]
663 #define ALTER_ADD_INDEX (1ULL << 3)
664 // Set for DROP PRIMARY KEY | DROP FOREIGN KEY | DROP KEY | DROP INDEX
665 #define ALTER_DROP_INDEX (1ULL << 4)
666 // Set for RENAME [TO]
667 #define ALTER_RENAME (1ULL << 5)
668 // Set for ORDER BY
669 #define ALTER_ORDER (1ULL << 6)
670 // Set for table_options, like table comment
671 #define ALTER_OPTIONS (1ULL << 7)
672 // Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT
673 #define ALTER_CHANGE_COLUMN_DEFAULT (1ULL << 8)
674 // Set for DISABLE KEYS | ENABLE KEYS
675 #define ALTER_KEYS_ONOFF (1ULL << 9)
676 // Set for FORCE, ENGINE(same engine), by mysql_recreate_table()
677 #define ALTER_RECREATE (1ULL << 10)
678 // Set for CONVERT TO
679 #define ALTER_CONVERT_TO (1ULL << 11)
680 // Set for DROP ... ADD some_index
681 #define ALTER_RENAME_INDEX (1ULL << 12)
682 // Set for ADD FOREIGN KEY
683 #define ALTER_ADD_FOREIGN_KEY (1ULL << 21)
684 // Set for DROP FOREIGN KEY
685 #define ALTER_DROP_FOREIGN_KEY (1ULL << 22)
686 #define ALTER_CHANGE_INDEX_COMMENT (1ULL << 23)
687 // Set for ADD [COLUMN] FIRST | AFTER
688 #define ALTER_COLUMN_ORDER (1ULL << 25)
689 #define ALTER_ADD_CHECK_CONSTRAINT (1ULL << 27)
690 #define ALTER_DROP_CHECK_CONSTRAINT (1ULL << 28)
691 #define ALTER_RENAME_COLUMN (1ULL << 29)
692 #define ALTER_COLUMN_UNVERSIONED (1ULL << 30)
693 #define ALTER_ADD_SYSTEM_VERSIONING (1ULL << 31)
694 #define ALTER_DROP_SYSTEM_VERSIONING (1ULL << 32)
695 #define ALTER_ADD_PERIOD (1ULL << 33)
696 #define ALTER_DROP_PERIOD (1ULL << 34)
697
698 /*
699 Following defines are used by ALTER_INPLACE_TABLE
700
701 They do describe in more detail the type operation(s) to be executed
702 by the storage engine. For example, which type of type of index to be
703 added/dropped. These are set by fill_alter_inplace_info().
704 */
705
706 #define ALTER_RECREATE_TABLE ALTER_RECREATE
707 #define ALTER_CHANGE_CREATE_OPTION ALTER_OPTIONS
708 #define ALTER_ADD_COLUMN (ALTER_ADD_VIRTUAL_COLUMN | \
709 ALTER_ADD_STORED_BASE_COLUMN | \
710 ALTER_ADD_STORED_GENERATED_COLUMN)
711 #define ALTER_DROP_COLUMN (ALTER_DROP_VIRTUAL_COLUMN | \
712 ALTER_DROP_STORED_COLUMN)
713 #define ALTER_COLUMN_DEFAULT ALTER_CHANGE_COLUMN_DEFAULT
714
715 // Add non-unique, non-primary index
716 #define ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 35)
717
718 // Drop non-unique, non-primary index
719 #define ALTER_DROP_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 36)
720
721 // Add unique, non-primary index
722 #define ALTER_ADD_UNIQUE_INDEX (1ULL << 37)
723
724 // Drop unique, non-primary index
725 #define ALTER_DROP_UNIQUE_INDEX (1ULL << 38)
726
727 // Add primary index
728 #define ALTER_ADD_PK_INDEX (1ULL << 39)
729
730 // Drop primary index
731 #define ALTER_DROP_PK_INDEX (1ULL << 40)
732
733 // Virtual generated column
734 #define ALTER_ADD_VIRTUAL_COLUMN (1ULL << 41)
735 // Stored base (non-generated) column
736 #define ALTER_ADD_STORED_BASE_COLUMN (1ULL << 42)
737 // Stored generated column
738 #define ALTER_ADD_STORED_GENERATED_COLUMN (1ULL << 43)
739
740 // Drop column
741 #define ALTER_DROP_VIRTUAL_COLUMN (1ULL << 44)
742 #define ALTER_DROP_STORED_COLUMN (1ULL << 45)
743
744 // Rename column (verified; ALTER_RENAME_COLUMN may use original name)
745 #define ALTER_COLUMN_NAME (1ULL << 46)
746
747 // Change column datatype
748 #define ALTER_VIRTUAL_COLUMN_TYPE (1ULL << 47)
749 #define ALTER_STORED_COLUMN_TYPE (1ULL << 48)
750
751
752 // Engine can handle type change by itself in ALGORITHM=INPLACE
753 #define ALTER_COLUMN_TYPE_CHANGE_BY_ENGINE (1ULL << 49)
754
755 // Reorder column
756 #define ALTER_STORED_COLUMN_ORDER (1ULL << 50)
757
758 // Reorder column
759 #define ALTER_VIRTUAL_COLUMN_ORDER (1ULL << 51)
760
761 // Change column from NOT NULL to NULL
762 #define ALTER_COLUMN_NULLABLE (1ULL << 52)
763
764 // Change column from NULL to NOT NULL
765 #define ALTER_COLUMN_NOT_NULLABLE (1ULL << 53)
766
767 // Change column generation expression
768 #define ALTER_VIRTUAL_GCOL_EXPR (1ULL << 54)
769 #define ALTER_STORED_GCOL_EXPR (1ULL << 55)
770
771 // column's engine options changed, something in field->option_struct
772 #define ALTER_COLUMN_OPTION (1ULL << 56)
773
774 // MySQL alias for the same thing:
775 #define ALTER_COLUMN_STORAGE_TYPE ALTER_COLUMN_OPTION
776
777 // Change the column format of column
778 #define ALTER_COLUMN_COLUMN_FORMAT (1ULL << 57)
779
780 /**
781 Changes in generated columns that affect storage,
782 for example, when a vcol type or expression changes
783 and this vcol is indexed or used in a partitioning expression
784 */
785 #define ALTER_COLUMN_VCOL (1ULL << 58)
786
787 /**
788 ALTER TABLE for a partitioned table. The engine needs to commit
789 online alter of all partitions atomically (using group_commit_ctx)
790 */
791 #define ALTER_PARTITIONED (1ULL << 59)
792
793 /**
794 Change in index length such that it doesn't require index rebuild.
795 */
796 #define ALTER_COLUMN_INDEX_LENGTH (1ULL << 60)
797
798 /**
799 Indicate that index order might have been changed. Disables inplace algorithm
800 by default (not for InnoDB).
801 */
802 #define ALTER_INDEX_ORDER (1ULL << 61)
803
804
805 /*
806 Flags set in partition_flags when altering partitions
807 */
808
809 // Set for ADD PARTITION
810 #define ALTER_PARTITION_ADD (1ULL << 1)
811 // Set for DROP PARTITION
812 #define ALTER_PARTITION_DROP (1ULL << 2)
813 // Set for COALESCE PARTITION
814 #define ALTER_PARTITION_COALESCE (1ULL << 3)
815 // Set for REORGANIZE PARTITION ... INTO
816 #define ALTER_PARTITION_REORGANIZE (1ULL << 4)
817 // Set for partition_options
818 #define ALTER_PARTITION_INFO (1ULL << 5)
819 // Set for LOAD INDEX INTO CACHE ... PARTITION
820 // Set for CACHE INDEX ... PARTITION
821 #define ALTER_PARTITION_ADMIN (1ULL << 6)
822 // Set for REBUILD PARTITION
823 #define ALTER_PARTITION_REBUILD (1ULL << 7)
824 // Set for partitioning operations specifying ALL keyword
825 #define ALTER_PARTITION_ALL (1ULL << 8)
826 // Set for REMOVE PARTITIONING
827 #define ALTER_PARTITION_REMOVE (1ULL << 9)
828 // Set for EXCHANGE PARITION
829 #define ALTER_PARTITION_EXCHANGE (1ULL << 10)
830 // Set by Sql_cmd_alter_table_truncate_partition::execute()
831 #define ALTER_PARTITION_TRUNCATE (1ULL << 11)
832 // Set for REORGANIZE PARTITION
833 #define ALTER_PARTITION_TABLE_REORG (1ULL << 12)
834
835 /*
836 This is master database for most of system tables. However there
837 can be other databases which can hold system tables. Respective
838 storage engines define their own system database names.
839 */
840 extern const char *mysqld_system_database;
841
842 /*
843 Structure to hold list of system_database.system_table.
844 This is used at both mysqld and storage engine layer.
845 */
846 struct st_system_tablename
847 {
848 const char *db;
849 const char *tablename;
850 };
851
852
853 typedef ulonglong my_xid; // this line is the same as in log_event.h
854 #define MYSQL_XID_PREFIX "MySQLXid"
855 #define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8
856 #define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id))
857 #define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid))
858
859 #define XIDDATASIZE MYSQL_XIDDATASIZE
860 #define MAXGTRIDSIZE 64
861 #define MAXBQUALSIZE 64
862
863 #define COMPATIBLE_DATA_YES 0
864 #define COMPATIBLE_DATA_NO 1
865
866 /**
867 struct xid_t is binary compatible with the XID structure as
868 in the X/Open CAE Specification, Distributed Transaction Processing:
869 The XA Specification, X/Open Company Ltd., 1991.
870 http://www.opengroup.org/bookstore/catalog/c193.htm
871
872 @see MYSQL_XID in mysql/plugin.h
873 */
874 struct xid_t {
875 long formatID;
876 long gtrid_length;
877 long bqual_length;
878 char data[XIDDATASIZE]; // not \0-terminated !
879
xid_txid_t880 xid_t() {} /* Remove gcc warning */
eqxid_t881 bool eq(struct xid_t *xid) const
882 { return !xid->is_null() && eq(xid->gtrid_length, xid->bqual_length, xid->data); }
eqxid_t883 bool eq(long g, long b, const char *d) const
884 { return !is_null() && g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); }
setxid_t885 void set(struct xid_t *xid)
886 { memcpy(this, xid, xid->length()); }
setxid_t887 void set(long f, const char *g, long gl, const char *b, long bl)
888 {
889 formatID= f;
890 if ((gtrid_length= gl))
891 memcpy(data, g, gl);
892 if ((bqual_length= bl))
893 memcpy(data+gl, b, bl);
894 }
setxid_t895 void set(ulonglong xid)
896 {
897 my_xid tmp;
898 formatID= 1;
899 set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX);
900 memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id));
901 tmp= xid;
902 memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp));
903 gtrid_length=MYSQL_XID_GTRID_LEN;
904 }
setxid_t905 void set(long g, long b, const char *d)
906 {
907 formatID= 1;
908 gtrid_length= g;
909 bqual_length= b;
910 memcpy(data, d, g+b);
911 }
is_nullxid_t912 bool is_null() const { return formatID == -1; }
nullxid_t913 void null() { formatID= -1; }
quick_get_my_xidxid_t914 my_xid quick_get_my_xid()
915 {
916 my_xid tmp;
917 memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp));
918 return tmp;
919 }
get_my_xidxid_t920 my_xid get_my_xid()
921 {
922 return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 &&
923 !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ?
924 quick_get_my_xid() : 0;
925 }
lengthxid_t926 uint length()
927 {
928 return static_cast<uint>(sizeof(formatID)) + key_length();
929 }
keyxid_t930 uchar *key() const
931 {
932 return (uchar *)>rid_length;
933 }
key_lengthxid_t934 uint key_length() const
935 {
936 return static_cast<uint>(sizeof(gtrid_length)+sizeof(bqual_length)+
937 gtrid_length+bqual_length);
938 }
939 };
940 typedef struct xid_t XID;
941
942 /* for recover() handlerton call */
943 #define MIN_XID_LIST_SIZE 128
944 #define MAX_XID_LIST_SIZE (1024*128)
945
946 /*
947 These structures are used to pass information from a set of SQL commands
948 on add/drop/change tablespace definitions to the proper hton.
949 */
950 #define UNDEF_NODEGROUP 65535
951 enum ts_command_type
952 {
953 TS_CMD_NOT_DEFINED = -1,
954 CREATE_TABLESPACE = 0,
955 ALTER_TABLESPACE = 1,
956 CREATE_LOGFILE_GROUP = 2,
957 ALTER_LOGFILE_GROUP = 3,
958 DROP_TABLESPACE = 4,
959 DROP_LOGFILE_GROUP = 5,
960 CHANGE_FILE_TABLESPACE = 6,
961 ALTER_ACCESS_MODE_TABLESPACE = 7
962 };
963
964 enum ts_alter_tablespace_type
965 {
966 TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1,
967 ALTER_TABLESPACE_ADD_FILE = 1,
968 ALTER_TABLESPACE_DROP_FILE = 2
969 };
970
971 enum tablespace_access_mode
972 {
973 TS_NOT_DEFINED= -1,
974 TS_READ_ONLY = 0,
975 TS_READ_WRITE = 1,
976 TS_NOT_ACCESSIBLE = 2
977 };
978
979 /* Statistics about batch operations like bulk_insert */
980 struct ha_copy_info
981 {
982 ha_rows records; /* Used to check if rest of variables can be used */
983 ha_rows touched;
984 ha_rows copied;
985 ha_rows deleted;
986 ha_rows updated;
987 };
988
989 struct handlerton;
990 class st_alter_tablespace : public Sql_alloc
991 {
992 public:
993 const char *tablespace_name;
994 const char *logfile_group_name;
995 enum ts_command_type ts_cmd_type;
996 enum ts_alter_tablespace_type ts_alter_tablespace_type;
997 const char *data_file_name;
998 const char *undo_file_name;
999 const char *redo_file_name;
1000 ulonglong extent_size;
1001 ulonglong undo_buffer_size;
1002 ulonglong redo_buffer_size;
1003 ulonglong initial_size;
1004 ulonglong autoextend_size;
1005 ulonglong max_size;
1006 uint nodegroup_id;
1007 handlerton *storage_engine;
1008 bool wait_until_completed;
1009 const char *ts_comment;
1010 enum tablespace_access_mode ts_access_mode;
st_alter_tablespace()1011 st_alter_tablespace()
1012 {
1013 tablespace_name= NULL;
1014 logfile_group_name= "DEFAULT_LG"; //Default log file group
1015 ts_cmd_type= TS_CMD_NOT_DEFINED;
1016 data_file_name= NULL;
1017 undo_file_name= NULL;
1018 redo_file_name= NULL;
1019 extent_size= 1024*1024; //Default 1 MByte
1020 undo_buffer_size= 8*1024*1024; //Default 8 MByte
1021 redo_buffer_size= 8*1024*1024; //Default 8 MByte
1022 initial_size= 128*1024*1024; //Default 128 MByte
1023 autoextend_size= 0; //No autoextension as default
1024 max_size= 0; //Max size == initial size => no extension
1025 storage_engine= NULL;
1026 nodegroup_id= UNDEF_NODEGROUP;
1027 wait_until_completed= TRUE;
1028 ts_comment= NULL;
1029 ts_access_mode= TS_NOT_DEFINED;
1030 }
1031 };
1032
1033 /* The handler for a table type. Will be included in the TABLE structure */
1034
1035 struct TABLE;
1036
1037 /*
1038 Make sure that the order of schema_tables and enum_schema_tables are the same.
1039 */
1040 enum enum_schema_tables
1041 {
1042 SCH_ALL_PLUGINS,
1043 SCH_APPLICABLE_ROLES,
1044 SCH_CHARSETS,
1045 SCH_CHECK_CONSTRAINTS,
1046 SCH_COLLATIONS,
1047 SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
1048 SCH_COLUMNS,
1049 SCH_COLUMN_PRIVILEGES,
1050 SCH_ENABLED_ROLES,
1051 SCH_ENGINES,
1052 SCH_EVENTS,
1053 SCH_EXPLAIN,
1054 SCH_FILES,
1055 SCH_GLOBAL_STATUS,
1056 SCH_GLOBAL_VARIABLES,
1057 SCH_KEYWORDS,
1058 SCH_KEY_CACHES,
1059 SCH_KEY_COLUMN_USAGE,
1060 SCH_OPEN_TABLES,
1061 SCH_OPT_TRACE,
1062 SCH_PARAMETERS,
1063 SCH_PARTITIONS,
1064 SCH_PLUGINS,
1065 SCH_PROCESSLIST,
1066 SCH_PROFILES,
1067 SCH_REFERENTIAL_CONSTRAINTS,
1068 SCH_PROCEDURES,
1069 SCH_SCHEMATA,
1070 SCH_SCHEMA_PRIVILEGES,
1071 SCH_SESSION_STATUS,
1072 SCH_SESSION_VARIABLES,
1073 SCH_STATISTICS,
1074 SCH_SQL_FUNCTIONS,
1075 SCH_SYSTEM_VARIABLES,
1076 SCH_TABLES,
1077 SCH_TABLESPACES,
1078 SCH_TABLE_CONSTRAINTS,
1079 SCH_TABLE_NAMES,
1080 SCH_TABLE_PRIVILEGES,
1081 SCH_TRIGGERS,
1082 SCH_USER_PRIVILEGES,
1083 SCH_VIEWS
1084 };
1085
1086 struct TABLE_SHARE;
1087 struct HA_CREATE_INFO;
1088 struct st_foreign_key_info;
1089 typedef struct st_foreign_key_info FOREIGN_KEY_INFO;
1090 typedef bool (stat_print_fn)(THD *thd, const char *type, size_t type_len,
1091 const char *file, size_t file_len,
1092 const char *status, size_t status_len);
1093 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX };
1094 extern MYSQL_PLUGIN_IMPORT st_plugin_int *hton2plugin[MAX_HA];
1095
1096 /* Transaction log maintains type definitions */
1097 enum log_status
1098 {
1099 HA_LOG_STATUS_FREE= 0, /* log is free and can be deleted */
1100 HA_LOG_STATUS_INUSE= 1, /* log can't be deleted because it is in use */
1101 HA_LOG_STATUS_NOSUCHLOG= 2 /* no such log (can't be returned by
1102 the log iterator status) */
1103 };
1104 /*
1105 Function for signaling that the log file changed its state from
1106 LOG_STATUS_INUSE to LOG_STATUS_FREE
1107
1108 Now it do nothing, will be implemented as part of new transaction
1109 log management for engines.
1110 TODO: implement the function.
1111 */
1112 void signal_log_not_needed(struct handlerton, char *log_file);
1113 /*
1114 Data of transaction log iterator.
1115 */
1116 struct handler_log_file_data {
1117 LEX_STRING filename;
1118 enum log_status status;
1119 };
1120
1121 /*
1122 Definitions for engine-specific table/field/index options in the CREATE TABLE.
1123
1124 Options are declared with HA_*OPTION_* macros (HA_TOPTION_NUMBER,
1125 HA_FOPTION_ENUM, HA_IOPTION_STRING, etc).
1126
1127 Every macros takes the option name, and the name of the underlying field of
1128 the appropriate C structure. The "appropriate C structure" is
1129 ha_table_option_struct for table level options,
1130 ha_field_option_struct for field level options,
1131 ha_index_option_struct for key level options. The engine either
1132 defines a structure of this name, or uses #define's to map
1133 these "appropriate" names to the actual structure type name.
1134
1135 ULL options use a ulonglong as the backing store.
1136 HA_*OPTION_NUMBER() takes the option name, the structure field name,
1137 the default value for the option, min, max, and blk_siz values.
1138
1139 STRING options use a char* as a backing store.
1140 HA_*OPTION_STRING takes the option name and the structure field name.
1141 The default value will be 0.
1142
1143 ENUM options use a uint as a backing store (not enum!!!).
1144 HA_*OPTION_ENUM takes the option name, the structure field name,
1145 the default value for the option as a number, and a string with the
1146 permitted values for this enum - one string with comma separated values,
1147 for example: "gzip,bzip2,lzma"
1148
1149 BOOL options use a bool as a backing store.
1150 HA_*OPTION_BOOL takes the option name, the structure field name,
1151 and the default value for the option.
1152 From the SQL, BOOL options accept YES/NO, ON/OFF, and 1/0.
1153
1154 The name of the option is limited to 255 bytes,
1155 the value (for string options) - to the 32767 bytes.
1156
1157 See ha_example.cc for an example.
1158 */
1159
1160 struct ha_table_option_struct;
1161 struct ha_field_option_struct;
1162 struct ha_index_option_struct;
1163
1164 enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
1165 HA_OPTION_TYPE_STRING, /* char * */
1166 HA_OPTION_TYPE_ENUM, /* uint */
1167 HA_OPTION_TYPE_BOOL, /* bool */
1168 HA_OPTION_TYPE_SYSVAR};/* type of the sysval */
1169
1170 #define HA_xOPTION_NUMBER(name, struc, field, def, min, max, blk_siz) \
1171 { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \
1172 offsetof(struc, field), def, min, max, blk_siz, 0, 0 }
1173 #define HA_xOPTION_STRING(name, struc, field) \
1174 { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \
1175 offsetof(struc, field), 0, 0, 0, 0, 0, 0}
1176 #define HA_xOPTION_ENUM(name, struc, field, values, def) \
1177 { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \
1178 offsetof(struc, field), def, 0, \
1179 sizeof(values)-1, 0, values, 0 }
1180 #define HA_xOPTION_BOOL(name, struc, field, def) \
1181 { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \
1182 offsetof(struc, field), def, 0, 1, 0, 0, 0 }
1183 #define HA_xOPTION_SYSVAR(name, struc, field, sysvar) \
1184 { HA_OPTION_TYPE_SYSVAR, name, sizeof(name)-1, \
1185 offsetof(struc, field), 0, 0, 0, 0, 0, MYSQL_SYSVAR(sysvar) }
1186 #define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
1187
1188 #define HA_TOPTION_NUMBER(name, field, def, min, max, blk_siz) \
1189 HA_xOPTION_NUMBER(name, ha_table_option_struct, field, def, min, max, blk_siz)
1190 #define HA_TOPTION_STRING(name, field) \
1191 HA_xOPTION_STRING(name, ha_table_option_struct, field)
1192 #define HA_TOPTION_ENUM(name, field, values, def) \
1193 HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
1194 #define HA_TOPTION_BOOL(name, field, def) \
1195 HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
1196 #define HA_TOPTION_SYSVAR(name, field, sysvar) \
1197 HA_xOPTION_SYSVAR(name, ha_table_option_struct, field, sysvar)
1198 #define HA_TOPTION_END HA_xOPTION_END
1199
1200 #define HA_FOPTION_NUMBER(name, field, def, min, max, blk_siz) \
1201 HA_xOPTION_NUMBER(name, ha_field_option_struct, field, def, min, max, blk_siz)
1202 #define HA_FOPTION_STRING(name, field) \
1203 HA_xOPTION_STRING(name, ha_field_option_struct, field)
1204 #define HA_FOPTION_ENUM(name, field, values, def) \
1205 HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
1206 #define HA_FOPTION_BOOL(name, field, def) \
1207 HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
1208 #define HA_FOPTION_SYSVAR(name, field, sysvar) \
1209 HA_xOPTION_SYSVAR(name, ha_field_option_struct, field, sysvar)
1210 #define HA_FOPTION_END HA_xOPTION_END
1211
1212 #define HA_IOPTION_NUMBER(name, field, def, min, max, blk_siz) \
1213 HA_xOPTION_NUMBER(name, ha_index_option_struct, field, def, min, max, blk_siz)
1214 #define HA_IOPTION_STRING(name, field) \
1215 HA_xOPTION_STRING(name, ha_index_option_struct, field)
1216 #define HA_IOPTION_ENUM(name, field, values, def) \
1217 HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def)
1218 #define HA_IOPTION_BOOL(name, field, def) \
1219 HA_xOPTION_BOOL(name, ha_index_option_struct, field, def)
1220 #define HA_IOPTION_SYSVAR(name, field, sysvar) \
1221 HA_xOPTION_SYSVAR(name, ha_index_option_struct, field, sysvar)
1222 #define HA_IOPTION_END HA_xOPTION_END
1223
1224 typedef struct st_ha_create_table_option {
1225 enum ha_option_type type;
1226 const char *name;
1227 size_t name_length;
1228 ptrdiff_t offset;
1229 ulonglong def_value;
1230 ulonglong min_value, max_value, block_size;
1231 const char *values;
1232 struct st_mysql_sys_var *var;
1233 } ha_create_table_option;
1234
1235 enum handler_iterator_type
1236 {
1237 /* request of transaction log iterator */
1238 HA_TRANSACTLOG_ITERATOR= 1
1239 };
1240 enum handler_create_iterator_result
1241 {
1242 HA_ITERATOR_OK, /* iterator created */
1243 HA_ITERATOR_UNSUPPORTED, /* such type of iterator is not supported */
1244 HA_ITERATOR_ERROR /* error during iterator creation */
1245 };
1246
1247 /*
1248 Iterator structure. Can be used by handler/handlerton for different purposes.
1249
1250 Iterator should be created in the way to point "before" the first object
1251 it iterate, so next() call move it to the first object or return !=0 if
1252 there is nothing to iterate through.
1253 */
1254 struct handler_iterator {
1255 /*
1256 Moves iterator to next record and return 0 or return !=0
1257 if there is no records.
1258 iterator_object will be filled by this function if next() returns 0.
1259 Content of the iterator_object depend on iterator type.
1260 */
1261 int (*next)(struct handler_iterator *, void *iterator_object);
1262 /*
1263 Free resources allocated by iterator, after this call iterator
1264 is not usable.
1265 */
1266 void (*destroy)(struct handler_iterator *);
1267 /*
1268 Pointer to buffer for the iterator to use.
1269 Should be allocated by function which created the iterator and
1270 destroyed by freed by above "destroy" call
1271 */
1272 void *buffer;
1273 };
1274
1275 class handler;
1276 class group_by_handler;
1277 class derived_handler;
1278 class select_handler;
1279 struct Query;
1280 typedef class st_select_lex SELECT_LEX;
1281 typedef struct st_order ORDER;
1282
1283 /*
1284 handlerton is a singleton structure - one instance per storage engine -
1285 to provide access to storage engine functionality that works on the
1286 "global" level (unlike handler class that works on a per-table basis)
1287
1288 usually handlerton instance is defined statically in ha_xxx.cc as
1289
1290 static handlerton { ... } xxx_hton;
1291
1292 savepoint_*, prepare, recover, and *_by_xid pointers can be 0.
1293 */
1294 struct handlerton
1295 {
1296 /*
1297 Historical number used for frm file to determine the correct
1298 storage engine. This is going away and new engines will just use
1299 "name" for this.
1300 */
1301 enum legacy_db_type db_type;
1302 /*
1303 each storage engine has it's own memory area (actually a pointer)
1304 in the thd, for storing per-connection information.
1305 It is accessed as
1306
1307 thd->ha_data[xxx_hton.slot]
1308
1309 slot number is initialized by MySQL after xxx_init() is called.
1310 */
1311 uint slot;
1312 /*
1313 to store per-savepoint data storage engine is provided with an area
1314 of a requested size (0 is ok here).
1315 savepoint_offset must be initialized statically to the size of
1316 the needed memory to store per-savepoint information.
1317 After xxx_init it is changed to be an offset to savepoint storage
1318 area and need not be used by storage engine.
1319 see binlog_hton and binlog_savepoint_set/rollback for an example.
1320 */
1321 uint savepoint_offset;
1322 /*
1323 handlerton methods:
1324
1325 close_connection is only called if
1326 thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need
1327 this storage area - set it to something, so that MySQL would know
1328 this storage engine was accessed in this connection
1329 */
1330 int (*close_connection)(handlerton *hton, THD *thd);
1331 /*
1332 Tell handler that query has been killed.
1333 */
1334 void (*kill_query)(handlerton *hton, THD *thd, enum thd_kill_levels level);
1335 /*
1336 sv points to an uninitialized storage area of requested size
1337 (see savepoint_offset description)
1338 */
1339 int (*savepoint_set)(handlerton *hton, THD *thd, void *sv);
1340 /*
1341 sv points to a storage area, that was earlier passed
1342 to the savepoint_set call
1343 */
1344 int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv);
1345 /**
1346 Check if storage engine allows to release metadata locks which were
1347 acquired after the savepoint if rollback to savepoint is done.
1348 @return true - If it is safe to release MDL locks.
1349 false - If it is not.
1350 */
1351 bool (*savepoint_rollback_can_release_mdl)(handlerton *hton, THD *thd);
1352 int (*savepoint_release)(handlerton *hton, THD *thd, void *sv);
1353 /*
1354 'all' is true if it's a real commit, that makes persistent changes
1355 'all' is false if it's not in fact a commit but an end of the
1356 statement that is part of the transaction.
1357 NOTE 'all' is also false in auto-commit mode where 'end of statement'
1358 and 'real commit' mean the same event.
1359 */
1360 int (*commit)(handlerton *hton, THD *thd, bool all);
1361 /*
1362 The commit_ordered() method is called prior to the commit() method, after
1363 the transaction manager has decided to commit (not rollback) the
1364 transaction. Unlike commit(), commit_ordered() is called only when the
1365 full transaction is committed, not for each commit of statement
1366 transaction in a multi-statement transaction.
1367
1368 Not that like prepare(), commit_ordered() is only called when 2-phase
1369 commit takes place. Ie. when no binary log and only a single engine
1370 participates in a transaction, one commit() is called, no
1371 commit_ordered(). So engines must be prepared for this.
1372
1373 The calls to commit_ordered() in multiple parallel transactions is
1374 guaranteed to happen in the same order in every participating
1375 handler. This can be used to ensure the same commit order among multiple
1376 handlers (eg. in table handler and binlog). So if transaction T1 calls
1377 into commit_ordered() of handler A before T2, then T1 will also call
1378 commit_ordered() of handler B before T2.
1379
1380 Engines that implement this method should during this call make the
1381 transaction visible to other transactions, thereby making the order of
1382 transaction commits be defined by the order of commit_ordered() calls.
1383
1384 The intention is that commit_ordered() should do the minimal amount of
1385 work that needs to happen in consistent commit order among handlers. To
1386 preserve ordering, calls need to be serialised on a global mutex, so
1387 doing any time-consuming or blocking operations in commit_ordered() will
1388 limit scalability.
1389
1390 Handlers can rely on commit_ordered() calls to be serialised (no two
1391 calls can run in parallel, so no extra locking on the handler part is
1392 required to ensure this).
1393
1394 Note that commit_ordered() can be called from a different thread than the
1395 one handling the transaction! So it can not do anything that depends on
1396 thread local storage, in particular it can not call my_error() and
1397 friends (instead it can store the error code and delay the call of
1398 my_error() to the commit() method).
1399
1400 Similarly, since commit_ordered() returns void, any return error code
1401 must be saved and returned from the commit() method instead.
1402
1403 The commit_ordered method is optional, and can be left unset if not
1404 needed in a particular handler (then there will be no ordering guarantees
1405 wrt. other engines and binary log).
1406 */
1407 void (*commit_ordered)(handlerton *hton, THD *thd, bool all);
1408 int (*rollback)(handlerton *hton, THD *thd, bool all);
1409 int (*prepare)(handlerton *hton, THD *thd, bool all);
1410 /*
1411 The prepare_ordered method is optional. If set, it will be called after
1412 successful prepare() in all handlers participating in 2-phase
1413 commit. Like commit_ordered(), it is called only when the full
1414 transaction is committed, not for each commit of statement transaction.
1415
1416 The calls to prepare_ordered() among multiple parallel transactions are
1417 ordered consistently with calls to commit_ordered(). This means that
1418 calls to prepare_ordered() effectively define the commit order, and that
1419 each handler will see the same sequence of transactions calling into
1420 prepare_ordered() and commit_ordered().
1421
1422 Thus, prepare_ordered() can be used to define commit order for handlers
1423 that need to do this in the prepare step (like binlog). It can also be
1424 used to release transaction's locks early in an order consistent with the
1425 order transactions will be eventually committed.
1426
1427 Like commit_ordered(), prepare_ordered() calls are serialised to maintain
1428 ordering, so the intention is that they should execute fast, with only
1429 the minimal amount of work needed to define commit order. Handlers can
1430 rely on this serialisation, and do not need to do any extra locking to
1431 avoid two prepare_ordered() calls running in parallel.
1432
1433 Like commit_ordered(), prepare_ordered() is not guaranteed to be called
1434 in the context of the thread handling the rest of the transaction. So it
1435 cannot invoke code that relies on thread local storage, in particular it
1436 cannot call my_error().
1437
1438 prepare_ordered() cannot cause a rollback by returning an error, all
1439 possible errors must be handled in prepare() (the prepare_ordered()
1440 method returns void). In case of some fatal error, a record of the error
1441 must be made internally by the engine and returned from commit() later.
1442
1443 Note that for user-level XA SQL commands, no consistent ordering among
1444 prepare_ordered() and commit_ordered() is guaranteed (as that would
1445 require blocking all other commits for an indefinite time).
1446
1447 When 2-phase commit is not used (eg. only one engine (and no binlog) in
1448 transaction), neither prepare() nor prepare_ordered() is called.
1449 */
1450 void (*prepare_ordered)(handlerton *hton, THD *thd, bool all);
1451 int (*recover)(handlerton *hton, XID *xid_list, uint len);
1452 int (*commit_by_xid)(handlerton *hton, XID *xid);
1453 int (*rollback_by_xid)(handlerton *hton, XID *xid);
1454 /*
1455 The commit_checkpoint_request() handlerton method is used to checkpoint
1456 the XA recovery process for storage engines that support two-phase
1457 commit.
1458
1459 The method is optional - an engine that does not implemented is expected
1460 to work the traditional way, where every commit() durably flushes the
1461 transaction to disk in the engine before completion, so XA recovery will
1462 no longer be needed for that transaction.
1463
1464 An engine that does implement commit_checkpoint_request() is also
1465 expected to implement commit_ordered(), so that ordering of commits is
1466 consistent between 2pc participants. Such engine is no longer required to
1467 durably flush to disk transactions in commit(), provided that the
1468 transaction has been successfully prepare()d and commit_ordered(); thus
1469 potentionally saving one fsync() call. (Engine must still durably flush
1470 to disk in commit() when no prepare()/commit_ordered() steps took place,
1471 at least if durable commits are wanted; this happens eg. if binlog is
1472 disabled).
1473
1474 The TC will periodically (eg. once per binlog rotation) call
1475 commit_checkpoint_request(). When this happens, the engine must arrange
1476 for all transaction that have completed commit_ordered() to be durably
1477 flushed to disk (this does not include transactions that might be in the
1478 middle of executing commit_ordered()). When such flush has completed, the
1479 engine must call commit_checkpoint_notify_ha(), passing back the opaque
1480 "cookie".
1481
1482 The flush and call of commit_checkpoint_notify_ha() need not happen
1483 immediately - it can be scheduled and performed asynchronously (ie. as
1484 part of next prepare(), or sync every second, or whatever), but should
1485 not be postponed indefinitely. It is however also permissible to do it
1486 immediately, before returning from commit_checkpoint_request().
1487
1488 When commit_checkpoint_notify_ha() is called, the TC will know that the
1489 transactions are durably committed, and thus no longer require XA
1490 recovery. It uses that to reduce the work needed for any subsequent XA
1491 recovery process.
1492 */
1493 void (*commit_checkpoint_request)(void *cookie);
1494 /*
1495 "Disable or enable checkpointing internal to the storage engine. This is
1496 used for FLUSH TABLES WITH READ LOCK AND DISABLE CHECKPOINT to ensure that
1497 the engine will never start any recovery from a time between
1498 FLUSH TABLES ... ; UNLOCK TABLES.
1499
1500 While checkpointing is disabled, the engine should pause any background
1501 write activity (such as tablespace checkpointing) that require consistency
1502 between different files (such as transaction log and tablespace files) for
1503 crash recovery to succeed. The idea is to use this to make safe
1504 multi-volume LVM snapshot backups.
1505 */
1506 int (*checkpoint_state)(handlerton *hton, bool disabled);
1507 void *(*create_cursor_read_view)(handlerton *hton, THD *thd);
1508 void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
1509 void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view);
1510 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root);
1511 void (*drop_database)(handlerton *hton, char* path);
1512 /*
1513 return 0 if dropped successfully,
1514 -1 if nothing was done by design (as in e.g. blackhole)
1515 an error code (e.g. HA_ERR_NO_SUCH_TABLE) otherwise
1516 */
1517 int (*drop_table)(handlerton *hton, const char* path);
1518 int (*panic)(handlerton *hton, enum ha_panic_function flag);
1519 int (*start_consistent_snapshot)(handlerton *hton, THD *thd);
1520 bool (*flush_logs)(handlerton *hton);
1521 bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
1522 uint (*partition_flags)();
1523 alter_table_operations (*alter_table_flags)(alter_table_operations flags);
1524 int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
1525 int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
1526 class Item *cond,
1527 enum enum_schema_tables);
1528 uint32 flags; /* global handler flags */
1529 /*
1530 Those handlerton functions below are properly initialized at handler
1531 init.
1532 */
1533 int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg);
1534 void (*binlog_log_query)(handlerton *hton, THD *thd,
1535 enum_binlog_command binlog_command,
1536 const char *query, uint query_length,
1537 const char *db, const char *table_name);
1538
1539 /*
1540 Get log status.
1541 If log_status is null then the handler do not support transaction
1542 log information (i.e. log iterator can't be created).
1543 (see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE)
1544
1545 */
1546 enum log_status (*get_log_status)(handlerton *hton, char *log);
1547
1548 /*
1549 Iterators creator.
1550 Presence of the pointer should be checked before using
1551 */
1552 enum handler_create_iterator_result
1553 (*create_iterator)(handlerton *hton, enum handler_iterator_type type,
1554 struct handler_iterator *fill_this_in);
1555 void (*abort_transaction)(handlerton *hton, THD *bf_thd,
1556 THD *victim_thd, my_bool signal);
1557 int (*set_checkpoint)(handlerton *hton, const XID* xid);
1558 int (*get_checkpoint)(handlerton *hton, XID* xid);
1559 /*
1560 Optional clauses in the CREATE/ALTER TABLE
1561 */
1562 ha_create_table_option *table_options; // table level options
1563 ha_create_table_option *field_options; // these are specified per field
1564 ha_create_table_option *index_options; // these are specified per index
1565
1566 /**
1567 The list of extensions of files created for a single table in the
1568 database directory (datadir/db_name/).
1569
1570 Used by open_table_error(), by the default rename_table and delete_table
1571 handler methods, and by the default discovery implementation.
1572
1573 For engines that have more than one file name extensions (separate
1574 metadata, index, and/or data files), the order of elements is relevant.
1575 First element of engine file name extensions array should be metadata
1576 file extention. This is implied by the open_table_error()
1577 and the default discovery implementation.
1578
1579 Second element - data file extension. This is implied
1580 assumed by REPAIR TABLE ... USE_FRM implementation.
1581 */
1582 const char **tablefile_extensions; // by default - empty list
1583
1584 /**********************************************************************
1585 Functions to intercept queries
1586 **********************************************************************/
1587
1588 /*
1589 Create and return a group_by_handler, if the storage engine can execute
1590 the summary / group by query.
1591 If the storage engine can't do that, return NULL.
1592
1593 The server guaranteeds that all tables in the list belong to this
1594 storage engine.
1595 */
1596 group_by_handler *(*create_group_by)(THD *thd, Query *query);
1597
1598 /*
1599 Create and return a derived_handler if the storage engine can execute
1600 the derived table 'derived', otherwise return NULL.
1601 In a general case 'derived' may contain tables not from the engine.
1602 If the engine cannot handle or does not want to handle such pushed derived
1603 the function create_group_by has to return NULL.
1604 */
1605 derived_handler *(*create_derived)(THD *thd, TABLE_LIST *derived);
1606
1607 /*
1608 Create and return a select_handler if the storage engine can execute
1609 the select statement 'select, otherwise return NULL
1610 */
1611 select_handler *(*create_select) (THD *thd, SELECT_LEX *select);
1612
1613 /*********************************************************************
1614 Table discovery API.
1615 It allows the server to "discover" tables that exist in the storage
1616 engine, without user issuing an explicit CREATE TABLE statement.
1617 **********************************************************************/
1618
1619 /*
1620 This method is required for any engine that supports automatic table
1621 discovery, there is no default implementation.
1622
1623 Given a TABLE_SHARE discover_table() fills it in with a correct table
1624 structure using one of the TABLE_SHARE::init_from_* methods.
1625
1626 Returns HA_ERR_NO_SUCH_TABLE if the table did not exist in the engine,
1627 zero if the table was discovered successfully, or any other
1628 HA_ERR_* error code as appropriate if the table existed, but the
1629 discovery failed.
1630 */
1631 int (*discover_table)(handlerton *hton, THD* thd, TABLE_SHARE *share);
1632
1633 /*
1634 The discover_table_names method tells the server
1635 about all tables in the specified database that the engine
1636 knows about. Tables (or file names of tables) are added to
1637 the provided discovered_list collector object using
1638 add_table() or add_file() methods.
1639 */
1640 class discovered_list
1641 {
1642 public:
1643 virtual bool add_table(const char *tname, size_t tlen) = 0;
1644 virtual bool add_file(const char *fname) = 0;
~discovered_listhandlerton1645 protected: virtual ~discovered_list() {}
1646 };
1647
1648 /*
1649 By default (if not implemented by the engine, but the discover_table() is
1650 implemented) it will perform a file-based discovery:
1651
1652 - if tablefile_extensions[0] is not null, this will discovers all tables
1653 with the tablefile_extensions[0] extension.
1654
1655 Returns 0 on success and 1 on error.
1656 */
1657 int (*discover_table_names)(handlerton *hton, LEX_CSTRING *db, MY_DIR *dir,
1658 discovered_list *result);
1659
1660 /*
1661 This is a method that allows to server to check if a table exists without
1662 an overhead of the complete discovery.
1663
1664 By default (if not implemented by the engine, but the discovery_table() is
1665 implemented) it will try to perform a file-based discovery:
1666
1667 - if tablefile_extensions[0] is not null this will look for a file name
1668 with the tablefile_extensions[0] extension.
1669
1670 - if tablefile_extensions[0] is null, this will resort to discover_table().
1671
1672 Note that resorting to discover_table() is slow and the engine
1673 should probably implement its own discover_table_existence() method,
1674 if its tablefile_extensions[0] is null.
1675
1676 Returns 1 if the table exists and 0 if it does not.
1677 */
1678 int (*discover_table_existence)(handlerton *hton, const char *db,
1679 const char *table_name);
1680
1681 /*
1682 This is the assisted table discovery method. Unlike the fully
1683 automatic discovery as above, here a user is expected to issue an
1684 explicit CREATE TABLE with the appropriate table attributes to
1685 "assist" the discovery of a table. But this "discovering" CREATE TABLE
1686 statement will not specify the table structure - the engine discovers
1687 it using this method. For example, FederatedX uses it in
1688
1689 CREATE TABLE t1 ENGINE=FEDERATED CONNECTION="mysql://foo/bar/t1";
1690
1691 Given a TABLE_SHARE discover_table_structure() fills it in with a correct
1692 table structure using one of the TABLE_SHARE::init_from_* methods.
1693
1694 Assisted discovery works independently from the automatic discover.
1695 An engine is allowed to support only assisted discovery and not
1696 support automatic one. Or vice versa.
1697 */
1698 int (*discover_table_structure)(handlerton *hton, THD* thd,
1699 TABLE_SHARE *share, HA_CREATE_INFO *info);
1700
1701 /*
1702 Notify the storage engine that the definition of the table (and the .frm
1703 file) has changed. Returns 0 if ok.
1704 */
1705 int (*notify_tabledef_changed)(handlerton *hton, LEX_CSTRING *db,
1706 LEX_CSTRING *table_name, LEX_CUSTRING *frm,
1707 LEX_CUSTRING *org_tabledef_version,
1708 handler *file);
1709
1710 /*
1711 System Versioning
1712 */
1713 /** Determine if system-versioned data was modified by the transaction.
1714 @param[in,out] thd current session
1715 @param[out] trx_id transaction start ID
1716 @return transaction commit ID
1717 @retval 0 if no system-versioned data was affected by the transaction */
1718 ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
1719
1720 /* backup */
1721 void (*prepare_for_backup)(void);
1722 void (*end_backup)(void);
1723
1724 /* Server shutdown early notification.*/
1725 void (*pre_shutdown)(void);
1726
1727 /*
1728 Inform handler that partitioning engine has changed the .frm and the .par
1729 files
1730 */
1731 int (*create_partitioning_metadata)(const char *path,
1732 const char *old_path,
1733 chf_create_flags action_flag);
1734 };
1735
1736
hton_name(const handlerton * hton)1737 static inline LEX_CSTRING *hton_name(const handlerton *hton)
1738 {
1739 return &(hton2plugin[hton->slot]->name);
1740 }
1741
plugin_hton(plugin_ref plugin)1742 static inline handlerton *plugin_hton(plugin_ref plugin)
1743 {
1744 return plugin_data(plugin, handlerton *);
1745 }
1746
find_hton_sysvar(handlerton * hton,st_mysql_sys_var * var)1747 static inline sys_var *find_hton_sysvar(handlerton *hton, st_mysql_sys_var *var)
1748 {
1749 return find_plugin_sysvar(hton2plugin[hton->slot], var);
1750 }
1751
1752 handlerton *ha_default_handlerton(THD *thd);
1753 handlerton *ha_default_tmp_handlerton(THD *thd);
1754
1755 /* Possible flags of a handlerton (there can be 32 of them) */
1756 #define HTON_NO_FLAGS 0
1757 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
1758 #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
1759 #define HTON_CAN_RECREATE (1 << 2) //Delete all is used for truncate
1760 #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
1761 #define HTON_NOT_USER_SELECTABLE (1 << 5)
1762 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
1763 #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
1764 #define HTON_NO_PARTITION (1 << 8) //Not partition of these tables
1765
1766 /*
1767 This flag should be set when deciding that the engine does not allow
1768 row based binary logging (RBL) optimizations.
1769
1770 Currently, setting this flag, means that table's read/write_set will
1771 be left untouched when logging changes to tables in this engine. In
1772 practice this means that the server will not mess around with
1773 table->write_set and/or table->read_set when using RBL and deciding
1774 whether to log full or minimal rows.
1775
1776 It's valuable for instance for virtual tables, eg: Performance
1777 Schema which have no meaning for replication.
1778 */
1779 #define HTON_NO_BINLOG_ROW_OPT (1 << 9)
1780 #define HTON_SUPPORTS_EXTENDED_KEYS (1 <<10) //supports extended keys
1781 #define HTON_NATIVE_SYS_VERSIONING (1 << 11) //Engine supports System Versioning
1782
1783 // MySQL compatibility. Unused.
1784 #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 0) //Foreign key constraint supported.
1785
1786 #define HTON_CAN_MERGE (1 <<11) //Merge type table
1787 // Engine needs to access the main connect string in partitions
1788 #define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 <<12)
1789
1790 /* can be replicated by wsrep replication provider plugin */
1791 #define HTON_WSREP_REPLICATION (1 << 13)
1792
1793 /*
1794 Set this on the *slave* that's connected to a shared with a master storage.
1795 The slave will ignore any CREATE TABLE, DROP or updates for this engine.
1796 */
1797 #define HTON_IGNORE_UPDATES (1 << 14)
1798
1799 /*
1800 Set this on the *master* that's connected to a shared with a slave storage.
1801 The table may not exists on the slave. The effects of having this flag are:
1802 - ALTER TABLE that changes engine from this table to another engine will
1803 be replicated as CREATE + INSERT
1804 - CREATE ... LIKE shared_table will be replicated as a full CREATE TABLE
1805 - ALTER TABLE for this engine will have "IF EXISTS" added.
1806 - RENAME TABLE for this engine will have "IF EXISTS" added.
1807 - DROP TABLE for this engine will have "IF EXISTS" added.
1808 */
1809 #define HTON_TABLE_MAY_NOT_EXIST_ON_SLAVE (1 << 15)
1810
1811 /*
1812 True if handler cannot rollback transactions. If not true, the transaction
1813 will be put in the transactional binlog cache.
1814 For some engines, like Aria, the rollback can happen in case of crash, but
1815 not trough a handler rollback call.
1816 */
1817 #define HTON_NO_ROLLBACK (1 << 16)
1818
1819 /*
1820 This storage engine can support both transactional and non transactional
1821 tables
1822 */
1823 #define HTON_TRANSACTIONAL_AND_NON_TRANSACTIONAL (1 << 17)
1824
1825 /*
1826 Table requires and close and reopen after truncate
1827 If the handler has HTON_CAN_RECREATE, this flag is not used
1828 */
1829 #define HTON_REQUIRES_CLOSE_AFTER_TRUNCATE (1 << 18)
1830
1831 class Ha_trx_info;
1832
1833 struct THD_TRANS
1834 {
1835 /* true is not all entries in the ht[] support 2pc */
1836 bool no_2pc;
1837 /* storage engines that registered in this transaction */
1838 Ha_trx_info *ha_list;
1839 /*
1840 The purpose of this flag is to keep track of non-transactional
1841 tables that were modified in scope of:
1842 - transaction, when the variable is a member of
1843 THD::transaction.all
1844 - top-level statement or sub-statement, when the variable is a
1845 member of THD::transaction.stmt
1846 This member has the following life cycle:
1847 * stmt.modified_non_trans_table is used to keep track of
1848 modified non-transactional tables of top-level statements. At
1849 the end of the previous statement and at the beginning of the session,
1850 it is reset to FALSE. If such functions
1851 as mysql_insert, mysql_update, mysql_delete etc modify a
1852 non-transactional table, they set this flag to TRUE. At the
1853 end of the statement, the value of stmt.modified_non_trans_table
1854 is merged with all.modified_non_trans_table and gets reset.
1855 * all.modified_non_trans_table is reset at the end of transaction
1856
1857 * Since we do not have a dedicated context for execution of a
1858 sub-statement, to keep track of non-transactional changes in a
1859 sub-statement, we re-use stmt.modified_non_trans_table.
1860 At entrance into a sub-statement, a copy of the value of
1861 stmt.modified_non_trans_table (containing the changes of the
1862 outer statement) is saved on stack. Then
1863 stmt.modified_non_trans_table is reset to FALSE and the
1864 substatement is executed. Then the new value is merged with the
1865 saved value.
1866 */
1867 bool modified_non_trans_table;
1868
resetTHD_TRANS1869 void reset() {
1870 no_2pc= FALSE;
1871 modified_non_trans_table= FALSE;
1872 m_unsafe_rollback_flags= 0;
1873 }
is_emptyTHD_TRANS1874 bool is_empty() const { return ha_list == NULL; }
THD_TRANSTHD_TRANS1875 THD_TRANS() {} /* Remove gcc warning */
1876
1877 unsigned int m_unsafe_rollback_flags;
1878 /*
1879 Define the type of statements which cannot be rolled back safely.
1880 Each type occupies one bit in m_unsafe_rollback_flags.
1881 MODIFIED_NON_TRANS_TABLE is limited to mark only the temporary
1882 non-transactional table *when* it's cached along with the transactional
1883 events; the regular table is covered by the "namesake" bool var.
1884 */
1885 enum unsafe_statement_types
1886 {
1887 MODIFIED_NON_TRANS_TABLE= 1,
1888 CREATED_TEMP_TABLE= 2,
1889 DROPPED_TEMP_TABLE= 4,
1890 DID_WAIT= 8,
1891 DID_DDL= 0x10,
1892 EXECUTED_TABLE_ADMIN_CMD= 0x20
1893 };
1894
mark_modified_non_trans_temp_tableTHD_TRANS1895 void mark_modified_non_trans_temp_table()
1896 {
1897 m_unsafe_rollback_flags|= MODIFIED_NON_TRANS_TABLE;
1898 }
has_modified_non_trans_temp_tableTHD_TRANS1899 bool has_modified_non_trans_temp_table() const
1900 {
1901 return (m_unsafe_rollback_flags & MODIFIED_NON_TRANS_TABLE) != 0;
1902 }
mark_executed_table_admin_cmdTHD_TRANS1903 void mark_executed_table_admin_cmd()
1904 {
1905 DBUG_PRINT("debug", ("mark_executed_table_admin_cmd"));
1906 m_unsafe_rollback_flags|= EXECUTED_TABLE_ADMIN_CMD;
1907 }
trans_executed_admin_cmdTHD_TRANS1908 bool trans_executed_admin_cmd()
1909 {
1910 return (m_unsafe_rollback_flags & EXECUTED_TABLE_ADMIN_CMD) != 0;
1911 }
mark_created_temp_tableTHD_TRANS1912 void mark_created_temp_table()
1913 {
1914 DBUG_PRINT("debug", ("mark_created_temp_table"));
1915 m_unsafe_rollback_flags|= CREATED_TEMP_TABLE;
1916 }
mark_dropped_temp_tableTHD_TRANS1917 void mark_dropped_temp_table()
1918 {
1919 DBUG_PRINT("debug", ("mark_dropped_temp_table"));
1920 m_unsafe_rollback_flags|= DROPPED_TEMP_TABLE;
1921 }
has_created_dropped_temp_tableTHD_TRANS1922 bool has_created_dropped_temp_table() const {
1923 return
1924 (m_unsafe_rollback_flags & (CREATED_TEMP_TABLE|DROPPED_TEMP_TABLE)) != 0;
1925 }
mark_trans_did_waitTHD_TRANS1926 void mark_trans_did_wait() { m_unsafe_rollback_flags|= DID_WAIT; }
trans_did_waitTHD_TRANS1927 bool trans_did_wait() const {
1928 return (m_unsafe_rollback_flags & DID_WAIT) != 0;
1929 }
1930 bool is_trx_read_write() const;
mark_trans_did_ddlTHD_TRANS1931 void mark_trans_did_ddl() { m_unsafe_rollback_flags|= DID_DDL; }
trans_did_ddlTHD_TRANS1932 bool trans_did_ddl() const {
1933 return (m_unsafe_rollback_flags & DID_DDL) != 0;
1934 }
1935
1936 };
1937
1938
1939 /**
1940 Either statement transaction or normal transaction - related
1941 thread-specific storage engine data.
1942
1943 If a storage engine participates in a statement/transaction,
1944 an instance of this class is present in
1945 thd->transaction.{stmt|all}.ha_list. The addition to
1946 {stmt|all}.ha_list is made by trans_register_ha().
1947
1948 When it's time to commit or rollback, each element of ha_list
1949 is used to access storage engine's prepare()/commit()/rollback()
1950 methods, and also to evaluate if a full two phase commit is
1951 necessary.
1952
1953 @sa General description of transaction handling in handler.cc.
1954 */
1955
1956 class Ha_trx_info
1957 {
1958 public:
1959 /** Register this storage engine in the given transaction context. */
register_ha(THD_TRANS * trans,handlerton * ht_arg)1960 void register_ha(THD_TRANS *trans, handlerton *ht_arg)
1961 {
1962 DBUG_ASSERT(m_flags == 0);
1963 DBUG_ASSERT(m_ht == NULL);
1964 DBUG_ASSERT(m_next == NULL);
1965
1966 m_ht= ht_arg;
1967 m_flags= (int) TRX_READ_ONLY; /* Assume read-only at start. */
1968
1969 m_next= trans->ha_list;
1970 trans->ha_list= this;
1971 }
1972
1973 /** Clear, prepare for reuse. */
reset()1974 void reset()
1975 {
1976 m_next= NULL;
1977 m_ht= NULL;
1978 m_flags= 0;
1979 }
1980
Ha_trx_info()1981 Ha_trx_info() { reset(); }
1982
set_trx_read_write()1983 void set_trx_read_write()
1984 {
1985 DBUG_ASSERT(is_started());
1986 m_flags|= (int) TRX_READ_WRITE;
1987 }
is_trx_read_write()1988 bool is_trx_read_write() const
1989 {
1990 DBUG_ASSERT(is_started());
1991 return m_flags & (int) TRX_READ_WRITE;
1992 }
is_started()1993 bool is_started() const { return m_ht != NULL; }
1994 /** Mark this transaction read-write if the argument is read-write. */
coalesce_trx_with(const Ha_trx_info * stmt_trx)1995 void coalesce_trx_with(const Ha_trx_info *stmt_trx)
1996 {
1997 /*
1998 Must be called only after the transaction has been started.
1999 Can be called many times, e.g. when we have many
2000 read-write statements in a transaction.
2001 */
2002 DBUG_ASSERT(is_started());
2003 if (stmt_trx->is_trx_read_write())
2004 set_trx_read_write();
2005 }
next()2006 Ha_trx_info *next() const
2007 {
2008 DBUG_ASSERT(is_started());
2009 return m_next;
2010 }
ht()2011 handlerton *ht() const
2012 {
2013 DBUG_ASSERT(is_started());
2014 return m_ht;
2015 }
2016 private:
2017 enum { TRX_READ_ONLY= 0, TRX_READ_WRITE= 1 };
2018 /** Auxiliary, used for ha_list management */
2019 Ha_trx_info *m_next;
2020 /**
2021 Although a given Ha_trx_info instance is currently always used
2022 for the same storage engine, 'ht' is not-NULL only when the
2023 corresponding storage is a part of a transaction.
2024 */
2025 handlerton *m_ht;
2026 /**
2027 Transaction flags related to this engine.
2028 Not-null only if this instance is a part of transaction.
2029 May assume a combination of enum values above.
2030 */
2031 uchar m_flags;
2032 };
2033
2034
is_trx_read_write()2035 inline bool THD_TRANS::is_trx_read_write() const
2036 {
2037 Ha_trx_info *ha_info;
2038 for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
2039 if (ha_info->is_trx_read_write())
2040 return TRUE;
2041 return FALSE;
2042 }
2043
2044
2045 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
2046 ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
2047
2048
2049 typedef struct {
2050 ulonglong data_file_length;
2051 ulonglong max_data_file_length;
2052 ulonglong index_file_length;
2053 ulonglong max_index_file_length;
2054 ulonglong delete_length;
2055 ha_rows records;
2056 ulong mean_rec_length;
2057 time_t create_time;
2058 time_t check_time;
2059 time_t update_time;
2060 ulonglong check_sum;
2061 bool check_sum_null;
2062 } PARTITION_STATS;
2063
2064 #define UNDEF_NODEGROUP 65535
2065 class Item;
2066 struct st_table_log_memory_entry;
2067
2068 class partition_info;
2069
2070 struct st_partition_iter;
2071
2072 enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES, HA_CHOICE_MAX };
2073
2074 enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0,
2075 HA_STATS_AUTO_RECALC_ON,
2076 HA_STATS_AUTO_RECALC_OFF };
2077
2078 /**
2079 A helper struct for schema DDL statements:
2080 CREATE SCHEMA [IF NOT EXISTS] name [ schema_specification... ]
2081 ALTER SCHEMA name [ schema_specification... ]
2082
2083 It stores the "schema_specification" part of the CREATE/ALTER statements and
2084 is passed to mysql_create_db() and mysql_alter_db().
2085 Currently consists of the schema default character set, collation
2086 and schema_comment.
2087 */
2088 struct Schema_specification_st
2089 {
2090 CHARSET_INFO *default_table_charset;
2091 LEX_CSTRING *schema_comment;
initSchema_specification_st2092 void init()
2093 {
2094 bzero(this, sizeof(*this));
2095 }
2096 };
2097
2098 class Create_field;
2099
2100 struct Table_period_info: Sql_alloc
2101 {
Table_period_infoTable_period_info2102 Table_period_info() :
2103 create_if_not_exists(false),
2104 constr(NULL),
2105 unique_keys(0) {}
Table_period_infoTable_period_info2106 Table_period_info(const char *name_arg, size_t size) :
2107 name(name_arg, size),
2108 create_if_not_exists(false),
2109 constr(NULL),
2110 unique_keys(0){}
2111
2112 Lex_ident name;
2113
2114 struct start_end_t
2115 {
start_end_tTable_period_info::start_end_t2116 start_end_t() {};
start_end_tTable_period_info::start_end_t2117 start_end_t(const LEX_CSTRING& _start, const LEX_CSTRING& _end) :
2118 start(_start),
2119 end(_end) {}
2120 Lex_ident start;
2121 Lex_ident end;
2122 };
2123 start_end_t period;
2124 bool create_if_not_exists;
2125 Virtual_column_info *constr;
2126 uint unique_keys;
2127
is_setTable_period_info2128 bool is_set() const
2129 {
2130 DBUG_ASSERT(bool(period.start) == bool(period.end));
2131 return period.start;
2132 }
2133
set_periodTable_period_info2134 void set_period(const Lex_ident& start, const Lex_ident& end)
2135 {
2136 period.start= start;
2137 period.end= end;
2138 }
2139 bool check_field(const Create_field* f, const Lex_ident& f_name) const;
2140 };
2141
2142 struct Vers_parse_info: public Table_period_info
2143 {
Vers_parse_infoVers_parse_info2144 Vers_parse_info() :
2145 Table_period_info(STRING_WITH_LEN("SYSTEM_TIME")),
2146 versioned_fields(false),
2147 unversioned_fields(false)
2148 {}
2149
2150 Table_period_info::start_end_t as_row;
2151
2152 protected:
2153 friend struct Table_scope_and_contents_source_st;
set_startVers_parse_info2154 void set_start(const LEX_CSTRING field_name)
2155 {
2156 as_row.start= field_name;
2157 period.start= field_name;
2158 }
set_endVers_parse_info2159 void set_end(const LEX_CSTRING field_name)
2160 {
2161 as_row.end= field_name;
2162 period.end= field_name;
2163 }
2164 bool is_start(const char *name) const;
2165 bool is_end(const char *name) const;
2166 bool is_start(const Create_field &f) const;
2167 bool is_end(const Create_field &f) const;
2168 bool fix_implicit(THD *thd, Alter_info *alter_info);
2169 operator bool() const
2170 {
2171 return as_row.start || as_row.end || period.start || period.end;
2172 }
2173 bool need_check(const Alter_info *alter_info) const;
2174 bool check_conditions(const Lex_table_name &table_name,
2175 const Lex_table_name &db) const;
2176 public:
2177 static const Lex_ident default_start;
2178 static const Lex_ident default_end;
2179
2180 bool fix_alter_info(THD *thd, Alter_info *alter_info,
2181 HA_CREATE_INFO *create_info, TABLE *table);
2182 bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
2183 TABLE_LIST &src_table, TABLE_LIST &table);
2184 bool check_sys_fields(const Lex_table_name &table_name,
2185 const Lex_table_name &db, Alter_info *alter_info) const;
2186
2187 /**
2188 At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'.
2189 Useful for error handling.
2190 */
2191 bool versioned_fields : 1;
2192 bool unversioned_fields : 1;
2193 };
2194
2195 /**
2196 A helper struct for table DDL statements, e.g.:
2197 CREATE [OR REPLACE] [TEMPORARY]
2198 TABLE [IF NOT EXISTS] tbl_name table_contents_source;
2199
2200 Represents a combinations of:
2201 1. The scope, i.e. TEMPORARY or not TEMPORARY
2202 2. The "table_contents_source" part of the table DDL statements,
2203 which can be initialized from either of these:
2204 - table_element_list ... // Explicit definition (column and key list)
2205 - LIKE another_table_name ... // Copy structure from another table
2206 - [AS] SELECT ... // Copy structure from a subquery
2207 */
2208
2209 struct Table_scope_and_contents_source_pod_st // For trivial members
2210 {
2211 CHARSET_INFO *alter_table_convert_to_charset;
2212 LEX_CUSTRING tabledef_version;
2213 LEX_CSTRING connect_string;
2214 LEX_CSTRING comment;
2215 LEX_CSTRING alias;
2216 const char *password, *tablespace;
2217 const char *data_file_name, *index_file_name;
2218 ulonglong max_rows,min_rows;
2219 ulonglong auto_increment_value;
2220 ulong table_options; ///< HA_OPTION_ values
2221 ulong avg_row_length;
2222 ulong used_fields;
2223 ulong key_block_size;
2224 ulong expression_length;
2225 ulong field_check_constraints;
2226 /*
2227 number of pages to sample during
2228 stats estimation, if used, otherwise 0.
2229 */
2230 uint stats_sample_pages;
2231 uint null_bits; /* NULL bits at start of record */
2232 uint options; /* OR of HA_CREATE_ options */
2233 uint merge_insert_method;
2234 uint extra_size; /* length of extra data segment */
2235 handlerton *db_type;
2236 /**
2237 Row type of the table definition.
2238
2239 Defaults to ROW_TYPE_DEFAULT for all non-ALTER statements.
2240 For ALTER TABLE defaults to ROW_TYPE_NOT_USED (means "keep the current").
2241
2242 Can be changed either explicitly by the parser.
2243 If nothing specified inherits the value of the original table (if present).
2244 */
2245 enum row_type row_type;
2246 enum ha_choice transactional;
2247 enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY
2248 enum ha_choice page_checksum; ///< If we have page_checksums
2249 engine_option_value *option_list; ///< list of table create options
2250 enum_stats_auto_recalc stats_auto_recalc;
2251 bool varchar; ///< 1 if table has a VARCHAR
2252 bool sequence; // If SEQUENCE=1 was used
2253
2254 List<Virtual_column_info> *check_constraint_list;
2255
2256 /* the following three are only for ALTER TABLE, check_if_incompatible_data() */
2257 ha_table_option_struct *option_struct; ///< structure with parsed table options
2258 ha_field_option_struct **fields_option_struct; ///< array of field option structures
2259 ha_index_option_struct **indexes_option_struct; ///< array of index option structures
2260
2261 /* The following is used to remember the old state for CREATE OR REPLACE */
2262 TABLE *table;
2263 TABLE_LIST *pos_in_locked_tables;
2264 TABLE_LIST *merge_list;
2265 MDL_ticket *mdl_ticket;
2266 bool table_was_deleted;
2267 sequence_definition *seq_create_info;
2268
initTable_scope_and_contents_source_pod_st2269 void init()
2270 {
2271 bzero(this, sizeof(*this));
2272 }
tmp_tableTable_scope_and_contents_source_pod_st2273 bool tmp_table() const { return options & HA_LEX_CREATE_TMP_TABLE; }
use_default_db_typeTable_scope_and_contents_source_pod_st2274 void use_default_db_type(THD *thd)
2275 {
2276 db_type= tmp_table() ? ha_default_tmp_handlerton(thd)
2277 : ha_default_handlerton(thd);
2278 }
2279
versionedTable_scope_and_contents_source_pod_st2280 bool versioned() const
2281 {
2282 return options & HA_VERSIONED_TABLE;
2283 }
2284 };
2285
2286
2287 struct Table_scope_and_contents_source_st:
2288 public Table_scope_and_contents_source_pod_st
2289 {
2290 Vers_parse_info vers_info;
2291 Table_period_info period_info;
2292
initTable_scope_and_contents_source_st2293 void init()
2294 {
2295 Table_scope_and_contents_source_pod_st::init();
2296 vers_info= {};
2297 period_info= {};
2298 }
2299
2300 bool fix_create_fields(THD *thd, Alter_info *alter_info,
2301 const TABLE_LIST &create_table);
2302 bool fix_period_fields(THD *thd, Alter_info *alter_info);
2303 bool check_fields(THD *thd, Alter_info *alter_info,
2304 const Lex_table_name &table_name,
2305 const Lex_table_name &db,
2306 int select_count= 0);
2307 bool check_period_fields(THD *thd, Alter_info *alter_info);
2308
2309 bool vers_fix_system_fields(THD *thd, Alter_info *alter_info,
2310 const TABLE_LIST &create_table);
2311
2312 bool vers_check_system_fields(THD *thd, Alter_info *alter_info,
2313 const Lex_table_name &table_name,
2314 const Lex_table_name &db,
2315 int select_count= 0);
2316
2317 };
2318
2319
2320 /**
2321 This struct is passed to handler table routines, e.g. ha_create().
2322 It does not include the "OR REPLACE" and "IF NOT EXISTS" parts, as these
2323 parts are handled on the SQL level and are not needed on the handler level.
2324 */
2325 struct HA_CREATE_INFO: public Table_scope_and_contents_source_st,
2326 public Schema_specification_st
2327 {
2328 /* TODO: remove after MDEV-20865 */
2329 Alter_info *alter_info;
2330
initHA_CREATE_INFO2331 void init()
2332 {
2333 Table_scope_and_contents_source_st::init();
2334 Schema_specification_st::init();
2335 alter_info= NULL;
2336 }
2337 bool check_conflicting_charset_declarations(CHARSET_INFO *cs);
add_table_option_default_charsetHA_CREATE_INFO2338 bool add_table_option_default_charset(CHARSET_INFO *cs)
2339 {
2340 // cs can be NULL, e.g.: CREATE TABLE t1 (..) CHARACTER SET DEFAULT;
2341 if (check_conflicting_charset_declarations(cs))
2342 return true;
2343 default_table_charset= cs;
2344 used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
2345 return false;
2346 }
add_alter_list_item_convert_to_charsetHA_CREATE_INFO2347 bool add_alter_list_item_convert_to_charset(CHARSET_INFO *cs)
2348 {
2349 /*
2350 cs cannot be NULL, as sql_yacc.yy translates
2351 CONVERT TO CHARACTER SET DEFAULT
2352 to
2353 CONVERT TO CHARACTER SET <character-set-of-the-current-database>
2354 TODO: Shouldn't we postpone resolution of DEFAULT until the
2355 character set of the table owner database is loaded from its db.opt?
2356 */
2357 DBUG_ASSERT(cs);
2358 if (check_conflicting_charset_declarations(cs))
2359 return true;
2360 alter_table_convert_to_charset= default_table_charset= cs;
2361 used_fields|= (HA_CREATE_USED_CHARSET | HA_CREATE_USED_DEFAULT_CHARSET);
2362 return false;
2363 }
table_options_with_row_typeHA_CREATE_INFO2364 ulong table_options_with_row_type()
2365 {
2366 if (row_type == ROW_TYPE_DYNAMIC || row_type == ROW_TYPE_PAGE)
2367 return table_options | HA_OPTION_PACK_RECORD;
2368 else
2369 return table_options;
2370 }
2371 };
2372
2373
2374 /**
2375 This struct is passed to mysql_create_table() and similar creation functions,
2376 as well as to show_create_table().
2377 */
2378 struct Table_specification_st: public HA_CREATE_INFO,
2379 public DDL_options_st
2380 {
2381 // Deep initialization
initTable_specification_st2382 void init()
2383 {
2384 HA_CREATE_INFO::init();
2385 DDL_options_st::init();
2386 }
initTable_specification_st2387 void init(DDL_options_st::Options options_arg)
2388 {
2389 HA_CREATE_INFO::init();
2390 DDL_options_st::init(options_arg);
2391 }
2392 /*
2393 Quick initialization, for parser.
2394 Most of the HA_CREATE_INFO is left uninitialized.
2395 It gets fully initialized in sql_yacc.yy, only when the parser
2396 scans a related keyword (e.g. CREATE, ALTER).
2397 */
lex_startTable_specification_st2398 void lex_start()
2399 {
2400 HA_CREATE_INFO::options= 0;
2401 DDL_options_st::init();
2402 }
2403 };
2404
2405
2406 /**
2407 In-place alter handler context.
2408
2409 This is a superclass intended to be subclassed by individual handlers
2410 in order to store handler unique context between in-place alter API calls.
2411
2412 The handler is responsible for creating the object. This can be done
2413 as early as during check_if_supported_inplace_alter().
2414
2415 The SQL layer is responsible for destroying the object.
2416 The class extends Sql_alloc so the memory will be mem root allocated.
2417
2418 @see Alter_inplace_info
2419 */
2420
2421 class inplace_alter_handler_ctx : public Sql_alloc
2422 {
2423 public:
inplace_alter_handler_ctx()2424 inplace_alter_handler_ctx() {}
2425
~inplace_alter_handler_ctx()2426 virtual ~inplace_alter_handler_ctx() {}
set_shared_data(const inplace_alter_handler_ctx & ctx)2427 virtual void set_shared_data(const inplace_alter_handler_ctx& ctx) {}
2428 };
2429
2430
2431 /**
2432 Class describing changes to be done by ALTER TABLE.
2433 Instance of this class is passed to storage engine in order
2434 to determine if this ALTER TABLE can be done using in-place
2435 algorithm. It is also used for executing the ALTER TABLE
2436 using in-place algorithm.
2437 */
2438
2439 class Alter_inplace_info
2440 {
2441 public:
2442
2443 /**
2444 Create options (like MAX_ROWS) for the new version of table.
2445
2446 @note The referenced instance of HA_CREATE_INFO object was already
2447 used to create new .FRM file for table being altered. So it
2448 has been processed by mysql_prepare_create_table() already.
2449 For example, this means that it has HA_OPTION_PACK_RECORD
2450 flag in HA_CREATE_INFO::table_options member correctly set.
2451 */
2452 HA_CREATE_INFO *create_info;
2453
2454 /**
2455 Alter options, fields and keys for the new version of table.
2456
2457 @note The referenced instance of Alter_info object was already
2458 used to create new .FRM file for table being altered. So it
2459 has been processed by mysql_prepare_create_table() already.
2460 In particular, this means that in Create_field objects for
2461 fields which were present in some form in the old version
2462 of table, Create_field::field member points to corresponding
2463 Field instance for old version of table.
2464 */
2465 Alter_info *alter_info;
2466
2467 /**
2468 Array of KEYs for new version of table - including KEYs to be added.
2469
2470 @note Currently this array is produced as result of
2471 mysql_prepare_create_table() call.
2472 This means that it follows different convention for
2473 KEY_PART_INFO::fieldnr values than objects in TABLE::key_info
2474 array.
2475
2476 @todo This is mainly due to the fact that we need to keep compatibility
2477 with removed handler::add_index() call. We plan to switch to
2478 TABLE::key_info numbering later.
2479
2480 KEYs are sorted - see sort_keys().
2481 */
2482 KEY *key_info_buffer;
2483
2484 /** Size of key_info_buffer array. */
2485 uint key_count;
2486
2487 /** Size of index_drop_buffer array. */
2488 uint index_drop_count;
2489
2490 /**
2491 Array of pointers to KEYs to be dropped belonging to the TABLE instance
2492 for the old version of the table.
2493 */
2494 KEY **index_drop_buffer;
2495
2496 /** Size of index_add_buffer array. */
2497 uint index_add_count;
2498
2499 /**
2500 Array of indexes into key_info_buffer for KEYs to be added,
2501 sorted in increasing order.
2502 */
2503 uint *index_add_buffer;
2504
2505 /**
2506 Old and new index names. Used for index rename.
2507 */
2508 struct Rename_key_pair
2509 {
Rename_key_pairRename_key_pair2510 Rename_key_pair(const KEY *old_key, const KEY *new_key)
2511 : old_key(old_key), new_key(new_key)
2512 {
2513 }
2514 const KEY *old_key;
2515 const KEY *new_key;
2516 };
2517 /**
2518 Vector of key pairs from DROP/ADD index which can be renamed.
2519 */
2520 typedef Mem_root_array<Rename_key_pair, true> Rename_keys_vector;
2521
2522 /**
2523 A list of indexes which should be renamed.
2524 Index definitions stays the same.
2525 */
2526 Rename_keys_vector rename_keys;
2527
2528 /**
2529 Context information to allow handlers to keep context between in-place
2530 alter API calls.
2531
2532 @see inplace_alter_handler_ctx for information about object lifecycle.
2533 */
2534 inplace_alter_handler_ctx *handler_ctx;
2535
2536 /**
2537 If the table uses several handlers, like ha_partition uses one handler
2538 per partition, this contains a Null terminated array of ctx pointers
2539 that should all be committed together.
2540 Or NULL if only handler_ctx should be committed.
2541 Set to NULL if the low level handler::commit_inplace_alter_table uses it,
2542 to signal to the main handler that everything was committed as atomically.
2543
2544 @see inplace_alter_handler_ctx for information about object lifecycle.
2545 */
2546 inplace_alter_handler_ctx **group_commit_ctx;
2547
2548 /**
2549 Flags describing in detail which operations the storage engine is to
2550 execute. Flags are defined in sql_alter.h
2551 */
2552 alter_table_operations handler_flags;
2553
2554 /* Alter operations involving parititons are strored here */
2555 ulong partition_flags;
2556
2557 /**
2558 Partition_info taking into account the partition changes to be performed.
2559 Contains all partitions which are present in the old version of the table
2560 with partitions to be dropped or changed marked as such + all partitions
2561 to be added in the new version of table marked as such.
2562 */
2563 partition_info *modified_part_info;
2564
2565 /** true for ALTER IGNORE TABLE ... */
2566 const bool ignore;
2567
2568 /** true for online operation (LOCK=NONE) */
2569 bool online;
2570
2571 /** which ALGORITHM and LOCK are supported by the storage engine */
2572 enum_alter_inplace_result inplace_supported;
2573
2574 /**
2575 Can be set by handler to describe why a given operation cannot be done
2576 in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
2577 online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_COPY_NO_LOCK)
2578 If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
2579 results from handler::check_if_supported_inplace_alter() doesn't match
2580 requirements set by user. If not set, the more generic
2581 ER_ALTER_OPERATION_NOT_SUPPORTED will be used.
2582
2583 Please set to a properly localized string, for example using
2584 my_get_err_msg(), so that the error message as a whole is localized.
2585 */
2586 const char *unsupported_reason;
2587
2588 /** true when InnoDB should abort the alter when table is not empty */
2589 bool error_if_not_empty;
2590
2591 /** True when DDL should avoid downgrading the MDL */
2592 bool mdl_exclusive_after_prepare= false;
2593
2594 Alter_inplace_info(HA_CREATE_INFO *create_info_arg,
2595 Alter_info *alter_info_arg,
2596 KEY *key_info_arg, uint key_count_arg,
2597 partition_info *modified_part_info_arg,
2598 bool ignore_arg, bool error_non_empty);
2599
~Alter_inplace_info()2600 ~Alter_inplace_info()
2601 {
2602 delete handler_ctx;
2603 }
2604
2605 /**
2606 Used after check_if_supported_inplace_alter() to report
2607 error if the result does not match the LOCK/ALGORITHM
2608 requirements set by the user.
2609
2610 @param not_supported Part of statement that was not supported.
2611 @param try_instead Suggestion as to what the user should
2612 replace not_supported with.
2613 */
2614 void report_unsupported_error(const char *not_supported,
2615 const char *try_instead) const;
2616 };
2617
2618
2619 typedef struct st_key_create_information
2620 {
2621 enum ha_key_alg algorithm;
2622 ulong block_size;
2623 uint flags; /* HA_USE.. flags */
2624 LEX_CSTRING parser_name;
2625 LEX_CSTRING comment;
2626 /**
2627 A flag to determine if we will check for duplicate indexes.
2628 This typically means that the key information was specified
2629 directly by the user (set by the parser).
2630 */
2631 bool check_for_duplicate_indexes;
2632 } KEY_CREATE_INFO;
2633
2634
2635 /*
2636 Class for maintaining hooks used inside operations on tables such
2637 as: create table functions, delete table functions, and alter table
2638 functions.
2639
2640 Class is using the Template Method pattern to separate the public
2641 usage interface from the private inheritance interface. This
2642 imposes no overhead, since the public non-virtual function is small
2643 enough to be inlined.
2644
2645 The hooks are usually used for functions that does several things,
2646 e.g., create_table_from_items(), which both create a table and lock
2647 it.
2648 */
2649 class TABLEOP_HOOKS
2650 {
2651 public:
TABLEOP_HOOKS()2652 TABLEOP_HOOKS() {}
~TABLEOP_HOOKS()2653 virtual ~TABLEOP_HOOKS() {}
2654
prelock(TABLE ** tables,uint count)2655 inline void prelock(TABLE **tables, uint count)
2656 {
2657 do_prelock(tables, count);
2658 }
2659
postlock(TABLE ** tables,uint count)2660 inline int postlock(TABLE **tables, uint count)
2661 {
2662 return do_postlock(tables, count);
2663 }
2664 private:
2665 /* Function primitive that is called prior to locking tables */
do_prelock(TABLE ** tables,uint count)2666 virtual void do_prelock(TABLE **tables, uint count)
2667 {
2668 /* Default is to do nothing */
2669 }
2670
2671 /**
2672 Primitive called after tables are locked.
2673
2674 If an error is returned, the tables will be unlocked and error
2675 handling start.
2676
2677 @return Error code or zero.
2678 */
do_postlock(TABLE ** tables,uint count)2679 virtual int do_postlock(TABLE **tables, uint count)
2680 {
2681 return 0; /* Default is to do nothing */
2682 }
2683 };
2684
2685 typedef struct st_savepoint SAVEPOINT;
2686 extern ulong savepoint_alloc_size;
2687 extern KEY_CREATE_INFO default_key_create_info;
2688
2689 /* Forward declaration for condition pushdown to storage engine */
2690 typedef class Item COND;
2691
2692 typedef struct st_ha_check_opt
2693 {
st_ha_check_optst_ha_check_opt2694 st_ha_check_opt() {} /* Remove gcc warning */
2695 uint flags; /* isam layer flags (e.g. for myisamchk) */
2696 uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
2697 time_t start_time; /* When check/repair starts */
2698 KEY_CACHE *key_cache; /* new key cache when changing key cache */
2699 void init();
2700 } HA_CHECK_OPT;
2701
2702
2703 /********************************************************************************
2704 * MRR
2705 ********************************************************************************/
2706
2707 typedef void *range_seq_t;
2708
2709 typedef struct st_range_seq_if
2710 {
2711 /*
2712 Get key information
2713
2714 SYNOPSIS
2715 get_key_info()
2716 init_params The seq_init_param parameter
2717 length OUT length of the keys in this range sequence
2718 map OUT key_part_map of the keys in this range sequence
2719
2720 DESCRIPTION
2721 This function is set only when using HA_MRR_FIXED_KEY mode. In that mode,
2722 all ranges are single-point equality ranges that use the same set of key
2723 parts. This function allows the MRR implementation to get the length of
2724 a key, and which keyparts it uses.
2725 */
2726 void (*get_key_info)(void *init_params, uint *length, key_part_map *map);
2727
2728 /*
2729 Initialize the traversal of range sequence
2730
2731 SYNOPSIS
2732 init()
2733 init_params The seq_init_param parameter
2734 n_ranges The number of ranges obtained
2735 flags A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
2736
2737 RETURN
2738 An opaque value to be used as RANGE_SEQ_IF::next() parameter
2739 */
2740 range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
2741
2742
2743 /*
2744 Get the next range in the range sequence
2745
2746 SYNOPSIS
2747 next()
2748 seq The value returned by RANGE_SEQ_IF::init()
2749 range OUT Information about the next range
2750
2751 RETURN
2752 FALSE - Ok, the range structure filled with info about the next range
2753 TRUE - No more ranges
2754 */
2755 bool (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
2756
2757 /*
2758 Check whether range_info orders to skip the next record
2759
2760 SYNOPSIS
2761 skip_record()
2762 seq The value returned by RANGE_SEQ_IF::init()
2763 range_info Information about the next range
2764 (Ignored if MRR_NO_ASSOCIATION is set)
2765 rowid Rowid of the record to be checked (ignored if set to 0)
2766
2767 RETURN
2768 1 - Record with this range_info and/or this rowid shall be filtered
2769 out from the stream of records returned by multi_range_read_next()
2770 0 - The record shall be left in the stream
2771 */
2772 bool (*skip_record) (range_seq_t seq, range_id_t range_info, uchar *rowid);
2773
2774 /*
2775 Check if the record combination matches the index condition
2776 SYNOPSIS
2777 skip_index_tuple()
2778 seq The value returned by RANGE_SEQ_IF::init()
2779 range_info Information about the next range
2780
2781 RETURN
2782 0 - The record combination satisfies the index condition
2783 1 - Otherwise
2784 */
2785 bool (*skip_index_tuple) (range_seq_t seq, range_id_t range_info);
2786 } RANGE_SEQ_IF;
2787
2788 typedef bool (*SKIP_INDEX_TUPLE_FUNC) (range_seq_t seq, range_id_t range_info);
2789
2790 class Cost_estimate
2791 {
2792 public:
2793 double io_count; /* number of I/O to fetch records */
2794 double avg_io_cost; /* cost of an average I/O oper. to fetch records */
2795 double idx_io_count; /* number of I/O to read keys */
2796 double idx_avg_io_cost; /* cost of an average I/O oper. to fetch records */
2797 double cpu_cost; /* total cost of operations in CPU */
2798 double idx_cpu_cost; /* cost of operations in CPU for index */
2799 double import_cost; /* cost of remote operations */
2800 double mem_cost; /* cost of used memory */
2801
2802 static constexpr double IO_COEFF= 1;
2803 static constexpr double CPU_COEFF= 1;
2804 static constexpr double MEM_COEFF= 1;
2805 static constexpr double IMPORT_COEFF= 1;
2806
Cost_estimate()2807 Cost_estimate()
2808 {
2809 reset();
2810 }
2811
total_cost()2812 double total_cost() const
2813 {
2814 return IO_COEFF*io_count*avg_io_cost +
2815 IO_COEFF*idx_io_count*idx_avg_io_cost +
2816 CPU_COEFF*(cpu_cost + idx_cpu_cost) +
2817 MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost;
2818 }
2819
index_only_cost()2820 double index_only_cost()
2821 {
2822 return IO_COEFF*idx_io_count*idx_avg_io_cost +
2823 CPU_COEFF*idx_cpu_cost;
2824 }
2825
2826 /**
2827 Whether or not all costs in the object are zero
2828
2829 @return true if all costs are zero, false otherwise
2830 */
is_zero()2831 bool is_zero() const
2832 {
2833 return io_count == 0.0 && idx_io_count == 0.0 && cpu_cost == 0.0 &&
2834 import_cost == 0.0 && mem_cost == 0.0;
2835 }
2836
reset()2837 void reset()
2838 {
2839 avg_io_cost= 1.0;
2840 idx_avg_io_cost= 1.0;
2841 io_count= idx_io_count= cpu_cost= idx_cpu_cost= mem_cost= import_cost= 0.0;
2842 }
2843
multiply(double m)2844 void multiply(double m)
2845 {
2846 io_count *= m;
2847 cpu_cost *= m;
2848 idx_io_count *= m;
2849 idx_cpu_cost *= m;
2850 import_cost *= m;
2851 /* Don't multiply mem_cost */
2852 }
2853
add(const Cost_estimate * cost)2854 void add(const Cost_estimate* cost)
2855 {
2856 if (cost->io_count != 0.0)
2857 {
2858 double io_count_sum= io_count + cost->io_count;
2859 avg_io_cost= (io_count * avg_io_cost +
2860 cost->io_count * cost->avg_io_cost)
2861 /io_count_sum;
2862 io_count= io_count_sum;
2863 }
2864 if (cost->idx_io_count != 0.0)
2865 {
2866 double idx_io_count_sum= idx_io_count + cost->idx_io_count;
2867 idx_avg_io_cost= (idx_io_count * idx_avg_io_cost +
2868 cost->idx_io_count * cost->idx_avg_io_cost)
2869 /idx_io_count_sum;
2870 idx_io_count= idx_io_count_sum;
2871 }
2872 cpu_cost += cost->cpu_cost;
2873 idx_cpu_cost += cost->idx_cpu_cost;
2874 import_cost += cost->import_cost;
2875 }
2876
add_io(double add_io_cnt,double add_avg_cost)2877 void add_io(double add_io_cnt, double add_avg_cost)
2878 {
2879 /* In edge cases add_io_cnt may be zero */
2880 if (add_io_cnt > 0)
2881 {
2882 double io_count_sum= io_count + add_io_cnt;
2883 avg_io_cost= (io_count * avg_io_cost +
2884 add_io_cnt * add_avg_cost) / io_count_sum;
2885 io_count= io_count_sum;
2886 }
2887 }
2888
2889 /// Add to CPU cost
add_cpu(double add_cpu_cost)2890 void add_cpu(double add_cpu_cost) { cpu_cost+= add_cpu_cost; }
2891
2892 /// Add to import cost
add_import(double add_import_cost)2893 void add_import(double add_import_cost) { import_cost+= add_import_cost; }
2894
2895 /// Add to memory cost
add_mem(double add_mem_cost)2896 void add_mem(double add_mem_cost) { mem_cost+= add_mem_cost; }
2897
2898 /*
2899 To be used when we go from old single value-based cost calculations to
2900 the new Cost_estimate-based.
2901 */
convert_from_cost(double cost)2902 void convert_from_cost(double cost)
2903 {
2904 reset();
2905 io_count= cost;
2906 }
2907 };
2908
2909 void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
2910 Cost_estimate *cost);
2911
2912 /*
2913 Indicates that all scanned ranges will be singlepoint (aka equality) ranges.
2914 The ranges may not use the full key but all of them will use the same number
2915 of key parts.
2916 */
2917 #define HA_MRR_SINGLE_POINT 1U
2918 #define HA_MRR_FIXED_KEY 2U
2919
2920 /*
2921 Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
2922 'range' parameter.
2923 */
2924 #define HA_MRR_NO_ASSOCIATION 4U
2925
2926 /*
2927 The MRR user will provide ranges in key order, and MRR implementation
2928 must return rows in key order.
2929 */
2930 #define HA_MRR_SORTED 8U
2931
2932 /* MRR implementation doesn't have to retrieve full records */
2933 #define HA_MRR_INDEX_ONLY 16U
2934
2935 /*
2936 The passed memory buffer is of maximum possible size, the caller can't
2937 assume larger buffer.
2938 */
2939 #define HA_MRR_LIMITS 32U
2940
2941
2942 /*
2943 Flag set <=> default MRR implementation is used
2944 (The choice is made by **_info[_const]() function which may set this
2945 flag. SQL layer remembers the flag value and then passes it to
2946 multi_read_range_init().
2947 */
2948 #define HA_MRR_USE_DEFAULT_IMPL 64U
2949
2950 /*
2951 Used only as parameter to multi_range_read_info():
2952 Flag set <=> the caller guarantees that the bounds of the scanned ranges
2953 will not have NULL values.
2954 */
2955 #define HA_MRR_NO_NULL_ENDPOINTS 128U
2956
2957 /*
2958 The MRR user has materialized range keys somewhere in the user's buffer.
2959 This can be used for optimization of the procedure that sorts these keys
2960 since in this case key values don't have to be copied into the MRR buffer.
2961
2962 In other words, it is guaranteed that after RANGE_SEQ_IF::next() call the
2963 pointer in range->start_key.key will point to a key value that will remain
2964 there until the end of the MRR scan.
2965 */
2966 #define HA_MRR_MATERIALIZED_KEYS 256U
2967
2968 /*
2969 The following bits are reserved for use by MRR implementation. The intended
2970 use scenario:
2971
2972 * sql layer calls handler->multi_range_read_info[_const]()
2973 - MRR implementation figures out what kind of scan it will perform, saves
2974 the result in *mrr_mode parameter.
2975 * sql layer remembers what was returned in *mrr_mode
2976
2977 * the optimizer picks the query plan (which may or may not include the MRR
2978 scan that was estimated by the multi_range_read_info[_const] call)
2979
2980 * if the query is an EXPLAIN statement, sql layer will call
2981 handler->multi_range_read_explain_info(mrr_mode) to get a text description
2982 of the picked MRR scan; the description will be a part of EXPLAIN output.
2983 */
2984 #define HA_MRR_IMPLEMENTATION_FLAG1 512U
2985 #define HA_MRR_IMPLEMENTATION_FLAG2 1024U
2986 #define HA_MRR_IMPLEMENTATION_FLAG3 2048U
2987 #define HA_MRR_IMPLEMENTATION_FLAG4 4096U
2988 #define HA_MRR_IMPLEMENTATION_FLAG5 8192U
2989 #define HA_MRR_IMPLEMENTATION_FLAG6 16384U
2990
2991 #define HA_MRR_IMPLEMENTATION_FLAGS \
2992 (512U | 1024U | 2048U | 4096U | 8192U | 16384U)
2993
2994 /*
2995 This is a buffer area that the handler can use to store rows.
2996 'end_of_used_area' should be kept updated after calls to
2997 read-functions so that other parts of the code can use the
2998 remaining area (until next read calls is issued).
2999 */
3000
3001 typedef struct st_handler_buffer
3002 {
3003 /* const? */uchar *buffer; /* Buffer one can start using */
3004 /* const? */uchar *buffer_end; /* End of buffer */
3005 uchar *end_of_used_area; /* End of area that was used by handler */
3006 } HANDLER_BUFFER;
3007
3008 typedef struct system_status_var SSV;
3009
3010 class ha_statistics
3011 {
3012 public:
3013 ulonglong data_file_length; /* Length off data file */
3014 ulonglong max_data_file_length; /* Length off data file */
3015 ulonglong index_file_length;
3016 ulonglong max_index_file_length;
3017 ulonglong delete_length; /* Free bytes */
3018 ulonglong auto_increment_value;
3019 /*
3020 The number of records in the table.
3021 0 - means the table has exactly 0 rows
3022 other - if (table_flags() & HA_STATS_RECORDS_IS_EXACT)
3023 the value is the exact number of records in the table
3024 else
3025 it is an estimate
3026 */
3027 ha_rows records;
3028 ha_rows deleted; /* Deleted records */
3029 ulong mean_rec_length; /* physical reclength */
3030 time_t create_time; /* When table was created */
3031 time_t check_time;
3032 time_t update_time;
3033 uint block_size; /* index block size */
3034 ha_checksum checksum;
3035 bool checksum_null;
3036
3037 /*
3038 number of buffer bytes that native mrr implementation needs,
3039 */
3040 uint mrr_length_per_rec;
3041
ha_statistics()3042 ha_statistics():
3043 data_file_length(0), max_data_file_length(0),
3044 index_file_length(0), max_index_file_length(0), delete_length(0),
3045 auto_increment_value(0), records(0), deleted(0), mean_rec_length(0),
3046 create_time(0), check_time(0), update_time(0), block_size(8192),
3047 checksum(0), checksum_null(FALSE), mrr_length_per_rec(0)
3048 {}
3049 };
3050
3051 extern "C" check_result_t handler_index_cond_check(void* h_arg);
3052
3053 extern "C" check_result_t handler_rowid_filter_check(void* h_arg);
3054 extern "C" int handler_rowid_filter_is_active(void* h_arg);
3055
3056 uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map);
3057 /*
3058 bitmap with first N+1 bits set
3059 (keypart_map for a key prefix of [0..N] keyparts)
3060 */
3061 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1)
3062 /*
3063 bitmap with first N bits set
3064 (keypart_map for a key prefix of [0..N-1] keyparts)
3065 */
3066 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1)
3067
3068
3069 /** Base class to be used by handlers different shares */
3070 class Handler_share
3071 {
3072 public:
Handler_share()3073 Handler_share() {}
~Handler_share()3074 virtual ~Handler_share() {}
3075 };
3076
3077 enum class Compare_keys : uint32_t
3078 {
3079 Equal= 0,
3080 EqualButKeyPartLength,
3081 EqualButComment,
3082 NotEqual
3083 };
3084
3085 /**
3086 The handler class is the interface for dynamically loadable
3087 storage engines. Do not add ifdefs and take care when adding or
3088 changing virtual functions to avoid vtable confusion
3089
3090 Functions in this class accept and return table columns data. Two data
3091 representation formats are used:
3092 1. TableRecordFormat - Used to pass [partial] table records to/from
3093 storage engine
3094
3095 2. KeyTupleFormat - used to pass index search tuples (aka "keys") to
3096 storage engine. See opt_range.cc for description of this format.
3097
3098 TableRecordFormat
3099 =================
3100 [Warning: this description is work in progress and may be incomplete]
3101 The table record is stored in a fixed-size buffer:
3102
3103 record: null_bytes, column1_data, column2_data, ...
3104
3105 The offsets of the parts of the buffer are also fixed: every column has
3106 an offset to its column{i}_data, and if it is nullable it also has its own
3107 bit in null_bytes.
3108
3109 The record buffer only includes data about columns that are marked in the
3110 relevant column set (table->read_set and/or table->write_set, depending on
3111 the situation).
3112 <not-sure>It could be that it is required that null bits of non-present
3113 columns are set to 1</not-sure>
3114
3115 VARIOUS EXCEPTIONS AND SPECIAL CASES
3116
3117 If the table has no nullable columns, then null_bytes is still
3118 present, its length is one byte <not-sure> which must be set to 0xFF
3119 at all times. </not-sure>
3120
3121 If the table has columns of type BIT, then certain bits from those columns
3122 may be stored in null_bytes as well. Grep around for Field_bit for
3123 details.
3124
3125 For blob columns (see Field_blob), the record buffer stores length of the
3126 data, following by memory pointer to the blob data. The pointer is owned
3127 by the storage engine and is valid until the next operation.
3128
3129 If a blob column has NULL value, then its length and blob data pointer
3130 must be set to 0.
3131 */
3132
3133 class handler :public Sql_alloc
3134 {
3135 public:
3136 typedef ulonglong Table_flags;
3137 protected:
3138 TABLE_SHARE *table_share; /* The table definition */
3139 TABLE *table; /* The current open table */
3140 Table_flags cached_table_flags; /* Set on init() and open() */
3141
3142 ha_rows estimation_rows_to_insert;
3143 handler *lookup_handler;
3144 public:
3145 handlerton *ht; /* storage engine of this handler */
3146 uchar *ref; /* Pointer to current row */
3147 uchar *dup_ref; /* Pointer to duplicate row */
3148 uchar *lookup_buffer;
3149
3150 ha_statistics stats;
3151
3152 /** MultiRangeRead-related members: */
3153 range_seq_t mrr_iter; /* Iterator to traverse the range sequence */
3154 RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
3155 HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
3156 uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
3157 /** Current range (the one we're now returning rows from) */
3158 KEY_MULTI_RANGE mrr_cur_range;
3159
3160 /** The following are for read_range() */
3161 key_range save_end_range, *end_range;
3162 KEY_PART_INFO *range_key_part;
3163 int key_compare_result_on_equal;
3164
3165 /* TRUE <=> source MRR ranges and the output are ordered */
3166 bool mrr_is_output_sorted;
3167 /** TRUE <=> we're currently traversing a range in mrr_cur_range. */
3168 bool mrr_have_range;
3169 bool eq_range;
3170 bool internal_tmp_table; /* If internal tmp table */
3171 bool implicit_emptied; /* Can be !=0 only if HEAP */
3172 bool mark_trx_read_write_done; /* mark_trx_read_write was called */
3173 bool check_table_binlog_row_based_done; /* check_table_binlog.. was called */
3174 bool check_table_binlog_row_based_result; /* cached check_table_binlog... */
3175 /*
3176 TRUE <=> the engine guarantees that returned records are within the range
3177 being scanned.
3178 */
3179 bool in_range_check_pushed_down;
3180
3181 uint lookup_errkey;
3182 uint errkey; /* Last dup key */
3183 uint key_used_on_scan;
3184 uint active_index, keyread;
3185
3186 /** Length of ref (1-8 or the clustered key length) */
3187 uint ref_length;
3188 FT_INFO *ft_handler;
3189 enum init_stat { NONE=0, INDEX, RND };
3190 init_stat inited, pre_inited;
3191
3192 const COND *pushed_cond;
3193 /**
3194 next_insert_id is the next value which should be inserted into the
3195 auto_increment column: in a inserting-multi-row statement (like INSERT
3196 SELECT), for the first row where the autoinc value is not specified by the
3197 statement, get_auto_increment() called and asked to generate a value,
3198 next_insert_id is set to the next value, then for all other rows
3199 next_insert_id is used (and increased each time) without calling
3200 get_auto_increment().
3201 */
3202 ulonglong next_insert_id;
3203 /**
3204 insert id for the current row (*autogenerated*; if not
3205 autogenerated, it's 0).
3206 At first successful insertion, this variable is stored into
3207 THD::first_successful_insert_id_in_cur_stmt.
3208 */
3209 ulonglong insert_id_for_cur_row;
3210 /**
3211 Interval returned by get_auto_increment() and being consumed by the
3212 inserter.
3213 */
3214 /* Statistics variables */
3215 ulonglong rows_read;
3216 ulonglong rows_tmp_read;
3217 ulonglong rows_changed;
3218 /* One bigger than needed to avoid to test if key == MAX_KEY */
3219 ulonglong index_rows_read[MAX_KEY+1];
3220 ha_copy_info copy_info;
3221
3222 private:
3223 /* ANALYZE time tracker, if present */
3224 Exec_time_tracker *tracker;
3225 public:
set_time_tracker(Exec_time_tracker * tracker_arg)3226 void set_time_tracker(Exec_time_tracker *tracker_arg) { tracker=tracker_arg;}
get_time_tracker()3227 Exec_time_tracker *get_time_tracker() { return tracker; }
3228
3229 Item *pushed_idx_cond;
3230 uint pushed_idx_cond_keyno; /* The index which the above condition is for */
3231
3232 /* Rowid filter pushed into the engine */
3233 Rowid_filter *pushed_rowid_filter;
3234 /* true when the pushed rowid filter has been already filled */
3235 bool rowid_filter_is_active;
3236 /* Used for disabling/enabling pushed_rowid_filter */
3237 Rowid_filter *save_pushed_rowid_filter;
3238 bool save_rowid_filter_is_active;
3239
3240 Discrete_interval auto_inc_interval_for_cur_row;
3241 /**
3242 Number of reserved auto-increment intervals. Serves as a heuristic
3243 when we have no estimation of how many records the statement will insert:
3244 the more intervals we have reserved, the bigger the next one. Reset in
3245 handler::ha_release_auto_increment().
3246 */
3247 uint auto_inc_intervals_count;
3248
3249 /**
3250 Instrumented table associated with this handler.
3251 This member should be set to NULL when no instrumentation is in place,
3252 so that linking an instrumented/non instrumented server/plugin works.
3253 For example:
3254 - the server is compiled with the instrumentation.
3255 The server expects either NULL or valid pointers in m_psi.
3256 - an engine plugin is compiled without instrumentation.
3257 The plugin can not leave this pointer uninitialized,
3258 or can not leave a trash value on purpose in this pointer,
3259 as this would crash the server.
3260 */
3261 PSI_table *m_psi;
3262
3263 private:
3264 /** Internal state of the batch instrumentation. */
3265 enum batch_mode_t
3266 {
3267 /** Batch mode not used. */
3268 PSI_BATCH_MODE_NONE,
3269 /** Batch mode used, before first table io. */
3270 PSI_BATCH_MODE_STARTING,
3271 /** Batch mode used, after first table io. */
3272 PSI_BATCH_MODE_STARTED
3273 };
3274 /**
3275 Batch mode state.
3276 @sa start_psi_batch_mode.
3277 @sa end_psi_batch_mode.
3278 */
3279 batch_mode_t m_psi_batch_mode;
3280 /**
3281 The number of rows in the batch.
3282 @sa start_psi_batch_mode.
3283 @sa end_psi_batch_mode.
3284 */
3285 ulonglong m_psi_numrows;
3286 /**
3287 The current event in a batch.
3288 @sa start_psi_batch_mode.
3289 @sa end_psi_batch_mode.
3290 */
3291 PSI_table_locker *m_psi_locker;
3292 /**
3293 Storage for the event in a batch.
3294 @sa start_psi_batch_mode.
3295 @sa end_psi_batch_mode.
3296 */
3297 PSI_table_locker_state m_psi_locker_state;
3298
3299 public:
3300 virtual void unbind_psi();
3301 virtual void rebind_psi();
3302 /* Return error if definition doesn't match for already opened table */
discover_check_version()3303 virtual int discover_check_version() { return 0; }
3304
3305 /**
3306 Put the handler in 'batch' mode when collecting
3307 table io instrumented events.
3308 When operating in batch mode:
3309 - a single start event is generated in the performance schema.
3310 - all table io performed between @c start_psi_batch_mode
3311 and @c end_psi_batch_mode is not instrumented:
3312 the number of rows affected is counted instead in @c m_psi_numrows.
3313 - a single end event is generated in the performance schema
3314 when the batch mode ends with @c end_psi_batch_mode.
3315 */
3316 void start_psi_batch_mode();
3317 /** End a batch started with @c start_psi_batch_mode. */
3318 void end_psi_batch_mode();
3319
3320 /* If we have row logging enabled for this table */
3321 bool row_logging, row_logging_init;
3322 /* If the row logging should be done in transaction cache */
3323 bool row_logging_has_trans;
3324
3325 private:
3326 /**
3327 The lock type set by when calling::ha_external_lock(). This is
3328 propagated down to the storage engine. The reason for also storing
3329 it here, is that when doing MRR we need to create/clone a second handler
3330 object. This cloned handler object needs to know about the lock_type used.
3331 */
3332 int m_lock_type;
3333 /**
3334 Pointer where to store/retrieve the Handler_share pointer.
3335 For non partitioned handlers this is &TABLE_SHARE::ha_share.
3336 */
3337 Handler_share **ha_share;
3338
3339 public:
handler(handlerton * ht_arg,TABLE_SHARE * share_arg)3340 handler(handlerton *ht_arg, TABLE_SHARE *share_arg)
3341 :table_share(share_arg), table(0),
3342 estimation_rows_to_insert(0),
3343 lookup_handler(this),
3344 ht(ht_arg), ref(0), lookup_buffer(NULL), end_range(NULL),
3345 implicit_emptied(0),
3346 mark_trx_read_write_done(0),
3347 check_table_binlog_row_based_done(0),
3348 check_table_binlog_row_based_result(0),
3349 in_range_check_pushed_down(FALSE), lookup_errkey(-1), errkey(-1),
3350 key_used_on_scan(MAX_KEY),
3351 active_index(MAX_KEY), keyread(MAX_KEY),
3352 ref_length(sizeof(my_off_t)),
3353 ft_handler(0), inited(NONE), pre_inited(NONE),
3354 pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
3355 tracker(NULL),
3356 pushed_idx_cond(NULL),
3357 pushed_idx_cond_keyno(MAX_KEY),
3358 pushed_rowid_filter(NULL),
3359 rowid_filter_is_active(0),
3360 save_pushed_rowid_filter(NULL),
3361 save_rowid_filter_is_active(false),
3362 auto_inc_intervals_count(0),
3363 m_psi(NULL),
3364 m_psi_batch_mode(PSI_BATCH_MODE_NONE),
3365 m_psi_numrows(0),
3366 m_psi_locker(NULL),
3367 row_logging(0), row_logging_init(0),
3368 m_lock_type(F_UNLCK), ha_share(NULL)
3369 {
3370 DBUG_PRINT("info",
3371 ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
3372 F_UNLCK, F_RDLCK, F_WRLCK));
3373 reset_statistics();
3374 }
~handler(void)3375 virtual ~handler(void)
3376 {
3377 DBUG_ASSERT(m_lock_type == F_UNLCK);
3378 DBUG_ASSERT(inited == NONE);
3379 }
3380 /* To check if table has been properely opened */
is_open()3381 bool is_open()
3382 {
3383 return ref != 0;
3384 }
3385 virtual handler *clone(const char *name, MEM_ROOT *mem_root);
3386 /** This is called after create to allow us to set up cached variables */
init()3387 void init()
3388 {
3389 cached_table_flags= table_flags();
3390 }
3391 /* ha_ methods: public wrappers for private virtual API */
3392
3393 int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
3394 MEM_ROOT *mem_root= 0, List<String> *partitions_to_open=NULL);
ha_index_init(uint idx,bool sorted)3395 int ha_index_init(uint idx, bool sorted)
3396 {
3397 DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
3398 int result;
3399 DBUG_ENTER("ha_index_init");
3400 DBUG_ASSERT(inited==NONE);
3401 if (!(result= index_init(idx, sorted)))
3402 {
3403 inited= INDEX;
3404 active_index= idx;
3405 end_range= NULL;
3406 }
3407 DBUG_RETURN(result);
3408 }
ha_index_end()3409 int ha_index_end()
3410 {
3411 DBUG_ENTER("ha_index_end");
3412 DBUG_ASSERT(inited==INDEX);
3413 inited= NONE;
3414 active_index= MAX_KEY;
3415 end_range= NULL;
3416 DBUG_RETURN(index_end());
3417 }
3418 /* This is called after index_init() if we need to do a index scan */
prepare_index_scan()3419 virtual int prepare_index_scan() { return 0; }
prepare_index_key_scan_map(const uchar * key,key_part_map keypart_map)3420 virtual int prepare_index_key_scan_map(const uchar * key, key_part_map keypart_map)
3421 {
3422 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
3423 return prepare_index_key_scan(key, key_len);
3424 }
prepare_index_key_scan(const uchar * key,uint key_len)3425 virtual int prepare_index_key_scan( const uchar * key, uint key_len )
3426 { return 0; }
prepare_range_scan(const key_range * start_key,const key_range * end_key)3427 virtual int prepare_range_scan(const key_range *start_key, const key_range *end_key)
3428 { return 0; }
3429
ha_rnd_init(bool scan)3430 int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result))
3431 {
3432 DBUG_EXECUTE_IF("ha_rnd_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
3433 int result;
3434 DBUG_ENTER("ha_rnd_init");
3435 DBUG_ASSERT(inited==NONE || (inited==RND && scan));
3436 inited= (result= rnd_init(scan)) ? NONE: RND;
3437 end_range= NULL;
3438 DBUG_RETURN(result);
3439 }
ha_rnd_end()3440 int ha_rnd_end()
3441 {
3442 DBUG_ENTER("ha_rnd_end");
3443 DBUG_ASSERT(inited==RND);
3444 inited=NONE;
3445 end_range= NULL;
3446 DBUG_RETURN(rnd_end());
3447 }
3448 int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result));
3449 int ha_reset();
3450 /* this is necessary in many places, e.g. in HANDLER command */
ha_index_or_rnd_end()3451 int ha_index_or_rnd_end()
3452 {
3453 return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0;
3454 }
3455 /**
3456 The cached_table_flags is set at ha_open and ha_external_lock
3457 */
ha_table_flags()3458 Table_flags ha_table_flags() const
3459 {
3460 DBUG_ASSERT(cached_table_flags < (HA_LAST_TABLE_FLAG << 1));
3461 return cached_table_flags;
3462 }
3463 /**
3464 These functions represent the public interface to *users* of the
3465 handler class, hence they are *not* virtual. For the inheritance
3466 interface, see the (private) functions write_row(), update_row(),
3467 and delete_row() below.
3468 */
3469 int ha_external_lock(THD *thd, int lock_type);
ha_external_unlock(THD * thd)3470 int ha_external_unlock(THD *thd) { return ha_external_lock(thd, F_UNLCK); }
3471 int ha_write_row(const uchar * buf);
3472 int ha_update_row(const uchar * old_data, const uchar * new_data);
3473 int ha_delete_row(const uchar * buf);
3474 void ha_release_auto_increment();
3475
keyread_enabled()3476 bool keyread_enabled() { return keyread < MAX_KEY; }
ha_start_keyread(uint idx)3477 int ha_start_keyread(uint idx)
3478 {
3479 int res= keyread_enabled() ? 0 : extra_opt(HA_EXTRA_KEYREAD, idx);
3480 keyread= idx;
3481 return res;
3482 }
ha_end_keyread()3483 int ha_end_keyread()
3484 {
3485 if (!keyread_enabled())
3486 return 0;
3487 keyread= MAX_KEY;
3488 return extra(HA_EXTRA_NO_KEYREAD);
3489 }
3490
3491 int check_collation_compatibility();
3492 int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
3493 /** to be actually called to get 'check()' functionality*/
3494 int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
3495 int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
3496 void ha_start_bulk_insert(ha_rows rows, uint flags= 0)
3497 {
3498 DBUG_ENTER("handler::ha_start_bulk_insert");
3499 estimation_rows_to_insert= rows;
3500 bzero(©_info,sizeof(copy_info));
3501 start_bulk_insert(rows, flags);
3502 DBUG_VOID_RETURN;
3503 }
3504 int ha_end_bulk_insert();
3505 int ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
3506 ha_rows *dup_key_found);
3507 int ha_delete_all_rows();
3508 int ha_truncate();
3509 int ha_reset_auto_increment(ulonglong value);
3510 int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt);
3511 int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt);
3512 bool ha_check_and_repair(THD *thd);
3513 int ha_disable_indexes(uint mode);
3514 int ha_enable_indexes(uint mode);
3515 int ha_discard_or_import_tablespace(my_bool discard);
3516 int ha_rename_table(const char *from, const char *to);
3517 void ha_drop_table(const char *name);
3518
3519 int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info);
3520
3521 int ha_create_partitioning_metadata(const char *name, const char *old_name,
3522 chf_create_flags action_flag);
3523
3524 int ha_change_partitions(HA_CREATE_INFO *create_info,
3525 const char *path,
3526 ulonglong * const copied,
3527 ulonglong * const deleted,
3528 const uchar *pack_frm_data,
3529 size_t pack_frm_len);
3530 int ha_drop_partitions(const char *path);
3531 int ha_rename_partitions(const char *path);
3532
3533 void adjust_next_insert_id_after_explicit_value(ulonglong nr);
3534 int update_auto_increment();
3535 virtual void print_error(int error, myf errflag);
3536 virtual bool get_error_message(int error, String *buf);
3537 uint get_dup_key(int error);
3538 /**
3539 Retrieves the names of the table and the key for which there was a
3540 duplicate entry in the case of HA_ERR_FOREIGN_DUPLICATE_KEY.
3541
3542 If any of the table or key name is not available this method will return
3543 false and will not change any of child_table_name or child_key_name.
3544
3545 @param child_table_name[out] Table name
3546 @param child_table_name_len[in] Table name buffer size
3547 @param child_key_name[out] Key name
3548 @param child_key_name_len[in] Key name buffer size
3549
3550 @retval true table and key names were available
3551 and were written into the corresponding
3552 out parameters.
3553 @retval false table and key names were not available,
3554 the out parameters were not touched.
3555 */
get_foreign_dup_key(char * child_table_name,uint child_table_name_len,char * child_key_name,uint child_key_name_len)3556 virtual bool get_foreign_dup_key(char *child_table_name,
3557 uint child_table_name_len,
3558 char *child_key_name,
3559 uint child_key_name_len)
3560 { DBUG_ASSERT(false); return(false); }
reset_statistics()3561 void reset_statistics()
3562 {
3563 rows_read= rows_changed= rows_tmp_read= 0;
3564 bzero(index_rows_read, sizeof(index_rows_read));
3565 bzero(©_info, sizeof(copy_info));
3566 }
reset_copy_info()3567 virtual void reset_copy_info() {}
ha_reset_copy_info()3568 void ha_reset_copy_info()
3569 {
3570 bzero(©_info, sizeof(copy_info));
3571 reset_copy_info();
3572 }
change_table_ptr(TABLE * table_arg,TABLE_SHARE * share)3573 virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
3574 {
3575 table= table_arg;
3576 table_share= share;
3577 reset_statistics();
3578 }
scan_time()3579 virtual double scan_time()
3580 {
3581 return ((ulonglong2double(stats.data_file_length) / stats.block_size + 2) *
3582 avg_io_cost());
3583 }
3584
key_scan_time(uint index)3585 virtual double key_scan_time(uint index)
3586 {
3587 return keyread_time(index, 1, records());
3588 }
3589
avg_io_cost()3590 virtual double avg_io_cost()
3591 {
3592 return 1.0;
3593 }
3594
3595 /**
3596 The cost of reading a set of ranges from the table using an index
3597 to access it.
3598
3599 @param index The index number.
3600 @param ranges The number of ranges to be read. If 0, it means that
3601 we calculate separately the cost of reading the key.
3602 @param rows Total number of rows to be read.
3603
3604 This method can be used to calculate the total cost of scanning a table
3605 using an index by calling it using read_time(index, 1, table_size).
3606 */
read_time(uint index,uint ranges,ha_rows rows)3607 virtual double read_time(uint index, uint ranges, ha_rows rows)
3608 { return rows2double(ranges+rows); }
3609
3610 /**
3611 Calculate cost of 'keyread' scan for given index and number of records.
3612
3613 @param index index to read
3614 @param ranges #of ranges to read
3615 @param rows #of records to read
3616 */
3617 virtual double keyread_time(uint index, uint ranges, ha_rows rows);
3618
keys_to_use_for_scanning()3619 virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
3620
3621 /*
3622 True if changes to the table is persistent (if there are no rollback)
3623 This is used to decide:
3624 - If the table is stored in the transaction or non transactional binary
3625 log
3626 - How things are tracked in trx and in add_changed_table().
3627 - If we can combine several statements under one commit in the binary log.
3628 */
has_transactions()3629 bool has_transactions()
3630 {
3631 return ((ha_table_flags() & (HA_NO_TRANSACTIONS | HA_PERSISTENT_TABLE))
3632 == 0);
3633 }
3634 /*
3635 True if table has both transactions and rollback. This is used to decide
3636 if we should write the changes to the binary log. If this is true,
3637 we don't have to write failed statements to the log as they can be
3638 rolled back.
3639 */
has_transactions_and_rollback()3640 bool has_transactions_and_rollback()
3641 {
3642 return has_transactions() && has_rollback();
3643 }
3644 /*
3645 True if the underlaying table support transactions and rollback
3646 */
has_transaction_manager()3647 bool has_transaction_manager()
3648 {
3649 return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0 && has_rollback());
3650 }
3651
3652 /*
3653 True if table has rollback. Used to check if an update on the table
3654 can be killed fast.
3655 */
3656
has_rollback()3657 bool has_rollback()
3658 {
3659 return ((ht->flags & HTON_NO_ROLLBACK) == 0);
3660 }
3661
3662 /**
3663 This method is used to analyse the error to see whether the error
3664 is ignorable or not, certain handlers can have more error that are
3665 ignorable than others. E.g. the partition handler can get inserts
3666 into a range where there is no partition and this is an ignorable
3667 error.
3668 HA_ERR_FOUND_DUP_UNIQUE is a special case in MyISAM that means the
3669 same thing as HA_ERR_FOUND_DUP_KEY but can in some cases lead to
3670 a slightly different error message.
3671 */
is_fatal_error(int error,uint flags)3672 virtual bool is_fatal_error(int error, uint flags)
3673 {
3674 if (!error ||
3675 ((flags & HA_CHECK_DUP_KEY) &&
3676 (error == HA_ERR_FOUND_DUPP_KEY ||
3677 error == HA_ERR_FOUND_DUPP_UNIQUE)) ||
3678 error == HA_ERR_AUTOINC_ERANGE ||
3679 ((flags & HA_CHECK_FK_ERROR) &&
3680 (error == HA_ERR_ROW_IS_REFERENCED ||
3681 error == HA_ERR_NO_REFERENCED_ROW)))
3682 return FALSE;
3683 return TRUE;
3684 }
3685
3686 /**
3687 Number of rows in table. It will only be called if
3688 (table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
3689 */
pre_records()3690 virtual int pre_records() { return 0; }
records()3691 virtual ha_rows records() { return stats.records; }
3692 /**
3693 Return upper bound of current number of records in the table
3694 (max. of how many records one will retrieve when doing a full table scan)
3695 If upper bound is not known, HA_POS_ERROR should be returned as a max
3696 possible upper bound.
3697 */
estimate_rows_upper_bound()3698 virtual ha_rows estimate_rows_upper_bound()
3699 { return stats.records+EXTRA_RECORDS; }
3700
3701 /**
3702 Get the row type from the storage engine. If this method returns
3703 ROW_TYPE_NOT_USED, the information in HA_CREATE_INFO should be used.
3704 */
get_row_type()3705 virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; }
3706
index_type(uint key_number)3707 virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";}
3708
3709
3710 /**
3711 Signal that the table->read_set and table->write_set table maps changed
3712 The handler is allowed to set additional bits in the above map in this
3713 call. Normally the handler should ignore all calls until we have done
3714 a ha_rnd_init() or ha_index_init(), write_row(), update_row or delete_row()
3715 as there may be several calls to this routine.
3716 */
3717 virtual void column_bitmaps_signal();
3718 /*
3719 We have to check for inited as some engines, like innodb, sets
3720 active_index during table scan.
3721 */
get_index(void)3722 uint get_index(void) const
3723 { return inited == INDEX ? active_index : MAX_KEY; }
3724 int ha_close(void);
3725
3726 /**
3727 @retval 0 Bulk update used by handler
3728 @retval 1 Bulk update not used, normal operation used
3729 */
start_bulk_update()3730 virtual bool start_bulk_update() { return 1; }
3731 /**
3732 @retval 0 Bulk delete used by handler
3733 @retval 1 Bulk delete not used, normal operation used
3734 */
start_bulk_delete()3735 virtual bool start_bulk_delete() { return 1; }
3736 /**
3737 After this call all outstanding updates must be performed. The number
3738 of duplicate key errors are reported in the duplicate key parameter.
3739 It is allowed to continue to the batched update after this call, the
3740 handler has to wait until end_bulk_update with changing state.
3741
3742 @param dup_key_found Number of duplicate keys found
3743
3744 @retval 0 Success
3745 @retval >0 Error code
3746 */
exec_bulk_update(ha_rows * dup_key_found)3747 virtual int exec_bulk_update(ha_rows *dup_key_found)
3748 {
3749 DBUG_ASSERT(FALSE);
3750 return HA_ERR_WRONG_COMMAND;
3751 }
3752 /**
3753 Perform any needed clean-up, no outstanding updates are there at the
3754 moment.
3755 */
end_bulk_update()3756 virtual int end_bulk_update() { return 0; }
3757 /**
3758 Execute all outstanding deletes and close down the bulk delete.
3759
3760 @retval 0 Success
3761 @retval >0 Error code
3762 */
end_bulk_delete()3763 virtual int end_bulk_delete()
3764 {
3765 DBUG_ASSERT(FALSE);
3766 return HA_ERR_WRONG_COMMAND;
3767 }
pre_index_read_map(const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag,bool use_parallel)3768 virtual int pre_index_read_map(const uchar *key,
3769 key_part_map keypart_map,
3770 enum ha_rkey_function find_flag,
3771 bool use_parallel)
3772 { return 0; }
pre_index_first(bool use_parallel)3773 virtual int pre_index_first(bool use_parallel)
3774 { return 0; }
pre_index_last(bool use_parallel)3775 virtual int pre_index_last(bool use_parallel)
3776 { return 0; }
pre_index_read_last_map(const uchar * key,key_part_map keypart_map,bool use_parallel)3777 virtual int pre_index_read_last_map(const uchar *key,
3778 key_part_map keypart_map,
3779 bool use_parallel)
3780 { return 0; }
3781 /*
3782 virtual int pre_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
3783 KEY_MULTI_RANGE *ranges,
3784 uint range_count,
3785 bool sorted, HANDLER_BUFFER *buffer,
3786 bool use_parallel);
3787 */
pre_multi_range_read_next(bool use_parallel)3788 virtual int pre_multi_range_read_next(bool use_parallel)
3789 { return 0; }
pre_read_range_first(const key_range * start_key,const key_range * end_key,bool eq_range,bool sorted,bool use_parallel)3790 virtual int pre_read_range_first(const key_range *start_key,
3791 const key_range *end_key,
3792 bool eq_range, bool sorted,
3793 bool use_parallel)
3794 { return 0; }
pre_ft_read(bool use_parallel)3795 virtual int pre_ft_read(bool use_parallel)
3796 { return 0; }
pre_rnd_next(bool use_parallel)3797 virtual int pre_rnd_next(bool use_parallel)
3798 { return 0; }
ha_pre_rnd_init(bool scan)3799 int ha_pre_rnd_init(bool scan)
3800 {
3801 int result;
3802 DBUG_ENTER("ha_pre_rnd_init");
3803 DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan));
3804 pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND;
3805 DBUG_RETURN(result);
3806 }
ha_pre_rnd_end()3807 int ha_pre_rnd_end()
3808 {
3809 DBUG_ENTER("ha_pre_rnd_end");
3810 DBUG_ASSERT(pre_inited==RND);
3811 pre_inited=NONE;
3812 DBUG_RETURN(pre_rnd_end());
3813 }
pre_rnd_init(bool scan)3814 virtual int pre_rnd_init(bool scan) { return 0; }
pre_rnd_end()3815 virtual int pre_rnd_end() { return 0; }
pre_index_init(uint idx,bool sorted)3816 virtual int pre_index_init(uint idx, bool sorted) { return 0; }
pre_index_end()3817 virtual int pre_index_end() { return 0; }
ha_pre_index_init(uint idx,bool sorted)3818 int ha_pre_index_init(uint idx, bool sorted)
3819 {
3820 int result;
3821 DBUG_ENTER("ha_pre_index_init");
3822 DBUG_ASSERT(pre_inited==NONE);
3823 if (!(result= pre_index_init(idx, sorted)))
3824 pre_inited=INDEX;
3825 DBUG_RETURN(result);
3826 }
ha_pre_index_end()3827 int ha_pre_index_end()
3828 {
3829 DBUG_ENTER("ha_pre_index_end");
3830 DBUG_ASSERT(pre_inited==INDEX);
3831 pre_inited=NONE;
3832 DBUG_RETURN(pre_index_end());
3833 }
ha_pre_index_or_rnd_end()3834 int ha_pre_index_or_rnd_end()
3835 {
3836 return (pre_inited == INDEX ?
3837 ha_pre_index_end() :
3838 pre_inited == RND ? ha_pre_rnd_end() : 0 );
3839 }
vers_can_native(THD * thd)3840 virtual bool vers_can_native(THD *thd)
3841 {
3842 return ht->flags & HTON_NATIVE_SYS_VERSIONING;
3843 }
3844
3845 /**
3846 @brief
3847 Positions an index cursor to the index specified in the
3848 handle. Fetches the row if available. If the key value is null,
3849 begin at the first key of the index.
3850 */
3851 protected:
index_read_map(uchar * buf,const uchar * key,key_part_map keypart_map,enum ha_rkey_function find_flag)3852 virtual int index_read_map(uchar * buf, const uchar * key,
3853 key_part_map keypart_map,
3854 enum ha_rkey_function find_flag)
3855 {
3856 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
3857 return index_read(buf, key, key_len, find_flag);
3858 }
3859 /**
3860 @brief
3861 Positions an index cursor to the index specified in the
3862 handle. Fetches the row if available. If the key value is null,
3863 begin at the first key of the index.
3864 */
3865 virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
3866 key_part_map keypart_map,
3867 enum ha_rkey_function find_flag);
index_next(uchar * buf)3868 virtual int index_next(uchar * buf)
3869 { return HA_ERR_WRONG_COMMAND; }
index_prev(uchar * buf)3870 virtual int index_prev(uchar * buf)
3871 { return HA_ERR_WRONG_COMMAND; }
index_first(uchar * buf)3872 virtual int index_first(uchar * buf)
3873 { return HA_ERR_WRONG_COMMAND; }
index_last(uchar * buf)3874 virtual int index_last(uchar * buf)
3875 { return HA_ERR_WRONG_COMMAND; }
3876 virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
3877 /**
3878 @brief
3879 The following functions works like index_read, but it find the last
3880 row with the current key value or prefix.
3881 @returns @see index_read_map().
3882 */
index_read_last_map(uchar * buf,const uchar * key,key_part_map keypart_map)3883 virtual int index_read_last_map(uchar * buf, const uchar * key,
3884 key_part_map keypart_map)
3885 {
3886 uint key_len= calculate_key_len(table, active_index, key, keypart_map);
3887 return index_read_last(buf, key, key_len);
3888 }
3889 virtual int close(void)=0;
update_rows_read()3890 inline void update_rows_read()
3891 {
3892 if (likely(!internal_tmp_table))
3893 rows_read++;
3894 else
3895 rows_tmp_read++;
3896 }
update_index_statistics()3897 inline void update_index_statistics()
3898 {
3899 index_rows_read[active_index]++;
3900 update_rows_read();
3901 }
3902 public:
3903
3904 int ha_index_read_map(uchar * buf, const uchar * key,
3905 key_part_map keypart_map,
3906 enum ha_rkey_function find_flag);
3907 int ha_index_read_idx_map(uchar * buf, uint index, const uchar * key,
3908 key_part_map keypart_map,
3909 enum ha_rkey_function find_flag);
3910 int ha_index_next(uchar * buf);
3911 int ha_index_prev(uchar * buf);
3912 int ha_index_first(uchar * buf);
3913 int ha_index_last(uchar * buf);
3914 int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
3915 /*
3916 TODO: should we make for those functions non-virtual ha_func_name wrappers,
3917 too?
3918 */
3919 virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
3920 void *seq_init_param,
3921 uint n_ranges, uint *bufsz,
3922 uint *mrr_mode,
3923 Cost_estimate *cost);
3924 virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
3925 uint key_parts, uint *bufsz,
3926 uint *mrr_mode, Cost_estimate *cost);
3927 virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
3928 uint n_ranges, uint mrr_mode,
3929 HANDLER_BUFFER *buf);
3930 virtual int multi_range_read_next(range_id_t *range_info);
3931 /*
3932 Return string representation of the MRR plan.
3933
3934 This is intended to be used for EXPLAIN, via the following scenario:
3935 1. SQL layer calls handler->multi_range_read_info().
3936 1.1. Storage engine figures out whether it will use some non-default
3937 MRR strategy, sets appropritate bits in *mrr_mode, and returns
3938 control to SQL layer
3939 2. SQL layer remembers the returned mrr_mode
3940 3. SQL layer compares various options and choses the final query plan. As
3941 a part of that, it makes a choice of whether to use the MRR strategy
3942 picked in 1.1
3943 4. EXPLAIN code converts the query plan to its text representation. If MRR
3944 strategy is part of the plan, it calls
3945 multi_range_read_explain_info(mrr_mode) to get a text representation of
3946 the picked MRR strategy.
3947
3948 @param mrr_mode Mode which was returned by multi_range_read_info[_const]
3949 @param str INOUT string to be printed for EXPLAIN
3950 @param str_end End of the string buffer. The function is free to put the
3951 string into [str..str_end] memory range.
3952 */
multi_range_read_explain_info(uint mrr_mode,char * str,size_t size)3953 virtual int multi_range_read_explain_info(uint mrr_mode, char *str,
3954 size_t size)
3955 { return 0; }
3956
3957 virtual int read_range_first(const key_range *start_key,
3958 const key_range *end_key,
3959 bool eq_range, bool sorted);
3960 virtual int read_range_next();
3961 void set_end_range(const key_range *end_key);
3962 int compare_key(key_range *range);
3963 int compare_key2(key_range *range) const;
ft_init()3964 virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
pre_ft_init()3965 virtual int pre_ft_init() { return HA_ERR_WRONG_COMMAND; }
ft_end()3966 virtual void ft_end() {}
pre_ft_end()3967 virtual int pre_ft_end() { return 0; }
ft_init_ext(uint flags,uint inx,String * key)3968 virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
3969 { return NULL; }
3970 public:
ft_read(uchar * buf)3971 virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
3972 virtual int rnd_next(uchar *buf)=0;
3973 virtual int rnd_pos(uchar * buf, uchar *pos)=0;
3974 /**
3975 This function only works for handlers having
3976 HA_PRIMARY_KEY_REQUIRED_FOR_POSITION set.
3977 It will return the row with the PK given in the record argument.
3978 */
rnd_pos_by_record(uchar * record)3979 virtual int rnd_pos_by_record(uchar *record)
3980 {
3981 int error;
3982 DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION);
3983
3984 error = ha_rnd_init(false);
3985 if (error != 0)
3986 return error;
3987
3988 position(record);
3989 error = ha_rnd_pos(record, ref);
3990 ha_rnd_end();
3991 return error;
3992 }
3993 virtual int read_first_row(uchar *buf, uint primary_key);
3994 public:
3995
3996 /* Same as above, but with statistics */
3997 inline int ha_ft_read(uchar *buf);
ha_ft_end()3998 inline void ha_ft_end() { ft_end(); ft_handler=NULL; }
3999 int ha_rnd_next(uchar *buf);
4000 int ha_rnd_pos(uchar *buf, uchar *pos);
4001 inline int ha_rnd_pos_by_record(uchar *buf);
4002 inline int ha_read_first_row(uchar *buf, uint primary_key);
4003
4004 /**
4005 The following 3 function is only needed for tables that may be
4006 internal temporary tables during joins.
4007 */
remember_rnd_pos()4008 virtual int remember_rnd_pos()
4009 { return HA_ERR_WRONG_COMMAND; }
restart_rnd_next(uchar * buf)4010 virtual int restart_rnd_next(uchar *buf)
4011 { return HA_ERR_WRONG_COMMAND; }
rnd_same(uchar * buf,uint inx)4012 virtual int rnd_same(uchar *buf, uint inx)
4013 { return HA_ERR_WRONG_COMMAND; }
4014
records_in_range(uint inx,const key_range * min_key,const key_range * max_key,page_range * res)4015 virtual ha_rows records_in_range(uint inx, const key_range *min_key,
4016 const key_range *max_key,
4017 page_range *res)
4018 { return (ha_rows) 10; }
4019 /*
4020 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
4021 (reference to the row, aka position, with the primary key given in
4022 the record).
4023 Otherwise it set ref to the current row.
4024 */
4025 virtual void position(const uchar *record)=0;
4026 virtual int info(uint)=0; // see my_base.h for full description
4027 virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
4028 uint part_id);
set_partitions_to_open(List<String> * partition_names)4029 virtual void set_partitions_to_open(List<String> *partition_names) {}
4030 virtual bool check_if_updates_are_ignored(const char *op) const;
change_partitions_to_open(List<String> * partition_names)4031 virtual int change_partitions_to_open(List<String> *partition_names)
4032 { return 0; }
extra(enum ha_extra_function operation)4033 virtual int extra(enum ha_extra_function operation)
4034 { return 0; }
extra_opt(enum ha_extra_function operation,ulong arg)4035 virtual int extra_opt(enum ha_extra_function operation, ulong arg)
4036 { return extra(operation); }
4037
4038 /**
4039 In an UPDATE or DELETE, if the row under the cursor was locked by another
4040 transaction, and the engine used an optimistic read of the last
4041 committed row value under the cursor, then the engine returns 1 from this
4042 function. MySQL must NOT try to update this optimistic value. If the
4043 optimistic value does not match the WHERE condition, MySQL can decide to
4044 skip over this row. Currently only works for InnoDB. This can be used to
4045 avoid unnecessary lock waits.
4046
4047 If this method returns nonzero, it will also signal the storage
4048 engine that the next read will be a locking re-read of the row.
4049 */
4050 bool ha_was_semi_consistent_read();
was_semi_consistent_read()4051 virtual bool was_semi_consistent_read() { return 0; }
4052 /**
4053 Tell the engine whether it should avoid unnecessary lock waits.
4054 If yes, in an UPDATE or DELETE, if the row under the cursor was locked
4055 by another transaction, the engine may try an optimistic read of
4056 the last committed row value under the cursor.
4057 */
try_semi_consistent_read(bool)4058 virtual void try_semi_consistent_read(bool) {}
unlock_row()4059 virtual void unlock_row() {}
start_stmt(THD * thd,thr_lock_type lock_type)4060 virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
need_info_for_auto_inc()4061 virtual bool need_info_for_auto_inc() { return 0; }
can_use_for_auto_inc_init()4062 virtual bool can_use_for_auto_inc_init() { return 1; }
4063 virtual void get_auto_increment(ulonglong offset, ulonglong increment,
4064 ulonglong nb_desired_values,
4065 ulonglong *first_value,
4066 ulonglong *nb_reserved_values);
set_next_insert_id(ulonglong id)4067 void set_next_insert_id(ulonglong id)
4068 {
4069 DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id));
4070 next_insert_id= id;
4071 }
restore_auto_increment(ulonglong prev_insert_id)4072 virtual void restore_auto_increment(ulonglong prev_insert_id)
4073 {
4074 /*
4075 Insertion of a row failed, re-use the lastly generated auto_increment
4076 id, for the next row. This is achieved by resetting next_insert_id to
4077 what it was before the failed insertion (that old value is provided by
4078 the caller). If that value was 0, it was the first row of the INSERT;
4079 then if insert_id_for_cur_row contains 0 it means no id was generated
4080 for this first row, so no id was generated since the INSERT started, so
4081 we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
4082 is the generated id of the first and failed row, so we use it.
4083 */
4084 next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
4085 insert_id_for_cur_row;
4086 }
4087
update_create_info(HA_CREATE_INFO * create_info)4088 virtual void update_create_info(HA_CREATE_INFO *create_info) {}
4089 int check_old_types();
assign_to_keycache(THD * thd,HA_CHECK_OPT * check_opt)4090 virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt)
4091 { return HA_ADMIN_NOT_IMPLEMENTED; }
preload_keys(THD * thd,HA_CHECK_OPT * check_opt)4092 virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt)
4093 { return HA_ADMIN_NOT_IMPLEMENTED; }
4094 /* end of the list of admin commands */
4095
indexes_are_disabled(void)4096 virtual int indexes_are_disabled(void) {return 0;}
append_create_info(String * packet)4097 virtual void append_create_info(String *packet) {}
4098 /**
4099 If index == MAX_KEY then a check for table is made and if index <
4100 MAX_KEY then a check is made if the table has foreign keys and if
4101 a foreign key uses this index (and thus the index cannot be dropped).
4102
4103 @param index Index to check if foreign key uses it
4104
4105 @retval TRUE Foreign key defined on table or index
4106 @retval FALSE No foreign key defined
4107 */
is_fk_defined_on_table_or_index(uint index)4108 virtual bool is_fk_defined_on_table_or_index(uint index)
4109 { return FALSE; }
get_foreign_key_create_info()4110 virtual char* get_foreign_key_create_info()
4111 { return(NULL);} /* gets foreign key create string from InnoDB */
4112 /**
4113 Used in ALTER TABLE to check if changing storage engine is allowed.
4114
4115 @note Called without holding thr_lock.c lock.
4116
4117 @retval true Changing storage engine is allowed.
4118 @retval false Changing storage engine not allowed.
4119 */
can_switch_engines()4120 virtual bool can_switch_engines() { return true; }
can_continue_handler_scan()4121 virtual int can_continue_handler_scan() { return 0; }
4122 /**
4123 Get the list of foreign keys in this table.
4124
4125 @remark Returns the set of foreign keys where this table is the
4126 dependent or child table.
4127
4128 @param thd The thread handle.
4129 @param f_key_list[out] The list of foreign keys.
4130
4131 @return The handler error code or zero for success.
4132 */
4133 virtual int
get_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)4134 get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
4135 { return 0; }
4136 /**
4137 Get the list of foreign keys referencing this table.
4138
4139 @remark Returns the set of foreign keys where this table is the
4140 referenced or parent table.
4141
4142 @param thd The thread handle.
4143 @param f_key_list[out] The list of foreign keys.
4144
4145 @return The handler error code or zero for success.
4146 */
4147 virtual int
get_parent_foreign_key_list(THD * thd,List<FOREIGN_KEY_INFO> * f_key_list)4148 get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list)
4149 { return 0; }
referenced_by_foreign_key()4150 virtual uint referenced_by_foreign_key() { return 0;}
init_table_handle_for_HANDLER()4151 virtual void init_table_handle_for_HANDLER()
4152 { return; } /* prepare InnoDB for HANDLER */
free_foreign_key_create_info(char * str)4153 virtual void free_foreign_key_create_info(char* str) {}
4154 /** The following can be called without an open handler */
table_type()4155 const char *table_type() const { return hton_name(ht)->str; }
bas_ext()4156 const char **bas_ext() const { return ht->tablefile_extensions; }
4157
get_default_no_partitions(HA_CREATE_INFO * create_info)4158 virtual int get_default_no_partitions(HA_CREATE_INFO *create_info)
4159 { return 1;}
set_auto_partitions(partition_info * part_info)4160 virtual void set_auto_partitions(partition_info *part_info) { return; }
get_no_parts(const char * name,uint * no_parts)4161 virtual bool get_no_parts(const char *name,
4162 uint *no_parts)
4163 {
4164 *no_parts= 0;
4165 return 0;
4166 }
set_part_info(partition_info * part_info)4167 virtual void set_part_info(partition_info *part_info) {return;}
return_record_by_parent()4168 virtual void return_record_by_parent() { return; }
4169
4170 /* Information about index. Both index and part starts from 0 */
4171 virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
4172
max_record_length()4173 uint max_record_length() const
4174 { return MY_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
max_keys()4175 uint max_keys() const
4176 { return MY_MIN(MAX_KEY, max_supported_keys()); }
max_key_parts()4177 uint max_key_parts() const
4178 { return MY_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
max_key_length()4179 uint max_key_length() const
4180 { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_length()); }
max_key_part_length()4181 uint max_key_part_length() const
4182 { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_part_length()); }
4183
max_supported_record_length()4184 virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
max_supported_keys()4185 virtual uint max_supported_keys() const { return 0; }
max_supported_key_parts()4186 virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
max_supported_key_length()4187 virtual uint max_supported_key_length() const { return MAX_DATA_LENGTH_FOR_KEY; }
max_supported_key_part_length()4188 virtual uint max_supported_key_part_length() const { return 255; }
min_record_length(uint options)4189 virtual uint min_record_length(uint options) const { return 1; }
4190
pre_calculate_checksum()4191 virtual int pre_calculate_checksum() { return 0; }
4192 virtual int calculate_checksum();
is_crashed()4193 virtual bool is_crashed() const { return 0; }
auto_repair(int error)4194 virtual bool auto_repair(int error) const { return 0; }
4195
4196 void update_global_table_stats();
4197 void update_global_index_stats();
4198
4199 /**
4200 @note lock_count() can return > 1 if the table is MERGE or partitioned.
4201 */
lock_count(void)4202 virtual uint lock_count(void) const { return 1; }
4203 /**
4204 Is not invoked for non-transactional temporary tables.
4205
4206 @note store_lock() can return more than one lock if the table is MERGE
4207 or partitioned.
4208
4209 @note that one can NOT rely on table->in_use in store_lock(). It may
4210 refer to a different thread if called from mysql_lock_abort_for_thread().
4211
4212 @note If the table is MERGE, store_lock() can return less locks
4213 than lock_count() claimed. This can happen when the MERGE children
4214 are not attached when this is called from another thread.
4215 */
4216 virtual THR_LOCK_DATA **store_lock(THD *thd,
4217 THR_LOCK_DATA **to,
4218 enum thr_lock_type lock_type)=0;
4219
4220 /** Type of table for caching query */
table_cache_type()4221 virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; }
4222
4223
4224 /**
4225 @brief Register a named table with a call back function to the query cache.
4226
4227 @param thd The thread handle
4228 @param table_key A pointer to the table name in the table cache
4229 @param key_length The length of the table name
4230 @param[out] engine_callback The pointer to the storage engine call back
4231 function
4232 @param[out] engine_data Storage engine specific data which could be
4233 anything
4234
4235 This method offers the storage engine, the possibility to store a reference
4236 to a table name which is going to be used with query cache.
4237 The method is called each time a statement is written to the cache and can
4238 be used to verify if a specific statement is cacheable. It also offers
4239 the possibility to register a generic (but static) call back function which
4240 is called each time a statement is matched against the query cache.
4241
4242 @note If engine_data supplied with this function is different from
4243 engine_data supplied with the callback function, and the callback returns
4244 FALSE, a table invalidation on the current table will occur.
4245
4246 @return Upon success the engine_callback will point to the storage engine
4247 call back function, if any, and engine_data will point to any storage
4248 engine data used in the specific implementation.
4249 @retval TRUE Success
4250 @retval FALSE The specified table or current statement should not be
4251 cached
4252 */
4253
register_query_cache_table(THD * thd,const char * table_key,uint key_length,qc_engine_callback * callback,ulonglong * engine_data)4254 virtual my_bool register_query_cache_table(THD *thd, const char *table_key,
4255 uint key_length,
4256 qc_engine_callback *callback,
4257 ulonglong *engine_data)
4258 {
4259 *callback= 0;
4260 return TRUE;
4261 }
4262
4263 /*
4264 Count tables invisible from all tables list on which current one built
4265 (like myisammrg and partitioned tables)
4266
4267 tables_type mask for the tables should be added herdde
4268
4269 returns number of such tables
4270 */
4271
count_query_cache_dependant_tables(uint8 * tables_type)4272 virtual uint count_query_cache_dependant_tables(uint8 *tables_type
4273 __attribute__((unused)))
4274 {
4275 return 0;
4276 }
4277
4278 /*
4279 register tables invisible from all tables list on which current one built
4280 (like myisammrg and partitioned tables).
4281
4282 @note they should be counted by method above
4283
4284 cache Query cache pointer
4285 block Query cache block to write the table
4286 n Number of the table
4287
4288 @retval FALSE - OK
4289 @retval TRUE - Error
4290 */
4291
4292 virtual my_bool
register_query_cache_dependant_tables(THD * thd,Query_cache * cache,Query_cache_block_table ** block,uint * n)4293 register_query_cache_dependant_tables(THD *thd
4294 __attribute__((unused)),
4295 Query_cache *cache
4296 __attribute__((unused)),
4297 Query_cache_block_table **block
4298 __attribute__((unused)),
4299 uint *n __attribute__((unused)))
4300 {
4301 return FALSE;
4302 }
4303
4304 /*
4305 Check if the key is a clustering key
4306
4307 - Data is stored together with the primary key (no secondary lookup
4308 needed to find the row data). The optimizer uses this to find out
4309 the cost of fetching data.
4310
4311 Note that in many cases a clustered key is also a reference key.
4312 This means that:
4313
4314 - The key is part of each secondary key and is used
4315 to find the row data in the primary index when reading trough
4316 secondary indexes.
4317 - When doing a HA_KEYREAD_ONLY we get also all the primary key parts
4318 into the row. This is critical property used by index_merge.
4319
4320 All the above is usually true for engines that store the row
4321 data in the primary key index (e.g. in a b-tree), and use the key
4322 key value as a position(). InnoDB is an example of such an engine.
4323
4324 For a clustered (primary) key, the following should also hold:
4325 index_flags() should contain HA_CLUSTERED_INDEX
4326 table_flags() should contain HA_TABLE_SCAN_ON_INDEX
4327
4328 For a reference key the following should also hold:
4329 table_flags() should contain HA_PRIMARY_KEY_IS_READ_INDEX.
4330
4331 @retval TRUE yes
4332 @retval FALSE No.
4333 */
4334
4335 /* The following code is for primary keys */
pk_is_clustering_key(uint index)4336 bool pk_is_clustering_key(uint index) const
4337 {
4338 /*
4339 We have to check for MAX_INDEX as table->s->primary_key can be
4340 MAX_KEY in the case where there is no primary key.
4341 */
4342 return index != MAX_KEY && is_clustering_key(index);
4343 }
4344 /* Same as before but for other keys, in which case we can skip the check */
is_clustering_key(uint index)4345 bool is_clustering_key(uint index) const
4346 {
4347 DBUG_ASSERT(index != MAX_KEY);
4348 return (index_flags(index, 0, 1) & HA_CLUSTERED_INDEX);
4349 }
4350
cmp_ref(const uchar * ref1,const uchar * ref2)4351 virtual int cmp_ref(const uchar *ref1, const uchar *ref2)
4352 {
4353 return memcmp(ref1, ref2, ref_length);
4354 }
4355
4356 /*
4357 Condition pushdown to storage engines
4358 */
4359
4360 /**
4361 Push condition down to the table handler.
4362
4363 @param cond Condition to be pushed. The condition tree must not be
4364 modified by the by the caller.
4365
4366 @return
4367 The 'remainder' condition that caller must use to filter out records.
4368 NULL means the handler will not return rows that do not match the
4369 passed condition.
4370
4371 @note
4372 The pushed conditions form a stack (from which one can remove the
4373 last pushed condition using cond_pop).
4374 The table handler filters out rows using (pushed_cond1 AND pushed_cond2
4375 AND ... AND pushed_condN)
4376 or less restrictive condition, depending on handler's capabilities.
4377
4378 handler->ha_reset() call empties the condition stack.
4379 Calls to rnd_init/rnd_end, index_init/index_end etc do not affect the
4380 condition stack.
4381 */
cond_push(const COND * cond)4382 virtual const COND *cond_push(const COND *cond) { return cond; };
4383 /**
4384 Pop the top condition from the condition stack of the handler instance.
4385
4386 Pops the top if condition stack, if stack is not empty.
4387 */
cond_pop()4388 virtual void cond_pop() { return; };
4389
4390 /**
4391 Push metadata for the current operation down to the table handler.
4392 */
info_push(uint info_type,void * info)4393 virtual int info_push(uint info_type, void *info) { return 0; };
4394
4395 /**
4396 Push down an index condition to the handler.
4397
4398 The server will use this method to push down a condition it wants
4399 the handler to evaluate when retrieving records using a specified
4400 index. The pushed index condition will only refer to fields from
4401 this handler that is contained in the index (but it may also refer
4402 to fields in other handlers). Before the handler evaluates the
4403 condition it must read the content of the index entry into the
4404 record buffer.
4405
4406 The handler is free to decide if and how much of the condition it
4407 will take responsibility for evaluating. Based on this evaluation
4408 it should return the part of the condition it will not evaluate.
4409 If it decides to evaluate the entire condition it should return
4410 NULL. If it decides not to evaluate any part of the condition it
4411 should return a pointer to the same condition as given as argument.
4412
4413 @param keyno the index number to evaluate the condition on
4414 @param idx_cond the condition to be evaluated by the handler
4415
4416 @return The part of the pushed condition that the handler decides
4417 not to evaluate
4418 */
idx_cond_push(uint keyno,Item * idx_cond)4419 virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
4420
4421 /** Reset information about pushed index conditions */
cancel_pushed_idx_cond()4422 virtual void cancel_pushed_idx_cond()
4423 {
4424 pushed_idx_cond= NULL;
4425 pushed_idx_cond_keyno= MAX_KEY;
4426 in_range_check_pushed_down= false;
4427 }
4428
cancel_pushed_rowid_filter()4429 virtual void cancel_pushed_rowid_filter()
4430 {
4431 pushed_rowid_filter= NULL;
4432 rowid_filter_is_active= false;
4433 }
4434
disable_pushed_rowid_filter()4435 virtual void disable_pushed_rowid_filter()
4436 {
4437 DBUG_ASSERT(pushed_rowid_filter != NULL &&
4438 save_pushed_rowid_filter == NULL);
4439 save_pushed_rowid_filter= pushed_rowid_filter;
4440 if (rowid_filter_is_active)
4441 save_rowid_filter_is_active= rowid_filter_is_active;
4442 pushed_rowid_filter= NULL;
4443 rowid_filter_is_active= false;
4444 }
4445
enable_pushed_rowid_filter()4446 virtual void enable_pushed_rowid_filter()
4447 {
4448 DBUG_ASSERT(save_pushed_rowid_filter != NULL &&
4449 pushed_rowid_filter == NULL);
4450 pushed_rowid_filter= save_pushed_rowid_filter;
4451 if (save_rowid_filter_is_active)
4452 rowid_filter_is_active= true;
4453 save_pushed_rowid_filter= NULL;
4454 }
4455
rowid_filter_push(Rowid_filter * rowid_filter)4456 virtual bool rowid_filter_push(Rowid_filter *rowid_filter) { return true; }
4457
4458 /* Needed for partition / spider */
get_next_global_for_child()4459 virtual TABLE_LIST *get_next_global_for_child() { return NULL; }
4460
4461 /**
4462 Part of old, deprecated in-place ALTER API.
4463 */
check_if_incompatible_data(HA_CREATE_INFO * create_info,uint table_changes)4464 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
4465 uint table_changes)
4466 { return COMPATIBLE_DATA_NO; }
4467
4468 /* On-line/in-place ALTER TABLE interface. */
4469
4470 /*
4471 Here is an outline of on-line/in-place ALTER TABLE execution through
4472 this interface.
4473
4474 Phase 1 : Initialization
4475 ========================
4476 During this phase we determine which algorithm should be used
4477 for execution of ALTER TABLE and what level concurrency it will
4478 require.
4479
4480 *) This phase starts by opening the table and preparing description
4481 of the new version of the table.
4482 *) Then we check if it is impossible even in theory to carry out
4483 this ALTER TABLE using the in-place algorithm. For example, because
4484 we need to change storage engine or the user has explicitly requested
4485 usage of the "copy" algorithm.
4486 *) If in-place ALTER TABLE is theoretically possible, we continue
4487 by compiling differences between old and new versions of the table
4488 in the form of HA_ALTER_FLAGS bitmap. We also build a few
4489 auxiliary structures describing requested changes and store
4490 all these data in the Alter_inplace_info object.
4491 *) Then the handler::check_if_supported_inplace_alter() method is called
4492 in order to find if the storage engine can carry out changes requested
4493 by this ALTER TABLE using the in-place algorithm. To determine this,
4494 the engine can rely on data in HA_ALTER_FLAGS/Alter_inplace_info
4495 passed to it as well as on its own checks. If the in-place algorithm
4496 can be used for this ALTER TABLE, the level of required concurrency for
4497 its execution is also returned.
4498 If any errors occur during the handler call, ALTER TABLE is aborted
4499 and no further handler functions are called.
4500 *) Locking requirements of the in-place algorithm are compared to any
4501 concurrency requirements specified by user. If there is a conflict
4502 between them, we either switch to the copy algorithm or emit an error.
4503
4504 Phase 2 : Execution
4505 ===================
4506
4507 In this phase the operations are executed.
4508
4509 *) As the first step, we acquire a lock corresponding to the concurrency
4510 level which was returned by handler::check_if_supported_inplace_alter()
4511 and requested by the user. This lock is held for most of the
4512 duration of in-place ALTER (if HA_ALTER_INPLACE_COPY_LOCK
4513 or HA_ALTER_INPLACE_COPY_NO_LOCK were returned we acquire an
4514 exclusive lock for duration of the next step only).
4515 *) After that we call handler::ha_prepare_inplace_alter_table() to give the
4516 storage engine a chance to update its internal structures with a higher
4517 lock level than the one that will be used for the main step of algorithm.
4518 After that we downgrade the lock if it is necessary.
4519 *) After that, the main step of this phase and algorithm is executed.
4520 We call the handler::ha_inplace_alter_table() method, which carries out the
4521 changes requested by ALTER TABLE but does not makes them visible to other
4522 connections yet.
4523 *) We ensure that no other connection uses the table by upgrading our
4524 lock on it to exclusive.
4525 *) a) If the previous step succeeds, handler::ha_commit_inplace_alter_table() is
4526 called to allow the storage engine to do any final updates to its structures,
4527 to make all earlier changes durable and visible to other connections.
4528 b) If we have failed to upgrade lock or any errors have occurred during the
4529 handler functions calls (including commit), we call
4530 handler::ha_commit_inplace_alter_table()
4531 to rollback all changes which were done during previous steps.
4532
4533 Phase 3 : Final
4534 ===============
4535
4536 In this phase we:
4537
4538 *) Update SQL-layer data-dictionary by installing .FRM file for the new version
4539 of the table.
4540 *) Inform the storage engine about this change by calling the
4541 hton::notify_table_changed()
4542 *) Destroy the Alter_inplace_info and handler_ctx objects.
4543
4544 */
4545
4546 /**
4547 Check if a storage engine supports a particular alter table in-place
4548
4549 @param altered_table TABLE object for new version of table.
4550 @param ha_alter_info Structure describing changes to be done
4551 by ALTER TABLE and holding data used
4552 during in-place alter.
4553
4554 @retval HA_ALTER_ERROR Unexpected error.
4555 @retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported, must use copy.
4556 @retval HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
4557 @retval HA_ALTER_INPLACE_COPY_LOCK
4558 Supported, but requires SNW lock
4559 during main phase. Prepare phase
4560 requires X lock.
4561 @retval HA_ALTER_INPLACE_SHARED_LOCK Supported, but requires SNW lock.
4562 @retval HA_ALTER_INPLACE_COPY_NO_LOCK
4563 Supported, concurrent reads/writes
4564 allowed. However, prepare phase
4565 requires X lock.
4566 @retval HA_ALTER_INPLACE_NO_LOCK Supported, concurrent
4567 reads/writes allowed.
4568
4569 @note The default implementation uses the old in-place ALTER API
4570 to determine if the storage engine supports in-place ALTER or not.
4571
4572 @note Called without holding thr_lock.c lock.
4573 */
4574 virtual enum_alter_inplace_result
4575 check_if_supported_inplace_alter(TABLE *altered_table,
4576 Alter_inplace_info *ha_alter_info);
4577
4578
4579 /**
4580 Public functions wrapping the actual handler call.
4581 @see prepare_inplace_alter_table()
4582 */
4583 bool ha_prepare_inplace_alter_table(TABLE *altered_table,
4584 Alter_inplace_info *ha_alter_info);
4585
4586
4587 /**
4588 Public function wrapping the actual handler call.
4589 @see inplace_alter_table()
4590 */
ha_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)4591 bool ha_inplace_alter_table(TABLE *altered_table,
4592 Alter_inplace_info *ha_alter_info)
4593 {
4594 return inplace_alter_table(altered_table, ha_alter_info);
4595 }
4596
4597
4598 /**
4599 Public function wrapping the actual handler call.
4600 Allows us to enforce asserts regardless of handler implementation.
4601 @see commit_inplace_alter_table()
4602 */
4603 bool ha_commit_inplace_alter_table(TABLE *altered_table,
4604 Alter_inplace_info *ha_alter_info,
4605 bool commit);
4606
4607
4608 protected:
4609 /**
4610 Allows the storage engine to update internal structures with concurrent
4611 writes blocked. If check_if_supported_inplace_alter() returns
4612 HA_ALTER_INPLACE_COPY_NO_LOCK or HA_ALTER_INPLACE_COPY_LOCK,
4613 this function is called with exclusive lock otherwise the same level
4614 of locking as for inplace_alter_table() will be used.
4615
4616 @note Storage engines are responsible for reporting any errors by
4617 calling my_error()/print_error()
4618
4619 @note If this function reports error, commit_inplace_alter_table()
4620 will be called with commit= false.
4621
4622 @note For partitioning, failing to prepare one partition, means that
4623 commit_inplace_alter_table() will be called to roll back changes for
4624 all partitions. This means that commit_inplace_alter_table() might be
4625 called without prepare_inplace_alter_table() having been called first
4626 for a given partition.
4627
4628 @param altered_table TABLE object for new version of table.
4629 @param ha_alter_info Structure describing changes to be done
4630 by ALTER TABLE and holding data used
4631 during in-place alter.
4632
4633 @retval true Error
4634 @retval false Success
4635 */
prepare_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)4636 virtual bool prepare_inplace_alter_table(TABLE *altered_table,
4637 Alter_inplace_info *ha_alter_info)
4638 { return false; }
4639
4640
4641 /**
4642 Alter the table structure in-place with operations specified using HA_ALTER_FLAGS
4643 and Alter_inplace_info. The level of concurrency allowed during this
4644 operation depends on the return value from check_if_supported_inplace_alter().
4645
4646 @note Storage engines are responsible for reporting any errors by
4647 calling my_error()/print_error()
4648
4649 @note If this function reports error, commit_inplace_alter_table()
4650 will be called with commit= false.
4651
4652 @param altered_table TABLE object for new version of table.
4653 @param ha_alter_info Structure describing changes to be done
4654 by ALTER TABLE and holding data used
4655 during in-place alter.
4656
4657 @retval true Error
4658 @retval false Success
4659 */
inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info)4660 virtual bool inplace_alter_table(TABLE *altered_table,
4661 Alter_inplace_info *ha_alter_info)
4662 { return false; }
4663
4664
4665 /**
4666 Commit or rollback the changes made during prepare_inplace_alter_table()
4667 and inplace_alter_table() inside the storage engine.
4668 Note that in case of rollback the allowed level of concurrency during
4669 this operation will be the same as for inplace_alter_table() and thus
4670 might be higher than during prepare_inplace_alter_table(). (For example,
4671 concurrent writes were blocked during prepare, but might not be during
4672 rollback).
4673
4674 @note Storage engines are responsible for reporting any errors by
4675 calling my_error()/print_error()
4676
4677 @note If this function with commit= true reports error, it will be called
4678 again with commit= false.
4679
4680 @note In case of partitioning, this function might be called for rollback
4681 without prepare_inplace_alter_table() having been called first.
4682 Also partitioned tables sets ha_alter_info->group_commit_ctx to a NULL
4683 terminated array of the partitions handlers and if all of them are
4684 committed as one, then group_commit_ctx should be set to NULL to indicate
4685 to the partitioning handler that all partitions handlers are committed.
4686 @see prepare_inplace_alter_table().
4687
4688 @param altered_table TABLE object for new version of table.
4689 @param ha_alter_info Structure describing changes to be done
4690 by ALTER TABLE and holding data used
4691 during in-place alter.
4692 @param commit True => Commit, False => Rollback.
4693
4694 @retval true Error
4695 @retval false Success
4696 */
commit_inplace_alter_table(TABLE * altered_table,Alter_inplace_info * ha_alter_info,bool commit)4697 virtual bool commit_inplace_alter_table(TABLE *altered_table,
4698 Alter_inplace_info *ha_alter_info,
4699 bool commit)
4700 {
4701 /* Nothing to commit/rollback, mark all handlers committed! */
4702 ha_alter_info->group_commit_ctx= NULL;
4703 return false;
4704 }
4705
4706 public:
4707 /* End of On-line/in-place ALTER TABLE interface. */
4708
4709
4710 /**
4711 use_hidden_primary_key() is called in case of an update/delete when
4712 (table_flags() and HA_PRIMARY_KEY_REQUIRED_FOR_DELETE) is defined
4713 but we don't have a primary key
4714 */
4715 virtual void use_hidden_primary_key();
alter_table_flags(alter_table_operations flags)4716 virtual alter_table_operations alter_table_flags(alter_table_operations flags)
4717 {
4718 if (ht->alter_table_flags)
4719 return ht->alter_table_flags(flags);
4720 return 0;
4721 }
4722
4723 virtual LEX_CSTRING *engine_name();
4724
get_table()4725 TABLE* get_table() { return table; }
get_table_share()4726 TABLE_SHARE* get_table_share() { return table_share; }
4727 protected:
4728 /* Service methods for use by storage engines. */
4729 THD *ha_thd(void) const;
4730
4731 /**
4732 Acquire the instrumented table information from a table share.
4733 @return an instrumented table share, or NULL.
4734 */
4735 PSI_table_share *ha_table_share_psi() const;
4736
4737 /**
4738 Default rename_table() and delete_table() rename/delete files with a
4739 given name and extensions from bas_ext().
4740
4741 These methods can be overridden, but their default implementation
4742 provide useful functionality.
4743 */
4744 virtual int rename_table(const char *from, const char *to);
4745
4746
4747 public:
4748 /**
4749 Delete a table in the engine. Called for base as well as temporary
4750 tables.
4751 */
4752 virtual int delete_table(const char *name);
4753 bool check_table_binlog_row_based();
4754 bool prepare_for_row_logging();
4755 int prepare_for_insert(bool do_create);
4756 int binlog_log_row(TABLE *table,
4757 const uchar *before_record,
4758 const uchar *after_record,
4759 Log_func *log_func);
4760
clear_cached_table_binlog_row_based_flag()4761 inline void clear_cached_table_binlog_row_based_flag()
4762 {
4763 check_table_binlog_row_based_done= 0;
4764 }
4765 private:
4766 /* Cache result to avoid extra calls */
mark_trx_read_write()4767 inline void mark_trx_read_write()
4768 {
4769 if (unlikely(!mark_trx_read_write_done))
4770 {
4771 mark_trx_read_write_done= 1;
4772 mark_trx_read_write_internal();
4773 }
4774 }
4775
4776 private:
4777 void mark_trx_read_write_internal();
4778 bool check_table_binlog_row_based_internal();
4779
4780 int create_lookup_handler();
4781 void alloc_lookup_buffer();
4782 int check_duplicate_long_entries(const uchar *new_rec);
4783 int check_duplicate_long_entries_update(const uchar *new_rec);
4784 int check_duplicate_long_entry_key(const uchar *new_rec, uint key_no);
4785 /** PRIMARY KEY/UNIQUE WITHOUT OVERLAPS check */
4786 int ha_check_overlaps(const uchar *old_data, const uchar* new_data);
4787
4788 protected:
4789 /*
4790 These are intended to be used only by handler::ha_xxxx() functions
4791 However, engines that implement read_range_XXX() (like MariaRocks)
4792 or embed other engines (like ha_partition) may need to call these also
4793 */
4794 inline void increment_statistics(ulong SSV::*offset) const;
4795 inline void decrement_statistics(ulong SSV::*offset) const;
4796
4797 private:
4798 /*
4799 Low-level primitives for storage engines. These should be
4800 overridden by the storage engine class. To call these methods, use
4801 the corresponding 'ha_*' method above.
4802 */
4803
4804 virtual int open(const char *name, int mode, uint test_if_locked)=0;
4805 /* Note: ha_index_read_idx_map() may bypass index_init() */
index_init(uint idx,bool sorted)4806 virtual int index_init(uint idx, bool sorted) { return 0; }
index_end()4807 virtual int index_end() { return 0; }
4808 /**
4809 rnd_init() can be called two times without rnd_end() in between
4810 (it only makes sense if scan=1).
4811 then the second call should prepare for the new table scan (e.g
4812 if rnd_init allocates the cursor, second call should position it
4813 to the start of the table, no need to deallocate and allocate it again
4814 */
4815 virtual int rnd_init(bool scan)= 0;
rnd_end()4816 virtual int rnd_end() { return 0; }
write_row(const uchar * buf)4817 virtual int write_row(const uchar *buf __attribute__((unused)))
4818 {
4819 return HA_ERR_WRONG_COMMAND;
4820 }
4821
4822 /**
4823 Update a single row.
4824
4825 Note: If HA_ERR_FOUND_DUPP_KEY is returned, the handler must read
4826 all columns of the row so MySQL can create an error message. If
4827 the columns required for the error message are not read, the error
4828 message will contain garbage.
4829 */
update_row(const uchar * old_data,const uchar * new_data)4830 virtual int update_row(const uchar *old_data __attribute__((unused)),
4831 const uchar *new_data __attribute__((unused)))
4832 {
4833 return HA_ERR_WRONG_COMMAND;
4834 }
4835
4836 /*
4837 Optimized function for updating the first row. Only used by sequence
4838 tables
4839 */
4840 virtual int update_first_row(const uchar *new_data);
4841
delete_row(const uchar * buf)4842 virtual int delete_row(const uchar *buf __attribute__((unused)))
4843 {
4844 return HA_ERR_WRONG_COMMAND;
4845 }
4846
4847 /* Perform initialization for a direct update request */
4848 public:
4849 int ha_direct_update_rows(ha_rows *update_rows, ha_rows *found_rows);
direct_update_rows_init(List<Item> * update_fields)4850 virtual int direct_update_rows_init(List<Item> *update_fields)
4851 {
4852 return HA_ERR_WRONG_COMMAND;
4853 }
4854 private:
pre_direct_update_rows_init(List<Item> * update_fields)4855 virtual int pre_direct_update_rows_init(List<Item> *update_fields)
4856 {
4857 return HA_ERR_WRONG_COMMAND;
4858 }
direct_update_rows(ha_rows * update_rows,ha_rows * found_rows)4859 virtual int direct_update_rows(ha_rows *update_rows __attribute__((unused)),
4860 ha_rows *found_rows __attribute__((unused)))
4861 {
4862 return HA_ERR_WRONG_COMMAND;
4863 }
pre_direct_update_rows()4864 virtual int pre_direct_update_rows()
4865 {
4866 return HA_ERR_WRONG_COMMAND;
4867 }
4868
4869 /* Perform initialization for a direct delete request */
4870 public:
4871 int ha_direct_delete_rows(ha_rows *delete_rows);
direct_delete_rows_init()4872 virtual int direct_delete_rows_init()
4873 {
4874 return HA_ERR_WRONG_COMMAND;
4875 }
4876 private:
pre_direct_delete_rows_init()4877 virtual int pre_direct_delete_rows_init()
4878 {
4879 return HA_ERR_WRONG_COMMAND;
4880 }
direct_delete_rows(ha_rows * delete_rows)4881 virtual int direct_delete_rows(ha_rows *delete_rows __attribute__((unused)))
4882 {
4883 return HA_ERR_WRONG_COMMAND;
4884 }
pre_direct_delete_rows()4885 virtual int pre_direct_delete_rows()
4886 {
4887 return HA_ERR_WRONG_COMMAND;
4888 }
4889
4890 /**
4891 Reset state of file to after 'open'.
4892 This function is called after every statement for all tables used
4893 by that statement.
4894 */
reset()4895 virtual int reset() { return 0; }
4896 virtual Table_flags table_flags(void) const= 0;
4897 /**
4898 Is not invoked for non-transactional temporary tables.
4899
4900 Tells the storage engine that we intend to read or write data
4901 from the table. This call is prefixed with a call to handler::store_lock()
4902 and is invoked only for those handler instances that stored the lock.
4903
4904 Calls to rnd_init/index_init are prefixed with this call. When table
4905 IO is complete, we call external_lock(F_UNLCK).
4906 A storage engine writer should expect that each call to
4907 ::external_lock(F_[RD|WR]LOCK is followed by a call to
4908 ::external_lock(F_UNLCK). If it is not, it is a bug in MySQL.
4909
4910 The name and signature originate from the first implementation
4911 in MyISAM, which would call fcntl to set/clear an advisory
4912 lock on the data file in this method.
4913
4914 @param lock_type F_RDLCK, F_WRLCK, F_UNLCK
4915
4916 @return non-0 in case of failure, 0 in case of success.
4917 When lock_type is F_UNLCK, the return value is ignored.
4918 */
external_lock(THD * thd,int lock_type)4919 virtual int external_lock(THD *thd __attribute__((unused)),
4920 int lock_type __attribute__((unused)))
4921 {
4922 return 0;
4923 }
release_auto_increment()4924 virtual void release_auto_increment() { return; };
4925 /** admin commands - called from mysql_admin_table */
check_for_upgrade(HA_CHECK_OPT * check_opt)4926 virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
4927 { return 0; }
check(THD * thd,HA_CHECK_OPT * check_opt)4928 virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
4929 { return HA_ADMIN_NOT_IMPLEMENTED; }
4930
4931 /**
4932 In this method check_opt can be modified
4933 to specify CHECK option to use to call check()
4934 upon the table.
4935 */
repair(THD * thd,HA_CHECK_OPT * check_opt)4936 virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
4937 {
4938 DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR));
4939 return HA_ADMIN_NOT_IMPLEMENTED;
4940 }
4941 protected:
start_bulk_insert(ha_rows rows,uint flags)4942 virtual void start_bulk_insert(ha_rows rows, uint flags) {}
end_bulk_insert()4943 virtual int end_bulk_insert() { return 0; }
index_read(uchar * buf,const uchar * key,uint key_len,enum ha_rkey_function find_flag)4944 virtual int index_read(uchar * buf, const uchar * key, uint key_len,
4945 enum ha_rkey_function find_flag)
4946 { return HA_ERR_WRONG_COMMAND; }
index_read_last(uchar * buf,const uchar * key,uint key_len)4947 virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
4948 {
4949 my_errno= HA_ERR_WRONG_COMMAND;
4950 return HA_ERR_WRONG_COMMAND;
4951 }
4952 friend class ha_partition;
4953 friend class ha_sequence;
4954 public:
4955 /**
4956 This method is similar to update_row, however the handler doesn't need
4957 to execute the updates at this point in time. The handler can be certain
4958 that another call to bulk_update_row will occur OR a call to
4959 exec_bulk_update before the set of updates in this query is concluded.
4960
4961 @param old_data Old record
4962 @param new_data New record
4963 @param dup_key_found Number of duplicate keys found
4964
4965 @retval 0 Bulk delete used by handler
4966 @retval 1 Bulk delete not used, normal operation used
4967 */
bulk_update_row(const uchar * old_data,const uchar * new_data,ha_rows * dup_key_found)4968 virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
4969 ha_rows *dup_key_found)
4970 {
4971 DBUG_ASSERT(FALSE);
4972 return HA_ERR_WRONG_COMMAND;
4973 }
4974 /**
4975 This is called to delete all rows in a table
4976 If the handler don't support this, then this function will
4977 return HA_ERR_WRONG_COMMAND and MySQL will delete the rows one
4978 by one.
4979 */
delete_all_rows()4980 virtual int delete_all_rows()
4981 { return (my_errno=HA_ERR_WRONG_COMMAND); }
4982 /**
4983 Quickly remove all rows from a table.
4984
4985 @remark This method is responsible for implementing MySQL's TRUNCATE
4986 TABLE statement, which is a DDL operation. As such, a engine
4987 can bypass certain integrity checks and in some cases avoid
4988 fine-grained locking (e.g. row locks) which would normally be
4989 required for a DELETE statement.
4990
4991 @remark Typically, truncate is not used if it can result in integrity
4992 violation. For example, truncate is not used when a foreign
4993 key references the table, but it might be used if foreign key
4994 checks are disabled.
4995
4996 @remark Engine is responsible for resetting the auto-increment counter.
4997
4998 @remark The table is locked in exclusive mode.
4999 */
truncate()5000 virtual int truncate()
5001 {
5002 int error= delete_all_rows();
5003 return error ? error : reset_auto_increment(0);
5004 }
5005 /**
5006 Reset the auto-increment counter to the given value, i.e. the next row
5007 inserted will get the given value.
5008 */
reset_auto_increment(ulonglong value)5009 virtual int reset_auto_increment(ulonglong value)
5010 { return 0; }
optimize(THD * thd,HA_CHECK_OPT * check_opt)5011 virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
5012 { return HA_ADMIN_NOT_IMPLEMENTED; }
analyze(THD * thd,HA_CHECK_OPT * check_opt)5013 virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
5014 { return HA_ADMIN_NOT_IMPLEMENTED; }
check_and_repair(THD * thd)5015 virtual bool check_and_repair(THD *thd) { return TRUE; }
disable_indexes(uint mode)5016 virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
enable_indexes(uint mode)5017 virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
discard_or_import_tablespace(my_bool discard)5018 virtual int discard_or_import_tablespace(my_bool discard)
5019 { return (my_errno=HA_ERR_WRONG_COMMAND); }
5020 virtual void drop_table(const char *name);
5021 virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
5022
create_partitioning_metadata(const char * name,const char * old_name,chf_create_flags action_flag)5023 virtual int create_partitioning_metadata(const char *name,
5024 const char *old_name,
5025 chf_create_flags action_flag)
5026 { return FALSE; }
5027
change_partitions(HA_CREATE_INFO * create_info,const char * path,ulonglong * const copied,ulonglong * const deleted,const uchar * pack_frm_data,size_t pack_frm_len)5028 virtual int change_partitions(HA_CREATE_INFO *create_info,
5029 const char *path,
5030 ulonglong * const copied,
5031 ulonglong * const deleted,
5032 const uchar *pack_frm_data,
5033 size_t pack_frm_len)
5034 { return HA_ERR_WRONG_COMMAND; }
drop_partitions(const char * path)5035 virtual int drop_partitions(const char *path)
5036 { return HA_ERR_WRONG_COMMAND; }
rename_partitions(const char * path)5037 virtual int rename_partitions(const char *path)
5038 { return HA_ERR_WRONG_COMMAND; }
set_ha_share_ref(Handler_share ** arg_ha_share)5039 virtual bool set_ha_share_ref(Handler_share **arg_ha_share)
5040 {
5041 DBUG_ASSERT(!ha_share);
5042 DBUG_ASSERT(arg_ha_share);
5043 if (ha_share || !arg_ha_share)
5044 return true;
5045 ha_share= arg_ha_share;
5046 return false;
5047 }
set_table(TABLE * table_arg)5048 void set_table(TABLE* table_arg) { table= table_arg; }
get_lock_type()5049 int get_lock_type() const { return m_lock_type; }
5050 public:
5051 /* XXX to be removed, see ha_partition::partition_ht() */
partition_ht()5052 virtual handlerton *partition_ht() const
5053 { return ht; }
5054 inline int ha_write_tmp_row(uchar *buf);
5055 inline int ha_delete_tmp_row(uchar *buf);
5056 inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
5057
5058 virtual void set_lock_type(enum thr_lock_type lock);
5059 friend check_result_t handler_index_cond_check(void* h_arg);
5060 friend check_result_t handler_rowid_filter_check(void *h_arg);
5061
5062 /**
5063 Find unique record by index or unique constrain
5064
5065 @param record record to find (also will be fillded with
5066 actual record fields)
5067 @param unique_ref index or unique constraiun number (depends
5068 on what used in the engine
5069
5070 @retval -1 Error
5071 @retval 1 Not found
5072 @retval 0 Found
5073 */
find_unique_row(uchar * record,uint unique_ref)5074 virtual int find_unique_row(uchar *record, uint unique_ref)
5075 { return -1; /*unsupported */}
5076
native_versioned()5077 bool native_versioned() const
5078 { DBUG_ASSERT(ht); return partition_ht()->flags & HTON_NATIVE_SYS_VERSIONING; }
update_partition(uint part_id)5079 virtual void update_partition(uint part_id)
5080 {}
5081
5082 /**
5083 Some engines can perform column type conversion with ALGORITHM=INPLACE.
5084 These functions check for such possibility.
5085 Implementation could be based on Field_xxx::is_equal()
5086 */
can_convert_string(const Field_string * field,const Column_definition & new_type)5087 virtual bool can_convert_string(const Field_string *field,
5088 const Column_definition &new_type) const
5089 {
5090 return false;
5091 }
can_convert_varstring(const Field_varstring * field,const Column_definition & new_type)5092 virtual bool can_convert_varstring(const Field_varstring *field,
5093 const Column_definition &new_type) const
5094 {
5095 return false;
5096 }
can_convert_blob(const Field_blob * field,const Column_definition & new_type)5097 virtual bool can_convert_blob(const Field_blob *field,
5098 const Column_definition &new_type) const
5099 {
5100 return false;
5101 }
5102 /* If the table is using sql level unique constraints on some column */
5103 inline bool has_long_unique();
5104
5105 /* Used for ALTER TABLE.
5106 Some engines can handle some differences in indexes by themself. */
5107 virtual Compare_keys compare_key_parts(const Field &old_field,
5108 const Column_definition &new_field,
5109 const KEY_PART_INFO &old_part,
5110 const KEY_PART_INFO &new_part) const;
5111
5112 protected:
5113 Handler_share *get_ha_share_ptr();
5114 void set_ha_share_ptr(Handler_share *arg_ha_share);
5115 void lock_shared_ha_data();
5116 void unlock_shared_ha_data();
5117 };
5118
5119 #include "multi_range_read.h"
5120 #include "group_by_handler.h"
5121
5122 bool key_uses_partial_cols(TABLE_SHARE *table, uint keyno);
5123
5124 /* Some extern variables used with handlers */
5125
5126 extern const char *ha_row_type[];
5127 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[];
5128 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[];
5129 extern TYPELIB tx_isolation_typelib;
5130 extern const char *myisam_stats_method_names[];
5131 extern ulong total_ha, total_ha_2pc;
5132
5133 /* lookups */
5134 plugin_ref ha_resolve_by_name(THD *thd, const LEX_CSTRING *name, bool tmp_table);
5135 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
5136 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
5137 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
5138 handlerton *db_type);
5139 handlerton *ha_checktype(THD *thd, handlerton *hton, bool no_substitute);
5140
5141 static inline handlerton *ha_checktype(THD *thd, enum legacy_db_type type,
5142 bool no_substitute = 0)
5143 {
5144 return ha_checktype(thd, ha_resolve_by_legacy_type(thd, type), no_substitute);
5145 }
5146
ha_legacy_type(const handlerton * db_type)5147 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
5148 {
5149 return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type;
5150 }
5151
ha_resolve_storage_engine_name(const handlerton * db_type)5152 static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
5153 {
5154 return db_type == NULL ? "UNKNOWN" : hton_name(db_type)->str;
5155 }
5156
ha_check_storage_engine_flag(const handlerton * db_type,uint32 flag)5157 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
5158 {
5159 return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag);
5160 }
5161
ha_storage_engine_is_enabled(const handlerton * db_type)5162 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type)
5163 {
5164 return db_type && db_type->create;
5165 }
5166
5167 #define view_pseudo_hton ((handlerton *)1)
5168
5169 /* basic stuff */
5170 int ha_init_errors(void);
5171 int ha_init(void);
5172 int ha_end(void);
5173 int ha_initialize_handlerton(st_plugin_int *plugin);
5174 int ha_finalize_handlerton(st_plugin_int *plugin);
5175
5176 TYPELIB *ha_known_exts(void);
5177 int ha_panic(enum ha_panic_function flag);
5178 void ha_close_connection(THD* thd);
5179 void ha_kill_query(THD* thd, enum thd_kill_levels level);
5180 bool ha_flush_logs();
5181 void ha_drop_database(char* path);
5182 void ha_checkpoint_state(bool disable);
5183 void ha_commit_checkpoint_request(void *cookie, void (*pre_hook)(void *));
5184 int ha_create_table(THD *thd, const char *path,
5185 const char *db, const char *table_name,
5186 HA_CREATE_INFO *create_info, LEX_CUSTRING *frm);
5187 int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
5188 const LEX_CSTRING *db, const LEX_CSTRING *alias,
5189 bool generate_warning);
5190 int ha_delete_table_force(THD *thd, const char *path, const LEX_CSTRING *db,
5191 const LEX_CSTRING *alias);
5192
5193 void ha_prepare_for_backup();
5194 void ha_end_backup();
5195 void ha_pre_shutdown();
5196
5197 /* statistics and info */
5198 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
5199
5200 /* discovery */
5201 #ifdef MYSQL_SERVER
5202 class Discovered_table_list: public handlerton::discovered_list
5203 {
5204 THD *thd;
5205 const char *wild, *wend;
5206 bool with_temps; // whether to include temp tables in the result
5207 public:
5208 Dynamic_array<LEX_CSTRING*> *tables;
5209
5210 Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_CSTRING*> *tables_arg,
5211 const LEX_CSTRING *wild_arg);
Discovered_table_list(THD * thd_arg,Dynamic_array<LEX_CSTRING * > * tables_arg)5212 Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_CSTRING*> *tables_arg)
5213 : thd(thd_arg), wild(NULL), with_temps(true), tables(tables_arg) {}
~Discovered_table_list()5214 ~Discovered_table_list() {}
5215
5216 bool add_table(const char *tname, size_t tlen);
5217 bool add_file(const char *fname);
5218
5219 void sort();
5220 void remove_duplicates(); // assumes that the list is sorted
5221 #ifndef DBUG_OFF
5222 /*
5223 Used to find unstable mtr tests querying
5224 INFORMATION_SCHEMA.TABLES without ORDER BY.
5225 */
5226 void sort_desc();
5227 #endif /* DBUG_OFF */
5228 };
5229
5230 int ha_discover_table(THD *thd, TABLE_SHARE *share);
5231 int ha_discover_table_names(THD *thd, LEX_CSTRING *db, MY_DIR *dirp,
5232 Discovered_table_list *result, bool reusable);
5233 bool ha_table_exists(THD *thd, const LEX_CSTRING *db,
5234 const LEX_CSTRING *table_name,
5235 handlerton **hton= 0, bool *is_sequence= 0);
5236 bool ha_check_if_updates_are_ignored(THD *thd, handlerton *hton,
5237 const char *op);
5238 #endif /* MYSQL_SERVER */
5239
5240 /* key cache */
5241 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache, void *);
5242 int ha_resize_key_cache(KEY_CACHE *key_cache);
5243 int ha_change_key_cache_param(KEY_CACHE *key_cache);
5244 int ha_repartition_key_cache(KEY_CACHE *key_cache);
5245 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
5246
5247 /* transactions: interface to handlerton functions */
5248 int ha_start_consistent_snapshot(THD *thd);
5249 int ha_commit_or_rollback_by_xid(XID *xid, bool commit);
5250 int ha_commit_one_phase(THD *thd, bool all);
5251 int ha_commit_trans(THD *thd, bool all);
5252 int ha_rollback_trans(THD *thd, bool all);
5253 int ha_prepare(THD *thd);
5254 int ha_recover(HASH *commit_list);
5255
5256 /* transactions: these functions never call handlerton functions directly */
5257 int ha_enable_transaction(THD *thd, bool on);
5258
5259 /* savepoints */
5260 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv);
5261 bool ha_rollback_to_savepoint_can_release_mdl(THD *thd);
5262 int ha_savepoint(THD *thd, SAVEPOINT *sv);
5263 int ha_release_savepoint(THD *thd, SAVEPOINT *sv);
5264 #ifdef WITH_WSREP
5265 int ha_abort_transaction(THD *bf_thd, THD *victim_thd, my_bool signal);
5266 #endif
5267
5268 /* these are called by storage engines */
5269 void trans_register_ha(THD *thd, bool all, handlerton *ht,
5270 ulonglong trxid);
5271
5272 /*
5273 Storage engine has to assume the transaction will end up with 2pc if
5274 - there is more than one 2pc-capable storage engine available
5275 - in the current transaction 2pc was not disabled yet
5276 */
5277 #define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \
5278 !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc))
5279
5280 const char *get_canonical_filename(handler *file, const char *path,
5281 char *tmp_path);
5282 void commit_checkpoint_notify_ha(void *cookie);
5283
table_case_name(HA_CREATE_INFO * info,const LEX_CSTRING * name)5284 inline const LEX_CSTRING *table_case_name(HA_CREATE_INFO *info, const LEX_CSTRING *name)
5285 {
5286 return ((lower_case_table_names == 2 && info->alias.str) ? &info->alias : name);
5287 }
5288
5289 typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
5290 int binlog_log_row(TABLE* table,
5291 const uchar *before_record,
5292 const uchar *after_record,
5293 Log_func *log_func);
5294
5295 /**
5296 @def MYSQL_TABLE_IO_WAIT
5297 Instrumentation helper for table io_waits.
5298 Note that this helper is intended to be used from
5299 within the handler class only, as it uses members
5300 from @c handler
5301 Performance schema events are instrumented as follows:
5302 - in non batch mode, one event is generated per call
5303 - in batch mode, the number of rows affected is saved
5304 in @c m_psi_numrows, so that @c end_psi_batch_mode()
5305 generates a single event for the batch.
5306 @param OP the table operation to be performed
5307 @param INDEX the table index used if any, or MAX_KEY.
5308 @param PAYLOAD instrumented code to execute
5309 @sa handler::end_psi_batch_mode.
5310 */
5311 #ifdef HAVE_PSI_TABLE_INTERFACE
5312 #define MYSQL_TABLE_IO_WAIT(OP, INDEX, RESULT, PAYLOAD) \
5313 { \
5314 if (m_psi != NULL) \
5315 { \
5316 switch (m_psi_batch_mode) \
5317 { \
5318 case PSI_BATCH_MODE_NONE: \
5319 { \
5320 PSI_table_locker *sub_locker= NULL; \
5321 PSI_table_locker_state reentrant_safe_state; \
5322 sub_locker= PSI_TABLE_CALL(start_table_io_wait) \
5323 (& reentrant_safe_state, m_psi, OP, INDEX, \
5324 __FILE__, __LINE__); \
5325 PAYLOAD \
5326 if (sub_locker != NULL) \
5327 PSI_TABLE_CALL(end_table_io_wait) \
5328 (sub_locker, 1); \
5329 break; \
5330 } \
5331 case PSI_BATCH_MODE_STARTING: \
5332 { \
5333 m_psi_locker= PSI_TABLE_CALL(start_table_io_wait) \
5334 (& m_psi_locker_state, m_psi, OP, INDEX, \
5335 __FILE__, __LINE__); \
5336 PAYLOAD \
5337 if (!RESULT) \
5338 m_psi_numrows++; \
5339 m_psi_batch_mode= PSI_BATCH_MODE_STARTED; \
5340 break; \
5341 } \
5342 case PSI_BATCH_MODE_STARTED: \
5343 default: \
5344 { \
5345 DBUG_ASSERT(m_psi_batch_mode \
5346 == PSI_BATCH_MODE_STARTED); \
5347 PAYLOAD \
5348 if (!RESULT) \
5349 m_psi_numrows++; \
5350 break; \
5351 } \
5352 } \
5353 } \
5354 else \
5355 { \
5356 PAYLOAD \
5357 } \
5358 }
5359 #else
5360 #define MYSQL_TABLE_IO_WAIT(OP, INDEX, RESULT, PAYLOAD) \
5361 PAYLOAD
5362 #endif
5363
5364 #define TABLE_IO_WAIT(TRACKER, OP, INDEX, RESULT, PAYLOAD) \
5365 { \
5366 Exec_time_tracker *this_tracker; \
5367 if (unlikely((this_tracker= tracker))) \
5368 tracker->start_tracking(table->in_use); \
5369 \
5370 MYSQL_TABLE_IO_WAIT(OP, INDEX, RESULT, PAYLOAD); \
5371 \
5372 if (unlikely(this_tracker)) \
5373 tracker->stop_tracking(table->in_use); \
5374 }
5375 void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag);
5376 void print_keydup_error(TABLE *table, KEY *key, myf errflag);
5377
5378 int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info);
5379 int del_global_table_stat(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table);
5380 uint ha_count_rw_all(THD *thd, Ha_trx_info **ptr_ha_info);
5381 bool non_existing_table_error(int error);
5382 #endif /* HANDLER_INCLUDED */
5383