00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #pragma once
00021
00022 #include <drizzled/atomics.h>
00023 #include <drizzled/definitions.h>
00024 #include <drizzled/discrete_interval.h>
00025 #include <drizzled/error_t.h>
00026 #include <drizzled/ha_statistics.h>
00027 #include <drizzled/handler_structs.h>
00028 #include <drizzled/identifier.h>
00029 #include <drizzled/key_map.h>
00030 #include <drizzled/message/table.h>
00031 #include <drizzled/sql_list.h>
00032 #include <drizzled/thr_lock.h>
00033
00034 #include <bitset>
00035 #include <algorithm>
00036
00037 #include <drizzled/visibility.h>
00038
00039 namespace drizzled
00040 {
00041
00042 #define HA_MAX_ALTER_FLAGS 40
00043
00044 typedef std::bitset<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
00045
00046 class AlterInfo;
00047 class CreateField;
00048 class ForeignKeyInfo;
00049 class Item;
00050 class Item_ident;
00051 class LEX;
00052 class Select_Lex;
00053 class Select_Lex_Unit;
00054 class String;
00055 class Table;
00056 class TableList;
00057 class TableShare;
00058 class select_result;
00059 class sys_var_str;
00060 struct Order;
00061
00062 typedef List<Item> List_item;
00063 extern KEY_CREATE_INFO default_key_create_info;
00064
00065
00066 typedef class Item COND;
00067
00068 typedef struct system_status_var system_status_var;
00069
00070 namespace optimizer { class CostVector; }
00071 namespace plugin { class StorageEngine; }
00072
00073
00074
00075
00076
00077 template<class T>
00078 inline key_part_map make_keypart_map(T a)
00079 {
00080 return (((key_part_map)2 << a) - 1);
00081 }
00082
00083
00084
00085
00086
00087 template<class T>
00088 inline key_part_map make_prev_keypart_map(T a)
00089 {
00090 return (((key_part_map)1 << a) - 1);
00091 }
00092
00136 class DRIZZLED_API Cursor
00137 {
00138 friend class SEAPITesterCursor;
00139 Table &table;
00140 plugin::StorageEngine &engine;
00141
00142 protected:
00143 ha_rows estimation_rows_to_insert;
00144
00145 public:
00146 inline plugin::StorageEngine *getEngine() const
00147 {
00148 return &engine;
00149 }
00150 unsigned char *ref;
00151 unsigned char *dup_ref;
00152
00153 TableShare *getShare();
00154
00155 Table *getTable() const
00156 {
00157 return &table;
00158 }
00159
00160 ha_statistics stats;
00162 range_seq_t mrr_iter;
00163 RANGE_SEQ_IF mrr_funcs;
00164
00165 uint32_t ranges_in_seq;
00166
00167 bool mrr_is_output_sorted;
00168
00170 bool mrr_have_range;
00171
00172 bool eq_range;
00173
00175 KEY_MULTI_RANGE mrr_cur_range;
00176
00178 key_range save_end_range, *end_range;
00179 KeyPartInfo *range_key_part;
00180 int key_compare_result_on_equal;
00181
00182 uint32_t errkey;
00183 uint32_t key_used_on_scan;
00184 uint32_t active_index;
00186 uint32_t ref_length;
00187 enum {NONE=0, INDEX, RND} inited;
00188 bool locked;
00189
00199 uint64_t next_insert_id;
00200 uint64_t getNextInsertId()
00201 {
00202 return next_insert_id;
00203 }
00204
00208 uint64_t getAutoIncrement()
00209 {
00210 return stats.auto_increment_value;
00211 }
00212
00219 uint64_t insert_id_for_cur_row;
00224 Discrete_interval auto_inc_interval_for_cur_row;
00225
00226 Cursor(plugin::StorageEngine &engine_arg, Table &share_arg);
00227 virtual ~Cursor(void);
00228 virtual Cursor *clone(memory::Root *mem_root);
00229
00230
00231
00232 int ha_open(const identifier::Table &identifier, int mode, int test_if_locked);
00233 int startIndexScan(uint32_t idx, bool sorted) __attribute__ ((warn_unused_result));
00234 int endIndexScan();
00235 int startTableScan(bool scan) __attribute__ ((warn_unused_result));
00236 int endTableScan();
00237 int ha_reset();
00238
00239
00240 int ha_index_or_rnd_end();
00241
00248 int ha_external_lock(Session *session, int lock_type);
00249 int insertRecord(unsigned char * buf) __attribute__ ((warn_unused_result));
00250 int updateRecord(const unsigned char * old_data, unsigned char * new_data) __attribute__ ((warn_unused_result));
00251 int deleteRecord(const unsigned char * buf) __attribute__ ((warn_unused_result));
00252 void ha_release_auto_increment();
00253
00255 int ha_check(Session *session, HA_CHECK_OPT *check_opt);
00256
00257 void ha_start_bulk_insert(ha_rows rows);
00258 int ha_end_bulk_insert();
00259 int ha_delete_all_rows();
00260 int ha_reset_auto_increment(uint64_t value);
00261 int ha_analyze(Session* session, HA_CHECK_OPT* check_opt);
00262
00263 int ha_disable_indexes(uint32_t mode);
00264 int ha_enable_indexes(uint32_t mode);
00265 int ha_discard_or_import_tablespace(bool discard);
00266 void closeMarkForDelete(const char *name);
00267
00268 void adjust_next_insert_id_after_explicit_value(uint64_t nr);
00269 int update_auto_increment();
00270
00271
00272 virtual double scan_time(void)
00273 { return static_cast<double>(stats.data_file_length) / IO_SIZE + 2; }
00274 virtual double read_time(uint32_t, uint32_t ranges, ha_rows rows)
00275 { return ranges + rows; }
00276
00277 virtual double index_only_read_time(uint32_t keynr, double records);
00278
00279 virtual ha_rows multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
00280 void *seq_init_param,
00281 uint32_t n_ranges, uint32_t *bufsz,
00282 uint32_t *flags, optimizer::CostVector *cost);
00283 virtual int multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
00284 uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost);
00285 virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
00286 uint32_t n_ranges, uint32_t mode);
00287 virtual int multi_range_read_next(char **range_info);
00288
00289
00290 virtual const key_map *keys_to_use_for_scanning();
00291 bool has_transactions();
00292
00303 virtual bool is_fatal_error(int error, uint32_t flags);
00304
00309 virtual ha_rows records();
00310 virtual uint64_t tableSize();
00311 virtual uint64_t rowSize();
00318 virtual ha_rows estimate_rows_upper_bound()
00319 { return stats.records+EXTRA_RECORDS; }
00320
00321 virtual const char *index_type(uint32_t)
00322 { assert(0); return "";}
00323
00324
00325 uint32_t get_index(void) const { return active_index; }
00326 virtual int close(void)=0;
00327
00334 virtual int index_read_map(unsigned char * buf, const unsigned char *key,
00335 key_part_map keypart_map,
00336 enum ha_rkey_function find_flag)
00337 {
00338 uint32_t key_len= calculate_key_len(active_index, keypart_map);
00339 return index_read(buf, key, key_len, find_flag);
00340 }
00347 virtual int index_read_idx_map(unsigned char * buf, uint32_t index,
00348 const unsigned char * key,
00349 key_part_map keypart_map,
00350 enum ha_rkey_function find_flag);
00351 virtual int index_next(unsigned char *) __attribute__ ((warn_unused_result))
00352 { return HA_ERR_WRONG_COMMAND; }
00353 virtual int index_prev(unsigned char *)
00354 { return HA_ERR_WRONG_COMMAND; }
00355 virtual int index_first(unsigned char *)
00356 { return HA_ERR_WRONG_COMMAND; }
00357 virtual int index_last(unsigned char *)
00358 { return HA_ERR_WRONG_COMMAND; }
00359 virtual int index_next_same(unsigned char *, const unsigned char *, uint32_t);
00360
00361 private:
00362 uint32_t calculate_key_len(uint32_t key_position, key_part_map keypart_map_arg);
00363 public:
00364
00370 virtual int index_read_last_map(unsigned char * buf, const unsigned char * key,
00371 key_part_map keypart_map)
00372 {
00373 uint32_t key_len= calculate_key_len(active_index, keypart_map);
00374 return index_read_last(buf, key, key_len);
00375 }
00376 virtual int read_range_first(const key_range *start_key,
00377 const key_range *end_key,
00378 bool eq_range, bool sorted);
00379 virtual int read_range_next();
00380 int compare_key(key_range *range);
00381 virtual int rnd_next(unsigned char *)=0;
00382 virtual int rnd_pos(unsigned char *, unsigned char *)=0;
00383 virtual int read_first_row(unsigned char *buf, uint32_t primary_key);
00384 virtual int rnd_same(unsigned char *, uint32_t)
00385 { return HA_ERR_WRONG_COMMAND; }
00386 virtual ha_rows records_in_range(uint32_t, key_range *, key_range *)
00387 { return (ha_rows) 10; }
00388 virtual void position(const unsigned char *record)=0;
00389 virtual int info(uint32_t)=0;
00390 virtual uint32_t calculate_key_hash_value(Field **)
00391 { assert(0); return 0; }
00392 virtual int extra(enum ha_extra_function)
00393 { return 0; }
00394 virtual int extra_opt(enum ha_extra_function operation, uint32_t)
00395 { return extra(operation); }
00396
00409 virtual bool was_semi_consistent_read() { return 0; }
00416 virtual void try_semi_consistent_read(bool) {}
00417 virtual void unlock_row(void) {}
00418 virtual void get_auto_increment(uint64_t offset, uint64_t increment,
00419 uint64_t nb_desired_values,
00420 uint64_t *first_value,
00421 uint64_t *nb_reserved_values)= 0;
00422
00423 void set_next_insert_id(uint64_t id)
00424 {
00425 next_insert_id= id;
00426 }
00427 void restore_auto_increment(uint64_t prev_insert_id)
00428 {
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439 next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
00440 insert_id_for_cur_row;
00441 }
00442
00443
00444
00445 virtual int indexes_are_disabled(void) {return 0;}
00446 virtual void append_create_info(String *)
00447 {}
00458 virtual char* get_foreign_key_create_info(void)
00459 { return NULL;}
00463 virtual bool can_switch_engines(void) { return true; }
00465 virtual int get_foreign_key_list(Session *, List<ForeignKeyInfo> *)
00466 { return 0; }
00467 virtual uint32_t referenced_by_foreign_key() { return 0;}
00468 virtual void free_foreign_key_create_info(char *) {}
00469
00483 virtual THR_LOCK_DATA **store_lock(Session *,
00484 THR_LOCK_DATA **to,
00485 enum thr_lock_type)
00486 {
00487 assert(0);
00488
00489 return(to);
00490 }
00491
00492
00493
00494
00495
00496
00497 virtual bool primary_key_is_clustered() { return false; }
00498 virtual int cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
00499 {
00500 return memcmp(ref1, ref2, ref_length);
00501 }
00502
00503 virtual bool isOrdered(void)
00504 {
00505 return false;
00506 }
00507
00508
00509 protected:
00510
00511 void ha_statistic_increment(uint64_t system_status_var::*offset) const;
00512 void **ha_data(Session *) const;
00513
00514 private:
00515
00516 inline void setTransactionReadWrite();
00517 private:
00518
00519
00520
00521
00522
00523
00524 virtual int open(const char *, int , uint32_t ) { assert(0); return -1; }
00525 virtual int doOpen(const identifier::Table &identifier, int mode, uint32_t test_if_locked);
00526 virtual int doStartIndexScan(uint32_t idx, bool)
00527 { active_index= idx; return 0; }
00528 virtual int doEndIndexScan() { active_index= MAX_KEY; return 0; }
00536 virtual int doStartTableScan(bool scan) __attribute__ ((warn_unused_result)) = 0;
00537 virtual int doEndTableScan() { return 0; }
00538 virtual int doInsertRecord(unsigned char *)
00539 {
00540 return HA_ERR_WRONG_COMMAND;
00541 }
00542
00543 virtual int doUpdateRecord(const unsigned char *, unsigned char *)
00544 {
00545 return HA_ERR_WRONG_COMMAND;
00546 }
00547
00548 virtual int doDeleteRecord(const unsigned char *)
00549 {
00550 return HA_ERR_WRONG_COMMAND;
00551 }
00557 virtual int reset() { return 0; }
00558
00581 virtual int external_lock(Session *, int)
00582 {
00583 return 0;
00584 }
00585 virtual void release_auto_increment(void) { return; }
00587 virtual int check(Session *)
00588 { return HA_ADMIN_NOT_IMPLEMENTED; }
00589
00590 virtual void start_bulk_insert(ha_rows)
00591 {}
00592 virtual int end_bulk_insert(void) { return 0; }
00593 virtual int index_read(unsigned char *, const unsigned char *,
00594 uint32_t, enum ha_rkey_function)
00595 { return HA_ERR_WRONG_COMMAND; }
00596 virtual int index_read_last(unsigned char *, const unsigned char *, uint32_t)
00597 { return (errno= HA_ERR_WRONG_COMMAND); }
00604 virtual int delete_all_rows(void)
00605 { return (errno=HA_ERR_WRONG_COMMAND); }
00612 virtual int reset_auto_increment(uint64_t)
00613 { return HA_ERR_WRONG_COMMAND; }
00614
00615 virtual int analyze(Session *)
00616 { return HA_ADMIN_NOT_IMPLEMENTED; }
00617
00618 virtual int disable_indexes(uint32_t)
00619 { return HA_ERR_WRONG_COMMAND; }
00620
00621 virtual int enable_indexes(uint32_t)
00622 { return HA_ERR_WRONG_COMMAND; }
00623
00624 virtual int discard_or_import_tablespace(bool)
00625 { return (errno=HA_ERR_WRONG_COMMAND); }
00626
00627
00628
00629
00630
00631
00632
00633 virtual void drop_table(const char *name);
00634 };
00635
00636 extern const char *ha_row_type[];
00637
00638
00639 void ha_init_errors(void);
00640
00641 class SortField;
00642 SortField *make_unireg_sortorder(Order *order, uint32_t *length,
00643 SortField *sortorder);
00644 int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
00645 List<Item> &fields, List <Item> &all_fields, Order *order);
00646 int setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
00647 List<Item> &fields, List<Item> &all_fields, Order *order,
00648 bool *hidden_group_fields);
00649 bool fix_inner_refs(Session *session, List<Item> &all_fields, Select_Lex *select,
00650 Item **ref_pointer_array);
00651
00652 bool handle_select(Session *session, LEX *lex, select_result *result,
00653 uint64_t setup_tables_done_option);
00654 void free_underlaid_joins(Session *session, Select_Lex *select);
00655
00656 bool handle_derived(LEX *lex, bool (*processor)(Session *session,
00657 LEX *lex,
00658 TableList *table));
00659 bool derived_prepare(Session *session, LEX *lex, TableList *t);
00660 bool derived_filling(Session *session, LEX *lex, TableList *t);
00661 int prepare_create_field(CreateField *sql_field,
00662 uint32_t *blob_columns,
00663 int *timestamps, int *timestamps_with_niladic);
00664
00665 bool create_table(Session *session,
00666 const identifier::Table &identifier,
00667 HA_CREATE_INFO *create_info,
00668 message::Table &table_proto,
00669 AlterInfo *alter_info,
00670 bool tmp_table, uint32_t select_field_count,
00671 bool is_if_not_exists);
00672
00673 bool create_table_no_lock(Session *session,
00674 const identifier::Table &identifier,
00675 HA_CREATE_INFO *create_info,
00676 message::Table &table_proto,
00677 AlterInfo *alter_info,
00678 bool tmp_table, uint32_t select_field_count,
00679 bool is_if_not_exists);
00680
00681 bool create_like_table(Session* session,
00682 identifier::Table::const_reference destination_identifier,
00683 identifier::Table::const_reference source_identifier,
00684 message::Table &create_table_proto,
00685 bool is_if_not_exists,
00686 bool is_engine_set);
00687
00688 bool rename_table(Session &session,
00689 plugin::StorageEngine *base,
00690 const identifier::Table &old_identifier,
00691 const identifier::Table &new_identifier);
00692
00693 bool prepare_update(Session *session, TableList *table_list,
00694 Item **conds, uint32_t order_num, Order *order);
00695 int update_query(Session *session,TableList *tables,List<Item> &fields,
00696 List<Item> &values,COND *conds,
00697 uint32_t order_num, Order *order, ha_rows limit,
00698 enum enum_duplicates handle_duplicates, bool ignore);
00699 bool prepare_insert(Session *session, TableList *table_list, Table *table,
00700 List<Item> &fields, List_item *values,
00701 List<Item> &update_fields,
00702 List<Item> &update_values, enum_duplicates duplic,
00703 COND **where, bool select_insert,
00704 bool check_fields, bool abort_on_warning);
00705 bool insert_query(Session *session,TableList *table,List<Item> &fields,
00706 List<List_item> &values, List<Item> &update_fields,
00707 List<Item> &update_values, enum_duplicates flag,
00708 bool ignore);
00709 int check_that_all_fields_are_given_values(Session *session, Table *entry,
00710 TableList *table_list);
00711 int prepare_delete(Session *session, TableList *table_list, Item **conds);
00712 bool delete_query(Session *session, TableList *table_list, COND *conds,
00713 SQL_LIST *order, ha_rows rows, uint64_t options,
00714 bool reset_auto_increment);
00715 bool truncate(Session& session, TableList *table_list);
00716 TableShare *get_table_share(Session *session, TableList *table_list, char *key,
00717 uint32_t key_length, uint32_t db_flags, int *error);
00718 TableShare *get_cached_table_share(const char *db, const char *table_name);
00719 bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in);
00720 bool reopen_tables(Session *session,bool get_locks,bool in_refresh);
00721 void close_handle_and_leave_table_as_lock(Table *table);
00722 bool wait_for_tables(Session *session);
00723 bool table_is_used(Table *table, bool wait_for_name_lock);
00724 Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier);
00725 void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier);
00726 extern Field *not_found_field;
00727 extern Field *view_ref_found;
00728
00729 Field *
00730 find_field_in_tables(Session *session, Item_ident *item,
00731 TableList *first_table, TableList *last_table,
00732 Item **ref, find_item_error_report_type report_error,
00733 bool register_tree_change);
00734 Field *
00735 find_field_in_table_ref(Session *session, TableList *table_list,
00736 const char *name, uint32_t length,
00737 const char *item_name, const char *db_name,
00738 const char *table_name, Item **ref,
00739 bool allow_rowid,
00740 uint32_t *cached_field_index_ptr,
00741 bool register_tree_change, TableList **actual_table);
00742 Field *
00743 find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
00744 bool allow_rowid, uint32_t *cached_field_index_ptr);
00745
00746 }
00747