Drizzled Public API Documentation

cursor.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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 /* Forward declaration for condition pushdown to storage engine */
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   bitmap with first N+1 bits set
00075   (keypart_map for a key prefix of [0..N] keyparts)
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   bitmap with first N bits set
00085   (keypart_map for a key prefix of [0..N-1] keyparts)
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;               /* The current open table */
00140   plugin::StorageEngine &engine;      /* storage engine of this Cursor */
00141 
00142 protected:
00143   ha_rows estimation_rows_to_insert;
00144 
00145 public:
00146   inline plugin::StorageEngine *getEngine() const /* table_type for handler */
00147   {
00148     return &engine;
00149   }
00150   unsigned char *ref;       /* Pointer to current row */
00151   unsigned char *dup_ref;     /* Pointer to duplicate row */
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;    /* Interator to traverse the range sequence */
00163   RANGE_SEQ_IF mrr_funcs;  /* Range sequence traversal functions */
00164 
00165   uint32_t ranges_in_seq; /* Total number of ranges in the traversed sequence */
00166   /* true <=> source MRR ranges and the output are ordered */
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;        /* Last dup key */
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   /* ha_ methods: pubilc wrappers for private virtual API */
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   /* this is necessary in many places, e.g. in HANDLER command */
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   /* Estimates calculation */
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; // see my_base.h for full description
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       Insertion of a row failed, re-use the lastly generated auto_increment
00431       id, for the next row. This is achieved by resetting next_insert_id to
00432       what it was before the failed insertion (that old value is provided by
00433       the caller). If that value was 0, it was the first row of the INSERT;
00434       then if insert_id_for_cur_row contains 0 it means no id was generated
00435       for this first row, so no id was generated since the INSERT started, so
00436       we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
00437       is the generated id of the first and failed row, so we use it.
00438     */
00439     next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
00440       insert_id_for_cur_row;
00441   }
00442 
00443   /* end of the list of admin commands */
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;}  /* gets foreign key create string from InnoDB */
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); // Impossible programming situation
00488 
00489     return(to);
00490   }
00491 
00492  /*
00493    @retval true   Primary key (if there is one) is clustered
00494                   key covering all fields
00495    @retval false  otherwise
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   /* Service methods for use by storage engines. */
00511   void ha_statistic_increment(uint64_t system_status_var::*offset) const;
00512   void **ha_data(Session *) const;
00513 
00514 private:
00515   /* Private helpers */
00516   inline void setTransactionReadWrite();
00517 private:
00518   /*
00519     Low-level primitives for storage engines.  These should be
00520     overridden by the storage engine class. To call these methods, use
00521     the corresponding 'ha_*' method above.
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     @todo this is just for the HEAP engine, it should
00629     be removed at some point in the future (and
00630     no new engine should ever use it). Right
00631     now HEAP does rely on it, so we cannot remove it.
00632   */
00633   virtual void drop_table(const char *name);
00634 };
00635 
00636 extern const char *ha_row_type[];
00637 
00638 /* basic stuff */
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 } /* namespace drizzled */
00747