summaryrefslogtreecommitdiff
path: root/sql/handler.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.h')
-rw-r--r--sql/handler.h943
1 files changed, 716 insertions, 227 deletions
diff --git a/sql/handler.h b/sql/handler.h
index a777b7c595a..1c336e7e35f 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -25,7 +25,6 @@
#pragma interface /* gcc class implementation */
#endif
-#include <my_global.h> /* For handlers */
#include "sql_const.h"
#include "sql_basic_types.h"
#include "mysqld.h" /* server_id */
@@ -35,6 +34,7 @@
#include "structs.h" /* SHOW_COMP_OPTION */
#include "sql_array.h" /* Dynamic_array<> */
#include "mdl.h"
+#include "vers_string.h"
#include "sql_analyze_stmt.h" // for Exec_time_tracker
@@ -42,9 +42,11 @@
#include <ft_global.h>
#include <keycache.h>
#include <mysql/psi/mysql_table.h>
+#include "sql_sequence.h"
class Alter_info;
class Virtual_column_info;
+class sequence_definition;
// the following is for checking tables
@@ -71,11 +73,14 @@ class Virtual_column_info;
*/
enum enum_alter_inplace_result {
HA_ALTER_ERROR,
+ HA_ALTER_INPLACE_COPY_NO_LOCK,
+ HA_ALTER_INPLACE_COPY_LOCK,
+ HA_ALTER_INPLACE_NOCOPY_LOCK,
+ HA_ALTER_INPLACE_NOCOPY_NO_LOCK,
+ HA_ALTER_INPLACE_INSTANT,
HA_ALTER_INPLACE_NOT_SUPPORTED,
HA_ALTER_INPLACE_EXCLUSIVE_LOCK,
- HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE,
HA_ALTER_INPLACE_SHARED_LOCK,
- HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE,
HA_ALTER_INPLACE_NO_LOCK
};
@@ -146,7 +151,6 @@ enum enum_alter_inplace_result {
#define HA_HAS_OLD_CHECKSUM (1ULL << 24)
/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1ULL << 26)
-#define HA_NO_VARCHAR (1ULL << 27) /* unused */
#define HA_CAN_BIT_FIELD (1ULL << 28) /* supports bit fields */
#define HA_NEED_READ_RANGE_BUFFER (1ULL << 29) /* for read_multi_range */
#define HA_ANY_INDEX_MAY_BE_UNIQUE (1ULL << 30)
@@ -160,6 +164,7 @@ enum enum_alter_inplace_result {
*/
#define HA_BINLOG_ROW_CAPABLE (1ULL << 34)
#define HA_BINLOG_STMT_CAPABLE (1ULL << 35)
+
/*
When a multiple key conflict happens in a REPLACE command mysql
expects the conflicts to be reported in the ascending order of
@@ -262,11 +267,43 @@ enum enum_alter_inplace_result {
#define HA_CONCURRENT_OPTIMIZE (1ULL << 46)
/*
+ If the storage engine support tables that will not roll back on commit
+ In addition the table should not lock rows and support READ and WRITE
+ UNCOMMITTED.
+ This is useful for implementing things like SEQUENCE but can also in
+ the future be useful to do logging that should never roll back.
+*/
+#define HA_CAN_TABLES_WITHOUT_ROLLBACK (1ULL << 47)
+
+/*
+ Mainly for usage by SEQUENCE engine. Setting this flag means
+ that the table will never roll back and that all operations
+ for this table should stored in the non transactional log
+ space that will always be written, even on rollback.
+*/
+
+#define HA_PERSISTENT_TABLE (1ULL << 48)
+
+/*
Set of all binlog flags. Currently only contain the capabilities
flags.
*/
#define HA_BINLOG_FLAGS (HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE)
+/* The following are used by Spider */
+#define HA_CAN_FORCE_BULK_UPDATE (1ULL << 50)
+#define HA_CAN_FORCE_BULK_DELETE (1ULL << 51)
+#define HA_CAN_DIRECT_UPDATE_AND_DELETE (1ULL << 52)
+
+/* The following is for partition handler */
+#define HA_CAN_MULTISTEP_MERGE (1LL << 53)
+
+/* calling cmp_ref() on the engine is expensive */
+#define HA_CMP_REF_IS_EXPENSIVE (1ULL << 54)
+
+/* Engine wants primary keys for everything except sequences */
+#define HA_WANTS_PRIMARY_KEY (1ULL << 55)
+
/* bits in index_flags(index_number) for what you can do with index */
#define HA_READ_NEXT 1 /* TODO really use this flag */
#define HA_READ_PREV 2 /* supports ::index_prev */
@@ -386,6 +423,8 @@ enum enum_alter_inplace_result {
#define HA_LEX_CREATE_TMP_TABLE 1U
#define HA_CREATE_TMP_ALTER 8U
+#define HA_LEX_CREATE_SEQUENCE 16U
+#define HA_VERSIONED_TABLE 32U
#define HA_MAX_REC_LENGTH 65535
@@ -421,6 +460,12 @@ static const uint MYSQL_START_TRANS_OPT_READ_WRITE = 4;
#define HA_CHECK_DUP (HA_CHECK_DUP_KEY + HA_CHECK_DUP_UNIQUE)
#define HA_CHECK_ALL (~0U)
+/* Options for info_push() */
+#define INFO_KIND_UPDATE_FIELDS 101
+#define INFO_KIND_UPDATE_VALUES 102
+#define INFO_KIND_FORCE_LIMIT_BEGIN 103
+#define INFO_KIND_FORCE_LIMIT_END 104
+
enum legacy_db_type
{
/* note these numerical values are fixed and can *not* be changed */
@@ -440,7 +485,8 @@ enum legacy_db_type
DB_TYPE_PERFORMANCE_SCHEMA=28,
DB_TYPE_ARIA=42,
DB_TYPE_TOKUDB=43,
- DB_TYPE_FIRST_DYNAMIC=44,
+ DB_TYPE_SEQUENCE=44,
+ DB_TYPE_FIRST_DYNAMIC=45,
DB_TYPE_DEFAULT=127 // Must be last
};
/*
@@ -528,6 +574,187 @@ given at all. */
*/
#define HA_CREATE_USED_STATS_SAMPLE_PAGES (1UL << 24)
+/* Create a sequence */
+#define HA_CREATE_USED_SEQUENCE (1UL << 25)
+
+typedef ulonglong alter_table_operations;
+
+/*
+ These flags are set by the parser and describes the type of
+ operation(s) specified by the ALTER TABLE statement.
+*/
+
+// Set by parser for ADD [COLUMN]
+#define ALTER_PARSER_ADD_COLUMN (1ULL << 0)
+// Set by parser for DROP [COLUMN]
+#define ALTER_PARSER_DROP_COLUMN (1ULL << 1)
+// Set for CHANGE [COLUMN] | MODIFY [CHANGE] & mysql_recreate_table
+#define ALTER_CHANGE_COLUMN (1ULL << 2)
+// Set for ADD INDEX | ADD KEY | ADD PRIMARY KEY | ADD UNIQUE KEY |
+// ADD UNIQUE INDEX | ALTER ADD [COLUMN]
+#define ALTER_ADD_INDEX (1ULL << 3)
+// Set for DROP PRIMARY KEY | DROP FOREIGN KEY | DROP KEY | DROP INDEX
+#define ALTER_DROP_INDEX (1ULL << 4)
+// Set for RENAME [TO]
+#define ALTER_RENAME (1ULL << 5)
+// Set for ORDER BY
+#define ALTER_ORDER (1ULL << 6)
+// Set for table_options, like table comment
+#define ALTER_OPTIONS (1ULL << 7)
+// Set for ALTER [COLUMN] ... SET DEFAULT ... | DROP DEFAULT
+#define ALTER_CHANGE_COLUMN_DEFAULT (1ULL << 8)
+// Set for DISABLE KEYS | ENABLE KEYS
+#define ALTER_KEYS_ONOFF (1ULL << 9)
+// Set for FORCE, ENGINE(same engine), by mysql_recreate_table()
+#define ALTER_RECREATE (1ULL << 10)
+// Set for ADD FOREIGN KEY
+#define ALTER_ADD_FOREIGN_KEY (1ULL << 21)
+// Set for DROP FOREIGN KEY
+#define ALTER_DROP_FOREIGN_KEY (1ULL << 22)
+// Set for ADD [COLUMN] FIRST | AFTER
+#define ALTER_COLUMN_ORDER (1ULL << 25)
+#define ALTER_ADD_CHECK_CONSTRAINT (1ULL << 27)
+#define ALTER_DROP_CHECK_CONSTRAINT (1ULL << 28)
+#define ALTER_RENAME_COLUMN (1ULL << 29)
+#define ALTER_COLUMN_UNVERSIONED (1ULL << 30)
+#define ALTER_ADD_SYSTEM_VERSIONING (1ULL << 31)
+#define ALTER_DROP_SYSTEM_VERSIONING (1ULL << 32)
+#define ALTER_ADD_PERIOD (1ULL << 33)
+#define ALTER_DROP_PERIOD (1ULL << 34)
+
+/*
+ Following defines are used by ALTER_INPLACE_TABLE
+
+ They do describe in more detail the type operation(s) to be executed
+ by the storage engine. For example, which type of type of index to be
+ added/dropped. These are set by fill_alter_inplace_info().
+*/
+
+#define ALTER_RECREATE_TABLE ALTER_RECREATE
+#define ALTER_CHANGE_CREATE_OPTION ALTER_OPTIONS
+#define ALTER_ADD_COLUMN (ALTER_ADD_VIRTUAL_COLUMN | \
+ ALTER_ADD_STORED_BASE_COLUMN | \
+ ALTER_ADD_STORED_GENERATED_COLUMN)
+#define ALTER_DROP_COLUMN (ALTER_DROP_VIRTUAL_COLUMN | \
+ ALTER_DROP_STORED_COLUMN)
+#define ALTER_COLUMN_DEFAULT ALTER_CHANGE_COLUMN_DEFAULT
+
+// Add non-unique, non-primary index
+#define ALTER_ADD_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 35)
+
+// Drop non-unique, non-primary index
+#define ALTER_DROP_NON_UNIQUE_NON_PRIM_INDEX (1ULL << 36)
+
+// Add unique, non-primary index
+#define ALTER_ADD_UNIQUE_INDEX (1ULL << 37)
+
+// Drop unique, non-primary index
+#define ALTER_DROP_UNIQUE_INDEX (1ULL << 38)
+
+// Add primary index
+#define ALTER_ADD_PK_INDEX (1ULL << 39)
+
+// Drop primary index
+#define ALTER_DROP_PK_INDEX (1ULL << 40)
+
+// Virtual generated column
+#define ALTER_ADD_VIRTUAL_COLUMN (1ULL << 41)
+// Stored base (non-generated) column
+#define ALTER_ADD_STORED_BASE_COLUMN (1ULL << 42)
+// Stored generated column
+#define ALTER_ADD_STORED_GENERATED_COLUMN (1ULL << 43)
+
+// Drop column
+#define ALTER_DROP_VIRTUAL_COLUMN (1ULL << 44)
+#define ALTER_DROP_STORED_COLUMN (1ULL << 45)
+
+// Rename column (verified; ALTER_RENAME_COLUMN may use original name)
+#define ALTER_COLUMN_NAME (1ULL << 46)
+
+// Change column datatype
+#define ALTER_VIRTUAL_COLUMN_TYPE (1ULL << 47)
+#define ALTER_STORED_COLUMN_TYPE (1ULL << 48)
+
+/**
+ Change column datatype in such way that new type has compatible
+ packed representation with old type, so it is theoretically
+ possible to perform change by only updating data dictionary
+ without changing table rows.
+*/
+#define ALTER_COLUMN_EQUAL_PACK_LENGTH (1ULL << 49)
+
+// Reorder column
+#define ALTER_STORED_COLUMN_ORDER (1ULL << 50)
+
+// Reorder column
+#define ALTER_VIRTUAL_COLUMN_ORDER (1ULL << 51)
+
+// Change column from NOT NULL to NULL
+#define ALTER_COLUMN_NULLABLE (1ULL << 52)
+
+// Change column from NULL to NOT NULL
+#define ALTER_COLUMN_NOT_NULLABLE (1ULL << 53)
+
+// Change column generation expression
+#define ALTER_VIRTUAL_GCOL_EXPR (1ULL << 54)
+#define ALTER_STORED_GCOL_EXPR (1ULL << 55)
+
+// column's engine options changed, something in field->option_struct
+#define ALTER_COLUMN_OPTION (1ULL << 56)
+
+// MySQL alias for the same thing:
+#define ALTER_COLUMN_STORAGE_TYPE ALTER_COLUMN_OPTION
+
+// Change the column format of column
+#define ALTER_COLUMN_COLUMN_FORMAT (1ULL << 57)
+
+/**
+ Changes in generated columns that affect storage,
+ for example, when a vcol type or expression changes
+ and this vcol is indexed or used in a partitioning expression
+*/
+#define ALTER_COLUMN_VCOL (1ULL << 58)
+
+/**
+ ALTER TABLE for a partitioned table. The engine needs to commit
+ online alter of all partitions atomically (using group_commit_ctx)
+*/
+#define ALTER_PARTITIONED (1ULL << 59)
+
+/**
+ Change in index length such that it doesn't require index rebuild.
+*/
+#define ALTER_COLUMN_INDEX_LENGTH (1ULL << 60)
+
+/*
+ Flags set in partition_flags when altering partitions
+*/
+
+// Set for ADD PARTITION
+#define ALTER_PARTITION_ADD (1ULL << 1)
+// Set for DROP PARTITION
+#define ALTER_PARTITION_DROP (1ULL << 2)
+// Set for COALESCE PARTITION
+#define ALTER_PARTITION_COALESCE (1ULL << 3)
+// Set for REORGANIZE PARTITION ... INTO
+#define ALTER_PARTITION_REORGANIZE (1ULL << 4)
+// Set for partition_options
+#define ALTER_PARTITION_INFO (1ULL << 5)
+// Set for LOAD INDEX INTO CACHE ... PARTITION
+// Set for CACHE INDEX ... PARTITION
+#define ALTER_PARTITION_ADMIN (1ULL << 6)
+// Set for REBUILD PARTITION
+#define ALTER_PARTITION_REBUILD (1ULL << 7)
+// Set for partitioning operations specifying ALL keyword
+#define ALTER_PARTITION_ALL (1ULL << 8)
+// Set for REMOVE PARTITIONING
+#define ALTER_PARTITION_REMOVE (1ULL << 9)
+// Set for EXCHANGE PARITION
+#define ALTER_PARTITION_EXCHANGE (1ULL << 10)
+// Set by Sql_cmd_alter_table_truncate_partition::execute()
+#define ALTER_PARTITION_TRUNCATE (1ULL << 11)
+// Set for REORGANIZE PARTITION
+#define ALTER_PARTITION_TABLE_REORG (1ULL << 12)
/*
This is master database for most of system tables. However there
@@ -634,6 +861,15 @@ struct xid_t {
};
typedef struct xid_t XID;
+/*
+ The size of XID string representation in the form
+ 'gtrid', 'bqual', formatID
+ see xid_t::get_sql_string() for details.
+*/
+#define SQL_XIDSIZE (XIDDATASIZE * 2 + 8 + MY_INT64_NUM_DECIMAL_DIGITS)
+/* The 'buf' has to have space for at least SQL_XIDSIZE bytes. */
+uint get_sql_xid(XID *xid, char *buf);
+
/* for recover() handlerton call */
#define MIN_XID_LIST_SIZE 128
#define MAX_XID_LIST_SIZE (1024*128)
@@ -1203,7 +1439,7 @@ struct handlerton
bool (*flush_logs)(handlerton *hton);
bool (*show_status)(handlerton *hton, THD *thd, stat_print_fn *print, enum ha_stat_type stat);
uint (*partition_flags)();
- uint (*alter_table_flags)(uint flags);
+ alter_table_operations (*alter_table_flags)(alter_table_operations flags);
int (*alter_tablespace)(handlerton *hton, THD *thd, st_alter_tablespace *ts_info);
int (*fill_is_table)(handlerton *hton, THD *thd, TABLE_LIST *tables,
class Item *cond,
@@ -1323,7 +1559,7 @@ struct handlerton
Returns 0 on success and 1 on error.
*/
- int (*discover_table_names)(handlerton *hton, LEX_STRING *db, MY_DIR *dir,
+ int (*discover_table_names)(handlerton *hton, LEX_CSTRING *db, MY_DIR *dir,
discovered_list *result);
/*
@@ -1366,10 +1602,20 @@ struct handlerton
*/
int (*discover_table_structure)(handlerton *hton, THD* thd,
TABLE_SHARE *share, HA_CREATE_INFO *info);
+
+ /*
+ System Versioning
+ */
+ /** Determine if system-versioned data was modified by the transaction.
+ @param[in,out] thd current session
+ @param[out] trx_id transaction start ID
+ @return transaction commit ID
+ @retval 0 if no system-versioned data was affected by the transaction */
+ ulonglong (*prepare_commit_versioned)(THD *thd, ulonglong *trx_id);
};
-static inline LEX_STRING *hton_name(const handlerton *hton)
+static inline LEX_CSTRING *hton_name(const handlerton *hton)
{
return &(hton2plugin[hton->slot]->name);
}
@@ -1413,10 +1659,15 @@ handlerton *ha_default_tmp_handlerton(THD *thd);
*/
#define HTON_NO_BINLOG_ROW_OPT (1 << 9)
#define HTON_SUPPORTS_EXTENDED_KEYS (1 <<10) //supports extended keys
+#define HTON_NATIVE_SYS_VERSIONING (1 << 11) //Engine supports System Versioning
// MySQL compatibility. Unused.
#define HTON_SUPPORTS_FOREIGN_KEYS (1 << 0) //Foreign key constraint supported.
+#define HTON_CAN_MERGE (1 <<11) //Merge type table
+// Engine needs to access the main connect string in partitions
+#define HTON_CAN_READ_CONNECT_STRING_IN_PARTITION (1 <<12)
+
class Ha_trx_info;
struct THD_TRANS
@@ -1465,14 +1716,16 @@ struct THD_TRANS
unsigned int m_unsafe_rollback_flags;
/*
- Define the type of statemens which cannot be rolled back safely.
+ Define the type of statements which cannot be rolled back safely.
Each type occupies one bit in m_unsafe_rollback_flags.
*/
- static unsigned int const MODIFIED_NON_TRANS_TABLE= 0x01;
- static unsigned int const CREATED_TEMP_TABLE= 0x02;
- static unsigned int const DROPPED_TEMP_TABLE= 0x04;
- static unsigned int const DID_WAIT= 0x08;
- static unsigned int const DID_DDL= 0x10;
+ enum unsafe_statement_types
+ {
+ CREATED_TEMP_TABLE= 2,
+ DROPPED_TEMP_TABLE= 4,
+ DID_WAIT= 8,
+ DID_DDL= 0x10
+ };
void mark_created_temp_table()
{
@@ -1492,6 +1745,7 @@ struct THD_TRANS
bool trans_did_wait() const {
return (m_unsafe_rollback_flags & DID_WAIT) != 0;
}
+ bool is_trx_read_write() const;
void mark_trans_did_ddl() { m_unsafe_rollback_flags|= DID_DDL; }
bool trans_did_ddl() const {
return (m_unsafe_rollback_flags & DID_DDL) != 0;
@@ -1596,6 +1850,16 @@ private:
};
+inline bool THD_TRANS::is_trx_read_write() const
+{
+ Ha_trx_info *ha_info;
+ for (ha_info= ha_list; ha_info; ha_info= ha_info->next())
+ if (ha_info->is_trx_read_write())
+ return TRUE;
+ return FALSE;
+}
+
+
enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
ISO_REPEATABLE_READ, ISO_SERIALIZABLE};
@@ -1604,6 +1868,7 @@ typedef struct {
ulonglong data_file_length;
ulonglong max_data_file_length;
ulonglong index_file_length;
+ ulonglong max_index_file_length;
ulonglong delete_length;
ha_rows records;
ulong mean_rec_length;
@@ -1645,6 +1910,98 @@ struct Schema_specification_st
}
};
+class Create_field;
+
+enum vers_sys_type_t
+{
+ VERS_UNDEFINED= 0,
+ VERS_TIMESTAMP,
+ VERS_TRX_ID
+};
+
+extern const LEX_CSTRING null_clex_str;
+
+struct Vers_parse_info
+{
+ Vers_parse_info() :
+ check_unit(VERS_UNDEFINED),
+ versioned_fields(false),
+ unversioned_fields(false)
+ {}
+
+ void init() // Deep initialization
+ {
+ system_time= start_end_t(null_clex_str, null_clex_str);
+ as_row= start_end_t(null_clex_str, null_clex_str);
+ check_unit= VERS_UNDEFINED;
+ versioned_fields= false;
+ unversioned_fields= false;
+ }
+
+ struct start_end_t
+ {
+ start_end_t()
+ {}
+ start_end_t(LEX_CSTRING _start, LEX_CSTRING _end) :
+ start(_start),
+ end(_end) {}
+ Lex_ident start;
+ Lex_ident end;
+ };
+
+ start_end_t system_time;
+ start_end_t as_row;
+ vers_sys_type_t check_unit;
+
+ void set_system_time(Lex_ident start, Lex_ident end)
+ {
+ system_time.start= start;
+ system_time.end= end;
+ }
+
+protected:
+ friend struct Table_scope_and_contents_source_st;
+ void set_start(const LEX_CSTRING field_name)
+ {
+ as_row.start= field_name;
+ system_time.start= field_name;
+ }
+ void set_end(const LEX_CSTRING field_name)
+ {
+ as_row.end= field_name;
+ system_time.end= field_name;
+ }
+ bool is_start(const char *name) const;
+ bool is_end(const char *name) const;
+ bool is_start(const Create_field &f) const;
+ bool is_end(const Create_field &f) const;
+ bool fix_implicit(THD *thd, Alter_info *alter_info);
+ operator bool() const
+ {
+ return as_row.start || as_row.end || system_time.start || system_time.end;
+ }
+ bool need_check(const Alter_info *alter_info) const;
+ bool check_conditions(const Lex_table_name &table_name,
+ const Lex_table_name &db) const;
+public:
+ static const Lex_ident default_start;
+ static const Lex_ident default_end;
+
+ bool fix_alter_info(THD *thd, Alter_info *alter_info,
+ HA_CREATE_INFO *create_info, TABLE *table);
+ bool fix_create_like(Alter_info &alter_info, HA_CREATE_INFO &create_info,
+ TABLE_LIST &src_table, TABLE_LIST &table);
+ bool check_sys_fields(const Lex_table_name &table_name,
+ const Lex_table_name &db,
+ Alter_info *alter_info);
+
+ /**
+ At least one field was specified 'WITH/WITHOUT SYSTEM VERSIONING'.
+ Useful for error handling.
+ */
+ bool versioned_fields : 1;
+ bool unversioned_fields : 1;
+};
/**
A helper struct for table DDL statements, e.g.:
@@ -1660,15 +2017,15 @@ struct Schema_specification_st
- [AS] SELECT ... // Copy structure from a subquery
*/
-struct Table_scope_and_contents_source_st
+struct Table_scope_and_contents_source_pod_st // For trivial members
{
CHARSET_INFO *table_charset;
LEX_CUSTRING tabledef_version;
- LEX_STRING connect_string;
+ LEX_CSTRING connect_string;
+ LEX_CSTRING comment;
+ LEX_CSTRING alias;
const char *password, *tablespace;
- LEX_STRING comment;
const char *data_file_name, *index_file_name;
- const char *alias;
ulonglong max_rows,min_rows;
ulonglong auto_increment_value;
ulong table_options; ///< HA_OPTION_ values
@@ -1703,6 +2060,7 @@ struct Table_scope_and_contents_source_st
engine_option_value *option_list; ///< list of table create options
enum_stats_auto_recalc stats_auto_recalc;
bool varchar; ///< 1 if table has a VARCHAR
+ bool sequence; // If SEQUENCE=1 was used
List<Virtual_column_info> *check_constraint_list;
@@ -1714,9 +2072,10 @@ struct Table_scope_and_contents_source_st
/* The following is used to remember the old state for CREATE OR REPLACE */
TABLE *table;
TABLE_LIST *pos_in_locked_tables;
+ TABLE_LIST *merge_list;
MDL_ticket *mdl_ticket;
bool table_was_deleted;
- TABLE_LIST *merge_list;
+ sequence_definition *seq_create_info;
void init()
{
@@ -1728,6 +2087,32 @@ struct Table_scope_and_contents_source_st
db_type= tmp_table() ? ha_default_tmp_handlerton(thd)
: ha_default_handlerton(thd);
}
+
+ bool versioned() const
+ {
+ return options & HA_VERSIONED_TABLE;
+ }
+};
+
+
+struct Table_scope_and_contents_source_st:
+ public Table_scope_and_contents_source_pod_st
+{
+ Vers_parse_info vers_info;
+
+ void init()
+ {
+ Table_scope_and_contents_source_pod_st::init();
+ vers_info.init();
+ }
+
+ bool vers_fix_system_fields(THD *thd, Alter_info *alter_info,
+ const TABLE_LIST &create_table,
+ bool create_select= false);
+
+ bool vers_check_system_fields(THD *thd, Alter_info *alter_info,
+ const TABLE_LIST &create_table);
+
};
@@ -1849,163 +2234,6 @@ public:
class Alter_inplace_info
{
public:
- /**
- Bits to show in detail what operations the storage engine is
- to execute.
-
- All these operations are supported as in-place operations by the
- SQL layer. This means that operations that by their nature must
- be performed by copying the table to a temporary table, will not
- have their own flags here.
-
- We generally try to specify handler flags only if there are real
- changes. But in cases when it is cumbersome to determine if some
- attribute has really changed we might choose to set flag
- pessimistically, for example, relying on parser output only.
- */
- typedef ulonglong HA_ALTER_FLAGS;
-
- // Add non-unique, non-primary index
- static const HA_ALTER_FLAGS ADD_INDEX = 1ULL << 0;
-
- // Drop non-unique, non-primary index
- static const HA_ALTER_FLAGS DROP_INDEX = 1ULL << 1;
-
- // Add unique, non-primary index
- static const HA_ALTER_FLAGS ADD_UNIQUE_INDEX = 1ULL << 2;
-
- // Drop unique, non-primary index
- static const HA_ALTER_FLAGS DROP_UNIQUE_INDEX = 1ULL << 3;
-
- // Add primary index
- static const HA_ALTER_FLAGS ADD_PK_INDEX = 1ULL << 4;
-
- // Drop primary index
- static const HA_ALTER_FLAGS DROP_PK_INDEX = 1ULL << 5;
-
- // Virtual generated column
- static const HA_ALTER_FLAGS ADD_VIRTUAL_COLUMN = 1ULL << 6;
- // Stored base (non-generated) column
- static const HA_ALTER_FLAGS ADD_STORED_BASE_COLUMN = 1ULL << 7;
- // Stored generated column
- static const HA_ALTER_FLAGS ADD_STORED_GENERATED_COLUMN= 1ULL << 8;
- // Add generic column (convience constant).
- static const HA_ALTER_FLAGS ADD_COLUMN= ADD_VIRTUAL_COLUMN |
- ADD_STORED_BASE_COLUMN |
- ADD_STORED_GENERATED_COLUMN;
-
- // Drop column
- static const HA_ALTER_FLAGS DROP_VIRTUAL_COLUMN = 1ULL << 9;
- static const HA_ALTER_FLAGS DROP_STORED_COLUMN = 1ULL << 10;
- static const HA_ALTER_FLAGS DROP_COLUMN= DROP_VIRTUAL_COLUMN |
- DROP_STORED_COLUMN;
-
- // Rename column
- static const HA_ALTER_FLAGS ALTER_COLUMN_NAME = 1ULL << 11;
-
- // Change column datatype
- static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_TYPE = 1ULL << 12;
- static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_TYPE = 1ULL << 13;
-
- /**
- Change column datatype in such way that new type has compatible
- packed representation with old type, so it is theoretically
- possible to perform change by only updating data dictionary
- without changing table rows.
- */
- static const HA_ALTER_FLAGS ALTER_COLUMN_EQUAL_PACK_LENGTH = 1ULL << 14;
-
- // Reorder column
- static const HA_ALTER_FLAGS ALTER_STORED_COLUMN_ORDER = 1ULL << 15;
-
- // Reorder column
- static const HA_ALTER_FLAGS ALTER_VIRTUAL_COLUMN_ORDER = 1ULL << 16;
-
- // Change column from NOT NULL to NULL
- static const HA_ALTER_FLAGS ALTER_COLUMN_NULLABLE = 1ULL << 17;
-
- // Change column from NULL to NOT NULL
- static const HA_ALTER_FLAGS ALTER_COLUMN_NOT_NULLABLE = 1ULL << 18;
-
- // Set or remove default column value
- static const HA_ALTER_FLAGS ALTER_COLUMN_DEFAULT = 1ULL << 19;
-
- // Change column generation expression
- static const HA_ALTER_FLAGS ALTER_VIRTUAL_GCOL_EXPR = 1ULL << 20;
- static const HA_ALTER_FLAGS ALTER_STORED_GCOL_EXPR = 1ULL << 21;
- //
- // Add foreign key
- static const HA_ALTER_FLAGS ADD_FOREIGN_KEY = 1ULL << 22;
-
- // Drop foreign key
- static const HA_ALTER_FLAGS DROP_FOREIGN_KEY = 1ULL << 23;
-
- // table_options changed, see HA_CREATE_INFO::used_fields for details.
- static const HA_ALTER_FLAGS CHANGE_CREATE_OPTION = 1ULL << 24;
-
- // Table is renamed
- static const HA_ALTER_FLAGS ALTER_RENAME = 1ULL << 25;
-
- // column's engine options changed, something in field->option_struct
- static const HA_ALTER_FLAGS ALTER_COLUMN_OPTION = 1ULL << 26;
-
- // MySQL alias for the same thing:
- static const HA_ALTER_FLAGS ALTER_COLUMN_STORAGE_TYPE = 1ULL << 26;
-
- // Change the column format of column
- static const HA_ALTER_FLAGS ALTER_COLUMN_COLUMN_FORMAT = 1ULL << 27;
-
- // Add partition
- static const HA_ALTER_FLAGS ADD_PARTITION = 1ULL << 28;
-
- // Drop partition
- static const HA_ALTER_FLAGS DROP_PARTITION = 1ULL << 29;
-
- // Changing partition options
- static const HA_ALTER_FLAGS ALTER_PARTITION = 1ULL << 30;
-
- // Coalesce partition
- static const HA_ALTER_FLAGS COALESCE_PARTITION = 1ULL << 31;
-
- // Reorganize partition ... into
- static const HA_ALTER_FLAGS REORGANIZE_PARTITION = 1ULL << 32;
-
- // Reorganize partition
- static const HA_ALTER_FLAGS ALTER_TABLE_REORG = 1ULL << 33;
-
- // Remove partitioning
- static const HA_ALTER_FLAGS ALTER_REMOVE_PARTITIONING = 1ULL << 34;
-
- // Partition operation with ALL keyword
- static const HA_ALTER_FLAGS ALTER_ALL_PARTITION = 1ULL << 35;
-
- /**
- Recreate the table for ALTER TABLE FORCE, ALTER TABLE ENGINE
- and OPTIMIZE TABLE operations.
- */
- static const HA_ALTER_FLAGS RECREATE_TABLE = 1ULL << 36;
-
- /**
- Changes in generated columns that affect storage,
- for example, when a vcol type or expression changes
- and this vcol is indexed or used in a partitioning expression
- */
- static const HA_ALTER_FLAGS ALTER_COLUMN_VCOL = 1ULL << 37;
-
- /**
- ALTER TABLE for a partitioned table. The engine needs to commit
- online alter of all partitions atomically (using group_commit_ctx)
- */
- static const HA_ALTER_FLAGS ALTER_PARTITIONED = 1ULL << 38;
-
- static const HA_ALTER_FLAGS ALTER_ADD_CHECK_CONSTRAINT = 1ULL << 39;
-
- static const HA_ALTER_FLAGS ALTER_DROP_CHECK_CONSTRAINT= 1ULL << 40;
-
- /**
- Change in index length such that it doesn't require index rebuild.
- */
- static const HA_ALTER_FLAGS ALTER_COLUMN_INDEX_LENGTH= 1ULL << 41;
/**
Create options (like MAX_ROWS) for the new version of table.
@@ -2090,9 +2318,13 @@ public:
inplace_alter_handler_ctx **group_commit_ctx;
/**
- Flags describing in detail which operations the storage engine is to execute.
+ Flags describing in detail which operations the storage engine is to
+ execute. Flags are defined in sql_alter.h
*/
- HA_ALTER_FLAGS handler_flags;
+ alter_table_operations handler_flags;
+
+ /* Alter operations involving parititons are strored here */
+ ulong partition_flags;
/**
Partition_info taking into account the partition changes to be performed.
@@ -2111,8 +2343,7 @@ public:
/**
Can be set by handler to describe why a given operation cannot be done
in-place (HA_ALTER_INPLACE_NOT_SUPPORTED) or why it cannot be done
- online (HA_ALTER_INPLACE_NO_LOCK or
- HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE)
+ online (HA_ALTER_INPLACE_NO_LOCK or HA_ALTER_INPLACE_COPY_NO_LOCK)
If set, it will be used with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON if
results from handler::check_if_supported_inplace_alter() doesn't match
requirements set by user. If not set, the more generic
@@ -2160,7 +2391,7 @@ public:
replace not_supported with.
*/
void report_unsupported_error(const char *not_supported,
- const char *try_instead);
+ const char *try_instead) const;
};
@@ -2168,8 +2399,9 @@ typedef struct st_key_create_information
{
enum ha_key_alg algorithm;
ulong block_size;
- LEX_STRING parser_name;
- LEX_STRING comment;
+ uint flags; /* HA_USE.. flags */
+ LEX_CSTRING parser_name;
+ LEX_CSTRING comment;
/**
A flag to determine if we will check for duplicate indexes.
This typically means that the key information was specified
@@ -2549,6 +2781,7 @@ public:
time_t check_time;
time_t update_time;
uint block_size; /* index block size */
+ ha_checksum checksum;
/*
number of buffer bytes that native mrr implementation needs,
@@ -2557,9 +2790,10 @@ public:
ha_statistics():
data_file_length(0), max_data_file_length(0),
- index_file_length(0), delete_length(0), auto_increment_value(0),
- records(0), deleted(0), mean_rec_length(0), create_time(0),
- check_time(0), update_time(0), block_size(0), mrr_length_per_rec(0)
+ index_file_length(0), max_index_file_length(0), delete_length(0),
+ auto_increment_value(0), records(0), deleted(0), mean_rec_length(0),
+ create_time(0), check_time(0), update_time(0), block_size(0),
+ mrr_length_per_rec(0)
{}
};
@@ -2675,6 +2909,8 @@ public:
bool mark_trx_read_write_done; /* mark_trx_read_write was called */
bool check_table_binlog_row_based_done; /* check_table_binlog.. was called */
bool check_table_binlog_row_based_result; /* cached check_table_binlog... */
+ /* Set to 1 if handler logged last insert/update/delete operation */
+ bool row_already_logged;
/*
TRUE <=> the engine guarantees that returned records are within the range
being scanned.
@@ -2688,7 +2924,8 @@ public:
/** Length of ref (1-8 or the clustered key length) */
uint ref_length;
FT_INFO *ft_handler;
- enum {NONE=0, INDEX, RND} inited;
+ enum init_stat { NONE=0, INDEX, RND };
+ init_stat inited, pre_inited;
const COND *pushed_cond;
/**
@@ -2754,6 +2991,11 @@ public:
virtual void unbind_psi();
virtual void rebind_psi();
+ bool set_top_table_fields;
+ struct TABLE *top_table;
+ Field **top_table_field;
+ uint top_table_fields;
+
private:
/**
The lock type set by when calling::ha_external_lock(). This is
@@ -2777,17 +3019,20 @@ public:
mark_trx_read_write_done(0),
check_table_binlog_row_based_done(0),
check_table_binlog_row_based_result(0),
+ row_already_logged(0),
in_range_check_pushed_down(FALSE),
key_used_on_scan(MAX_KEY),
active_index(MAX_KEY), keyread(MAX_KEY),
ref_length(sizeof(my_off_t)),
- ft_handler(0), inited(NONE),
+ ft_handler(0), inited(NONE), pre_inited(NONE),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
tracker(NULL),
pushed_idx_cond(NULL),
pushed_idx_cond_keyno(MAX_KEY),
auto_inc_intervals_count(0),
- m_psi(NULL), m_lock_type(F_UNLCK), ha_share(NULL)
+ m_psi(NULL), set_top_table_fields(FALSE), top_table(0),
+ top_table_field(0), top_table_fields(0),
+ m_lock_type(F_UNLCK), ha_share(NULL)
{
DBUG_PRINT("info",
("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d",
@@ -2807,7 +3052,8 @@ public:
}
/* ha_ methods: pubilc wrappers for private virtual API */
- int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked);
+ int ha_open(TABLE *table, const char *name, int mode, uint test_if_locked,
+ MEM_ROOT *mem_root= 0, List<String> *partitions_to_open=NULL);
int ha_index_init(uint idx, bool sorted)
{
DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;);
@@ -2880,7 +3126,7 @@ public:
*/
int ha_external_lock(THD *thd, int lock_type);
int ha_write_row(uchar * buf);
- int ha_update_row(const uchar * old_data, uchar * new_data);
+ int ha_update_row(const uchar * old_data, const uchar * new_data);
int ha_delete_row(const uchar * buf);
void ha_release_auto_increment();
@@ -2918,8 +3164,8 @@ public:
int ret= end_bulk_insert();
DBUG_RETURN(ret);
}
- int ha_bulk_update_row(const uchar *old_data, uchar *new_data,
- uint *dup_key_found);
+ int ha_bulk_update_row(const uchar *old_data, const uchar *new_data,
+ ha_rows *dup_key_found);
int ha_delete_all_rows();
int ha_truncate();
int ha_reset_auto_increment(ulonglong value);
@@ -3013,8 +3259,24 @@ public:
virtual double keyread_time(uint index, uint ranges, ha_rows rows);
virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
+
+ /*
+ True if changes to the table is persistent (no rollback)
+ This is manly used to decide how to log changes to the table in
+ the binary log.
+ */
bool has_transactions()
- { return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
+ {
+ return ((ha_table_flags() & (HA_NO_TRANSACTIONS | HA_PERSISTENT_TABLE))
+ == 0);
+ }
+ /*
+ True if the underlaying table doesn't support transactions
+ */
+ bool has_transaction_manager()
+ {
+ return ((ha_table_flags() & HA_NO_TRANSACTIONS) == 0);
+ }
/**
This method is used to analyse the error to see whether the error
@@ -3044,6 +3306,7 @@ public:
Number of rows in table. It will only be called if
(table_flags() & (HA_HAS_RECORDS | HA_STATS_RECORDS_IS_EXACT)) != 0
*/
+ virtual int pre_records() { return 0; }
virtual ha_rows records() { return stats.records; }
/**
Return upper bound of current number of records in the table
@@ -3100,7 +3363,7 @@ public:
@retval 0 Success
@retval >0 Error code
*/
- virtual int exec_bulk_update(uint *dup_key_found)
+ virtual int exec_bulk_update(ha_rows *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
@@ -3109,7 +3372,7 @@ public:
Perform any needed clean-up, no outstanding updates are there at the
moment.
*/
- virtual void end_bulk_update() { return; }
+ virtual int end_bulk_update() { return 0; }
/**
Execute all outstanding deletes and close down the bulk delete.
@@ -3121,6 +3384,83 @@ public:
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
}
+ virtual int pre_index_read_map(const uchar *key,
+ key_part_map keypart_map,
+ enum ha_rkey_function find_flag,
+ bool use_parallel)
+ { return 0; }
+ virtual int pre_index_first(bool use_parallel)
+ { return 0; }
+ virtual int pre_index_last(bool use_parallel)
+ { return 0; }
+ virtual int pre_index_read_last_map(const uchar *key,
+ key_part_map keypart_map,
+ bool use_parallel)
+ { return 0; }
+/*
+ virtual int pre_read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
+ KEY_MULTI_RANGE *ranges,
+ uint range_count,
+ bool sorted, HANDLER_BUFFER *buffer,
+ bool use_parallel);
+*/
+ virtual int pre_multi_range_read_next(bool use_parallel)
+ { return 0; }
+ virtual int pre_read_range_first(const key_range *start_key,
+ const key_range *end_key,
+ bool eq_range, bool sorted,
+ bool use_parallel)
+ { return 0; }
+ virtual int pre_ft_read(bool use_parallel)
+ { return 0; }
+ virtual int pre_rnd_next(bool use_parallel)
+ { return 0; }
+ int ha_pre_rnd_init(bool scan)
+ {
+ int result;
+ DBUG_ENTER("ha_pre_rnd_init");
+ DBUG_ASSERT(pre_inited==NONE || (pre_inited==RND && scan));
+ pre_inited= (result= pre_rnd_init(scan)) ? NONE: RND;
+ DBUG_RETURN(result);
+ }
+ int ha_pre_rnd_end()
+ {
+ DBUG_ENTER("ha_pre_rnd_end");
+ DBUG_ASSERT(pre_inited==RND);
+ pre_inited=NONE;
+ DBUG_RETURN(pre_rnd_end());
+ }
+ virtual int pre_rnd_init(bool scan) { return 0; }
+ virtual int pre_rnd_end() { return 0; }
+ virtual int pre_index_init(uint idx, bool sorted) { return 0; }
+ virtual int pre_index_end() { return 0; }
+ int ha_pre_index_init(uint idx, bool sorted)
+ {
+ int result;
+ DBUG_ENTER("ha_pre_index_init");
+ DBUG_ASSERT(pre_inited==NONE);
+ if (!(result= pre_index_init(idx, sorted)))
+ pre_inited=INDEX;
+ DBUG_RETURN(result);
+ }
+ int ha_pre_index_end()
+ {
+ DBUG_ENTER("ha_pre_index_end");
+ DBUG_ASSERT(pre_inited==INDEX);
+ pre_inited=NONE;
+ DBUG_RETURN(pre_index_end());
+ }
+ int ha_pre_index_or_rnd_end()
+ {
+ return (pre_inited == INDEX ?
+ ha_pre_index_end() :
+ pre_inited == RND ? ha_pre_rnd_end() : 0 );
+ }
+ virtual bool vers_can_native(THD *thd)
+ {
+ return ht->flags & HTON_NATIVE_SYS_VERSIONING;
+ }
+
/**
@brief
Positions an index cursor to the index specified in the
@@ -3153,6 +3493,18 @@ protected:
virtual int index_last(uchar * buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int index_next_same(uchar *buf, const uchar *key, uint keylen);
+ /**
+ @brief
+ The following functions works like index_read, but it find the last
+ row with the current key value or prefix.
+ @returns @see index_read_map().
+ */
+ virtual int index_read_last_map(uchar * buf, const uchar * key,
+ key_part_map keypart_map)
+ {
+ uint key_len= calculate_key_len(table, active_index, key, keypart_map);
+ return index_read_last(buf, key, key_len);
+ }
virtual int close(void)=0;
inline void update_rows_read()
{
@@ -3229,10 +3581,12 @@ public:
int compare_key(key_range *range);
int compare_key2(key_range *range) const;
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
- void ft_end() { ft_handler=NULL; }
+ virtual int pre_ft_init() { return HA_ERR_WRONG_COMMAND; }
+ virtual void ft_end() {}
+ virtual int pre_ft_end() { return 0; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return NULL; }
-private:
+public:
virtual int ft_read(uchar *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(uchar *buf)=0;
virtual int rnd_pos(uchar * buf, uchar *pos)=0;
@@ -3260,6 +3614,7 @@ public:
/* Same as above, but with statistics */
inline int ha_ft_read(uchar *buf);
+ inline void ha_ft_end() { ft_end(); ft_handler=NULL; }
int ha_rnd_next(uchar *buf);
int ha_rnd_pos(uchar *buf, uchar *pos);
inline int ha_rnd_pos_by_record(uchar *buf);
@@ -3289,6 +3644,9 @@ public:
virtual int info(uint)=0; // see my_base.h for full description
virtual void get_dynamic_partition_info(PARTITION_STATS *stat_info,
uint part_id);
+ virtual void set_partitions_to_open(List<String> *partition_names) {}
+ virtual int change_partitions_to_open(List<String> *partition_names)
+ { return 0; }
virtual int extra(enum ha_extra_function operation)
{ return 0; }
virtual int extra_opt(enum ha_extra_function operation, ulong arg)
@@ -3317,6 +3675,8 @@ public:
virtual void try_semi_consistent_read(bool) {}
virtual void unlock_row() {}
virtual int start_stmt(THD *thd, thr_lock_type lock_type) {return 0;}
+ virtual bool need_info_for_auto_inc() { return 0; }
+ virtual bool can_use_for_auto_inc_init() { return 1; }
virtual void get_auto_increment(ulonglong offset, ulonglong increment,
ulonglong nb_desired_values,
ulonglong *first_value,
@@ -3424,6 +3784,7 @@ public:
return 0;
}
virtual void set_part_info(partition_info *part_info) {return;}
+ virtual void return_record_by_parent() { return; }
virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0;
@@ -3445,7 +3806,7 @@ public:
virtual uint max_supported_key_part_length() const { return 255; }
virtual uint min_record_length(uint options) const { return 1; }
- virtual uint checksum() const { return 0; }
+ virtual int calculate_checksum();
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair(int error) const { return 0; }
@@ -3512,7 +3873,7 @@ public:
cached
*/
- virtual my_bool register_query_cache_table(THD *thd, char *table_key,
+ virtual my_bool register_query_cache_table(THD *thd, const char *table_key,
uint key_length,
qc_engine_callback
*engine_callback,
@@ -3628,6 +3989,41 @@ public:
virtual void cond_pop() { return; };
/**
+ Push metadata for the current operation down to the table handler.
+ */
+ virtual int info_push(uint info_type, void *info) { return 0; };
+
+ /**
+ This function is used to get correlating of a parent (table/column)
+ and children (table/column). When conditions are pushed down to child
+ table (like child of myisam_merge), child table needs to know about
+ which table/column is my parent for understanding conditions.
+ */
+ virtual int set_top_table_and_fields(TABLE *top_table,
+ Field **top_table_field,
+ uint top_table_fields)
+ {
+ if (!set_top_table_fields)
+ {
+ set_top_table_fields= TRUE;
+ this->top_table= top_table;
+ this->top_table_field= top_table_field;
+ this->top_table_fields= top_table_fields;
+ }
+ return 0;
+ }
+ virtual void clear_top_table_fields()
+ {
+ if (set_top_table_fields)
+ {
+ set_top_table_fields= FALSE;
+ top_table= NULL;
+ top_table_field= NULL;
+ top_table_fields= 0;
+ }
+ }
+
+ /**
Push down an index condition to the handler.
The server will use this method to push down a condition it wants
@@ -3660,6 +4056,10 @@ public:
pushed_idx_cond_keyno= MAX_KEY;
in_range_check_pushed_down= false;
}
+
+ /* Needed for partition / spider */
+ virtual TABLE_LIST *get_next_global_for_child() { return NULL; }
+
/**
Part of old, deprecated in-place ALTER API.
*/
@@ -3711,8 +4111,8 @@ public:
*) As the first step, we acquire a lock corresponding to the concurrency
level which was returned by handler::check_if_supported_inplace_alter()
and requested by the user. This lock is held for most of the
- duration of in-place ALTER (if HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
- or HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE were returned we acquire an
+ duration of in-place ALTER (if HA_ALTER_INPLACE_COPY_LOCK
+ or HA_ALTER_INPLACE_COPY_NO_LOCK were returned we acquire an
exclusive lock for duration of the next step only).
*) After that we call handler::ha_prepare_inplace_alter_table() to give the
storage engine a chance to update its internal structures with a higher
@@ -3756,12 +4156,12 @@ public:
@retval HA_ALTER_ERROR Unexpected error.
@retval HA_ALTER_INPLACE_NOT_SUPPORTED Not supported, must use copy.
@retval HA_ALTER_INPLACE_EXCLUSIVE_LOCK Supported, but requires X lock.
- @retval HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE
+ @retval HA_ALTER_INPLACE_COPY_LOCK
Supported, but requires SNW lock
during main phase. Prepare phase
requires X lock.
@retval HA_ALTER_INPLACE_SHARED_LOCK Supported, but requires SNW lock.
- @retval HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE
+ @retval HA_ALTER_INPLACE_COPY_NO_LOCK
Supported, concurrent reads/writes
allowed. However, prepare phase
requires X lock.
@@ -3821,10 +4221,9 @@ protected:
/**
Allows the storage engine to update internal structures with concurrent
writes blocked. If check_if_supported_inplace_alter() returns
- HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE or
- HA_ALTER_INPLACE_SHARED_AFTER_PREPARE, this function is called with
- exclusive lock otherwise the same level of locking as for
- inplace_alter_table() will be used.
+ HA_ALTER_INPLACE_COPY_NO_LOCK or HA_ALTER_INPLACE_COPY_LOCK,
+ this function is called with exclusive lock otherwise the same level
+ of locking as for inplace_alter_table() will be used.
@note Storage engines are responsible for reporting any errors by
calling my_error()/print_error()
@@ -3934,14 +4333,14 @@ public:
but we don't have a primary key
*/
virtual void use_hidden_primary_key();
- virtual uint alter_table_flags(uint flags)
+ virtual alter_table_operations alter_table_flags(alter_table_operations flags)
{
if (ht->alter_table_flags)
return ht->alter_table_flags(flags);
return 0;
}
- LEX_STRING *engine_name() { return hton_name(ht); }
+ virtual LEX_CSTRING *engine_name();
TABLE* get_table() { return table; }
TABLE_SHARE* get_table_share() { return table_share; }
@@ -3971,7 +4370,8 @@ protected:
virtual int delete_table(const char *name);
public:
- inline bool check_table_binlog_row_based(bool binlog_row);
+ bool check_table_binlog_row_based(bool binlog_row);
+
inline void clear_cached_table_binlog_row_based_flag()
{
check_table_binlog_row_based_done= 0;
@@ -3987,6 +4387,8 @@ private:
mark_trx_read_write_internal();
}
}
+
+private:
void mark_trx_read_write_internal();
bool check_table_binlog_row_based_internal(bool binlog_row);
@@ -4033,15 +4435,64 @@ private:
message will contain garbage.
*/
virtual int update_row(const uchar *old_data __attribute__((unused)),
- uchar *new_data __attribute__((unused)))
+ const uchar *new_data __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
+ /*
+ Optimized function for updating the first row. Only used by sequence
+ tables
+ */
+ virtual int update_first_row(uchar *new_data);
+
virtual int delete_row(const uchar *buf __attribute__((unused)))
{
return HA_ERR_WRONG_COMMAND;
}
+
+ /* Perform initialization for a direct update request */
+public:
+ int ha_direct_update_rows(ha_rows *update_rows);
+ virtual int direct_update_rows_init(List<Item> *update_fields)
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+private:
+ virtual int pre_direct_update_rows_init(List<Item> *update_fields)
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int direct_update_rows(ha_rows *update_rows __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int pre_direct_update_rows()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+
+ /* Perform initialization for a direct delete request */
+public:
+ int ha_direct_delete_rows(ha_rows *delete_rows);
+ virtual int direct_delete_rows_init()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+private:
+ virtual int pre_direct_delete_rows_init()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int direct_delete_rows(ha_rows *delete_rows __attribute__((unused)))
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+ virtual int pre_direct_delete_rows()
+ {
+ return HA_ERR_WRONG_COMMAND;
+ }
+
/**
Reset state of file to after 'open'.
This function is called after every statement for all tables used
@@ -4099,7 +4550,13 @@ protected:
virtual int index_read(uchar * buf, const uchar * key, uint key_len,
enum ha_rkey_function find_flag)
{ return HA_ERR_WRONG_COMMAND; }
+ virtual int index_read_last(uchar * buf, const uchar * key, uint key_len)
+ {
+ my_errno= HA_ERR_WRONG_COMMAND;
+ return HA_ERR_WRONG_COMMAND;
+ }
friend class ha_partition;
+ friend class ha_sequence;
public:
/**
This method is similar to update_row, however the handler doesn't need
@@ -4114,8 +4571,8 @@ public:
@retval 0 Bulk delete used by handler
@retval 1 Bulk delete not used, normal operation used
*/
- virtual int bulk_update_row(const uchar *old_data, uchar *new_data,
- uint *dup_key_found)
+ virtual int bulk_update_row(const uchar *old_data, const uchar *new_data,
+ ha_rows *dup_key_found)
{
DBUG_ASSERT(FALSE);
return HA_ERR_WRONG_COMMAND;
@@ -4166,7 +4623,6 @@ public:
virtual int enable_indexes(uint mode) { return HA_ERR_WRONG_COMMAND; }
virtual int discard_or_import_tablespace(my_bool discard)
{ return (my_errno=HA_ERR_WRONG_COMMAND); }
- virtual void prepare_for_alter() { return; }
virtual void drop_table(const char *name);
virtual int create(const char *name, TABLE *form, HA_CREATE_INFO *info)=0;
@@ -4200,11 +4656,32 @@ public:
virtual handlerton *partition_ht() const
{ return ht; }
inline int ha_write_tmp_row(uchar *buf);
+ inline int ha_delete_tmp_row(uchar *buf);
inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data);
virtual void set_lock_type(enum thr_lock_type lock);
friend enum icp_result handler_index_cond_check(void* h_arg);
+
+ /**
+ Find unique record by index or unique constrain
+
+ @param record record to find (also will be fillded with
+ actual record fields)
+ @param unique_ref index or unique constraiun number (depends
+ on what used in the engine
+
+ @retval -1 Error
+ @retval 1 Not found
+ @retval 0 Found
+ */
+ virtual int find_unique_row(uchar *record, uint unique_ref)
+ { return -1; /*unsupported */}
+
+ bool native_versioned() const
+ { DBUG_ASSERT(ht); return partition_ht()->flags & HTON_NATIVE_SYS_VERSIONING; }
+ virtual void update_partition(uint part_id)
+ {}
protected:
Handler_share *get_ha_share_ptr();
void set_ha_share_ptr(Handler_share *arg_ha_share);
@@ -4227,7 +4704,7 @@ extern const char *myisam_stats_method_names[];
extern ulong total_ha, total_ha_2pc;
/* lookups */
-plugin_ref ha_resolve_by_name(THD *thd, const LEX_STRING *name, bool tmp_table);
+plugin_ref ha_resolve_by_name(THD *thd, const LEX_CSTRING *name, bool tmp_table);
plugin_ref ha_lock_engine(THD *thd, const handlerton *hton);
handlerton *ha_resolve_by_legacy_type(THD *thd, enum legacy_db_type db_type);
handler *get_new_handler(TABLE_SHARE *share, MEM_ROOT *alloc,
@@ -4282,7 +4759,7 @@ int ha_create_table(THD *thd, const char *path,
const char *db, const char *table_name,
HA_CREATE_INFO *create_info, LEX_CUSTRING *frm);
int ha_delete_table(THD *thd, handlerton *db_type, const char *path,
- const char *db, const char *alias, bool generate_warning);
+ const LEX_CSTRING *db, const LEX_CSTRING *alias, bool generate_warning);
/* statistics and info */
bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat);
@@ -4295,11 +4772,11 @@ class Discovered_table_list: public handlerton::discovered_list
const char *wild, *wend;
bool with_temps; // whether to include temp tables in the result
public:
- Dynamic_array<LEX_STRING*> *tables;
+ Dynamic_array<LEX_CSTRING*> *tables;
- Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_STRING*> *tables_arg,
- const LEX_STRING *wild_arg);
- Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_STRING*> *tables_arg)
+ Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_CSTRING*> *tables_arg,
+ const LEX_CSTRING *wild_arg);
+ Discovered_table_list(THD *thd_arg, Dynamic_array<LEX_CSTRING*> *tables_arg)
: thd(thd_arg), wild(NULL), with_temps(true), tables(tables_arg) {}
~Discovered_table_list() {}
@@ -4308,13 +4785,20 @@ public:
void sort();
void remove_duplicates(); // assumes that the list is sorted
+#ifndef DBUG_OFF
+ /*
+ Used to find unstable mtr tests querying
+ INFORMATION_SCHEMA.TABLES without ORDER BY.
+ */
+ void sort_desc();
+#endif
};
int ha_discover_table(THD *thd, TABLE_SHARE *share);
-int ha_discover_table_names(THD *thd, LEX_STRING *db, MY_DIR *dirp,
+int ha_discover_table_names(THD *thd, LEX_CSTRING *db, MY_DIR *dirp,
Discovered_table_list *result, bool reusable);
-bool ha_table_exists(THD *thd, const char *db, const char *table_name,
- handlerton **hton= 0);
+bool ha_table_exists(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table_name,
+ handlerton **hton= 0, bool *is_sequence= 0);
#endif
/* key cache */
@@ -4364,11 +4848,16 @@ const char *get_canonical_filename(handler *file, const char *path,
bool mysql_xa_recover(THD *thd);
void commit_checkpoint_notify_ha(handlerton *hton, void *cookie);
-inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
+inline const LEX_CSTRING *table_case_name(HA_CREATE_INFO *info, const LEX_CSTRING *name)
{
- return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
+ return ((lower_case_table_names == 2 && info->alias.str) ? &info->alias : name);
}
+typedef bool Log_func(THD*, TABLE*, bool, const uchar*, const uchar*);
+int binlog_log_row(TABLE* table,
+ const uchar *before_record,
+ const uchar *after_record,
+ Log_func *log_func);
#define TABLE_IO_WAIT(TRACKER, PSI, OP, INDEX, FLAGS, PAYLOAD) \
{ \
@@ -4386,5 +4875,5 @@ void print_keydup_error(TABLE *table, KEY *key, const char *msg, myf errflag);
void print_keydup_error(TABLE *table, KEY *key, myf errflag);
int del_global_index_stat(THD *thd, TABLE* table, KEY* key_info);
-int del_global_table_stat(THD *thd, LEX_STRING *db, LEX_STRING *table);
+int del_global_table_stat(THD *thd, const LEX_CSTRING *db, const LEX_CSTRING *table);
#endif /* HANDLER_INCLUDED */