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 #define HA_MAX_ALTER_FLAGS 40
00042
00043 typedef std::bitset<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
00044
00045 typedef List<Item> List_item;
00046 extern KEY_CREATE_INFO default_key_create_info;
00047
00048
00049
00050
00051
00052 inline key_part_map make_keypart_map(int a)
00053 {
00054 return (((key_part_map)2 << a) - 1);
00055 }
00056
00057
00058
00059
00060
00061 inline key_part_map make_prev_keypart_map(int a)
00062 {
00063 return (((key_part_map)1 << a) - 1);
00064 }
00065
00109 class DRIZZLED_API Cursor
00110 {
00111 friend class SEAPITesterCursor;
00112 Table &table;
00113 plugin::StorageEngine &engine;
00114
00115 protected:
00116 ha_rows estimation_rows_to_insert;
00117
00118 public:
00119 inline plugin::StorageEngine *getEngine() const
00120 {
00121 return &engine;
00122 }
00123 unsigned char *ref;
00124 unsigned char *dup_ref;
00125
00126 TableShare *getShare();
00127
00128 Table *getTable() const
00129 {
00130 return &table;
00131 }
00132
00133 ha_statistics stats;
00135 range_seq_t mrr_iter;
00136 RANGE_SEQ_IF mrr_funcs;
00137
00138 uint32_t ranges_in_seq;
00139
00140 bool mrr_is_output_sorted;
00141
00143 bool mrr_have_range;
00144
00145 bool eq_range;
00146
00148 KEY_MULTI_RANGE mrr_cur_range;
00149
00151 key_range save_end_range, *end_range;
00152 KeyPartInfo *range_key_part;
00153 int key_compare_result_on_equal;
00154
00155 uint32_t errkey;
00156 uint32_t key_used_on_scan;
00157 uint32_t active_index;
00159 uint32_t ref_length;
00160 enum {NONE=0, INDEX, RND} inited;
00161 bool locked;
00162
00172 uint64_t next_insert_id;
00173 uint64_t getNextInsertId() const
00174 {
00175 return next_insert_id;
00176 }
00177
00181 uint64_t getAutoIncrement() const
00182 {
00183 return stats.auto_increment_value;
00184 }
00185
00192 uint64_t insert_id_for_cur_row;
00197 Discrete_interval auto_inc_interval_for_cur_row;
00198
00199 Cursor(plugin::StorageEngine &engine_arg, Table &share_arg);
00200 virtual ~Cursor(void);
00201 virtual Cursor *clone(memory::Root *mem_root);
00202
00203
00204
00205 int ha_open(const identifier::Table &identifier, int mode, int test_if_locked);
00206 int startIndexScan(uint32_t idx, bool sorted) __attribute__ ((warn_unused_result));
00207 int endIndexScan();
00208 int startTableScan(bool scan) __attribute__ ((warn_unused_result));
00209 int endTableScan();
00210 int ha_reset();
00211
00212
00213 int ha_index_or_rnd_end();
00214
00221 int ha_external_lock(Session *session, int lock_type);
00222 int insertRecord(unsigned char * buf) __attribute__ ((warn_unused_result));
00223 int updateRecord(const unsigned char * old_data, unsigned char * new_data) __attribute__ ((warn_unused_result));
00224 int deleteRecord(const unsigned char * buf) __attribute__ ((warn_unused_result));
00225 void ha_release_auto_increment();
00226 int ha_check(Session*);
00227 void ha_start_bulk_insert(ha_rows rows);
00228 int ha_end_bulk_insert();
00229 int ha_delete_all_rows();
00230 int ha_reset_auto_increment(uint64_t value);
00231 int ha_analyze(Session*);
00232
00233 int ha_disable_indexes(uint32_t mode);
00234 int ha_enable_indexes(uint32_t mode);
00235 int ha_discard_or_import_tablespace(bool discard);
00236 void closeMarkForDelete();
00237
00238 void adjust_next_insert_id_after_explicit_value(uint64_t nr);
00239 int update_auto_increment();
00240
00241
00242 virtual double scan_time(void)
00243 { return static_cast<double>(stats.data_file_length) / IO_SIZE + 2; }
00244 virtual double read_time(uint32_t, uint32_t ranges, ha_rows rows)
00245 { return ranges + rows; }
00246
00247 virtual double index_only_read_time(uint32_t keynr, double records);
00248
00249 virtual ha_rows multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
00250 void *seq_init_param,
00251 uint32_t n_ranges, uint32_t *bufsz,
00252 uint32_t *flags, optimizer::CostVector *cost);
00253 virtual int multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
00254 uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost);
00255 virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
00256 uint32_t n_ranges, uint32_t mode);
00257 virtual int multi_range_read_next(char **range_info);
00258
00259
00260 virtual const key_map *keys_to_use_for_scanning();
00261 bool has_transactions();
00262
00273 virtual bool is_fatal_error(int error, uint32_t flags);
00274
00279 virtual ha_rows records();
00280 virtual uint64_t tableSize();
00281 virtual uint64_t rowSize();
00288 virtual ha_rows estimate_rows_upper_bound()
00289 { return stats.records+EXTRA_RECORDS; }
00290
00291 virtual const char *index_type(uint32_t)
00292 { assert(0); return "";}
00293
00294
00295 uint32_t get_index(void) const { return active_index; }
00296 virtual int close(void)=0;
00297
00304 virtual int index_read_map(unsigned char * buf, const unsigned char *key,
00305 key_part_map keypart_map,
00306 enum ha_rkey_function find_flag)
00307 {
00308 uint32_t key_len= calculate_key_len(active_index, keypart_map);
00309 return index_read(buf, key, key_len, find_flag);
00310 }
00317 virtual int index_read_idx_map(unsigned char * buf, uint32_t index,
00318 const unsigned char * key,
00319 key_part_map keypart_map,
00320 enum ha_rkey_function find_flag);
00321 virtual int index_next(unsigned char *) __attribute__ ((warn_unused_result))
00322 { return HA_ERR_WRONG_COMMAND; }
00323 virtual int index_prev(unsigned char *)
00324 { return HA_ERR_WRONG_COMMAND; }
00325 virtual int index_first(unsigned char *)
00326 { return HA_ERR_WRONG_COMMAND; }
00327 virtual int index_last(unsigned char *)
00328 { return HA_ERR_WRONG_COMMAND; }
00329 virtual int index_next_same(unsigned char *, const unsigned char *, uint32_t);
00330
00331 private:
00332 uint32_t calculate_key_len(uint32_t key_position, key_part_map keypart_map_arg);
00333 public:
00334
00340 virtual int index_read_last_map(unsigned char * buf, const unsigned char * key,
00341 key_part_map keypart_map)
00342 {
00343 uint32_t key_len= calculate_key_len(active_index, keypart_map);
00344 return index_read_last(buf, key, key_len);
00345 }
00346 virtual int read_range_first(const key_range *start_key,
00347 const key_range *end_key,
00348 bool eq_range, bool sorted);
00349 virtual int read_range_next();
00350 int compare_key(key_range *range);
00351 virtual int rnd_next(unsigned char *)=0;
00352 virtual int rnd_pos(unsigned char *, unsigned char *)=0;
00353 virtual int read_first_row(unsigned char *buf, uint32_t primary_key);
00354 virtual int rnd_same(unsigned char *, uint32_t)
00355 { return HA_ERR_WRONG_COMMAND; }
00356 virtual ha_rows records_in_range(uint32_t, key_range *, key_range *)
00357 { return (ha_rows) 10; }
00358 virtual void position(const unsigned char *record)=0;
00359 virtual int info(uint32_t)=0;
00360 virtual uint32_t calculate_key_hash_value(Field **)
00361 { assert(0); return 0; }
00362 virtual int extra(enum ha_extra_function)
00363 { return 0; }
00364 virtual int extra_opt(enum ha_extra_function operation, uint32_t)
00365 { return extra(operation); }
00366
00379 virtual bool was_semi_consistent_read() { return 0; }
00386 virtual void try_semi_consistent_read(bool) {}
00387 virtual void unlock_row(void) {}
00388 virtual void get_auto_increment(uint64_t offset, uint64_t increment,
00389 uint64_t nb_desired_values,
00390 uint64_t *first_value,
00391 uint64_t *nb_reserved_values)= 0;
00392
00393 void set_next_insert_id(uint64_t id)
00394 {
00395 next_insert_id= id;
00396 }
00397 void restore_auto_increment(uint64_t prev_insert_id)
00398 {
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
00410 insert_id_for_cur_row;
00411 }
00412
00413
00414
00415 virtual int indexes_are_disabled(void) {return 0;}
00416 virtual void append_create_info(String *)
00417 {}
00428 virtual char* get_foreign_key_create_info(void)
00429 { return NULL;}
00433 virtual bool can_switch_engines(void) { return true; }
00435 virtual int get_foreign_key_list(Session *, List<ForeignKeyInfo> *)
00436 { return 0; }
00437 virtual uint32_t referenced_by_foreign_key() { return 0;}
00438 virtual void free_foreign_key_create_info(char *) {}
00439
00453 virtual THR_LOCK_DATA **store_lock(Session *,
00454 THR_LOCK_DATA **to,
00455 enum thr_lock_type)
00456 {
00457 assert(0);
00458
00459 return(to);
00460 }
00461
00462
00463
00464
00465
00466
00467 virtual bool primary_key_is_clustered() { return false; }
00468 virtual int cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
00469 {
00470 return memcmp(ref1, ref2, ref_length);
00471 }
00472
00473 virtual bool isOrdered(void)
00474 {
00475 return false;
00476 }
00477
00478
00479 protected:
00480
00481 void ha_statistic_increment(uint64_t system_status_var::*offset) const;
00482 void **ha_data(Session *) const;
00483
00484 private:
00485
00486 inline void setTransactionReadWrite();
00487 private:
00488
00489
00490
00491
00492
00493
00494 virtual int open(const char *, int , uint32_t ) { assert(0); return -1; }
00495 virtual int doOpen(const identifier::Table &identifier, int mode, uint32_t test_if_locked);
00496 virtual int doStartIndexScan(uint32_t idx, bool)
00497 { active_index= idx; return 0; }
00498 virtual int doEndIndexScan() { active_index= MAX_KEY; return 0; }
00506 virtual int doStartTableScan(bool scan) __attribute__ ((warn_unused_result)) = 0;
00507 virtual int doEndTableScan() { return 0; }
00508 virtual int doInsertRecord(unsigned char *)
00509 {
00510 return HA_ERR_WRONG_COMMAND;
00511 }
00512
00513 virtual int doUpdateRecord(const unsigned char *, unsigned char *)
00514 {
00515 return HA_ERR_WRONG_COMMAND;
00516 }
00517
00518 virtual int doDeleteRecord(const unsigned char *)
00519 {
00520 return HA_ERR_WRONG_COMMAND;
00521 }
00527 virtual int reset() { return 0; }
00528
00551 virtual int external_lock(Session *, int)
00552 {
00553 return 0;
00554 }
00555 virtual void release_auto_increment(void) { return; }
00557 virtual int check(Session *)
00558 { return HA_ADMIN_NOT_IMPLEMENTED; }
00559
00560 virtual void start_bulk_insert(ha_rows)
00561 {}
00562 virtual int end_bulk_insert(void) { return 0; }
00563 virtual int index_read(unsigned char *, const unsigned char *,
00564 uint32_t, enum ha_rkey_function)
00565 { return HA_ERR_WRONG_COMMAND; }
00566 virtual int index_read_last(unsigned char *, const unsigned char *, uint32_t)
00567 { return (errno= HA_ERR_WRONG_COMMAND); }
00574 virtual int delete_all_rows(void)
00575 { return (errno=HA_ERR_WRONG_COMMAND); }
00582 virtual int reset_auto_increment(uint64_t)
00583 { return HA_ERR_WRONG_COMMAND; }
00584
00585 virtual int analyze(Session *)
00586 { return HA_ADMIN_NOT_IMPLEMENTED; }
00587
00588 virtual int disable_indexes(uint32_t)
00589 { return HA_ERR_WRONG_COMMAND; }
00590
00591 virtual int enable_indexes(uint32_t)
00592 { return HA_ERR_WRONG_COMMAND; }
00593
00594 virtual int discard_or_import_tablespace(bool)
00595 { return (errno=HA_ERR_WRONG_COMMAND); }
00596
00597
00598
00599
00600
00601
00602
00603 virtual void drop_table();
00604 };
00605
00606 extern const char *ha_row_type[];
00607
00608
00609 void ha_init_errors(void);
00610
00611 SortField *make_unireg_sortorder(Order *order, uint32_t *length,
00612 SortField *sortorder);
00613 int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
00614 List<Item> &fields, List <Item> &all_fields, Order *order);
00615 int setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
00616 List<Item> &fields, List<Item> &all_fields, Order *order,
00617 bool *hidden_group_fields);
00618 bool fix_inner_refs(Session *session, List<Item> &all_fields, Select_Lex *select,
00619 Item **ref_pointer_array);
00620
00621 bool handle_select(Session *session, LEX *lex, select_result *result,
00622 uint64_t setup_tables_done_option);
00623 void free_underlaid_joins(Session *session, Select_Lex *select);
00624
00625 bool handle_derived(LEX *lex, bool (*processor)(Session *session,
00626 LEX *lex,
00627 TableList *table));
00628 bool derived_prepare(Session *session, LEX *lex, TableList *t);
00629 bool derived_filling(Session *session, LEX *lex, TableList *t);
00630 int prepare_create_field(CreateField *sql_field,
00631 uint32_t *blob_columns,
00632 int *timestamps, int *timestamps_with_niladic);
00633
00634 bool create_table(Session *session,
00635 const identifier::Table &identifier,
00636 HA_CREATE_INFO *create_info,
00637 message::Table &table_proto,
00638 AlterInfo *alter_info,
00639 bool tmp_table, uint32_t select_field_count,
00640 bool is_if_not_exists);
00641
00642 bool create_table_no_lock(Session *session,
00643 const identifier::Table &identifier,
00644 HA_CREATE_INFO *create_info,
00645 message::Table &table_proto,
00646 AlterInfo *alter_info,
00647 bool tmp_table, uint32_t select_field_count,
00648 bool is_if_not_exists);
00649
00650 bool create_like_table(Session* session,
00651 const identifier::Table& destination_identifier,
00652 const identifier::Table& source_identifier,
00653 message::Table &create_table_proto,
00654 bool is_if_not_exists,
00655 bool is_engine_set);
00656
00657 bool rename_table(Session &session,
00658 plugin::StorageEngine *base,
00659 const identifier::Table &old_identifier,
00660 const identifier::Table &new_identifier);
00661
00662 bool prepare_update(Session *session, TableList *table_list,
00663 Item **conds, uint32_t order_num, Order *order);
00664 int update_query(Session *session,TableList *tables,List<Item> &fields,
00665 List<Item> &values,COND *conds,
00666 uint32_t order_num, Order *order, ha_rows limit,
00667 enum enum_duplicates handle_duplicates, bool ignore);
00668 bool prepare_insert(Session *session, TableList *table_list, Table *table,
00669 List<Item> &fields, List_item *values,
00670 List<Item> &update_fields,
00671 List<Item> &update_values, enum_duplicates duplic,
00672 COND **where, bool select_insert,
00673 bool check_fields, bool abort_on_warning);
00674 bool insert_query(Session *session,TableList *table,List<Item> &fields,
00675 List<List_item> &values, List<Item> &update_fields,
00676 List<Item> &update_values, enum_duplicates flag,
00677 bool ignore);
00678 int check_that_all_fields_are_given_values(Session *session, Table *entry,
00679 TableList *table_list);
00680 int prepare_delete(Session *session, TableList *table_list, Item **conds);
00681 bool delete_query(Session *session, TableList *table_list, COND *conds,
00682 SQL_LIST *order, ha_rows rows, uint64_t options,
00683 bool reset_auto_increment);
00684 bool truncate(Session& session, TableList *table_list);
00685 TableShare *get_table_share(Session *session, TableList *table_list, char *key,
00686 uint32_t key_length, uint32_t db_flags, int *error);
00687 TableShare *get_cached_table_share(const char *db, const char *table_name);
00688 bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in);
00689 bool reopen_tables(Session *session,bool get_locks,bool in_refresh);
00690 void close_handle_and_leave_table_as_lock(Table *table);
00691 bool wait_for_tables(Session *session);
00692 bool table_is_used(Table *table, bool wait_for_name_lock);
00693 Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier);
00694 void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier);
00695 extern Field *not_found_field;
00696 extern Field *view_ref_found;
00697
00698 Field *
00699 find_field_in_tables(Session *session, Item_ident *item,
00700 TableList *first_table, TableList *last_table,
00701 Item **ref, find_item_error_report_type report_error,
00702 bool register_tree_change);
00703 Field *
00704 find_field_in_table_ref(Session *session, TableList *table_list,
00705 const char *name, uint32_t length,
00706 const char *item_name, const char *db_name,
00707 const char *table_name, Item **ref,
00708 bool allow_rowid,
00709 uint32_t *cached_field_index_ptr,
00710 bool register_tree_change, TableList **actual_table);
00711 Field *
00712 find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
00713 bool allow_rowid, uint32_t *cached_field_index_ptr);
00714
00715 }
00716