My Project
|
00001 #ifndef HANDLER_INCLUDED 00002 #define HANDLER_INCLUDED 00003 00004 /* 00005 Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. 00006 00007 This program is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU General Public License 00009 as published by the Free Software Foundation; version 2 of 00010 the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program; if not, write to the Free Software 00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 /* Definitions for parameters to do with handler-routines */ 00023 00024 #include "my_pthread.h" 00025 #include <algorithm> 00026 #include "sql_const.h" 00027 #include "mysqld.h" /* server_id */ 00028 #include "sql_plugin.h" /* plugin_ref, st_plugin_int, plugin */ 00029 #include "thr_lock.h" /* thr_lock_type, THR_LOCK_DATA */ 00030 #include "sql_cache.h" 00031 #include "structs.h" /* SHOW_COMP_OPTION */ 00032 00033 #include <my_global.h> 00034 #include <my_compare.h> 00035 #include <ft_global.h> 00036 #include <keycache.h> 00037 00038 class Alter_info; 00039 00040 // the following is for checking tables 00041 00042 #define HA_ADMIN_ALREADY_DONE 1 00043 #define HA_ADMIN_OK 0 00044 #define HA_ADMIN_NOT_IMPLEMENTED -1 00045 #define HA_ADMIN_FAILED -2 00046 #define HA_ADMIN_CORRUPT -3 00047 #define HA_ADMIN_INTERNAL_ERROR -4 00048 #define HA_ADMIN_INVALID -5 00049 #define HA_ADMIN_REJECT -6 00050 #define HA_ADMIN_TRY_ALTER -7 00051 #define HA_ADMIN_WRONG_CHECKSUM -8 00052 #define HA_ADMIN_NOT_BASE_TABLE -9 00053 #define HA_ADMIN_NEEDS_UPGRADE -10 00054 #define HA_ADMIN_NEEDS_ALTER -11 00055 #define HA_ADMIN_NEEDS_CHECK -12 00056 00063 enum enum_alter_inplace_result { 00064 HA_ALTER_ERROR, 00065 HA_ALTER_INPLACE_NOT_SUPPORTED, 00066 HA_ALTER_INPLACE_EXCLUSIVE_LOCK, 00067 HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE, 00068 HA_ALTER_INPLACE_SHARED_LOCK, 00069 HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE, 00070 HA_ALTER_INPLACE_NO_LOCK 00071 }; 00072 00073 /* Bits in table_flags() to show what database can do */ 00074 00075 #define HA_NO_TRANSACTIONS (1 << 0) /* Doesn't support transactions */ 00076 #define HA_PARTIAL_COLUMN_READ (1 << 1) /* read may not return all columns */ 00077 #define HA_TABLE_SCAN_ON_INDEX (1 << 2) /* No separate data/index file */ 00078 /* 00079 The following should be set if the following is not true when scanning 00080 a table with rnd_next() 00081 - We will see all rows (including deleted ones) 00082 - Row positions are 'table->s->db_record_offset' apart 00083 If this flag is not set, filesort will do a position() call for each matched 00084 row to be able to find the row later. 00085 */ 00086 #define HA_REC_NOT_IN_SEQ (1 << 3) 00087 #define HA_CAN_GEOMETRY (1 << 4) 00088 /* 00089 Reading keys in random order is as fast as reading keys in sort order 00090 (Used in records.cc to decide if we should use a record cache and by 00091 filesort to decide if we should sort key + data or key + pointer-to-row 00092 */ 00093 #define HA_FAST_KEY_READ (1 << 5) 00094 /* 00095 Set the following flag if we on delete should force all key to be read 00096 and on update read all keys that changes 00097 */ 00098 #define HA_REQUIRES_KEY_COLUMNS_FOR_DELETE (1 << 6) 00099 #define HA_NULL_IN_KEY (1 << 7) /* One can have keys with NULL */ 00100 #define HA_DUPLICATE_POS (1 << 8) /* position() gives dup row */ 00101 #define HA_NO_BLOBS (1 << 9) /* Doesn't support blobs */ 00102 #define HA_CAN_INDEX_BLOBS (1 << 10) 00103 #define HA_AUTO_PART_KEY (1 << 11) /* auto-increment in multi-part key */ 00104 #define HA_REQUIRE_PRIMARY_KEY (1 << 12) /* .. and can't create a hidden one */ 00105 #define HA_STATS_RECORDS_IS_EXACT (1 << 13) /* stats.records is exact */ 00106 /* 00107 INSERT_DELAYED only works with handlers that uses MySQL internal table 00108 level locks 00109 */ 00110 #define HA_CAN_INSERT_DELAYED (1 << 14) 00111 /* 00112 If we get the primary key columns for free when we do an index read 00113 (usually, it also implies that HA_PRIMARY_KEY_REQUIRED_FOR_POSITION 00114 flag is set). 00115 */ 00116 #define HA_PRIMARY_KEY_IN_READ_INDEX (1 << 15) 00117 /* 00118 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, it means that to position() 00119 uses a primary key given by the record argument. 00120 Without primary key, we can't call position(). 00121 If not set, the position is returned as the current rows position 00122 regardless of what argument is given. 00123 */ 00124 #define HA_PRIMARY_KEY_REQUIRED_FOR_POSITION (1 << 16) 00125 #define HA_CAN_RTREEKEYS (1 << 17) 00126 #define HA_NOT_DELETE_WITH_CACHE (1 << 18) 00127 /* 00128 The following is we need to a primary key to delete (and update) a row. 00129 If there is no primary key, all columns needs to be read on update and delete 00130 */ 00131 #define HA_PRIMARY_KEY_REQUIRED_FOR_DELETE (1 << 19) 00132 #define HA_NO_PREFIX_CHAR_KEYS (1 << 20) 00133 #define HA_CAN_FULLTEXT (1 << 21) 00134 #define HA_CAN_SQL_HANDLER (1 << 22) 00135 #define HA_NO_AUTO_INCREMENT (1 << 23) 00136 #define HA_HAS_CHECKSUM (1 << 24) 00137 /* Table data are stored in separate files (for lower_case_table_names) */ 00138 #define HA_FILE_BASED (1 << 26) 00139 #define HA_NO_VARCHAR (1 << 27) 00140 #define HA_CAN_BIT_FIELD (1 << 28) /* supports bit fields */ 00141 #define HA_ANY_INDEX_MAY_BE_UNIQUE (1 << 30) 00142 #define HA_NO_COPY_ON_ALTER (LL(1) << 31) 00143 #define HA_HAS_RECORDS (LL(1) << 32) /* records() gives exact count*/ 00144 /* Has it's own method of binlog logging */ 00145 #define HA_HAS_OWN_BINLOGGING (LL(1) << 33) 00146 /* 00147 Engine is capable of row-format and statement-format logging, 00148 respectively 00149 */ 00150 #define HA_BINLOG_ROW_CAPABLE (LL(1) << 34) 00151 #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) 00152 /* 00153 When a multiple key conflict happens in a REPLACE command mysql 00154 expects the conflicts to be reported in the ascending order of 00155 key names. 00156 00157 For e.g. 00158 00159 CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT 00160 NULL, INDEX(c)); 00161 00162 REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3); 00163 00164 MySQL expects the conflict with 'a' to be reported before the conflict with 00165 'b'. 00166 00167 If the underlying storage engine does not report the conflicting keys in 00168 ascending order, it causes unexpected errors when the REPLACE command is 00169 executed. 00170 00171 This flag helps the underlying SE to inform the server that the keys are not 00172 ordered. 00173 */ 00174 #define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36) 00175 /* 00176 Engine supports REPAIR TABLE. Used by CHECK TABLE FOR UPGRADE if an 00177 incompatible table is detected. If this flag is set, CHECK TABLE FOR UPGRADE 00178 will report ER_TABLE_NEEDS_UPGRADE, otherwise ER_TABLE_NEED_REBUILD. 00179 */ 00180 #define HA_CAN_REPAIR (LL(1) << 37) 00181 00182 /* 00183 Set of all binlog flags. Currently only contain the capabilities 00184 flags. 00185 */ 00186 #define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE) 00187 00220 #define HA_READ_BEFORE_WRITE_REMOVAL (LL(1) << 38) 00221 00222 /* 00223 Engine supports extended fulltext API 00224 */ 00225 #define HA_CAN_FULLTEXT_EXT (LL(1) << 39) 00226 00227 /* 00228 Storage engine doesn't synchronize result set with expected table contents. 00229 Used by replication slave to check if it is possible to retrieve rows from 00230 the table when deciding whether to do a full table scan, index scan or hash 00231 scan while applying a row event. 00232 */ 00233 #define HA_READ_OUT_OF_SYNC (LL(1) << 40) 00234 00235 /* 00236 Storage engine supports table export using the 00237 FLUSH TABLE <table_list> FOR EXPORT statement. 00238 */ 00239 #define HA_CAN_EXPORT (LL(1) << 41) 00240 00241 /* 00242 The handler don't want accesses to this table to 00243 be const-table optimized 00244 */ 00245 #define HA_BLOCK_CONST_TABLE (LL(1) << 42) 00246 00247 /* bits in index_flags(index_number) for what you can do with index */ 00248 #define HA_READ_NEXT 1 /* TODO really use this flag */ 00249 #define HA_READ_PREV 2 /* supports ::index_prev */ 00250 #define HA_READ_ORDER 4 /* index_next/prev follow sort order */ 00251 #define HA_READ_RANGE 8 /* can find all records in a range */ 00252 #define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */ 00253 #define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */ 00254 /* 00255 Index scan will not return records in rowid order. Not guaranteed to be 00256 set for unordered (e.g. HASH) indexes. 00257 */ 00258 #define HA_KEY_SCAN_NOT_ROR 128 00259 #define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */ 00260 00261 00262 00290 #define HA_PARTITION_FUNCTION_SUPPORTED (1L << 0) 00291 #define HA_FAST_CHANGE_PARTITION (1L << 1) 00292 #define HA_PARTITION_ONE_PHASE (1L << 2) 00293 00294 /* operations for disable/enable indexes */ 00295 #define HA_KEY_SWITCH_NONUNIQ 0 00296 #define HA_KEY_SWITCH_ALL 1 00297 #define HA_KEY_SWITCH_NONUNIQ_SAVE 2 00298 #define HA_KEY_SWITCH_ALL_SAVE 3 00299 00300 /* 00301 Note: the following includes binlog and closing 0. 00302 so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive + 00303 example + csv + heap + blackhole + federated + 0 00304 (yes, the sum is deliberately inaccurate) 00305 TODO remove the limit, use dynarrays 00306 */ 00307 #define MAX_HA 15 00308 00309 /* 00310 Use this instead of 0 as the initial value for the slot number of 00311 handlerton, so that we can distinguish uninitialized slot number 00312 from slot 0. 00313 */ 00314 #define HA_SLOT_UNDEF ((uint)-1) 00315 00316 /* 00317 Parameters for open() (in register form->filestat) 00318 HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED 00319 */ 00320 00321 #define HA_OPEN_KEYFILE 1 00322 #define HA_OPEN_RNDFILE 2 00323 #define HA_GET_INDEX 4 00324 #define HA_GET_INFO 8 /* do a ha_info() after open */ 00325 #define HA_READ_ONLY 16 /* File opened as readonly */ 00326 /* Try readonly if can't open with read and write */ 00327 #define HA_TRY_READ_ONLY 32 00328 #define HA_WAIT_IF_LOCKED 64 /* Wait if locked on open */ 00329 #define HA_ABORT_IF_LOCKED 128 /* skip if locked on open.*/ 00330 #define HA_BLOCK_LOCK 256 /* unlock when reading some records */ 00331 #define HA_OPEN_TEMPORARY 512 00332 00333 /* Some key definitions */ 00334 #define HA_KEY_NULL_LENGTH 1 00335 #define HA_KEY_BLOB_LENGTH 2 00336 00337 #define HA_LEX_CREATE_TMP_TABLE 1 00338 #define HA_LEX_CREATE_IF_NOT_EXISTS 2 00339 #define HA_LEX_CREATE_TABLE_LIKE 4 00340 #define HA_OPTION_NO_CHECKSUM (1L << 17) 00341 #define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18) 00342 #define HA_MAX_REC_LENGTH 65535U 00343 00344 /* Table caching type */ 00345 #define HA_CACHE_TBL_NONTRANSACT 0 00346 #define HA_CACHE_TBL_NOCACHE 1 00347 #define HA_CACHE_TBL_ASKTRANSACT 2 00348 #define HA_CACHE_TBL_TRANSACT 4 00349 00362 // WITH CONSISTENT SNAPSHOT option 00363 static const uint MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT = 1; 00364 // READ ONLY option 00365 static const uint MYSQL_START_TRANS_OPT_READ_ONLY = 2; 00366 // READ WRITE option 00367 static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4; 00368 00369 /* Flags for method is_fatal_error */ 00370 #define HA_CHECK_DUP_KEY 1 00371 #define HA_CHECK_DUP_UNIQUE 2 00372 #define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE) 00373 00374 enum legacy_db_type 00375 { 00376 DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, 00377 DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM, 00378 DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM, 00379 DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM, 00380 DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, 00381 DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER, 00382 DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB, 00383 DB_TYPE_FEDERATED_DB, 00384 DB_TYPE_BLACKHOLE_DB, 00385 DB_TYPE_PARTITION_DB, 00386 DB_TYPE_BINLOG, 00387 DB_TYPE_SOLID, 00388 DB_TYPE_PBXT, 00389 DB_TYPE_TABLE_FUNCTION, 00390 DB_TYPE_MEMCACHE, 00391 DB_TYPE_FALCON, 00392 DB_TYPE_MARIA, 00394 DB_TYPE_PERFORMANCE_SCHEMA, 00395 DB_TYPE_FIRST_DYNAMIC=42, 00396 DB_TYPE_DEFAULT=127 // Must be last 00397 }; 00398 00399 enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, 00400 ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED, 00401 ROW_TYPE_REDUNDANT, ROW_TYPE_COMPACT, 00403 ROW_TYPE_PAGE }; 00404 00405 /* Specifies data storage format for individual columns */ 00406 enum column_format_type { 00407 COLUMN_FORMAT_TYPE_DEFAULT= 0, /* Not specified (use engine default) */ 00408 COLUMN_FORMAT_TYPE_FIXED= 1, /* FIXED format */ 00409 COLUMN_FORMAT_TYPE_DYNAMIC= 2 /* DYNAMIC format */ 00410 }; 00411 00412 enum enum_binlog_func { 00413 BFN_RESET_LOGS= 1, 00414 BFN_RESET_SLAVE= 2, 00415 BFN_BINLOG_WAIT= 3, 00416 BFN_BINLOG_END= 4, 00417 BFN_BINLOG_PURGE_FILE= 5 00418 }; 00419 00420 enum enum_binlog_command { 00421 LOGCOM_CREATE_TABLE, 00422 LOGCOM_ALTER_TABLE, 00423 LOGCOM_RENAME_TABLE, 00424 LOGCOM_DROP_TABLE, 00425 LOGCOM_CREATE_DB, 00426 LOGCOM_ALTER_DB, 00427 LOGCOM_DROP_DB 00428 }; 00429 00430 /* struct to hold information about the table that should be created */ 00431 00432 /* Bits in used_fields */ 00433 #define HA_CREATE_USED_AUTO (1L << 0) 00434 #define HA_CREATE_USED_RAID (1L << 1) //RAID is no longer availble 00435 #define HA_CREATE_USED_UNION (1L << 2) 00436 #define HA_CREATE_USED_INSERT_METHOD (1L << 3) 00437 #define HA_CREATE_USED_MIN_ROWS (1L << 4) 00438 #define HA_CREATE_USED_MAX_ROWS (1L << 5) 00439 #define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6) 00440 #define HA_CREATE_USED_PACK_KEYS (1L << 7) 00441 #define HA_CREATE_USED_CHARSET (1L << 8) 00442 #define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9) 00443 #define HA_CREATE_USED_DATADIR (1L << 10) 00444 #define HA_CREATE_USED_INDEXDIR (1L << 11) 00445 #define HA_CREATE_USED_ENGINE (1L << 12) 00446 #define HA_CREATE_USED_CHECKSUM (1L << 13) 00447 #define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14) 00448 #define HA_CREATE_USED_ROW_FORMAT (1L << 15) 00449 #define HA_CREATE_USED_COMMENT (1L << 16) 00450 #define HA_CREATE_USED_PASSWORD (1L << 17) 00451 #define HA_CREATE_USED_CONNECTION (1L << 18) 00452 #define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19) 00453 00454 #define HA_CREATE_USED_TRANSACTIONAL (1L << 20) 00455 00456 #define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21) 00457 00462 #define HA_CREATE_USED_STATS_PERSISTENT (1L << 22) 00463 00469 #define HA_CREATE_USED_STATS_AUTO_RECALC (1L << 23) 00470 00476 #define HA_CREATE_USED_STATS_SAMPLE_PAGES (1L << 24) 00477 00478 00479 /* 00480 This is master database for most of system tables. However there 00481 can be other databases which can hold system tables. Respective 00482 storage engines define their own system database names. 00483 */ 00484 extern const char *mysqld_system_database; 00485 00486 /* 00487 Structure to hold list of system_database.system_table. 00488 This is used at both mysqld and storage engine layer. 00489 */ 00490 struct st_system_tablename 00491 { 00492 const char *db; 00493 const char *tablename; 00494 }; 00495 00496 00497 typedef ulonglong my_xid; // this line is the same as in log_event.h 00498 #define MYSQL_XID_PREFIX "MySQLXid" 00499 #define MYSQL_XID_PREFIX_LEN 8 // must be a multiple of 8 00500 #define MYSQL_XID_OFFSET (MYSQL_XID_PREFIX_LEN+sizeof(server_id)) 00501 #define MYSQL_XID_GTRID_LEN (MYSQL_XID_OFFSET+sizeof(my_xid)) 00502 00503 #define XIDDATASIZE MYSQL_XIDDATASIZE 00504 #define MAXGTRIDSIZE 64 00505 #define MAXBQUALSIZE 64 00506 00507 #define COMPATIBLE_DATA_YES 0 00508 #define COMPATIBLE_DATA_NO 1 00509 00510 namespace AQP { 00511 class Join_plan; 00512 }; 00513 00522 struct xid_t { 00523 long formatID; 00524 long gtrid_length; 00525 long bqual_length; 00526 char data[XIDDATASIZE]; // not \0-terminated ! 00527 00528 xid_t() {} /* Remove gcc warning */ 00529 bool eq(struct xid_t *xid) 00530 { return eq(xid->gtrid_length, xid->bqual_length, xid->data); } 00531 bool eq(long g, long b, const char *d) 00532 { return g == gtrid_length && b == bqual_length && !memcmp(d, data, g+b); } 00533 void set(struct xid_t *xid) 00534 { memcpy(this, xid, xid->length()); } 00535 void set(long f, const char *g, long gl, const char *b, long bl) 00536 { 00537 formatID= f; 00538 memcpy(data, g, gtrid_length= gl); 00539 memcpy(data+gl, b, bqual_length= bl); 00540 } 00541 void set(ulonglong xid) 00542 { 00543 my_xid tmp; 00544 formatID= 1; 00545 set(MYSQL_XID_PREFIX_LEN, 0, MYSQL_XID_PREFIX); 00546 memcpy(data+MYSQL_XID_PREFIX_LEN, &server_id, sizeof(server_id)); 00547 tmp= xid; 00548 memcpy(data+MYSQL_XID_OFFSET, &tmp, sizeof(tmp)); 00549 gtrid_length=MYSQL_XID_GTRID_LEN; 00550 } 00551 void set(long g, long b, const char *d) 00552 { 00553 formatID= 1; 00554 gtrid_length= g; 00555 bqual_length= b; 00556 memcpy(data, d, g+b); 00557 } 00558 bool is_null() { return formatID == -1; } 00559 void null() { formatID= -1; } 00560 my_xid quick_get_my_xid() 00561 { 00562 my_xid tmp; 00563 memcpy(&tmp, data+MYSQL_XID_OFFSET, sizeof(tmp)); 00564 return tmp; 00565 } 00566 my_xid get_my_xid() 00567 { 00568 return gtrid_length == MYSQL_XID_GTRID_LEN && bqual_length == 0 && 00569 !memcmp(data, MYSQL_XID_PREFIX, MYSQL_XID_PREFIX_LEN) ? 00570 quick_get_my_xid() : 0; 00571 } 00572 uint length() 00573 { 00574 return sizeof(formatID)+sizeof(gtrid_length)+sizeof(bqual_length)+ 00575 gtrid_length+bqual_length; 00576 } 00577 uchar *key() 00578 { 00579 return (uchar *)>rid_length; 00580 } 00581 uint key_length() 00582 { 00583 return sizeof(gtrid_length)+sizeof(bqual_length)+gtrid_length+bqual_length; 00584 } 00585 }; 00586 typedef struct xid_t XID; 00587 00588 /* for recover() handlerton call */ 00589 #define MIN_XID_LIST_SIZE 128 00590 #define MAX_XID_LIST_SIZE (1024*128) 00591 00592 /* 00593 These structures are used to pass information from a set of SQL commands 00594 on add/drop/change tablespace definitions to the proper hton. 00595 */ 00596 #define UNDEF_NODEGROUP 65535 00597 enum ts_command_type 00598 { 00599 TS_CMD_NOT_DEFINED = -1, 00600 CREATE_TABLESPACE = 0, 00601 ALTER_TABLESPACE = 1, 00602 CREATE_LOGFILE_GROUP = 2, 00603 ALTER_LOGFILE_GROUP = 3, 00604 DROP_TABLESPACE = 4, 00605 DROP_LOGFILE_GROUP = 5, 00606 CHANGE_FILE_TABLESPACE = 6, 00607 ALTER_ACCESS_MODE_TABLESPACE = 7 00608 }; 00609 00610 enum ts_alter_tablespace_type 00611 { 00612 TS_ALTER_TABLESPACE_TYPE_NOT_DEFINED = -1, 00613 ALTER_TABLESPACE_ADD_FILE = 1, 00614 ALTER_TABLESPACE_DROP_FILE = 2 00615 }; 00616 00617 enum tablespace_access_mode 00618 { 00619 TS_NOT_DEFINED= -1, 00620 TS_READ_ONLY = 0, 00621 TS_READ_WRITE = 1, 00622 TS_NOT_ACCESSIBLE = 2 00623 }; 00624 00625 struct handlerton; 00626 class st_alter_tablespace : public Sql_alloc 00627 { 00628 public: 00629 const char *tablespace_name; 00630 const char *logfile_group_name; 00631 enum ts_command_type ts_cmd_type; 00632 enum ts_alter_tablespace_type ts_alter_tablespace_type; 00633 const char *data_file_name; 00634 const char *undo_file_name; 00635 const char *redo_file_name; 00636 ulonglong extent_size; 00637 ulonglong undo_buffer_size; 00638 ulonglong redo_buffer_size; 00639 ulonglong initial_size; 00640 ulonglong autoextend_size; 00641 ulonglong max_size; 00642 uint nodegroup_id; 00643 handlerton *storage_engine; 00644 bool wait_until_completed; 00645 const char *ts_comment; 00646 enum tablespace_access_mode ts_access_mode; 00647 st_alter_tablespace() 00648 { 00649 tablespace_name= NULL; 00650 logfile_group_name= "DEFAULT_LG"; //Default log file group 00651 ts_cmd_type= TS_CMD_NOT_DEFINED; 00652 data_file_name= NULL; 00653 undo_file_name= NULL; 00654 redo_file_name= NULL; 00655 extent_size= 1024*1024; //Default 1 MByte 00656 undo_buffer_size= 8*1024*1024; //Default 8 MByte 00657 redo_buffer_size= 8*1024*1024; //Default 8 MByte 00658 initial_size= 128*1024*1024; //Default 128 MByte 00659 autoextend_size= 0; //No autoextension as default 00660 max_size= 0; //Max size == initial size => no extension 00661 storage_engine= NULL; 00662 nodegroup_id= UNDEF_NODEGROUP; 00663 wait_until_completed= TRUE; 00664 ts_comment= NULL; 00665 ts_access_mode= TS_NOT_DEFINED; 00666 } 00667 }; 00668 00669 /* The handler for a table type. Will be included in the TABLE structure */ 00670 00671 struct TABLE; 00672 00673 /* 00674 Make sure that the order of schema_tables and enum_schema_tables are the same. 00675 */ 00676 enum enum_schema_tables 00677 { 00678 SCH_CHARSETS= 0, 00679 SCH_COLLATIONS, 00680 SCH_COLLATION_CHARACTER_SET_APPLICABILITY, 00681 SCH_COLUMNS, 00682 SCH_COLUMN_PRIVILEGES, 00683 SCH_ENGINES, 00684 SCH_EVENTS, 00685 SCH_FILES, 00686 SCH_GLOBAL_STATUS, 00687 SCH_GLOBAL_VARIABLES, 00688 SCH_KEY_COLUMN_USAGE, 00689 SCH_OPEN_TABLES, 00690 SCH_OPTIMIZER_TRACE, 00691 SCH_PARAMETERS, 00692 SCH_PARTITIONS, 00693 SCH_PLUGINS, 00694 SCH_PROCESSLIST, 00695 SCH_PROFILES, 00696 SCH_REFERENTIAL_CONSTRAINTS, 00697 SCH_PROCEDURES, 00698 SCH_SCHEMATA, 00699 SCH_SCHEMA_PRIVILEGES, 00700 SCH_SESSION_STATUS, 00701 SCH_SESSION_VARIABLES, 00702 SCH_STATISTICS, 00703 SCH_STATUS, 00704 SCH_TABLES, 00705 SCH_TABLESPACES, 00706 SCH_TABLE_CONSTRAINTS, 00707 SCH_TABLE_NAMES, 00708 SCH_TABLE_PRIVILEGES, 00709 SCH_TRIGGERS, 00710 SCH_USER_PRIVILEGES, 00711 SCH_VARIABLES, 00712 SCH_VIEWS 00713 }; 00714 00715 struct TABLE_SHARE; 00716 struct st_foreign_key_info; 00717 typedef struct st_foreign_key_info FOREIGN_KEY_INFO; 00718 typedef bool (stat_print_fn)(THD *thd, const char *type, uint type_len, 00719 const char *file, uint file_len, 00720 const char *status, uint status_len); 00721 enum ha_stat_type { HA_ENGINE_STATUS, HA_ENGINE_LOGS, HA_ENGINE_MUTEX }; 00722 extern st_plugin_int *hton2plugin[MAX_HA]; 00723 00724 /* Transaction log maintains type definitions */ 00725 enum log_status 00726 { 00727 HA_LOG_STATUS_FREE= 0, /* log is free and can be deleted */ 00728 HA_LOG_STATUS_INUSE= 1, /* log can't be deleted because it is in use */ 00729 HA_LOG_STATUS_NOSUCHLOG= 2 /* no such log (can't be returned by 00730 the log iterator status) */ 00731 }; 00732 /* 00733 Function for signaling that the log file changed its state from 00734 LOG_STATUS_INUSE to LOG_STATUS_FREE 00735 00736 Now it do nothing, will be implemented as part of new transaction 00737 log management for engines. 00738 TODO: implement the function. 00739 */ 00740 void signal_log_not_needed(struct handlerton, char *log_file); 00741 /* 00742 Data of transaction log iterator. 00743 */ 00744 struct handler_log_file_data { 00745 LEX_STRING filename; 00746 enum log_status status; 00747 }; 00748 00749 00750 enum handler_iterator_type 00751 { 00752 /* request of transaction log iterator */ 00753 HA_TRANSACTLOG_ITERATOR= 1 00754 }; 00755 enum handler_create_iterator_result 00756 { 00757 HA_ITERATOR_OK, /* iterator created */ 00758 HA_ITERATOR_UNSUPPORTED, /* such type of iterator is not supported */ 00759 HA_ITERATOR_ERROR /* error during iterator creation */ 00760 }; 00761 00762 /* 00763 Iterator structure. Can be used by handler/handlerton for different purposes. 00764 00765 Iterator should be created in the way to point "before" the first object 00766 it iterate, so next() call move it to the first object or return !=0 if 00767 there is nothing to iterate through. 00768 */ 00769 struct handler_iterator { 00770 /* 00771 Moves iterator to next record and return 0 or return !=0 00772 if there is no records. 00773 iterator_object will be filled by this function if next() returns 0. 00774 Content of the iterator_object depend on iterator type. 00775 */ 00776 int (*next)(struct handler_iterator *, void *iterator_object); 00777 /* 00778 Free resources allocated by iterator, after this call iterator 00779 is not usable. 00780 */ 00781 void (*destroy)(struct handler_iterator *); 00782 /* 00783 Pointer to buffer for the iterator to use. 00784 Should be allocated by function which created the iterator and 00785 destroied by freed by above "destroy" call 00786 */ 00787 void *buffer; 00788 }; 00789 00790 class handler; 00791 /* 00792 handlerton is a singleton structure - one instance per storage engine - 00793 to provide access to storage engine functionality that works on the 00794 "global" level (unlike handler class that works on a per-table basis) 00795 00796 usually handlerton instance is defined statically in ha_xxx.cc as 00797 00798 static handlerton { ... } xxx_hton; 00799 00800 savepoint_*, prepare, recover, and *_by_xid pointers can be 0. 00801 */ 00802 struct handlerton 00803 { 00804 /* 00805 Historical marker for if the engine is available of not 00806 */ 00807 SHOW_COMP_OPTION state; 00808 00809 /* 00810 Historical number used for frm file to determine the correct storage engine. 00811 This is going away and new engines will just use "name" for this. 00812 */ 00813 enum legacy_db_type db_type; 00814 /* 00815 each storage engine has it's own memory area (actually a pointer) 00816 in the thd, for storing per-connection information. 00817 It is accessed as 00818 00819 thd->ha_data[xxx_hton.slot] 00820 00821 slot number is initialized by MySQL after xxx_init() is called. 00822 */ 00823 uint slot; 00824 /* 00825 to store per-savepoint data storage engine is provided with an area 00826 of a requested size (0 is ok here). 00827 savepoint_offset must be initialized statically to the size of 00828 the needed memory to store per-savepoint information. 00829 After xxx_init it is changed to be an offset to savepoint storage 00830 area and need not be used by storage engine. 00831 see binlog_hton and binlog_savepoint_set/rollback for an example. 00832 */ 00833 uint savepoint_offset; 00834 /* 00835 handlerton methods: 00836 00837 close_connection is only called if 00838 thd->ha_data[xxx_hton.slot] is non-zero, so even if you don't need 00839 this storage area - set it to something, so that MySQL would know 00840 this storage engine was accessed in this connection 00841 */ 00842 int (*close_connection)(handlerton *hton, THD *thd); 00843 /* 00844 sv points to an uninitialized storage area of requested size 00845 (see savepoint_offset description) 00846 */ 00847 int (*savepoint_set)(handlerton *hton, THD *thd, void *sv); 00848 /* 00849 sv points to a storage area, that was earlier passed 00850 to the savepoint_set call 00851 */ 00852 int (*savepoint_rollback)(handlerton *hton, THD *thd, void *sv); 00859 bool (*savepoint_rollback_can_release_mdl)(handlerton *hton, THD *thd); 00860 int (*savepoint_release)(handlerton *hton, THD *thd, void *sv); 00861 /* 00862 'all' is true if it's a real commit, that makes persistent changes 00863 'all' is false if it's not in fact a commit but an end of the 00864 statement that is part of the transaction. 00865 NOTE 'all' is also false in auto-commit mode where 'end of statement' 00866 and 'real commit' mean the same event. 00867 */ 00868 int (*commit)(handlerton *hton, THD *thd, bool all); 00869 int (*rollback)(handlerton *hton, THD *thd, bool all); 00870 int (*prepare)(handlerton *hton, THD *thd, bool all); 00871 int (*recover)(handlerton *hton, XID *xid_list, uint len); 00872 int (*commit_by_xid)(handlerton *hton, XID *xid); 00873 int (*rollback_by_xid)(handlerton *hton, XID *xid); 00874 void *(*create_cursor_read_view)(handlerton *hton, THD *thd); 00875 void (*set_cursor_read_view)(handlerton *hton, THD *thd, void *read_view); 00876 void (*close_cursor_read_view)(handlerton *hton, THD *thd, void *read_view); 00877 handler *(*create)(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root); 00878 void (*drop_database)(handlerton *hton, char* path); 00879 int (*panic)(handlerton *hton, enum ha_panic_function flag); 00880 int (*start_consistent_snapshot)(handlerton *hton, THD *thd); 00881 bool (*flush_logs)(handlerton *hton); 00882 bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat); 00883 uint (*partition_flags)(); 00884 uint (*alter_table_flags)(uint flags); 00885 int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info); 00886 int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables, 00887 class Item *cond, 00888 enum enum_schema_tables); 00889 uint32 flags; /* global handler flags */ 00890 /* 00891 Those handlerton functions below are properly initialized at handler 00892 init. 00893 */ 00894 int (*binlog_func)(handlerton *hton, THD *thd, enum_binlog_func fn, void *arg); 00895 void (*binlog_log_query)(handlerton *hton, THD *thd, 00896 enum_binlog_command binlog_command, 00897 const char *query, uint query_length, 00898 const char *db, const char *table_name); 00899 int (*release_temporary_latches)(handlerton *hton, THD *thd); 00900 00901 /* 00902 Get log status. 00903 If log_status is null then the handler do not support transaction 00904 log information (i.e. log iterator can't be created). 00905 (see example of implementation in handler.cc, TRANS_LOG_MGM_EXAMPLE_CODE) 00906 00907 */ 00908 enum log_status (*get_log_status)(handlerton *hton, char *log); 00909 00910 /* 00911 Iterators creator. 00912 Presence of the pointer should be checked before using 00913 */ 00914 enum handler_create_iterator_result 00915 (*create_iterator)(handlerton *hton, enum handler_iterator_type type, 00916 struct handler_iterator *fill_this_in); 00917 int (*discover)(handlerton *hton, THD* thd, const char *db, 00918 const char *name, 00919 uchar **frmblob, 00920 size_t *frmlen); 00921 int (*find_files)(handlerton *hton, THD *thd, 00922 const char *db, 00923 const char *path, 00924 const char *wild, bool dir, List<LEX_STRING> *files); 00925 int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db, 00926 const char *name); 00927 int (*make_pushed_join)(handlerton *hton, THD* thd, 00928 const AQP::Join_plan* plan); 00929 00941 const char* (*system_database)(); 00942 00958 bool (*is_supported_system_table)(const char *db, 00959 const char *table_name, 00960 bool is_sql_layer_system_table); 00961 00962 uint32 license; /* Flag for Engine License */ 00963 void *data; /* Location for engines to keep personal structures */ 00964 }; 00965 00966 00967 /* Possible flags of a handlerton (there can be 32 of them) */ 00968 #define HTON_NO_FLAGS 0 00969 #define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0) 00970 #define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter 00971 #define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate 00972 #define HTON_HIDDEN (1 << 3) //Engine does not appear in lists 00973 #define HTON_FLUSH_AFTER_RENAME (1 << 4) 00974 #define HTON_NOT_USER_SELECTABLE (1 << 5) 00975 #define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported 00976 #define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables 00977 #define HTON_NO_PARTITION (1 << 8) //You can not partition these tables 00978 00979 /* 00980 This flag should be set when deciding that the engine does not allow row based 00981 binary logging (RBL) optimizations. 00982 00983 Currently, setting this flag, means that table's read/write_set will be left 00984 untouched when logging changes to tables in this engine. In practice this 00985 means that the server will not mess around with table->write_set and/or 00986 table->read_set when using RBL and deciding whether to log full or minimal rows. 00987 00988 It's valuable for instance for virtual tables, eg: Performance Schema which have 00989 no meaning for replication. 00990 */ 00991 #define HTON_NO_BINLOG_ROW_OPT (1 << 9) 00992 01001 #define HTON_SUPPORTS_EXTENDED_KEYS (1 << 10) 01002 // Engine supports foreign key constraint. 01003 #define HTON_SUPPORTS_FOREIGN_KEYS (1 << 11) 01004 01005 01006 enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED, 01007 ISO_REPEATABLE_READ, ISO_SERIALIZABLE}; 01008 01009 01010 typedef struct { 01011 ulonglong data_file_length; 01012 ulonglong max_data_file_length; 01013 ulonglong index_file_length; 01014 ulonglong delete_length; 01015 ha_rows records; 01016 ulong mean_rec_length; 01017 ulong create_time; 01018 ulong check_time; 01019 ulong update_time; 01020 ulonglong check_sum; 01021 } PARTITION_STATS; 01022 01023 #define UNDEF_NODEGROUP 65535 01024 class Item; 01025 struct st_table_log_memory_entry; 01026 01027 class partition_info; 01028 01029 struct st_partition_iter; 01030 01031 enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES }; 01032 01033 enum enum_stats_auto_recalc { HA_STATS_AUTO_RECALC_DEFAULT= 0, 01034 HA_STATS_AUTO_RECALC_ON, 01035 HA_STATS_AUTO_RECALC_OFF }; 01036 01037 typedef struct st_ha_create_information 01038 { 01039 const CHARSET_INFO *table_charset, *default_table_charset; 01040 LEX_STRING connect_string; 01041 const char *password, *tablespace; 01042 LEX_STRING comment; 01043 const char *data_file_name, *index_file_name; 01044 const char *alias; 01045 ulonglong max_rows,min_rows; 01046 ulonglong auto_increment_value; 01047 ulong table_options; 01048 ulong avg_row_length; 01049 ulong used_fields; 01050 ulong key_block_size; 01051 uint stats_sample_pages; /* number of pages to sample during 01052 stats estimation, if used, otherwise 0. */ 01053 enum_stats_auto_recalc stats_auto_recalc; 01054 SQL_I_List<TABLE_LIST> merge_list; 01055 handlerton *db_type; 01065 enum row_type row_type; 01066 uint null_bits; /* NULL bits at start of record */ 01067 uint options; /* OR of HA_CREATE_ options */ 01068 uint merge_insert_method; 01069 uint extra_size; /* length of extra data segment */ 01070 bool varchar; /* 1 if table has a VARCHAR */ 01071 enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */ 01072 } HA_CREATE_INFO; 01073 01089 class inplace_alter_handler_ctx : public Sql_alloc 01090 { 01091 public: 01092 inplace_alter_handler_ctx() {} 01093 01094 virtual ~inplace_alter_handler_ctx() {} 01095 }; 01096 01097 01106 class Alter_inplace_info 01107 { 01108 public: 01123 typedef ulong HA_ALTER_FLAGS; 01124 01125 // Add non-unique, non-primary index 01126 static const HA_ALTER_FLAGS ADD_INDEX = 1L << 0; 01127 01128 // Drop non-unique, non-primary index 01129 static const HA_ALTER_FLAGS DROP_INDEX = 1L << 1; 01130 01131 // Add unique, non-primary index 01132 static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1L << 2; 01133 01134 // Drop unique, non-primary index 01135 static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1L << 3; 01136 01137 // Add primary index 01138 static const HA_ALTER_FLAGS ADD_PK_INDEX = 1L << 4; 01139 01140 // Drop primary index 01141 static const HA_ALTER_FLAGS DROP_PK_INDEX = 1L << 5; 01142 01143 // Add column 01144 static const HA_ALTER_FLAGS ADD_COLUMN = 1L << 6; 01145 01146 // Drop column 01147 static const HA_ALTER_FLAGS DROP_COLUMN = 1L << 7; 01148 01149 // Rename column 01150 static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1L << 8; 01151 01152 // Change column datatype 01153 static const HA_ALTER_FLAGS ALTER_COLUMN_TYPE = 1L << 9; 01154 01161 static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1L << 10; 01162 01163 // Reorder column 01164 static const HA_ALTER_FLAGS ALTER_COLUMN_ORDER = 1L << 11; 01165 01166 // Change column from NOT NULL to NULL 01167 static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1L << 12; 01168 01169 // Change column from NULL to NOT NULL 01170 static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE = 1L << 13; 01171 01172 // Set or remove default column value 01173 static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1L << 14; 01174 01175 // Add foreign key 01176 static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1L << 15; 01177 01178 // Drop foreign key 01179 static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1L << 16; 01180 01181 // table_options changed, see HA_CREATE_INFO::used_fields for details. 01182 static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1L << 17; 01183 01184 // Table is renamed 01185 static const HA_ALTER_FLAGS ALTER_RENAME = 1L << 18; 01186 01187 // Change the storage type of column 01188 static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1L << 19; 01189 01190 // Change the column format of column 01191 static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1L << 20; 01192 01193 // Add partition 01194 static const HA_ALTER_FLAGS ADD_PARTITION = 1L << 21; 01195 01196 // Drop partition 01197 static const HA_ALTER_FLAGS DROP_PARTITION = 1L << 22; 01198 01199 // Changing partition options 01200 static const HA_ALTER_FLAGS ALTER_PARTITION = 1L << 23; 01201 01202 // Coalesce partition 01203 static const HA_ALTER_FLAGS COALESCE_PARTITION = 1L << 24; 01204 01205 // Reorganize partition ... into 01206 static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1L << 25; 01207 01208 // Reorganize partition 01209 static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1L << 26; 01210 01211 // Remove partitioning 01212 static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING = 1L << 27; 01213 01214 // Partition operation with ALL keyword 01215 static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1L << 28; 01216 01221 static const HA_ALTER_FLAGS RECREATE_TABLE = 1L << 29; 01222 01232 HA_CREATE_INFO *create_info; 01233 01245 Alter_info *alter_info; 01246 01262 KEY *key_info_buffer; 01263 01265 uint key_count; 01266 01268 uint index_drop_count; 01269 01274 KEY **index_drop_buffer; 01275 01277 uint index_add_count; 01278 01283 uint *index_add_buffer; 01284 01291 inplace_alter_handler_ctx *handler_ctx; 01292 01303 inplace_alter_handler_ctx **group_commit_ctx; 01304 01308 HA_ALTER_FLAGS handler_flags; 01309 01316 partition_info *modified_part_info; 01317 01319 const bool ignore; 01320 01322 bool online; 01323 01336 const char *unsupported_reason; 01337 01338 Alter_inplace_info(HA_CREATE_INFO *create_info_arg, 01339 Alter_info *alter_info_arg, 01340 KEY *key_info_arg, uint key_count_arg, 01341 partition_info *modified_part_info_arg, 01342 bool ignore_arg) 01343 : create_info(create_info_arg), 01344 alter_info(alter_info_arg), 01345 key_info_buffer(key_info_arg), 01346 key_count(key_count_arg), 01347 index_drop_count(0), 01348 index_drop_buffer(NULL), 01349 index_add_count(0), 01350 index_add_buffer(NULL), 01351 handler_ctx(NULL), 01352 group_commit_ctx(NULL), 01353 handler_flags(0), 01354 modified_part_info(modified_part_info_arg), 01355 ignore(ignore_arg), 01356 online(false), 01357 unsupported_reason(NULL) 01358 {} 01359 01360 ~Alter_inplace_info() 01361 { 01362 delete handler_ctx; 01363 } 01364 01374 void report_unsupported_error(const char *not_supported, 01375 const char *try_instead); 01376 }; 01377 01378 01379 typedef struct st_key_create_information 01380 { 01381 enum ha_key_alg algorithm; 01382 ulong block_size; 01383 LEX_STRING parser_name; 01384 LEX_STRING comment; 01391 bool check_for_duplicate_indexes; 01392 } KEY_CREATE_INFO; 01393 01394 01395 /* 01396 Class for maintaining hooks used inside operations on tables such 01397 as: create table functions, delete table functions, and alter table 01398 functions. 01399 01400 Class is using the Template Method pattern to separate the public 01401 usage interface from the private inheritance interface. This 01402 imposes no overhead, since the public non-virtual function is small 01403 enough to be inlined. 01404 01405 The hooks are usually used for functions that does several things, 01406 e.g., create_table_from_items(), which both create a table and lock 01407 it. 01408 */ 01409 class TABLEOP_HOOKS 01410 { 01411 public: 01412 TABLEOP_HOOKS() {} 01413 virtual ~TABLEOP_HOOKS() {} 01414 01415 inline void prelock(TABLE **tables, uint count) 01416 { 01417 do_prelock(tables, count); 01418 } 01419 01420 inline int postlock(TABLE **tables, uint count) 01421 { 01422 return do_postlock(tables, count); 01423 } 01424 private: 01425 /* Function primitive that is called prior to locking tables */ 01426 virtual void do_prelock(TABLE **tables, uint count) 01427 { 01428 /* Default is to do nothing */ 01429 } 01430 01439 virtual int do_postlock(TABLE **tables, uint count) 01440 { 01441 return 0; /* Default is to do nothing */ 01442 } 01443 }; 01444 01445 typedef struct st_savepoint SAVEPOINT; 01446 extern ulong savepoint_alloc_size; 01447 extern KEY_CREATE_INFO default_key_create_info; 01448 01449 typedef struct st_ha_check_opt 01450 { 01451 st_ha_check_opt() {} /* Remove gcc warning */ 01452 uint flags; /* isam layer flags (e.g. for myisamchk) */ 01453 uint sql_flags; /* sql layer flags - for something myisamchk cannot do */ 01454 KEY_CACHE *key_cache; /* new key cache when changing key cache */ 01455 void init(); 01456 } HA_CHECK_OPT; 01457 01458 01459 01460 /* 01461 This is a buffer area that the handler can use to store rows. 01462 'end_of_used_area' should be kept updated after calls to 01463 read-functions so that other parts of the code can use the 01464 remaining area (until next read calls is issued). 01465 */ 01466 01467 typedef struct st_handler_buffer 01468 { 01469 uchar *buffer; /* Buffer one can start using */ 01470 uchar *buffer_end; /* End of buffer */ 01471 uchar *end_of_used_area; /* End of area that was used by handler */ 01472 } HANDLER_BUFFER; 01473 01474 typedef struct system_status_var SSV; 01475 01476 01477 typedef void *range_seq_t; 01478 01479 typedef struct st_range_seq_if 01480 { 01481 /* 01482 Initialize the traversal of range sequence 01483 01484 SYNOPSIS 01485 init() 01486 init_params The seq_init_param parameter 01487 n_ranges The number of ranges obtained 01488 flags A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY 01489 01490 RETURN 01491 An opaque value to be used as RANGE_SEQ_IF::next() parameter 01492 */ 01493 range_seq_t (*init)(void *init_params, uint n_ranges, uint flags); 01494 01495 01496 /* 01497 Get the next range in the range sequence 01498 01499 SYNOPSIS 01500 next() 01501 seq The value returned by RANGE_SEQ_IF::init() 01502 range OUT Information about the next range 01503 01504 RETURN 01505 0 - Ok, the range structure filled with info about the next range 01506 1 - No more ranges 01507 */ 01508 uint (*next) (range_seq_t seq, KEY_MULTI_RANGE *range); 01509 01510 /* 01511 Check whether range_info orders to skip the next record 01512 01513 SYNOPSIS 01514 skip_record() 01515 seq The value returned by RANGE_SEQ_IF::init() 01516 range_info Information about the next range 01517 (Ignored if MRR_NO_ASSOCIATION is set) 01518 rowid Rowid of the record to be checked (ignored if set to 0) 01519 01520 RETURN 01521 1 - Record with this range_info and/or this rowid shall be filtered 01522 out from the stream of records returned by multi_range_read_next() 01523 0 - The record shall be left in the stream 01524 */ 01525 bool (*skip_record) (range_seq_t seq, char *range_info, uchar *rowid); 01526 01527 /* 01528 Check if the record combination matches the index condition 01529 SYNOPSIS 01530 skip_index_tuple() 01531 seq The value returned by RANGE_SEQ_IF::init() 01532 range_info Information about the next range 01533 01534 RETURN 01535 0 - The record combination satisfies the index condition 01536 1 - Otherwise 01537 */ 01538 bool (*skip_index_tuple) (range_seq_t seq, char *range_info); 01539 } RANGE_SEQ_IF; 01540 01541 uint16 &mrr_persistent_flag_storage(range_seq_t seq, uint idx); 01542 char* &mrr_get_ptr_by_idx(range_seq_t seq, uint idx); 01543 01550 class Cost_estimate 01551 { 01552 private: 01553 double io_cost; 01554 double cpu_cost; 01555 double import_cost; 01556 double mem_cost; 01557 01558 public: 01559 01561 static double IO_BLOCK_READ_COST() { return 1.0; } 01562 01563 Cost_estimate() : 01564 io_cost(0), 01565 cpu_cost(0), 01566 import_cost(0), 01567 mem_cost(0) 01568 {} 01569 01571 double total_cost() const { return io_cost + cpu_cost + import_cost; } 01572 double get_io_cost() const { return io_cost; } 01573 double get_cpu_cost() const { return cpu_cost; } 01574 double get_import_cost() const { return import_cost; } 01575 double get_mem_cost() const { return mem_cost; } 01576 01582 bool is_zero() const 01583 { 01584 return !(io_cost || cpu_cost || import_cost || mem_cost); 01585 } 01586 01588 void reset() 01589 { 01590 io_cost= cpu_cost= import_cost= mem_cost= 0; 01591 } 01592 01594 void multiply(double m) 01595 { 01596 io_cost *= m; 01597 cpu_cost *= m; 01598 import_cost *= m; 01599 /* Don't multiply mem_cost */ 01600 } 01601 01602 Cost_estimate& operator+= (const Cost_estimate &other) 01603 { 01604 io_cost+= other.io_cost; 01605 cpu_cost+= other.cpu_cost; 01606 import_cost+= other.import_cost; 01607 mem_cost+= other.mem_cost; 01608 01609 return *this; 01610 } 01611 01612 Cost_estimate operator+ (const Cost_estimate &other) 01613 { 01614 Cost_estimate result= *this; 01615 result+= other; 01616 return result; 01617 } 01618 01620 void add_io(double add_io_cost) { io_cost+= add_io_cost; } 01621 01623 void add_cpu(double add_cpu_cost) { cpu_cost+= add_cpu_cost; } 01624 01626 void add_import(double add_import_cost) { import_cost+= add_import_cost; } 01627 01629 void add_mem(double add_mem_cost) { mem_cost+= add_mem_cost; } 01630 }; 01631 01632 void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted, 01633 Cost_estimate *cost); 01634 01635 /* 01636 The below two are not used (and not handled) in this milestone of this WL 01637 entry because there seems to be no use for them at this stage of 01638 implementation. 01639 */ 01640 #define HA_MRR_SINGLE_POINT 1 01641 #define HA_MRR_FIXED_KEY 2 01642 01643 /* 01644 Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the 01645 'range' parameter. 01646 */ 01647 #define HA_MRR_NO_ASSOCIATION 4 01648 01649 /* 01650 The MRR user will provide ranges in key order, and MRR implementation 01651 must return rows in key order. 01652 Passing this flag to multi_read_range_init() may cause the 01653 default MRR handler to be used even if HA_MRR_USE_DEFAULT_IMPL 01654 was not specified. 01655 (If the native MRR impl. can not provide SORTED result) 01656 */ 01657 #define HA_MRR_SORTED 8 01658 01659 /* MRR implementation doesn't have to retrieve full records */ 01660 #define HA_MRR_INDEX_ONLY 16 01661 01662 /* 01663 The passed memory buffer is of maximum possible size, the caller can't 01664 assume larger buffer. 01665 */ 01666 #define HA_MRR_LIMITS 32 01667 01668 01669 /* 01670 Flag set <=> default MRR implementation is used 01671 (The choice is made by **_info[_const]() function which may set this 01672 flag. SQL layer remembers the flag value and then passes it to 01673 multi_read_range_init(). 01674 */ 01675 #define HA_MRR_USE_DEFAULT_IMPL 64 01676 01677 /* 01678 Used only as parameter to multi_range_read_info(): 01679 Flag set <=> the caller guarantees that the bounds of the scanned ranges 01680 will not have NULL values. 01681 */ 01682 #define HA_MRR_NO_NULL_ENDPOINTS 128 01683 01684 /* 01685 Set by the MRR implementation to signal that it will natively 01686 produced sorted result if multi_range_read_init() is called with 01687 the HA_MRR_SORTED flag - Else multi_range_read_init(HA_MRR_SORTED) 01688 will revert to use the default MRR implementation. 01689 */ 01690 #define HA_MRR_SUPPORT_SORTED 256 01691 01692 01693 class ha_statistics 01694 { 01695 public: 01696 ulonglong data_file_length; /* Length off data file */ 01697 ulonglong max_data_file_length; /* Length off data file */ 01698 ulonglong index_file_length; 01699 ulonglong max_index_file_length; 01700 ulonglong delete_length; /* Free bytes */ 01701 ulonglong auto_increment_value; 01702 /* 01703 The number of records in the table. 01704 0 - means the table has exactly 0 rows 01705 other - if (table_flags() & HA_STATS_RECORDS_IS_EXACT) 01706 the value is the exact number of records in the table 01707 else 01708 it is an estimate 01709 */ 01710 ha_rows records; 01711 ha_rows deleted; /* Deleted records */ 01712 ulong mean_rec_length; /* physical reclength */ 01713 ulong create_time; /* When table was created */ 01714 ulong check_time; 01715 ulong update_time; 01716 uint block_size; /* index block size */ 01717 01718 /* 01719 number of buffer bytes that native mrr implementation needs, 01720 */ 01721 uint mrr_length_per_rec; 01722 01723 ha_statistics(): 01724 data_file_length(0), max_data_file_length(0), 01725 index_file_length(0), delete_length(0), auto_increment_value(0), 01726 records(0), deleted(0), mean_rec_length(0), create_time(0), 01727 check_time(0), update_time(0), block_size(0) 01728 {} 01729 }; 01730 01731 uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); 01732 /* 01733 bitmap with first N+1 bits set 01734 (keypart_map for a key prefix of [0..N] keyparts) 01735 */ 01736 #define make_keypart_map(N) (((key_part_map)2 << (N)) - 1) 01737 /* 01738 bitmap with first N bits set 01739 (keypart_map for a key prefix of [0..N-1] keyparts) 01740 */ 01741 #define make_prev_keypart_map(N) (((key_part_map)1 << (N)) - 1) 01742 01743 01745 class Handler_share 01746 { 01747 public: 01748 Handler_share() {} 01749 virtual ~Handler_share() {} 01750 }; 01751 01752 01801 class handler :public Sql_alloc 01802 { 01803 public: 01804 typedef ulonglong Table_flags; 01805 protected: 01806 TABLE_SHARE *table_share; /* The table definition */ 01807 TABLE *table; /* The current open table */ 01808 Table_flags cached_table_flags; /* Set on init() and open() */ 01809 01810 ha_rows estimation_rows_to_insert; 01811 public: 01812 handlerton *ht; /* storage engine of this handler */ 01813 uchar *ref; /* Pointer to current row */ 01814 uchar *dup_ref; /* Pointer to duplicate row */ 01815 01816 ha_statistics stats; 01817 01818 /* MultiRangeRead-related members: */ 01819 range_seq_t mrr_iter; /* Interator to traverse the range sequence */ 01820 RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */ 01821 HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */ 01822 uint ranges_in_seq; /* Total number of ranges in the traversed sequence */ 01823 /* TRUE <=> source MRR ranges and the output are ordered */ 01824 bool mrr_is_output_sorted; 01825 01826 /* TRUE <=> we're currently traversing a range in mrr_cur_range. */ 01827 bool mrr_have_range; 01828 /* Current range (the one we're now returning rows from) */ 01829 KEY_MULTI_RANGE mrr_cur_range; 01830 01831 /* 01832 The direction of the current range or index scan. This is used by 01833 the ICP implementation to determine if it has reached the end 01834 of the current range. 01835 */ 01836 enum enum_range_scan_direction { 01837 RANGE_SCAN_ASC, 01838 RANGE_SCAN_DESC 01839 }; 01840 private: 01841 /* 01842 Storage space for the end range value. Should only be accessed using 01843 the end_range pointer. The content is invalid when end_range is NULL. 01844 */ 01845 key_range save_end_range; 01846 enum_range_scan_direction range_scan_direction; 01847 int key_compare_result_on_equal; 01848 01849 protected: 01850 KEY_PART_INFO *range_key_part; 01851 bool eq_range; 01852 /* 01853 TRUE <=> the engine guarantees that returned records are within the range 01854 being scanned. 01855 */ 01856 bool in_range_check_pushed_down; 01857 01858 public: 01859 /* 01860 End value for a range scan. If this is NULL the range scan has no 01861 end value. Should also be NULL when there is no ongoing range scan. 01862 Used by the read_range() functions and also evaluated by pushed 01863 index conditions. 01864 */ 01865 key_range *end_range; 01866 uint errkey; /* Last dup key */ 01867 uint key_used_on_scan; 01868 uint active_index; 01870 uint ref_length; 01871 FT_INFO *ft_handler; 01872 enum {NONE=0, INDEX, RND} inited; 01873 bool implicit_emptied; /* Can be !=0 only if HEAP */ 01874 const Item *pushed_cond; 01875 01876 Item *pushed_idx_cond; 01877 uint pushed_idx_cond_keyno; /* The index which the above condition is for */ 01878 01888 ulonglong next_insert_id; 01895 ulonglong insert_id_for_cur_row; 01900 Discrete_interval auto_inc_interval_for_cur_row; 01907 uint auto_inc_intervals_count; 01908 01921 PSI_table *m_psi; 01922 01923 virtual void unbind_psi(); 01924 virtual void rebind_psi(); 01925 01926 private: 01927 friend class DsMrr_impl; 01934 int m_lock_type; 01939 Handler_share **ha_share; 01940 01941 public: 01942 handler(handlerton *ht_arg, TABLE_SHARE *share_arg) 01943 :table_share(share_arg), table(0), 01944 estimation_rows_to_insert(0), ht(ht_arg), 01945 ref(0), range_scan_direction(RANGE_SCAN_ASC), 01946 in_range_check_pushed_down(false), end_range(NULL), 01947 key_used_on_scan(MAX_KEY), active_index(MAX_KEY), 01948 ref_length(sizeof(my_off_t)), 01949 ft_handler(0), inited(NONE), 01950 implicit_emptied(0), 01951 pushed_cond(0), pushed_idx_cond(NULL), pushed_idx_cond_keyno(MAX_KEY), 01952 next_insert_id(0), insert_id_for_cur_row(0), 01953 auto_inc_intervals_count(0), 01954 m_psi(NULL), m_lock_type(F_UNLCK), ha_share(NULL) 01955 { 01956 DBUG_PRINT("info", 01957 ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d", 01958 F_UNLCK, F_RDLCK, F_WRLCK)); 01959 } 01960 virtual ~handler(void) 01961 { 01962 DBUG_ASSERT(m_lock_type == F_UNLCK); 01963 DBUG_ASSERT(inited == NONE); 01964 } 01965 virtual handler *clone(const char *name, MEM_ROOT *mem_root); 01967 void init() 01968 { 01969 cached_table_flags= table_flags(); 01970 } 01971 /* ha_ methods: public wrappers for private virtual API */ 01972 01973 int ha_open(TABLE *table, const char *name, int mode, int test_if_locked); 01974 int ha_close(void); 01975 int ha_index_init(uint idx, bool sorted); 01976 int ha_index_end(); 01977 int ha_rnd_init(bool scan); 01978 int ha_rnd_end(); 01979 int ha_rnd_next(uchar *buf); 01980 int ha_rnd_pos(uchar * buf, uchar *pos); 01981 int ha_index_read_map(uchar *buf, const uchar *key, 01982 key_part_map keypart_map, 01983 enum ha_rkey_function find_flag); 01984 int ha_index_read_last_map(uchar * buf, const uchar * key, 01985 key_part_map keypart_map); 01986 int ha_index_read_idx_map(uchar *buf, uint index, const uchar *key, 01987 key_part_map keypart_map, 01988 enum ha_rkey_function find_flag); 01989 int ha_index_next(uchar * buf); 01990 int ha_index_prev(uchar * buf); 01991 int ha_index_first(uchar * buf); 01992 int ha_index_last(uchar * buf); 01993 int ha_index_next_same(uchar *buf, const uchar *key, uint keylen); 01994 int ha_index_read(uchar *buf, const uchar *key, uint key_len, 01995 enum ha_rkey_function find_flag); 01996 int ha_index_read_last(uchar *buf, const uchar *key, uint key_len); 01997 int ha_reset(); 01998 /* this is necessary in many places, e.g. in HANDLER command */ 01999 int ha_index_or_rnd_end() 02000 { 02001 return inited == INDEX ? ha_index_end() : inited == RND ? ha_rnd_end() : 0; 02002 } 02006 Table_flags ha_table_flags() const { return cached_table_flags; } 02013 int ha_external_lock(THD *thd, int lock_type); 02014 int ha_write_row(uchar * buf); 02015 int ha_update_row(const uchar * old_data, uchar * new_data); 02016 int ha_delete_row(const uchar * buf); 02017 void ha_release_auto_increment(); 02018 02019 int check_collation_compatibility(); 02020 int ha_check_for_upgrade(HA_CHECK_OPT *check_opt); 02022 int ha_check(THD *thd, HA_CHECK_OPT *check_opt); 02023 int ha_repair(THD* thd, HA_CHECK_OPT* check_opt); 02024 void ha_start_bulk_insert(ha_rows rows); 02025 int ha_end_bulk_insert(); 02026 int ha_bulk_update_row(const uchar *old_data, uchar *new_data, 02027 uint *dup_key_found); 02028 int ha_delete_all_rows(); 02029 int ha_truncate(); 02030 int ha_reset_auto_increment(ulonglong value); 02031 int ha_optimize(THD* thd, HA_CHECK_OPT* check_opt); 02032 int ha_analyze(THD* thd, HA_CHECK_OPT* check_opt); 02033 bool ha_check_and_repair(THD *thd); 02034 int ha_disable_indexes(uint mode); 02035 int ha_enable_indexes(uint mode); 02036 int ha_discard_or_import_tablespace(my_bool discard); 02037 int ha_rename_table(const char *from, const char *to); 02038 int ha_delete_table(const char *name); 02039 void ha_drop_table(const char *name); 02040 02041 int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info); 02042 02043 int ha_create_handler_files(const char *name, const char *old_name, 02044 int action_flag, HA_CREATE_INFO *info); 02045 02046 int ha_change_partitions(HA_CREATE_INFO *create_info, 02047 const char *path, 02048 ulonglong * const copied, 02049 ulonglong * const deleted, 02050 const uchar *pack_frm_data, 02051 size_t pack_frm_len); 02052 int ha_drop_partitions(const char *path); 02053 int ha_rename_partitions(const char *path); 02054 02055 void adjust_next_insert_id_after_explicit_value(ulonglong nr); 02056 int update_auto_increment(); 02057 virtual void print_error(int error, myf errflag); 02058 virtual bool get_error_message(int error, String *buf); 02059 uint get_dup_key(int error); 02078 virtual bool get_foreign_dup_key(char *child_table_name, 02079 uint child_table_name_len, 02080 char *child_key_name, 02081 uint child_key_name_len) 02082 { DBUG_ASSERT(false); return(false); } 02083 virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share) 02084 { 02085 table= table_arg; 02086 table_share= share; 02087 } 02088 /* Estimates calculation */ 02089 virtual double scan_time() 02090 { return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; } 02091 02092 02104 virtual double read_time(uint index, uint ranges, ha_rows rows) 02105 { return rows2double(ranges+rows); } 02106 02107 virtual double index_only_read_time(uint keynr, double records); 02108 02114 virtual longlong get_memory_buffer_size() const { return -1; } 02115 02116 virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq, 02117 void *seq_init_param, 02118 uint n_ranges, uint *bufsz, 02119 uint *flags, 02120 Cost_estimate *cost); 02121 virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys, 02122 uint *bufsz, uint *flags, 02123 Cost_estimate *cost); 02124 virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param, 02125 uint n_ranges, uint mode, 02126 HANDLER_BUFFER *buf); 02127 virtual int multi_range_read_next(char **range_info); 02128 02129 02130 virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; } 02131 bool has_transactions() 02132 { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; } 02133 virtual uint extra_rec_buf_length() const { return 0; } 02134 02145 virtual bool is_fatal_error(int error, uint flags) 02146 { 02147 if (!error || 02148 ((flags & HA_CHECK_DUP_KEY) && 02149 (error == HA_ERR_FOUND_DUPP_KEY || 02150 error == HA_ERR_FOUND_DUPP_UNIQUE))) 02151 return FALSE; 02152 return TRUE; 02153 } 02154 02159 virtual ha_rows records() { return stats.records; } 02166 virtual ha_rows estimate_rows_upper_bound() 02167 { return stats.records+EXTRA_RECORDS; } 02168 02173 virtual enum row_type get_row_type() const { return ROW_TYPE_NOT_USED; } 02174 02175 virtual const char *index_type(uint key_number) { DBUG_ASSERT(0); return "";} 02176 02177 02185 virtual void column_bitmaps_signal(); 02186 uint get_index(void) const { return active_index; } 02187 02192 virtual bool start_bulk_update() { return 1; } 02197 virtual bool start_bulk_delete() { return 1; } 02209 virtual int exec_bulk_update(uint *dup_key_found) 02210 { 02211 DBUG_ASSERT(FALSE); 02212 return HA_ERR_WRONG_COMMAND; 02213 } 02218 virtual void end_bulk_update() { return; } 02225 virtual int end_bulk_delete() 02226 { 02227 DBUG_ASSERT(FALSE); 02228 return HA_ERR_WRONG_COMMAND; 02229 } 02230 protected: 02240 virtual int index_read_map(uchar * buf, const uchar * key, 02241 key_part_map keypart_map, 02242 enum ha_rkey_function find_flag) 02243 { 02244 uint key_len= calculate_key_len(table, active_index, key, keypart_map); 02245 return index_read(buf, key, key_len, find_flag); 02246 } 02254 virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key, 02255 key_part_map keypart_map, 02256 enum ha_rkey_function find_flag); 02258 virtual int index_next(uchar * buf) 02259 { return HA_ERR_WRONG_COMMAND; } 02261 virtual int index_prev(uchar * buf) 02262 { return HA_ERR_WRONG_COMMAND; } 02264 virtual int index_first(uchar * buf) 02265 { return HA_ERR_WRONG_COMMAND; } 02267 virtual int index_last(uchar * buf) 02268 { return HA_ERR_WRONG_COMMAND; } 02270 virtual int index_next_same(uchar *buf, const uchar *key, uint keylen); 02277 virtual int index_read_last_map(uchar * buf, const uchar * key, 02278 key_part_map keypart_map) 02279 { 02280 uint key_len= calculate_key_len(table, active_index, key, keypart_map); 02281 return index_read_last(buf, key, key_len); 02282 } 02283 public: 02284 virtual int read_range_first(const key_range *start_key, 02285 const key_range *end_key, 02286 bool eq_range, bool sorted); 02287 virtual int read_range_next(); 02288 02297 void set_end_range(const key_range* range, 02298 enum_range_scan_direction direction); 02299 int compare_key(key_range *range); 02300 int compare_key_icp(const key_range *range) const; 02301 virtual int ft_init() { return HA_ERR_WRONG_COMMAND; } 02302 void ft_end() { ft_handler=NULL; } 02303 virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key) 02304 { return NULL; } 02305 virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; } 02306 protected: 02308 virtual int rnd_next(uchar *buf)=0; 02310 virtual int rnd_pos(uchar * buf, uchar *pos)=0; 02311 public: 02317 virtual int rnd_pos_by_record(uchar *record) 02318 { 02319 DBUG_ASSERT(table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION); 02320 position(record); 02321 return ha_rnd_pos(record, ref); 02322 } 02323 virtual int read_first_row(uchar *buf, uint primary_key); 02328 virtual int restart_rnd_next(uchar *buf, uchar *pos) 02329 { return HA_ERR_WRONG_COMMAND; } 02330 virtual int rnd_same(uchar *buf, uint inx) 02331 { return HA_ERR_WRONG_COMMAND; } 02332 virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key) 02333 { return (ha_rows) 10; } 02334 /* 02335 If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref 02336 (reference to the row, aka position, with the primary key given in 02337 the record). 02338 Otherwise it set ref to the current row. 02339 */ 02340 virtual void position(const uchar *record)=0; 02341 virtual int info(uint)=0; // see my_base.h for full description 02342 virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info, 02343 uint part_id); 02344 virtual uint32 calculate_key_hash_value(Field **field_array) 02345 { DBUG_ASSERT(0); return 0; } 02346 virtual int extra(enum ha_extra_function operation) 02347 { return 0; } 02348 virtual int extra_opt(enum ha_extra_function operation, ulong cache_size) 02349 { return extra(operation); } 02350 02355 virtual bool start_read_removal(void) 02356 { DBUG_ASSERT(0); return false; } 02357 02363 virtual ha_rows end_read_removal(void) 02364 { DBUG_ASSERT(0); return (ha_rows) 0; } 02365 02378 virtual bool was_semi_consistent_read() { return 0; } 02385 virtual void try_semi_consistent_read(bool) {} 02386 virtual void unlock_row() {} 02387 virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;} 02388 virtual void get_auto_increment(ulonglong offset, ulonglong increment, 02389 ulonglong nb_desired_values, 02390 ulonglong *first_value, 02391 ulonglong *nb_reserved_values); 02392 void set_next_insert_id(ulonglong id) 02393 { 02394 DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id)); 02395 next_insert_id= id; 02396 } 02397 void restore_auto_increment(ulonglong prev_insert_id) 02398 { 02399 /* 02400 Insertion of a row failed, re-use the lastly generated auto_increment 02401 id, for the next row. This is achieved by resetting next_insert_id to 02402 what it was before the failed insertion (that old value is provided by 02403 the caller). If that value was 0, it was the first row of the INSERT; 02404 then if insert_id_for_cur_row contains 0 it means no id was generated 02405 for this first row, so no id was generated since the INSERT started, so 02406 we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it 02407 is the generated id of the first and failed row, so we use it. 02408 */ 02409 next_insert_id= (prev_insert_id > 0) ? prev_insert_id : 02410 insert_id_for_cur_row; 02411 } 02412 02413 virtual void update_create_info(HA_CREATE_INFO *create_info) {} 02414 int check_old_types(); 02415 virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) 02416 { return HA_ADMIN_NOT_IMPLEMENTED; } 02417 virtual int preload_keys(THD* thd, HA_CHECK_OPT* check_opt) 02418 { return HA_ADMIN_NOT_IMPLEMENTED; } 02419 /* end of the list of admin commands */ 02420 02421 virtual int indexes_are_disabled(void) {return 0;} 02422 virtual char *update_table_comment(const char * comment) 02423 { return (char*) comment;} 02424 virtual void append_create_info(String *packet) {} 02435 virtual bool is_fk_defined_on_table_or_index(uint index) 02436 { return FALSE; } 02437 virtual char* get_foreign_key_create_info() 02438 { return(NULL);} /* gets foreign key create string from InnoDB */ 02447 virtual bool can_switch_engines() { return true; } 02459 virtual int 02460 get_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) 02461 { return 0; } 02473 virtual int 02474 get_parent_foreign_key_list(THD *thd, List<FOREIGN_KEY_INFO> *f_key_list) 02475 { return 0; } 02476 virtual uint referenced_by_foreign_key() { return 0;} 02477 virtual void init_table_handle_for_HANDLER() 02478 { return; } /* prepare InnoDB for HANDLER */ 02479 virtual void free_foreign_key_create_info(char* str) {} 02481 virtual const char *table_type() const =0; 02493 virtual const char **bas_ext() const =0; 02494 02495 virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;} 02496 virtual void set_auto_partitions(partition_info *part_info) { return; } 02497 02508 virtual bool get_no_parts(const char *name, 02509 uint *no_parts) 02510 { 02511 *no_parts= 0; 02512 return 0; 02513 } 02514 virtual void set_part_info(partition_info *part_info, bool early) {return;} 02515 02516 virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; 02517 02518 uint max_record_length() const 02519 { 02520 using std::min; 02521 return min(HA_MAX_REC_LENGTH, max_supported_record_length()); 02522 } 02523 uint max_keys() const 02524 { 02525 using std::min; 02526 return min(MAX_KEY, max_supported_keys()); 02527 } 02528 uint max_key_parts() const 02529 { 02530 using std::min; 02531 return min(MAX_REF_PARTS, max_supported_key_parts()); 02532 } 02533 uint max_key_length() const 02534 { 02535 using std::min; 02536 return min(MAX_KEY_LENGTH, max_supported_key_length()); 02537 } 02538 uint max_key_part_length() const 02539 { 02540 using std::min; 02541 return min(MAX_KEY_LENGTH, max_supported_key_part_length()); 02542 } 02543 02544 virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; } 02545 virtual uint max_supported_keys() const { return 0; } 02546 virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; } 02547 virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; } 02548 virtual uint max_supported_key_part_length() const { return 255; } 02549 virtual uint min_record_length(uint options) const { return 1; } 02550 02551 virtual bool low_byte_first() const { return 1; } 02552 virtual uint checksum() const { return 0; } 02553 virtual bool is_crashed() const { return 0; } 02554 virtual bool auto_repair() const { return 0; } 02555 02556 02557 #define CHF_CREATE_FLAG 0 02558 #define CHF_DELETE_FLAG 1 02559 #define CHF_RENAME_FLAG 2 02560 #define CHF_INDEX_FLAG 3 02561 02562 02566 virtual uint lock_count(void) const { return 1; } 02580 virtual THR_LOCK_DATA **store_lock(THD *thd, 02581 THR_LOCK_DATA **to, 02582 enum thr_lock_type lock_type)=0; 02583 02585 virtual uint8 table_cache_type() { return HA_CACHE_TBL_NONTRANSACT; } 02586 02587 02618 virtual my_bool register_query_cache_table(THD *thd, char *table_key, 02619 uint key_length, 02620 qc_engine_callback 02621 *engine_callback, 02622 ulonglong *engine_data) 02623 { 02624 *engine_callback= 0; 02625 return TRUE; 02626 } 02627 02628 02629 /* 02630 @retval TRUE Primary key (if there is one) is clustered 02631 key covering all fields 02632 @retval FALSE otherwise 02633 */ 02634 virtual bool primary_key_is_clustered() { return FALSE; } 02635 virtual int cmp_ref(const uchar *ref1, const uchar *ref2) 02636 { 02637 return memcmp(ref1, ref2, ref_length); 02638 } 02639 02640 /* 02641 Condition pushdown to storage engines 02642 */ 02643 02666 virtual const Item *cond_push(const Item *cond) { return cond; }; 02672 virtual void cond_pop() { return; } 02673 02699 virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; } 02700 02702 virtual void cancel_pushed_idx_cond() 02703 { 02704 pushed_idx_cond= NULL; 02705 pushed_idx_cond_keyno= MAX_KEY; 02706 in_range_check_pushed_down= false; 02707 } 02708 02713 virtual uint number_of_pushed_joins() const 02714 { return 0; } 02715 02720 virtual const TABLE* root_of_pushed_join() const 02721 { return NULL; } 02722 02727 virtual const TABLE* parent_of_pushed_join() const 02728 { return NULL; } 02729 02730 virtual int index_read_pushed(uchar * buf, const uchar * key, 02731 key_part_map keypart_map) 02732 { return HA_ERR_WRONG_COMMAND; } 02733 02734 virtual int index_next_pushed(uchar * buf) 02735 { return HA_ERR_WRONG_COMMAND; } 02736 02740 virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info, 02741 uint table_changes) 02742 { return COMPATIBLE_DATA_NO; } 02743 02744 /* On-line/in-place ALTER TABLE interface. */ 02745 02746 /* 02747 Here is an outline of on-line/in-place ALTER TABLE execution through 02748 this interface. 02749 02750 Phase 1 : Initialization 02751 ======================== 02752 During this phase we determine which algorithm should be used 02753 for execution of ALTER TABLE and what level concurrency it will 02754 require. 02755 02756 *) This phase starts by opening the table and preparing description 02757 of the new version of the table. 02758 *) Then we check if it is impossible even in theory to carry out 02759 this ALTER TABLE using the in-place algorithm. For example, because 02760 we need to change storage engine or the user has explicitly requested 02761 usage of the "copy" algorithm. 02762 *) If in-place ALTER TABLE is theoretically possible, we continue 02763 by compiling differences between old and new versions of the table 02764 in the form of HA_ALTER_FLAGS bitmap. We also build a few 02765 auxiliary structures describing requested changes and store 02766 all these data in the Alter_inplace_info object. 02767 *) Then the handler::check_if_supported_inplace_alter() method is called 02768 in order to find if the storage engine can carry out changes requested 02769 by this ALTER TABLE using the in-place algorithm. To determine this, 02770 the engine can rely on data in HA_ALTER_FLAGS/Alter_inplace_info 02771 passed to it as well as on its own checks. If the in-place algorithm 02772 can be used for this ALTER TABLE, the level of required concurrency for 02773 its execution is also returned. 02774 If any errors occur during the handler call, ALTER TABLE is aborted 02775 and no further handler functions are called. 02776 *) Locking requirements of the in-place algorithm are compared to any 02777 concurrency requirements specified by user. If there is a conflict 02778 between them, we either switch to the copy algorithm or emit an error. 02779 02780 Phase 2 : Execution 02781 =================== 02782 02783 In this phase the operations are executed. 02784 02785 *) As the first step, we acquire a lock corresponding to the concurrency 02786 level which was returned by handler::check_if_supported_inplace_alter() 02787 and requested by the user. This lock is held for most of the 02788 duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE 02789 or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an 02790 exclusive lock for duration of the next step only). 02791 *) After that we call handler::ha_prepare_inplace_alter_table() to give the 02792 storage engine a chance to update its internal structures with a higher 02793 lock level than the one that will be used for the main step of algorithm. 02794 After that we downgrade the lock if it is necessary. 02795 *) After that, the main step of this phase and algorithm is executed. 02796 We call the handler::ha_inplace_alter_table() method, which carries out the 02797 changes requested by ALTER TABLE but does not makes them visible to other 02798 connections yet. 02799 *) We ensure that no other connection uses the table by upgrading our 02800 lock on it to exclusive. 02801 *) a) If the previous step succeeds, handler::ha_commit_inplace_alter_table() is 02802 called to allow the storage engine to do any final updates to its structures, 02803 to make all earlier changes durable and visible to other connections. 02804 b) If we have failed to upgrade lock or any errors have occured during the 02805 handler functions calls (including commit), we call 02806 handler::ha_commit_inplace_alter_table() 02807 to rollback all changes which were done during previous steps. 02808 02809 Phase 3 : Final 02810 =============== 02811 02812 In this phase we: 02813 02814 *) Update SQL-layer data-dictionary by installing .FRM file for the new version 02815 of the table. 02816 *) Inform the storage engine about this change by calling the 02817 handler::ha_notify_table_changed() method. 02818 *) Destroy the Alter_inplace_info and handler_ctx objects. 02819 02820 */ 02821 02850 virtual enum_alter_inplace_result 02851 check_if_supported_inplace_alter(TABLE *altered_table, 02852 Alter_inplace_info *ha_alter_info); 02853 02854 02859 bool ha_prepare_inplace_alter_table(TABLE *altered_table, 02860 Alter_inplace_info *ha_alter_info); 02861 02862 02867 bool ha_inplace_alter_table(TABLE *altered_table, 02868 Alter_inplace_info *ha_alter_info) 02869 { 02870 return inplace_alter_table(altered_table, ha_alter_info); 02871 } 02872 02873 02879 bool ha_commit_inplace_alter_table(TABLE *altered_table, 02880 Alter_inplace_info *ha_alter_info, 02881 bool commit); 02882 02883 02888 void ha_notify_table_changed() 02889 { 02890 notify_table_changed(); 02891 } 02892 02893 02894 protected: 02923 virtual bool prepare_inplace_alter_table(TABLE *altered_table, 02924 Alter_inplace_info *ha_alter_info) 02925 { return false; } 02926 02927 02947 virtual bool inplace_alter_table(TABLE *altered_table, 02948 Alter_inplace_info *ha_alter_info) 02949 { return false; } 02950 02951 02984 virtual bool commit_inplace_alter_table(TABLE *altered_table, 02985 Alter_inplace_info *ha_alter_info, 02986 bool commit) 02987 { 02988 /* Nothing to commit/rollback, mark all handlers committed! */ 02989 ha_alter_info->group_commit_ctx= NULL; 02990 return false; 02991 } 02992 02993 02999 virtual void notify_table_changed(); 03000 03001 public: 03002 /* End of On-line/in-place ALTER TABLE interface. */ 03003 03004 03010 virtual void use_hidden_primary_key(); 03011 virtual uint alter_table_flags(uint flags) 03012 { 03013 if (ht->alter_table_flags) 03014 return ht->alter_table_flags(flags); 03015 return 0; 03016 } 03017 03018 protected: 03019 /* Service methods for use by storage engines. */ 03020 void ha_statistic_increment(ulonglong SSV::*offset) const; 03021 void **ha_data(THD *) const; 03022 THD *ha_thd(void) const; 03023 03029 PSI_table_share *ha_table_share_psi(const TABLE_SHARE *share) const; 03030 03038 virtual int rename_table(const char *from, const char *to); 03043 virtual int delete_table(const char *name); 03044 private: 03045 /* Private helpers */ 03046 inline void mark_trx_read_write(); 03047 /* 03048 Low-level primitives for storage engines. These should be 03049 overridden by the storage engine class. To call these methods, use 03050 the corresponding 'ha_*' method above. 03051 */ 03052 03053 virtual int open(const char *name, int mode, uint test_if_locked)=0; 03054 virtual int close(void)=0; 03055 virtual int index_init(uint idx, bool sorted) { active_index= idx; return 0; } 03056 virtual int index_end() { active_index= MAX_KEY; return 0; } 03064 virtual int rnd_init(bool scan)= 0; 03065 virtual int rnd_end() { return 0; } 03066 virtual int write_row(uchar *buf __attribute__((unused))) 03067 { 03068 return HA_ERR_WRONG_COMMAND; 03069 } 03070 03079 virtual int update_row(const uchar *old_data __attribute__((unused)), 03080 uchar *new_data __attribute__((unused))) 03081 { 03082 return HA_ERR_WRONG_COMMAND; 03083 } 03084 03085 virtual int delete_row(const uchar *buf __attribute__((unused))) 03086 { 03087 return HA_ERR_WRONG_COMMAND; 03088 } 03094 virtual int reset() { return 0; } 03095 virtual Table_flags table_flags(void) const= 0; 03118 virtual int external_lock(THD *thd __attribute__((unused)), 03119 int lock_type __attribute__((unused))) 03120 { 03121 return 0; 03122 } 03123 virtual void release_auto_increment() { return; }; 03125 virtual int check_for_upgrade(HA_CHECK_OPT *check_opt) 03126 { return 0; } 03127 virtual int check(THD* thd, HA_CHECK_OPT* check_opt) 03128 { return HA_ADMIN_NOT_IMPLEMENTED; } 03129 03135 virtual int repair(THD* thd, HA_CHECK_OPT* check_opt) 03136 { 03137 DBUG_ASSERT(!(ha_table_flags() & HA_CAN_REPAIR)); 03138 return HA_ADMIN_NOT_IMPLEMENTED; 03139 } 03140 virtual void start_bulk_insert(ha_rows rows) {} 03141 virtual int end_bulk_insert() { return 0; } 03142 protected: 03143 virtual int index_read(uchar * buf, const uchar * key, uint key_len, 03144 enum ha_rkey_function find_flag) 03145 { return HA_ERR_WRONG_COMMAND; } 03146 virtual int index_read_last(uchar * buf, const uchar * key, uint key_len) 03147 { return (my_errno= HA_ERR_WRONG_COMMAND); } 03148 public: 03165 virtual int bulk_update_row(const uchar *old_data, uchar *new_data, 03166 uint *dup_key_found) 03167 { 03168 DBUG_ASSERT(FALSE); 03169 return HA_ERR_WRONG_COMMAND; 03170 } 03177 virtual int delete_all_rows() 03178 { return (my_errno=HA_ERR_WRONG_COMMAND); } 03197 virtual int truncate() 03198 { return HA_ERR_WRONG_COMMAND; } 03204 virtual int reset_auto_increment(ulonglong value) 03205 { return HA_ERR_WRONG_COMMAND; } 03206 virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt) 03207 { return HA_ADMIN_NOT_IMPLEMENTED; } 03208 virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt) 03209 { return HA_ADMIN_NOT_IMPLEMENTED; } 03210 virtual bool check_and_repair(THD *thd) { return TRUE; } 03211 virtual int disable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } 03212 virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; } 03213 virtual int discard_or_import_tablespace(my_bool discard) 03214 { return (my_errno=HA_ERR_WRONG_COMMAND); } 03215 virtual void drop_table(const char *name); 03216 virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0; 03217 03218 virtual int create_handler_files(const char *name, const char *old_name, 03219 int action_flag, HA_CREATE_INFO *info) 03220 { return FALSE; } 03221 03222 virtual int change_partitions(HA_CREATE_INFO *create_info, 03223 const char *path, 03224 ulonglong * const copied, 03225 ulonglong * const deleted, 03226 const uchar *pack_frm_data, 03227 size_t pack_frm_len) 03228 { return HA_ERR_WRONG_COMMAND; } 03229 virtual int drop_partitions(const char *path) 03230 { return HA_ERR_WRONG_COMMAND; } 03231 virtual int rename_partitions(const char *path) 03232 { return HA_ERR_WRONG_COMMAND; } 03233 virtual bool set_ha_share_ref(Handler_share **arg_ha_share) 03234 { 03235 DBUG_ASSERT(!ha_share); 03236 DBUG_ASSERT(arg_ha_share); 03237 if (ha_share || !arg_ha_share) 03238 return true; 03239 ha_share= arg_ha_share; 03240 return false; 03241 } 03242 int get_lock_type() const { return m_lock_type; } 03243 protected: 03244 Handler_share *get_ha_share_ptr(); 03245 void set_ha_share_ptr(Handler_share *arg_ha_share); 03246 void lock_shared_ha_data(); 03247 void unlock_shared_ha_data(); 03248 }; 03249 03250 03251 bool key_uses_partial_cols(TABLE *table, uint keyno); 03252 03253 /* 03254 A Disk-Sweep MRR interface implementation 03255 03256 This implementation makes range (and, in the future, 'ref') scans to read 03257 table rows in disk sweeps. 03258 03259 Currently it is used by MyISAM and InnoDB. Potentially it can be used with 03260 any table handler that has non-clustered indexes and on-disk rows. 03261 */ 03262 03263 class DsMrr_impl 03264 { 03265 public: 03266 typedef void (handler::*range_check_toggle_func_t)(bool on); 03267 03268 DsMrr_impl() 03269 : h2(NULL) {}; 03270 ~DsMrr_impl() { DBUG_ASSERT(h2 == NULL); } 03271 03272 /* 03273 The "owner" handler object (the one that calls dsmrr_XXX functions. 03274 It is used to retrieve full table rows by calling rnd_pos(). 03275 */ 03276 handler *h; 03277 TABLE *table; /* Always equal to h->table */ 03278 private: 03279 /* Secondary handler object. It is used for scanning the index */ 03280 handler *h2; 03281 03282 /* Buffer to store rowids, or (rowid, range_id) pairs */ 03283 uchar *rowids_buf; 03284 uchar *rowids_buf_cur; /* Current position when reading/writing */ 03285 uchar *rowids_buf_last; /* When reading: end of used buffer space */ 03286 uchar *rowids_buf_end; /* End of the buffer */ 03287 03288 bool dsmrr_eof; /* TRUE <=> We have reached EOF when reading index tuples */ 03289 03290 /* TRUE <=> need range association, buffer holds {rowid, range_id} pairs */ 03291 bool is_mrr_assoc; 03292 03293 bool use_default_impl; /* TRUE <=> shortcut all calls to default MRR impl */ 03294 public: 03295 void init(handler *h_arg, TABLE *table_arg) 03296 { 03297 h= h_arg; 03298 table= table_arg; 03299 } 03300 int dsmrr_init(handler *h, RANGE_SEQ_IF *seq_funcs, void *seq_init_param, 03301 uint n_ranges, uint mode, HANDLER_BUFFER *buf); 03302 void dsmrr_close(); 03303 03314 void reset(); 03315 int dsmrr_fill_buffer(); 03316 int dsmrr_next(char **range_info); 03317 03318 ha_rows dsmrr_info(uint keyno, uint n_ranges, uint keys, uint *bufsz, 03319 uint *flags, Cost_estimate *cost); 03320 03321 ha_rows dsmrr_info_const(uint keyno, RANGE_SEQ_IF *seq, 03322 void *seq_init_param, uint n_ranges, uint *bufsz, 03323 uint *flags, Cost_estimate *cost); 03324 private: 03325 bool choose_mrr_impl(uint keyno, ha_rows rows, uint *flags, uint *bufsz, 03326 Cost_estimate *cost); 03327 bool get_disk_sweep_mrr_cost(uint keynr, ha_rows rows, uint flags, 03328 uint *buffer_size, Cost_estimate *cost); 03329 }; 03330 /* Some extern variables used with handlers */ 03331 03332 extern const char *ha_row_type[]; 03333 extern MYSQL_PLUGIN_IMPORT const char *tx_isolation_names[]; 03334 extern MYSQL_PLUGIN_IMPORT const char *binlog_format_names[]; 03335 extern TYPELIB tx_isolation_typelib; 03336 extern const char *myisam_stats_method_names[]; 03337 extern ulong total_ha, total_ha_2pc; 03338 03339 /* lookups */ 03340 handlerton *ha_default_handlerton(THD *thd); 03341 handlerton *ha_default_temp_handlerton(THD *thd); 03342 plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name, 03343 bool is_temp_table); 03344 plugin_ref ha_lock_engine(THD *thd, const handlerton *hton); 03345 handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type); 03346 handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc, 03347 handlerton *db_type); 03348 handlerton *ha_checktype(THD *thd, enum legacy_db_type database_type, 03349 bool no_substitute, bool report_error); 03350 03351 03352 static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type) 03353 { 03354 return (db_type == NULL) ? DB_TYPE_UNKNOWN : db_type->db_type; 03355 } 03356 03357 static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type) 03358 { 03359 return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str; 03360 } 03361 03362 static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag) 03363 { 03364 return db_type == NULL ? FALSE : MY_TEST(db_type->flags & flag); 03365 } 03366 03367 static inline bool ha_storage_engine_is_enabled(const handlerton *db_type) 03368 { 03369 return (db_type && db_type->create) ? 03370 (db_type->state == SHOW_OPTION_YES) : FALSE; 03371 } 03372 03373 /* basic stuff */ 03374 int ha_init_errors(void); 03375 int ha_init(void); 03376 int ha_end(void); 03377 int ha_initialize_handlerton(st_plugin_int *plugin); 03378 int ha_finalize_handlerton(st_plugin_int *plugin); 03379 03380 TYPELIB* ha_known_exts(); 03381 int ha_panic(enum ha_panic_function flag); 03382 void ha_close_connection(THD* thd); 03383 bool ha_flush_logs(handlerton *db_type); 03384 void ha_drop_database(char* path); 03385 int ha_create_table(THD *thd, const char *path, 03386 const char *db, const char *table_name, 03387 HA_CREATE_INFO *create_info, 03388 bool update_create_info, 03389 bool is_temp_table= false); 03390 03391 int ha_delete_table(THD *thd, handlerton *db_type, const char *path, 03392 const char *db, const char *alias, bool generate_warning); 03393 03394 /* statistics and info */ 03395 bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat); 03396 03397 /* discovery */ 03398 int ha_create_table_from_engine(THD* thd, const char *db, const char *name); 03399 bool ha_check_if_table_exists(THD* thd, const char *db, const char *name, 03400 bool *exists); 03401 int ha_discover(THD* thd, const char* dbname, const char* name, 03402 uchar** frmblob, size_t* frmlen); 03403 int ha_find_files(THD *thd,const char *db,const char *path, 03404 const char *wild, bool dir, List<LEX_STRING>* files); 03405 int ha_table_exists_in_engine(THD* thd, const char* db, const char* name); 03406 bool ha_check_if_supported_system_table(handlerton *hton, const char* db, 03407 const char* table_name); 03408 03409 /* key cache */ 03410 extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache); 03411 int ha_resize_key_cache(KEY_CACHE *key_cache); 03412 int ha_change_key_cache_param(KEY_CACHE *key_cache); 03413 int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache); 03414 03415 /* report to InnoDB that control passes to the client */ 03416 int ha_release_temporary_latches(THD *thd); 03417 03418 /* transactions: interface to handlerton functions */ 03419 int ha_start_consistent_snapshot(THD *thd); 03420 int ha_commit_or_rollback_by_xid(THD *thd, XID *xid, bool commit); 03421 int ha_commit_trans(THD *thd, bool all, bool ignore_global_read_lock= false); 03422 int ha_rollback_trans(THD *thd, bool all); 03423 int ha_prepare(THD *thd); 03424 int ha_recover(HASH *commit_list); 03425 03426 /* 03427 transactions: interface to low-level handlerton functions. These are 03428 intended to be used by the transaction coordinators to 03429 commit/prepare/rollback transactions in the engines. 03430 */ 03431 int ha_commit_low(THD *thd, bool all, bool run_after_commit= true); 03432 int ha_prepare_low(THD *thd, bool all); 03433 int ha_rollback_low(THD *thd, bool all); 03434 03435 /* transactions: these functions never call handlerton functions directly */ 03436 int ha_enable_transaction(THD *thd, bool on); 03437 03438 /* savepoints */ 03439 int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv); 03440 bool ha_rollback_to_savepoint_can_release_mdl(THD *thd); 03441 int ha_savepoint(THD *thd, SAVEPOINT *sv); 03442 int ha_release_savepoint(THD *thd, SAVEPOINT *sv); 03443 03444 /* Build pushed joins in handlers implementing this feature */ 03445 int ha_make_pushed_joins(THD *thd, const AQP::Join_plan* plan); 03446 03447 /* these are called by storage engines */ 03448 void trans_register_ha(THD *thd, bool all, handlerton *ht); 03449 03450 /* 03451 Storage engine has to assume the transaction will end up with 2pc if 03452 - there is more than one 2pc-capable storage engine available 03453 - in the current transaction 2pc was not disabled yet 03454 */ 03455 #define trans_need_2pc(thd, all) ((total_ha_2pc > 1) && \ 03456 !((all ? &thd->transaction.all : &thd->transaction.stmt)->no_2pc)) 03457 03458 #ifdef HAVE_NDB_BINLOG 03459 int ha_reset_logs(THD *thd); 03460 int ha_binlog_index_purge_file(THD *thd, const char *file); 03461 void ha_reset_slave(THD *thd); 03462 void ha_binlog_log_query(THD *thd, handlerton *db_type, 03463 enum_binlog_command binlog_command, 03464 const char *query, uint query_length, 03465 const char *db, const char *table_name); 03466 void ha_binlog_wait(THD *thd); 03467 #else 03468 #define ha_reset_logs(a) do {} while (0) 03469 #define ha_binlog_index_purge_file(a,b) do {} while (0) 03470 #define ha_reset_slave(a) do {} while (0) 03471 #define ha_binlog_log_query(a,b,c,d,e,f,g) do {} while (0) 03472 #define ha_binlog_wait(a) do {} while (0) 03473 #endif 03474 03475 /* It is required by basic binlog features on both MySQL server and libmysqld */ 03476 int ha_binlog_end(THD *thd); 03477 03478 const char *ha_legacy_type_name(legacy_db_type legacy_type); 03479 const char *get_canonical_filename(handler *file, const char *path, 03480 char *tmp_path); 03481 bool mysql_xa_recover(THD *thd); 03482 03483 03484 inline const char *table_case_name(HA_CREATE_INFO *info, const char *name) 03485 { 03486 return ((lower_case_table_names == 2 && info->alias) ? info->alias : name); 03487 } 03488 03489 void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag); 03490 void print_keydup_error(TABLE *table, KEY *key, myf errflag); 03491 03492 #endif /* HANDLER_INCLUDED */