Drizzled Public API Documentation

cursor.h
1 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 #pragma once
21 
22 #include <drizzled/atomics.h>
23 #include <drizzled/definitions.h>
24 #include <drizzled/discrete_interval.h>
25 #include <drizzled/error_t.h>
26 #include <drizzled/ha_statistics.h>
27 #include <drizzled/handler_structs.h>
28 #include <drizzled/identifier.h>
29 #include <drizzled/key_map.h>
30 #include <drizzled/message/table.h>
31 #include <drizzled/sql_list.h>
32 #include <drizzled/thr_lock.h>
33 
34 #include <bitset>
35 #include <algorithm>
36 
37 #include <drizzled/visibility.h>
38 
39 namespace drizzled {
40 
41 #define HA_MAX_ALTER_FLAGS 40
42 
43 typedef std::bitset<HA_MAX_ALTER_FLAGS> HA_ALTER_FLAGS;
44 
45 typedef List<Item> List_item;
46 extern KEY_CREATE_INFO default_key_create_info;
47 
48 /*
49  bitmap with first N+1 bits set
50  (keypart_map for a key prefix of [0..N] keyparts)
51 */
52 inline key_part_map make_keypart_map(int a)
53 {
54  return (((key_part_map)2 << a) - 1);
55 }
56 
57 /*
58  bitmap with first N bits set
59  (keypart_map for a key prefix of [0..N-1] keyparts)
60 */
61 inline key_part_map make_prev_keypart_map(int a)
62 {
63  return (((key_part_map)1 << a) - 1);
64 }
65 
110 {
111  friend class SEAPITesterCursor;
112  Table &table; /* The current open table */
113  plugin::StorageEngine &engine; /* storage engine of this Cursor */
114 
115 protected:
116  ha_rows estimation_rows_to_insert;
117 
118 public:
119  inline plugin::StorageEngine *getEngine() const /* table_type for handler */
120  {
121  return &engine;
122  }
123  unsigned char *ref; /* Pointer to current row */
124  unsigned char *dup_ref; /* Pointer to duplicate row */
125 
126  TableShare *getShare();
127 
128  Table *getTable() const
129  {
130  return &table;
131  }
132 
133  ha_statistics stats;
135  range_seq_t mrr_iter; /* Interator to traverse the range sequence */
136  RANGE_SEQ_IF mrr_funcs; /* Range sequence traversal functions */
137 
138  uint32_t ranges_in_seq; /* Total number of ranges in the traversed sequence */
139  /* true <=> source MRR ranges and the output are ordered */
140  bool mrr_is_output_sorted;
141 
144 
145  bool eq_range;
146 
149 
152  KeyPartInfo *range_key_part;
153  int key_compare_result_on_equal;
154 
155  uint32_t errkey; /* Last dup key */
156  uint32_t key_used_on_scan;
157  uint32_t active_index;
159  uint32_t ref_length;
160  enum {NONE=0, INDEX, RND} inited;
161  bool locked;
162 
172  uint64_t next_insert_id;
173  uint64_t getNextInsertId() const
174  {
175  return next_insert_id;
176  }
177 
181  uint64_t getAutoIncrement() const
182  {
183  return stats.auto_increment_value;
184  }
185 
198 
199  Cursor(plugin::StorageEngine &engine_arg, Table &share_arg);
200  virtual ~Cursor(void);
201  virtual Cursor *clone(memory::Root *mem_root);
202 
203  /* ha_ methods: pubilc wrappers for private virtual API */
204 
205  int ha_open(const identifier::Table &identifier, int mode, int test_if_locked);
206  int startIndexScan(uint32_t idx, bool sorted) __attribute__ ((warn_unused_result));
207  int endIndexScan();
208  int startTableScan(bool scan) __attribute__ ((warn_unused_result));
209  int endTableScan();
210  int ha_reset();
211 
212  /* this is necessary in many places, e.g. in HANDLER command */
213  int ha_index_or_rnd_end();
214 
221  int ha_external_lock(Session *session, int lock_type);
222  int insertRecord(unsigned char * buf) __attribute__ ((warn_unused_result));
223  int updateRecord(const unsigned char * old_data, unsigned char * new_data) __attribute__ ((warn_unused_result));
224  int deleteRecord(const unsigned char * buf) __attribute__ ((warn_unused_result));
225  void ha_release_auto_increment();
226  int ha_check(Session*);
227  void ha_start_bulk_insert(ha_rows rows);
228  int ha_end_bulk_insert();
229  int ha_delete_all_rows();
230  int ha_reset_auto_increment(uint64_t value);
231  int ha_analyze(Session*);
232 
233  int ha_disable_indexes(uint32_t mode);
234  int ha_enable_indexes(uint32_t mode);
235  int ha_discard_or_import_tablespace(bool discard);
236  void closeMarkForDelete();
237 
238  void adjust_next_insert_id_after_explicit_value(uint64_t nr);
239  int update_auto_increment();
240 
241  /* Estimates calculation */
242  virtual double scan_time(void)
243  { return static_cast<double>(stats.data_file_length) / IO_SIZE + 2; }
244  virtual double read_time(uint32_t, uint32_t ranges, ha_rows rows)
245  { return ranges + rows; }
246 
247  virtual double index_only_read_time(uint32_t keynr, double records);
248 
249  virtual ha_rows multi_range_read_info_const(uint32_t keyno, RANGE_SEQ_IF *seq,
250  void *seq_init_param,
251  uint32_t n_ranges, uint32_t *bufsz,
252  uint32_t *flags, optimizer::CostVector *cost);
253  virtual int multi_range_read_info(uint32_t keyno, uint32_t n_ranges, uint32_t keys,
254  uint32_t *bufsz, uint32_t *flags, optimizer::CostVector *cost);
255  virtual int multi_range_read_init(RANGE_SEQ_IF *seq, void *seq_init_param,
256  uint32_t n_ranges, uint32_t mode);
257  virtual int multi_range_read_next(char **range_info);
258 
259 
260  virtual const key_map *keys_to_use_for_scanning();
261  bool has_transactions();
262 
273  virtual bool is_fatal_error(int error, uint32_t flags);
274 
279  virtual ha_rows records();
280  virtual uint64_t tableSize();
281  virtual uint64_t rowSize();
288  virtual ha_rows estimate_rows_upper_bound()
289  { return stats.records+EXTRA_RECORDS; }
290 
291  virtual const char *index_type(uint32_t)
292  { assert(0); return "";}
293 
294 
295  uint32_t get_index(void) const { return active_index; }
296  virtual int close(void)=0;
297 
304  virtual int index_read_map(unsigned char * buf, const unsigned char *key,
305  key_part_map keypart_map,
306  enum ha_rkey_function find_flag)
307  {
308  uint32_t key_len= calculate_key_len(active_index, keypart_map);
309  return index_read(buf, key, key_len, find_flag);
310  }
317  virtual int index_read_idx_map(unsigned char * buf, uint32_t index,
318  const unsigned char * key,
319  key_part_map keypart_map,
320  enum ha_rkey_function find_flag);
321  virtual int index_next(unsigned char *) __attribute__ ((warn_unused_result))
322  { return HA_ERR_WRONG_COMMAND; }
323  virtual int index_prev(unsigned char *)
324  { return HA_ERR_WRONG_COMMAND; }
325  virtual int index_first(unsigned char *)
326  { return HA_ERR_WRONG_COMMAND; }
327  virtual int index_last(unsigned char *)
328  { return HA_ERR_WRONG_COMMAND; }
329  virtual int index_next_same(unsigned char *, const unsigned char *, uint32_t);
330 
331 private:
332  uint32_t calculate_key_len(uint32_t key_position, key_part_map keypart_map_arg);
333 public:
334 
340  virtual int index_read_last_map(unsigned char * buf, const unsigned char * key,
341  key_part_map keypart_map)
342  {
343  uint32_t key_len= calculate_key_len(active_index, keypart_map);
344  return index_read_last(buf, key, key_len);
345  }
346  virtual int read_range_first(const key_range *start_key,
347  const key_range *end_key,
348  bool eq_range, bool sorted);
349  virtual int read_range_next();
350  int compare_key(key_range *range);
351  virtual int rnd_next(unsigned char *)=0;
352  virtual int rnd_pos(unsigned char *, unsigned char *)=0;
353  virtual int read_first_row(unsigned char *buf, uint32_t primary_key);
354  virtual int rnd_same(unsigned char *, uint32_t)
355  { return HA_ERR_WRONG_COMMAND; }
356  virtual ha_rows records_in_range(uint32_t, key_range *, key_range *)
357  { return (ha_rows) 10; }
358  virtual void position(const unsigned char *record)=0;
359  virtual int info(uint32_t)=0; // see my_base.h for full description
360  virtual uint32_t calculate_key_hash_value(Field **)
361  { assert(0); return 0; }
362  virtual int extra(enum ha_extra_function)
363  { return 0; }
364  virtual int extra_opt(enum ha_extra_function operation, uint32_t)
365  { return extra(operation); }
366 
379  virtual bool was_semi_consistent_read() { return 0; }
386  virtual void try_semi_consistent_read(bool) {}
387  virtual void unlock_row(void) {}
388  virtual void get_auto_increment(uint64_t offset, uint64_t increment,
389  uint64_t nb_desired_values,
390  uint64_t *first_value,
391  uint64_t *nb_reserved_values)= 0;
392 
393  void set_next_insert_id(uint64_t id)
394  {
395  next_insert_id= id;
396  }
397  void restore_auto_increment(uint64_t prev_insert_id)
398  {
399  /*
400  Insertion of a row failed, re-use the lastly generated auto_increment
401  id, for the next row. This is achieved by resetting next_insert_id to
402  what it was before the failed insertion (that old value is provided by
403  the caller). If that value was 0, it was the first row of the INSERT;
404  then if insert_id_for_cur_row contains 0 it means no id was generated
405  for this first row, so no id was generated since the INSERT started, so
406  we should set next_insert_id to 0; if insert_id_for_cur_row is not 0, it
407  is the generated id of the first and failed row, so we use it.
408  */
409  next_insert_id= (prev_insert_id > 0) ? prev_insert_id :
410  insert_id_for_cur_row;
411  }
412 
413  /* end of the list of admin commands */
414 
415  virtual int indexes_are_disabled(void) {return 0;}
416  virtual void append_create_info(String *)
417  {}
428  virtual char* get_foreign_key_create_info(void)
429  { return NULL;} /* gets foreign key create string from InnoDB */
433  virtual bool can_switch_engines(void) { return true; }
436  { return 0; }
437  virtual uint32_t referenced_by_foreign_key() { return 0;}
438  virtual void free_foreign_key_create_info(char *) {}
439 
454  THR_LOCK_DATA **to,
455  enum thr_lock_type)
456  {
457  assert(0); // Impossible programming situation
458 
459  return(to);
460  }
461 
462  /*
463  @retval true Primary key (if there is one) is clustered
464  key covering all fields
465  @retval false otherwise
466  */
467  virtual bool primary_key_is_clustered() { return false; }
468  virtual int cmp_ref(const unsigned char *ref1, const unsigned char *ref2)
469  {
470  return memcmp(ref1, ref2, ref_length);
471  }
472 
473  virtual bool isOrdered(void)
474  {
475  return false;
476  }
477 
478 
479 protected:
480  /* Service methods for use by storage engines. */
481  void ha_statistic_increment(uint64_t system_status_var::*offset) const;
482  void **ha_data(Session *) const;
483 
484 private:
485  /* Private helpers */
486  inline void setTransactionReadWrite();
487 private:
488  /*
489  Low-level primitives for storage engines. These should be
490  overridden by the storage engine class. To call these methods, use
491  the corresponding 'ha_*' method above.
492  */
493 
494  virtual int open(const char *, int , uint32_t ) { assert(0); return -1; }
495  virtual int doOpen(const identifier::Table &identifier, int mode, uint32_t test_if_locked);
496  virtual int doStartIndexScan(uint32_t idx, bool)
497  { active_index= idx; return 0; }
498  virtual int doEndIndexScan() { active_index= MAX_KEY; return 0; }
506  virtual int doStartTableScan(bool scan) __attribute__ ((warn_unused_result)) = 0;
507  virtual int doEndTableScan() { return 0; }
508  virtual int doInsertRecord(unsigned char *)
509  {
510  return HA_ERR_WRONG_COMMAND;
511  }
512 
513  virtual int doUpdateRecord(const unsigned char *, unsigned char *)
514  {
515  return HA_ERR_WRONG_COMMAND;
516  }
517 
518  virtual int doDeleteRecord(const unsigned char *)
519  {
520  return HA_ERR_WRONG_COMMAND;
521  }
527  virtual int reset() { return 0; }
528 
551  virtual int external_lock(Session *, int)
552  {
553  return 0;
554  }
555  virtual void release_auto_increment(void) { return; }
557  virtual int check(Session *)
558  { return HA_ADMIN_NOT_IMPLEMENTED; }
559 
560  virtual void start_bulk_insert(ha_rows)
561  {}
562  virtual int end_bulk_insert(void) { return 0; }
563  virtual int index_read(unsigned char *, const unsigned char *,
564  uint32_t, enum ha_rkey_function)
565  { return HA_ERR_WRONG_COMMAND; }
566  virtual int index_read_last(unsigned char *, const unsigned char *, uint32_t)
567  { return (errno= HA_ERR_WRONG_COMMAND); }
574  virtual int delete_all_rows(void)
575  { return (errno=HA_ERR_WRONG_COMMAND); }
582  virtual int reset_auto_increment(uint64_t)
583  { return HA_ERR_WRONG_COMMAND; }
584 
585  virtual int analyze(Session *)
586  { return HA_ADMIN_NOT_IMPLEMENTED; }
587 
588  virtual int disable_indexes(uint32_t)
589  { return HA_ERR_WRONG_COMMAND; }
590 
591  virtual int enable_indexes(uint32_t)
592  { return HA_ERR_WRONG_COMMAND; }
593 
594  virtual int discard_or_import_tablespace(bool)
595  { return (errno=HA_ERR_WRONG_COMMAND); }
596 
597  /*
598  @todo this is just for the HEAP engine, it should
599  be removed at some point in the future (and
600  no new engine should ever use it). Right
601  now HEAP does rely on it, so we cannot remove it.
602  */
603  virtual void drop_table();
604 };
605 
606 extern const char *ha_row_type[];
607 
608 /* basic stuff */
609 void ha_init_errors(void);
610 
611 SortField *make_unireg_sortorder(Order *order, uint32_t *length,
612  SortField *sortorder);
613 int setup_order(Session *session, Item **ref_pointer_array, TableList *tables,
614  List<Item> &fields, List <Item> &all_fields, Order *order);
615 int setup_group(Session *session, Item **ref_pointer_array, TableList *tables,
616  List<Item> &fields, List<Item> &all_fields, Order *order,
617  bool *hidden_group_fields);
618 bool fix_inner_refs(Session *session, List<Item> &all_fields, Select_Lex *select,
619  Item **ref_pointer_array);
620 
621 bool handle_select(Session *session, LEX *lex, select_result *result,
622  uint64_t setup_tables_done_option);
623 void free_underlaid_joins(Session *session, Select_Lex *select);
624 
625 bool handle_derived(LEX *lex, bool (*processor)(Session *session,
626  LEX *lex,
627  TableList *table));
628 bool derived_prepare(Session *session, LEX *lex, TableList *t);
629 bool derived_filling(Session *session, LEX *lex, TableList *t);
630 int prepare_create_field(CreateField *sql_field,
631  uint32_t *blob_columns,
632  int *timestamps, int *timestamps_with_niladic);
633 
634 bool create_table(Session *session,
635  const identifier::Table &identifier,
636  HA_CREATE_INFO *create_info,
637  message::Table &table_proto,
638  AlterInfo *alter_info,
639  bool tmp_table, uint32_t select_field_count,
640  bool is_if_not_exists);
641 
642 bool create_table_no_lock(Session *session,
643  const identifier::Table &identifier,
644  HA_CREATE_INFO *create_info,
645  message::Table &table_proto,
646  AlterInfo *alter_info,
647  bool tmp_table, uint32_t select_field_count,
648  bool is_if_not_exists);
649 
650 bool create_like_table(Session* session,
651  const identifier::Table& destination_identifier,
652  const identifier::Table& source_identifier,
653  message::Table &create_table_proto,
654  bool is_if_not_exists,
655  bool is_engine_set);
656 
657 bool rename_table(Session &session,
658  plugin::StorageEngine *base,
659  const identifier::Table &old_identifier,
660  const identifier::Table &new_identifier);
661 
662 bool prepare_update(Session *session, TableList *table_list,
663  Item **conds, uint32_t order_num, Order *order);
664 int update_query(Session *session,TableList *tables,List<Item> &fields,
665  List<Item> &values,COND *conds,
666  uint32_t order_num, Order *order, ha_rows limit,
667  enum enum_duplicates handle_duplicates, bool ignore);
668 bool prepare_insert(Session *session, TableList *table_list, Table *table,
669  List<Item> &fields, List_item *values,
670  List<Item> &update_fields,
671  List<Item> &update_values, enum_duplicates duplic,
672  COND **where, bool select_insert,
673  bool check_fields, bool abort_on_warning);
674 bool insert_query(Session *session,TableList *table,List<Item> &fields,
675  List<List_item> &values, List<Item> &update_fields,
676  List<Item> &update_values, enum_duplicates flag,
677  bool ignore);
678 int check_that_all_fields_are_given_values(Session *session, Table *entry,
679  TableList *table_list);
680 int prepare_delete(Session *session, TableList *table_list, Item **conds);
681 bool delete_query(Session *session, TableList *table_list, COND *conds,
682  SQL_LIST *order, ha_rows rows, uint64_t options,
683  bool reset_auto_increment);
684 bool truncate(Session& session, TableList *table_list);
685 TableShare *get_table_share(Session *session, TableList *table_list, char *key,
686  uint32_t key_length, uint32_t db_flags, int *error);
687 TableShare *get_cached_table_share(const char *db, const char *table_name);
688 bool reopen_name_locked_table(Session* session, TableList* table_list, bool link_in);
689 bool reopen_tables(Session *session,bool get_locks,bool in_refresh);
690 void close_handle_and_leave_table_as_lock(Table *table);
691 bool wait_for_tables(Session *session);
692 bool table_is_used(Table *table, bool wait_for_name_lock);
693 Table *drop_locked_tables(Session *session, const drizzled::identifier::Table &identifier);
694 void abort_locked_tables(Session *session, const drizzled::identifier::Table &identifier);
695 extern Field *not_found_field;
696 extern Field *view_ref_found;
697 
698 Field *
699 find_field_in_tables(Session *session, Item_ident *item,
700  TableList *first_table, TableList *last_table,
701  Item **ref, find_item_error_report_type report_error,
702  bool register_tree_change);
703 Field *
704 find_field_in_table_ref(Session *session, TableList *table_list,
705  const char *name, uint32_t length,
706  const char *item_name, const char *db_name,
707  const char *table_name, Item **ref,
708  bool allow_rowid,
709  uint32_t *cached_field_index_ptr,
710  bool register_tree_change, TableList **actual_table);
711 Field *
712 find_field_in_table(Session *session, Table *table, const char *name, uint32_t length,
713  bool allow_rowid, uint32_t *cached_field_index_ptr);
714 
715 } /* namespace drizzled */
716