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