diff options
Diffstat (limited to 'sql/handler.h')
-rw-r--r-- | sql/handler.h | 251 |
1 files changed, 215 insertions, 36 deletions
diff --git a/sql/handler.h b/sql/handler.h index e564d5562fe..32112fdcd13 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -16,6 +16,9 @@ /* Definitions for parameters to do with handler-routines */ +#ifndef SQL_HANDLER_INCLUDED +#define SQL_HANDLER_INCLUDED + #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ #endif @@ -29,6 +32,10 @@ #define USING_TRANSACTIONS +#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 @@ -129,6 +136,7 @@ #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) /* Has automatic checksums and uses the new checksum format */ #define HA_HAS_NEW_CHECKSUM (LL(1) << 36) +#define HA_CAN_VIRTUAL_COLUMNS (LL(1) << 37) /* Set of all binlog flags. Currently only contain the capabilities @@ -547,6 +555,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 { @@ -607,8 +712,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; /* @@ -718,7 +824,13 @@ 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 + }; @@ -734,7 +846,6 @@ inline LEX_STRING *hton_name(const handlerton *hton) #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 @@ -942,11 +1053,16 @@ typedef struct st_ha_create_information uint extra_size; /* length of extra data segment */ /** Transactional or not. Unused; reserved for future versions. */ enum ha_choice transactional; - bool table_existed; /* 1 in create if table existed */ - 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 */ + bool table_existed; ///< 1 in create if table existed + 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; @@ -1132,6 +1248,7 @@ public: 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; /** @@ -1155,6 +1272,12 @@ 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]; + Discrete_interval auto_inc_interval_for_cur_row; /** Number of reserved auto-increment intervals. Serves as a heuristic @@ -1170,10 +1293,13 @@ public: ref(0), key_used_on_scan(MAX_KEY), active_index(MAX_KEY), ref_length(sizeof(my_off_t)), ft_handler(0), inited(NONE), - locked(FALSE), implicit_emptied(0), cloned(0), + locked(FALSE), implicit_emptied(FALSE), mark_trx_done(FALSE), cloned(0), pushed_cond(0), next_insert_id(0), insert_id_for_cur_row(0), auto_inc_intervals_count(0) - {} + { + reset_statistics(); + } + virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); @@ -1210,7 +1336,7 @@ public: } /* 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) + int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result)) { int result; DBUG_ENTER("ha_rnd_init"); @@ -1225,7 +1351,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() { @@ -1299,10 +1433,16 @@ 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; } @@ -1426,22 +1566,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, @@ -1455,17 +1596,26 @@ 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++; } +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 int read_multi_range_first(KEY_MULTI_RANGE **found_range_p, KEY_MULTI_RANGE *ranges, uint range_count, bool sorted, HANDLER_BUFFER *buffer); @@ -1479,6 +1629,7 @@ public: 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; @@ -1488,11 +1639,20 @@ 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 3 function is only needed for tables that may be internal temporary tables during joins. @@ -1668,6 +1828,9 @@ 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 @@ -1803,8 +1966,10 @@ public: LEX_STRING *engine_name() { return hton_name(ht); } 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; @@ -1824,7 +1989,15 @@ protected: private: /* Private helpers */ - inline void mark_trx_read_write(); + 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 @@ -1911,8 +2084,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 @@ -1985,6 +2156,11 @@ private: { return HA_ERR_WRONG_COMMAND; } virtual int rename_partitions(const char *path) { return HA_ERR_WRONG_COMMAND; } + friend class ha_partition; +public: + /* XXX to be removed, see ha_partition::partition_ht() */ + virtual handlerton *partition_ht() const + { return ht; } }; @@ -2067,6 +2243,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); int ha_end_key_cache(KEY_CACHE *key_cache); @@ -2120,3 +2297,5 @@ int ha_binlog_end(THD *thd); #define ha_binlog_wait(a) do {} while (0) #define ha_binlog_end(a) do {} while (0) #endif + +#endif |