1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00
checkpoint.
does not compile.
This commit is contained in:
Sergei Golubchik
2010-11-25 18:17:28 +01:00
2732 changed files with 867504 additions and 20901 deletions

View File

@ -1,6 +1,6 @@
#ifndef HANDLER_INCLUDED
#define HANDLER_INCLUDED
#error don't forget to merge mysql_priv.h!
/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
This program is free software; you can redistribute it and/or modify
@ -33,6 +33,10 @@
#include <ft_global.h>
#include <keycache.h>
#if MAX_KEY > 128
#error MAX_KEY is too large. Values up to 128 are supported.
#endif
// the following is for checking tables
#define HA_ADMIN_ALREADY_DONE 1
@ -113,7 +117,8 @@
#define HA_CAN_FULLTEXT (1 << 21)
#define HA_CAN_SQL_HANDLER (1 << 22)
#define HA_NO_AUTO_INCREMENT (1 << 23)
#define HA_HAS_CHECKSUM (1 << 24)
/* Has automatic checksums and uses the old checksum format */
#define HA_HAS_OLD_CHECKSUM (1 << 24)
/* Table data are stored in separate files (for lower_case_table_names) */
#define HA_FILE_BASED (1 << 26)
#define HA_NO_VARCHAR (1 << 27)
@ -153,6 +158,10 @@
ordered.
*/
#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36)
/* Has automatic checksums and uses the new checksum format */
#define HA_HAS_NEW_CHECKSUM (LL(1) << 37)
#define HA_MRR_CANT_SORT (LL(1) << 38)
/*
Set of all binlog flags. Currently only contain the capabilities
@ -168,6 +177,15 @@
#define HA_ONLY_WHOLE_INDEX 16 /* Can't use part key searches */
#define HA_KEYREAD_ONLY 64 /* Support HA_EXTRA_KEYREAD */
/*
Index scan will not return records in rowid order. Not guaranteed to be
set for unordered (e.g. HASH) indexes.
*/
#define HA_KEY_SCAN_NOT_ROR 128
#define HA_DO_INDEX_COND_PUSHDOWN 256 /* Supports Index Condition Pushdown */
/*
bits in alter_table_flags:
*/
@ -221,12 +239,6 @@
#define HA_FAST_CHANGE_PARTITION (1L << 13)
#define HA_PARTITION_ONE_PHASE (1L << 14)
/*
Index scan will not return records in rowid order. Not guaranteed to be
set for unordered (e.g. HASH) indexes.
*/
#define HA_KEY_SCAN_NOT_ROR 128
/* operations for disable/enable indexes */
#define HA_KEY_SWITCH_NONUNIQ 0
#define HA_KEY_SWITCH_ALL 1
@ -273,8 +285,6 @@
#define HA_LEX_CREATE_TMP_TABLE 1
#define HA_LEX_CREATE_IF_NOT_EXISTS 2
#define HA_LEX_CREATE_TABLE_LIKE 4
#define HA_OPTION_NO_CHECKSUM (1L << 17)
#define HA_OPTION_NO_DELAY_KEY_WRITE (1L << 18)
#define HA_MAX_REC_LENGTH 65535
/* Table caching type */
@ -315,6 +325,11 @@ enum legacy_db_type
DB_TYPE_FIRST_DYNAMIC=42,
DB_TYPE_DEFAULT=127 // Must be last
};
/*
Better name for DB_TYPE_UNKNOWN. Should be used for engines that do not have
a hard-coded type value here.
*/
#define DB_TYPE_AUTOASSIGN DB_TYPE_UNKNOWN
enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED,
@ -363,9 +378,8 @@ enum enum_binlog_command {
#define HA_CREATE_USED_PASSWORD (1L << 17)
#define HA_CREATE_USED_CONNECTION (1L << 18)
#define HA_CREATE_USED_KEY_BLOCK_SIZE (1L << 19)
/** Unused. Reserved for future versions. */
/* The following two are used by Maria engine: */
#define HA_CREATE_USED_TRANSACTIONAL (1L << 20)
/** Unused. Reserved for future versions. */
#define HA_CREATE_USED_PAGE_CHECKSUM (1L << 21)
typedef ulonglong my_xid; // this line is the same as in log_event.h
@ -546,6 +560,7 @@ struct TABLE;
enum enum_schema_tables
{
SCH_CHARSETS= 0,
SCH_CLIENT_STATS,
SCH_COLLATIONS,
SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
SCH_COLUMNS,
@ -555,15 +570,17 @@ enum enum_schema_tables
SCH_FILES,
SCH_GLOBAL_STATUS,
SCH_GLOBAL_VARIABLES,
SCH_INDEX_STATS,
SCH_KEY_CACHES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
SCH_PARAMETERS,
SCH_PARTITIONS,
SCH_PLUGINS,
SCH_PROCEDURES,
SCH_PROCESSLIST,
SCH_PROFILES,
SCH_REFERENTIAL_CONSTRAINTS,
SCH_PROCEDURES,
SCH_SCHEMATA,
SCH_SCHEMA_PRIVILEGES,
SCH_SESSION_STATUS,
@ -575,8 +592,10 @@ enum enum_schema_tables
SCH_TABLE_CONSTRAINTS,
SCH_TABLE_NAMES,
SCH_TABLE_PRIVILEGES,
SCH_TABLE_STATS,
SCH_TRIGGERS,
SCH_USER_PRIVILEGES,
SCH_USER_STATS,
SCH_VARIABLES,
SCH_VIEWS
};
@ -615,6 +634,103 @@ struct handler_log_file_data {
enum log_status status;
};
/*
Definitions for engine-specific table/field/index options in the CREATE TABLE.
Options are declared with HA_*OPTION_* macros (HA_TOPTION_NUMBER,
HA_FOPTION_ENUM, HA_IOPTION_STRING, etc).
Every macros takes the option name, and the name of the underlying field of
the appropriate C structure. The "appropriate C structure" is
ha_table_option_struct for table level options,
ha_field_option_struct for field level options,
ha_index_option_struct for key level options. The engine either
defines a structure of this name, or uses #define's to map
these "appropriate" names to the actual structure type name.
ULL options use a ulonglong as the backing store.
HA_*OPTION_NUMBER() takes the option name, the structure field name,
the default value for the option, min, max, and blk_siz values.
STRING options use a char* as a backing store.
HA_*OPTION_STRING takes the option name and the structure field name.
The default value will be 0.
ENUM options use a uint as a backing store (not enum!!!).
HA_*OPTION_ENUM takes the option name, the structure field name,
the default value for the option as a number, and a string with the
permitted values for this enum - one string with comma separated values,
for example: "gzip,bzip2,lzma"
BOOL options use a bool as a backing store.
HA_*OPTION_BOOL takes the option name, the structure field name,
and the default value for the option.
From the SQL, BOOL options accept YES/NO, ON/OFF, and 1/0.
The name of the option is limited to 255 bytes,
the value (for string options) - to the 32767 bytes.
See ha_example.cc for an example.
*/
enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */
HA_OPTION_TYPE_STRING, /* char * */
HA_OPTION_TYPE_ENUM, /* uint */
HA_OPTION_TYPE_BOOL}; /* bool */
#define HA_xOPTION_NUMBER(name, struc, field, def, min, max, blk_siz) \
{ HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \
offsetof(struc, field), def, min, max, blk_siz, 0 }
#define HA_xOPTION_STRING(name, struc, field) \
{ HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \
offsetof(struc, field), 0, 0, 0, 0, 0 }
#define HA_xOPTION_ENUM(name, struc, field, values, def) \
{ HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \
offsetof(struc, field), def, 0, \
sizeof(values)-1, 0, values }
#define HA_xOPTION_BOOL(name, struc, field, def) \
{ HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \
offsetof(struc, field), def, 0, 1, 0, 0 }
#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 }
#define HA_TOPTION_NUMBER(name, field, def, min, max, blk_siz) \
HA_xOPTION_NUMBER(name, ha_table_option_struct, field, def, min, max, blk_siz)
#define HA_TOPTION_STRING(name, field) \
HA_xOPTION_STRING(name, ha_table_option_struct, field)
#define HA_TOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def)
#define HA_TOPTION_BOOL(name, field, def) \
HA_xOPTION_BOOL(name, ha_table_option_struct, field, def)
#define HA_TOPTION_END HA_xOPTION_END
#define HA_FOPTION_NUMBER(name, field, def, min, max, blk_siz) \
HA_xOPTION_NUMBER(name, ha_field_option_struct, field, def, min, max, blk_siz)
#define HA_FOPTION_STRING(name, field) \
HA_xOPTION_STRING(name, ha_field_option_struct, field)
#define HA_FOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def)
#define HA_FOPTION_BOOL(name, field, def) \
HA_xOPTION_BOOL(name, ha_field_option_struct, field, def)
#define HA_FOPTION_END HA_xOPTION_END
#define HA_IOPTION_NUMBER(name, field, def, min, max, blk_siz) \
HA_xOPTION_NUMBER(name, ha_index_option_struct, field, def, min, max, blk_siz)
#define HA_IOPTION_STRING(name, field) \
HA_xOPTION_STRING(name, ha_index_option_struct, field)
#define HA_IOPTION_ENUM(name, field, values, def) \
HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def)
#define HA_IOPTION_BOOL(name, field, values, def) \
HA_xOPTION_BOOL(name, ha_index_option_struct, field, values, def)
#define HA_IOPTION_END HA_xOPTION_END
typedef struct st_ha_create_table_option {
enum ha_option_type type;
const char *name;
size_t name_length;
ptrdiff_t offset;
ulonglong def_value;
ulonglong min_value, max_value, block_size;
const char *values;
} ha_create_table_option;
enum handler_iterator_type
{
@ -676,8 +792,9 @@ struct handlerton
SHOW_COMP_OPTION state;
/*
Historical number used for frm file to determine the correct storage engine.
This is going away and new engines will just use "name" for this.
Historical number used for frm file to determine the correct
storage engine. This is going away and new engines will just use
"name" for this.
*/
enum legacy_db_type db_type;
/*
@ -787,17 +904,28 @@ struct handlerton
int (*table_exists_in_engine)(handlerton *hton, THD* thd, const char *db,
const char *name);
uint32 license; /* Flag for Engine License */
void *data; /* Location for engines to keep personal structures */
/*
Optional clauses in the CREATE/ALTER TABLE
*/
ha_create_table_option *table_options; // table level options
ha_create_table_option *field_options; // these are specified per field
ha_create_table_option *index_options; // these are specified per index
};
inline LEX_STRING *hton_name(const handlerton *hton)
{
return &(hton2plugin[hton->slot]->name);
}
/* Possible flags of a handlerton (there can be 32 of them) */
#define HTON_NO_FLAGS 0
#define HTON_CLOSE_CURSORS_AT_COMMIT (1 << 0)
#define HTON_ALTER_NOT_SUPPORTED (1 << 1) //Engine does not support alter
#define HTON_CAN_RECREATE (1 << 2) //Delete all is used fro truncate
#define HTON_HIDDEN (1 << 3) //Engine does not appear in lists
#define HTON_FLUSH_AFTER_RENAME (1 << 4)
#define HTON_NOT_USER_SELECTABLE (1 << 5)
#define HTON_TEMPORARY_NOT_SUPPORTED (1 << 6) //Having temporary tables not supported
#define HTON_SUPPORT_LOG_TABLES (1 << 7) //Engine supports log tables
@ -843,6 +971,7 @@ struct THD_TRANS
void reset() { no_2pc= FALSE; modified_non_trans_table= FALSE; }
bool is_empty() const { return ha_list == NULL; }
THD_TRANS() {} /* Remove gcc warning */
};
@ -953,9 +1082,9 @@ typedef struct {
ulonglong delete_length;
ha_rows records;
ulong mean_rec_length;
ulong create_time;
ulong check_time;
ulong update_time;
time_t create_time;
time_t check_time;
time_t update_time;
ulonglong check_sum;
} PARTITION_STATS;
@ -968,7 +1097,7 @@ class partition_info;
struct st_partition_iter;
#define NOT_A_PARTITION_ID ((uint32)-1)
enum enum_ha_unused { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
enum ha_choice { HA_CHOICE_UNDEF, HA_CHOICE_NO, HA_CHOICE_YES };
typedef struct st_ha_create_information
{
@ -1000,11 +1129,16 @@ typedef struct st_ha_create_information
uint options; /* OR of HA_CREATE_ options */
uint merge_insert_method;
uint extra_size; /* length of extra data segment */
enum enum_ha_unused unused1;
bool frm_only; /* 1 if no ha_create_table() */
bool varchar; /* 1 if table has a VARCHAR */
enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */
enum enum_ha_unused unused2;
enum ha_choice transactional;
bool frm_only; ///< 1 if no ha_create_table()
bool varchar; ///< 1 if table has a VARCHAR
enum ha_storage_media storage_media; ///< DEFAULT, DISK or MEMORY
enum ha_choice page_checksum; ///< If we have page_checksums
engine_option_value *option_list; ///< list of table create options
/* the following three are only for ALTER TABLE, check_if_incompatible_data() */
void *option_struct; ///< structure with parsed table options
void **fileds_option_struct; ///< array of field option structures
void **indexes_option_struct; ///< array of index option structures
} HA_CREATE_INFO;
@ -1079,11 +1213,191 @@ typedef struct st_ha_check_opt
st_ha_check_opt() {} /* Remove gcc warning */
uint flags; /* isam layer flags (e.g. for myisamchk) */
uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
KEY_CACHE *key_cache; /* new key cache when changing key cache */
KEY_CACHE *key_cache; /* new key cache when changing key cache */
void init();
} HA_CHECK_OPT;
/********************************************************************************
* MRR
********************************************************************************/
typedef void *range_seq_t;
typedef struct st_range_seq_if
{
/*
Initialize the traversal of range sequence
SYNOPSIS
init()
init_params The seq_init_param parameter
n_ranges The number of ranges obtained
flags A combination of HA_MRR_SINGLE_POINT, HA_MRR_FIXED_KEY
RETURN
An opaque value to be used as RANGE_SEQ_IF::next() parameter
*/
range_seq_t (*init)(void *init_params, uint n_ranges, uint flags);
/*
Get the next range in the range sequence
SYNOPSIS
next()
seq The value returned by RANGE_SEQ_IF::init()
range OUT Information about the next range
RETURN
0 - Ok, the range structure filled with info about the next range
1 - No more ranges
*/
uint (*next) (range_seq_t seq, KEY_MULTI_RANGE *range);
/*
Check whether range_info orders to skip the next record
SYNOPSIS
skip_record()
seq The value returned by RANGE_SEQ_IF::init()
range_info Information about the next range
(Ignored if MRR_NO_ASSOCIATION is set)
rowid Rowid of the record to be checked (ignored if set to 0)
RETURN
1 - Record with this range_info and/or this rowid shall be filtered
out from the stream of records returned by multi_range_read_next()
0 - The record shall be left in the stream
*/
bool (*skip_record) (range_seq_t seq, char *range_info, uchar *rowid);
/*
Check if the record combination matches the index condition
SYNOPSIS
skip_index_tuple()
seq The value returned by RANGE_SEQ_IF::init()
range_info Information about the next range
RETURN
0 - The record combination satisfies the index condition
1 - Otherwise
*/
bool (*skip_index_tuple) (range_seq_t seq, char *range_info);
} RANGE_SEQ_IF;
class COST_VECT
{
public:
double io_count; /* number of I/O */
double avg_io_cost; /* cost of an average I/O oper. */
double cpu_cost; /* cost of operations in CPU */
double mem_cost; /* cost of used memory */
double import_cost; /* cost of remote operations */
enum { IO_COEFF=1 };
enum { CPU_COEFF=1 };
enum { MEM_COEFF=1 };
enum { IMPORT_COEFF=1 };
COST_VECT() {} // keep gcc happy
double total_cost()
{
return IO_COEFF*io_count*avg_io_cost + CPU_COEFF * cpu_cost +
MEM_COEFF*mem_cost + IMPORT_COEFF*import_cost;
}
void zero()
{
avg_io_cost= 1.0;
io_count= cpu_cost= mem_cost= import_cost= 0.0;
}
void multiply(double m)
{
io_count *= m;
cpu_cost *= m;
import_cost *= m;
/* Don't multiply mem_cost */
}
void add(const COST_VECT* cost)
{
double io_count_sum= io_count + cost->io_count;
add_io(cost->io_count, cost->avg_io_cost);
io_count= io_count_sum;
cpu_cost += cost->cpu_cost;
}
void add_io(double add_io_cnt, double add_avg_cost)
{
double io_count_sum= io_count + add_io_cnt;
avg_io_cost= (io_count * avg_io_cost +
add_io_cnt * add_avg_cost) / io_count_sum;
io_count= io_count_sum;
}
/*
To be used when we go from old single value-based cost calculations to
the new COST_VECT-based.
*/
void convert_from_cost(double cost)
{
zero();
avg_io_cost= 1.0;
io_count= cost;
}
};
void get_sweep_read_cost(TABLE *table, ha_rows nrows, bool interrupted,
COST_VECT *cost);
/*
The below two are not used (and not handled) in this milestone of this WL
entry because there seems to be no use for them at this stage of
implementation.
*/
#define HA_MRR_SINGLE_POINT 1
#define HA_MRR_FIXED_KEY 2
/*
Indicates that RANGE_SEQ_IF::next(&range) doesn't need to fill in the
'range' parameter.
*/
#define HA_MRR_NO_ASSOCIATION 4
/*
The MRR user will provide ranges in key order, and MRR implementation
must return rows in key order.
*/
#define HA_MRR_SORTED 8
/* MRR implementation doesn't have to retrieve full records */
#define HA_MRR_INDEX_ONLY 16
/*
The passed memory buffer is of maximum possible size, the caller can't
assume larger buffer.
*/
#define HA_MRR_LIMITS 32
/*
Flag set <=> default MRR implementation is used
(The choice is made by **_info[_const]() function which may set this
flag. SQL layer remembers the flag value and then passes it to
multi_read_range_init().
*/
#define HA_MRR_USE_DEFAULT_IMPL 64
/*
Used only as parameter to multi_range_read_info():
Flag set <=> the caller guarantees that the bounds of the scanned ranges
will not have NULL values.
*/
#define HA_MRR_NO_NULL_ENDPOINTS 128
/*
This is a buffer area that the handler can use to store rows.
@ -1094,8 +1408,8 @@ typedef struct st_ha_check_opt
typedef struct st_handler_buffer
{
const uchar *buffer; /* Buffer one can start using */
const uchar *buffer_end; /* End of buffer */
/* const? */uchar *buffer; /* Buffer one can start using */
/* const? */uchar *buffer_end; /* End of buffer */
uchar *end_of_used_area; /* End of area that was used by handler */
} HANDLER_BUFFER;
@ -1121,16 +1435,21 @@ public:
ha_rows records;
ha_rows deleted; /* Deleted records */
ulong mean_rec_length; /* physical reclength */
ulong create_time; /* When table was created */
ulong check_time;
ulong update_time;
time_t create_time; /* When table was created */
time_t check_time;
time_t update_time;
uint block_size; /* index block size */
/*
number of buffer bytes that native mrr implementation needs,
*/
uint mrr_length_per_rec;
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)
check_time(0), update_time(0), block_size(0), mrr_length_per_rec(0)
{}
};
@ -1169,11 +1488,18 @@ public:
ha_statistics stats;
/** The following are for read_multi_range */
bool multi_range_sorted;
KEY_MULTI_RANGE *multi_range_curr;
KEY_MULTI_RANGE *multi_range_end;
HANDLER_BUFFER *multi_range_buffer;
/** MultiRangeRead-related members: */
range_seq_t mrr_iter; /* Interator to traverse the range sequence */
RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
HANDLER_BUFFER *multi_range_buffer; /* MRR buffer info */
uint ranges_in_seq; /* Total number of ranges in the traversed sequence */
/* TRUE <=> source MRR ranges and the output are ordered */
bool mrr_is_output_sorted;
/** TRUE <=> we're currently traversing a range in mrr_cur_range. */
bool mrr_have_range;
/** Current range (the one we're now returning rows from) */
KEY_MULTI_RANGE mrr_cur_range;
/** The following are for read_range() */
key_range save_end_range, *end_range;
@ -1184,12 +1510,20 @@ public:
uint errkey; /* Last dup key */
uint key_used_on_scan;
uint active_index;
/*
TRUE <=> the engine guarantees that returned records are within the range
being scanned.
*/
bool in_range_check_pushed_down;
/** Length of ref (1-8 or the clustered key length) */
uint ref_length;
FT_INFO *ft_handler;
enum {NONE=0, INDEX, RND} inited;
bool locked;
bool implicit_emptied; /* Can be !=0 only if HEAP */
bool mark_trx_done;
bool cloned; /* 1 if this was created with clone */
const COND *pushed_cond;
/**
next_insert_id is the next value which should be inserted into the
@ -1212,6 +1546,15 @@ public:
Interval returned by get_auto_increment() and being consumed by the
inserter.
*/
/* Statistics variables */
ulonglong rows_read;
ulonglong rows_changed;
/* One bigger than needed to avoid to test if key == MAX_KEY */
ulonglong index_rows_read[MAX_KEY+1];
Item *pushed_idx_cond;
uint pushed_idx_cond_keyno; /* The index which the above condition is for */
Discrete_interval auto_inc_interval_for_cur_row;
/**
Number of reserved auto-increment intervals. Serves as a heuristic
@ -1239,13 +1582,18 @@ public:
:table_share(share_arg), table(0),
estimation_rows_to_insert(0), ht(ht_arg),
ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY),
in_range_check_pushed_down(FALSE),
ref_length(sizeof(my_off_t)),
ft_handler(0), inited(NONE),
locked(FALSE), implicit_emptied(0),
locked(FALSE), implicit_emptied(0), mark_trx_done(FALSE), cloned(0),
pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0),
pushed_idx_cond(NULL),
pushed_idx_cond_keyno(MAX_KEY),
auto_inc_intervals_count(0),
m_psi(NULL)
{}
{
reset_statistics();
}
virtual ~handler(void)
{
DBUG_ASSERT(locked == FALSE);
@ -1267,6 +1615,7 @@ public:
DBUG_ASSERT(inited==NONE);
if (!(result= index_init(idx, sorted)))
inited=INDEX;
end_range= NULL;
DBUG_RETURN(result);
}
int ha_index_end()
@ -1274,9 +1623,12 @@ public:
DBUG_ENTER("ha_index_end");
DBUG_ASSERT(inited==INDEX);
inited=NONE;
end_range= NULL;
DBUG_RETURN(index_end());
}
int ha_rnd_init(bool scan)
/* This is called after index_init() if we need to do a index scan */
virtual int prepare_index_scan() { return 0; }
int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result))
{
int result;
DBUG_ENTER("ha_rnd_init");
@ -1291,7 +1643,15 @@ public:
inited=NONE;
DBUG_RETURN(rnd_end());
}
int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result));
int ha_reset();
/* Tell handler (not storage engine) this is start of a new statement */
void ha_start_of_new_statement()
{
ft_handler= 0;
mark_trx_done= FALSE;
}
/* this is necessary in many places, e.g. in HANDLER command */
int ha_index_or_rnd_end()
{
@ -1363,15 +1723,31 @@ public:
virtual void print_error(int error, myf errflag);
virtual bool get_error_message(int error, String *buf);
uint get_dup_key(int error);
void reset_statistics()
{
rows_read= rows_changed= 0;
bzero(index_rows_read, sizeof(index_rows_read));
}
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share)
{
table= table_arg;
table_share= share;
reset_statistics();
}
virtual double scan_time()
{ return ulonglong2double(stats.data_file_length) / IO_SIZE + 2; }
virtual double read_time(uint index, uint ranges, ha_rows rows)
{ return rows2double(ranges+rows); }
/**
Calculate cost of 'keyread' scan for given index and number of records.
@param index index to read
@param ranges #of ranges to read
@param rows #of records to read
*/
virtual double keyread_time(uint index, uint ranges, ha_rows rows);
virtual const key_map *keys_to_use_for_scanning() { return &key_map_empty; }
bool has_transactions()
{ return (ha_table_flags() & HA_NO_TRANSACTIONS) == 0; }
@ -1475,22 +1851,23 @@ public:
}
/**
@brief
Positions an index cursor to the index specified in the handle. Fetches the
row if available. If the key value is null, begin at the first key of the
index.
Positions an index cursor to the index specified in the
handle. Fetches the row if available. If the key value is null,
begin at the first key of the index.
*/
protected:
virtual int index_read_map(uchar * buf, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag)
{
uint key_len= calculate_key_len(table, active_index, key, keypart_map);
return index_read(buf, key, key_len, find_flag);
return index_read(buf, key, key_len, find_flag);
}
/**
@brief
Positions an index cursor to the index specified in the handle. Fetches the
row if available. If the key value is null, begin at the first key of the
index.
Positions an index cursor to the index specified in the
handle. Fetches the row if available. If the key value is null,
begin at the first key of the index.
*/
virtual int index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
@ -1504,30 +1881,46 @@ public:
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.
*/
virtual int index_read_last_map(uchar * buf, const uchar * key,
key_part_map keypart_map)
inline void update_index_statistics()
{
uint key_len= calculate_key_len(table, active_index, key, keypart_map);
return index_read_last(buf, key, key_len);
index_rows_read[active_index]++;
rows_read++;
}
virtual int read_multi_range_first(KEY_MULTI_RANGE **found_range_p,
KEY_MULTI_RANGE *ranges, uint range_count,
bool sorted, HANDLER_BUFFER *buffer);
virtual int read_multi_range_next(KEY_MULTI_RANGE **found_range_p);
public:
/* Similar functions like the above, but does statistics counting */
inline int ha_index_read_map(uchar * buf, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag);
inline int ha_index_read_idx_map(uchar * buf, uint index, const uchar * key,
key_part_map keypart_map,
enum ha_rkey_function find_flag);
inline int ha_index_next(uchar * buf);
inline int ha_index_prev(uchar * buf);
inline int ha_index_first(uchar * buf);
inline int ha_index_last(uchar * buf);
inline int ha_index_next_same(uchar *buf, const uchar *key, uint keylen);
virtual ha_rows multi_range_read_info_const(uint keyno, RANGE_SEQ_IF *seq,
void *seq_init_param,
uint n_ranges, uint *bufsz,
uint *flags, COST_VECT *cost);
virtual ha_rows multi_range_read_info(uint keyno, uint n_ranges, uint keys,
uint *bufsz, uint *flags, COST_VECT *cost);
virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
uint n_ranges, uint mode,
HANDLER_BUFFER *buf);
virtual int multi_range_read_next(char **range_info);
virtual int read_range_first(const key_range *start_key,
const key_range *end_key,
bool eq_range, bool sorted);
virtual int read_range_next();
int compare_key(key_range *range);
int compare_key2(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
void ft_end() { ft_handler=NULL; }
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return NULL; }
private:
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;
@ -1537,20 +1930,33 @@ public:
It will return the row with the PK given in the record argument.
*/
virtual int rnd_pos_by_record(uchar *record)
{
position(record);
return rnd_pos(record, ref);
}
{
position(record);
return rnd_pos(record, ref);
}
virtual int read_first_row(uchar *buf, uint primary_key);
public:
/* Same as above, but with statistics */
inline int ha_ft_read(uchar *buf);
inline int ha_rnd_next(uchar *buf);
inline int ha_rnd_pos(uchar *buf, uchar *pos);
inline int ha_rnd_pos_by_record(uchar *buf);
inline int ha_read_first_row(uchar *buf, uint primary_key);
/**
The following function is only needed for tables that may be temporary
tables during joins.
The following 3 function is only needed for tables that may be
internal temporary tables during joins.
*/
virtual int restart_rnd_next(uchar *buf, uchar *pos)
virtual int remember_rnd_pos()
{ return HA_ERR_WRONG_COMMAND; }
virtual int restart_rnd_next(uchar *buf)
{ return HA_ERR_WRONG_COMMAND; }
virtual int rnd_same(uchar *buf, uint inx)
{ return HA_ERR_WRONG_COMMAND; }
virtual ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key)
virtual ha_rows records_in_range(uint inx, key_range *min_key,
key_range *max_key)
{ return (ha_rows) 10; }
/*
If HA_PRIMARY_KEY_REQUIRED_FOR_POSITION is set, then it sets ref
@ -1666,7 +2072,8 @@ public:
*/
virtual const char **bas_ext() const =0;
virtual int get_default_no_partitions(HA_CREATE_INFO *info) { return 1;}
virtual int get_default_no_partitions(HA_CREATE_INFO *create_info)
{ return 1;}
virtual void set_auto_partitions(partition_info *part_info) { return; }
virtual bool get_no_parts(const char *name,
uint *no_parts)
@ -1709,13 +2116,14 @@ public:
virtual bool is_crashed() const { return 0; }
virtual bool auto_repair() const { return 0; }
void update_global_table_stats();
void update_global_index_stats();
#define CHF_CREATE_FLAG 0
#define CHF_DELETE_FLAG 1
#define CHF_RENAME_FLAG 2
#define CHF_INDEX_FLAG 3
/**
@note lock_count() can return > 1 if the table is MERGE or partitioned.
*/
@ -1826,6 +2234,7 @@ public:
Pops the top if condition stack, if stack is not empty.
*/
virtual void cond_pop() { return; };
virtual Item *idx_cond_push(uint keyno, Item* idx_cond) { return idx_cond; }
virtual bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
uint table_changes)
{ return COMPATIBLE_DATA_NO; }
@ -1843,9 +2252,24 @@ public:
return 0;
}
LEX_STRING *engine_name() { return hton_name(ht); }
/*
@brief
Check whether the engine supports virtual columns
@retval
FALSE if the engine does not support virtual columns
@retval
TRUE if the engine supports virtual columns
*/
virtual bool check_if_supported_virtual_columns(void) { return FALSE;}
protected:
/* deprecated, don't use in new engines */
inline void ha_statistic_increment(ulong SSV::*offset) const { }
/* Service methods for use by storage engines. */
void ha_statistic_increment(ulong SSV::*offset) const;
void **ha_data(THD *) const;
THD *ha_thd(void) const;
@ -1895,10 +2319,18 @@ protected:
tables.
*/
virtual int delete_table(const char *name);
private:
/* Private helpers */
inline void mark_trx_read_write();
private:
void mark_trx_read_write_part2();
inline void mark_trx_read_write()
{
if (!mark_trx_done)
mark_trx_read_write_part2();
}
inline void increment_statistics(ulong SSV::*offset) const;
inline void decrement_statistics(ulong SSV::*offset) const;
/*
Low-level primitives for storage engines. These should be
overridden by the storage engine class. To call these methods, use
@ -1985,8 +2417,6 @@ private:
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)
{ return (my_errno= HA_ERR_WRONG_COMMAND); }
/**
This method is similar to update_row, however the handler doesn't need
to execute the updates at this point in time. The handler can be certain
@ -2051,8 +2481,17 @@ private:
{ return HA_ERR_WRONG_COMMAND; }
virtual int rename_partitions(const char *path)
{ return HA_ERR_WRONG_COMMAND; }
friend class ha_partition;
friend class DsMrr_impl;
public:
/* XXX to be removed, see ha_partition::partition_ht() */
virtual handlerton *partition_ht() const
{ return ht; }
};
#include "multi_range_read.h"
bool key_uses_partial_cols(TABLE *table, uint keyno);
/* Some extern variables used with handlers */
@ -2081,7 +2520,7 @@ static inline enum legacy_db_type ha_legacy_type(const handlerton *db_type)
static inline const char *ha_resolve_storage_engine_name(const handlerton *db_type)
{
return db_type == NULL ? "UNKNOWN" : hton2plugin[db_type->slot]->name.str;
return db_type == NULL ? "UNKNOWN" : hton_name(db_type)->str;
}
static inline bool ha_check_storage_engine_flag(const handlerton *db_type, uint32 flag)
@ -2131,6 +2570,7 @@ int ha_table_exists_in_engine(THD* thd, const char* db, const char* name);
extern "C" int ha_init_key_cache(const char *name, KEY_CACHE *key_cache);
int ha_resize_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache_param(KEY_CACHE *key_cache);
int ha_repartition_key_cache(KEY_CACHE *key_cache);
int ha_change_key_cache(KEY_CACHE *old_key_cache, KEY_CACHE *new_key_cache);
/* report to InnoDB that control passes to the client */
@ -2187,10 +2627,8 @@ const char *get_canonical_filename(handler *file, const char *path,
char *tmp_path);
bool mysql_xa_recover(THD *thd);
inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
{
return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
}
#endif /* HANDLER_INCLUDED */
#endif