Drizzled Public API Documentation

table.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; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #pragma once
22 
23 #include <string>
24 #include <boost/dynamic_bitset.hpp>
25 
26 #include <drizzled/order.h>
27 #include <drizzled/filesort_info.h>
28 #include <drizzled/natural_join_column.h>
29 #include <drizzled/field_iterator.h>
30 #include <drizzled/cursor.h>
31 #include <drizzled/lex_string.h>
32 #include <drizzled/table/instance.h>
33 #include <drizzled/atomics.h>
34 
35 #include <drizzled/visibility.h>
36 
37 namespace drizzled {
38 
44 {
47 public:
48  Field **getFields() const
49  {
50  return field;
51  }
52 
53  Field *getField(uint32_t arg) const
54  {
55  return field[arg];
56  }
57 
58  void setFields(Field **arg)
59  {
60  field= arg;
61  }
62 
63  void setFieldAt(Field *arg, uint32_t arg_pos)
64  {
65  field[arg_pos]= arg;
66  }
67 
70 private:
71  Table *next;
72 
73 public:
74  Table *getNext() const
75  {
76  return next;
77  }
78 
79  Table **getNextPtr()
80  {
81  return &next;
82  }
83 
84  void setNext(Table *arg)
85  {
86  next= arg;
87  }
88 
89  void unlink()
90  {
91  getNext()->setPrev(getPrev()); /* remove from used chain */
92  getPrev()->setNext(getNext());
93  }
94 
95 private:
96  Table *prev;
97 public:
98  Table *getPrev() const
99  {
100  return prev;
101  }
102 
103  Table **getPrevPtr()
104  {
105  return &prev;
106  }
107 
108  void setPrev(Table *arg)
109  {
110  prev= arg;
111  }
112 
113  boost::dynamic_bitset<> *read_set; /* Active column sets */
114  boost::dynamic_bitset<> *write_set; /* Active column sets */
115 
116  uint32_t tablenr;
117  uint32_t db_stat;
119  boost::dynamic_bitset<> def_read_set;
120  boost::dynamic_bitset<> def_write_set;
121  boost::dynamic_bitset<> tmp_set; /* Not sure about this... */
122 
124  Session *getSession()
125  {
126  return in_use;
127  }
128 
129  unsigned char *getInsertRecord() const
130  {
131  return record[0];
132  }
133 
134  unsigned char *getUpdateRecord()
135  {
136  return record[1];
137  }
138 
139  unsigned char *record[2];
140  std::vector<unsigned char> insert_values; /* used by INSERT ... UPDATE */
146  TableList *pos_in_table_list; /* Element referring to this table */
147  Order *group;
148 
149  const char *getAlias() const
150  {
151  return _alias.c_str();
152  }
153 
154  void clearAlias()
155  {
156  _alias.clear();
157  }
158 
159  void setAlias(const char *arg)
160  {
161  _alias= arg;
162  }
163 
164 private:
165  std::string _alias;
166 public:
167 
168  unsigned char *null_flags;
169 
170  uint32_t lock_position;
171  uint32_t lock_data_start;
172  uint32_t lock_count;
173  uint32_t used_fields;
174  uint32_t status; /* What's in getInsertRecord() */
175  /* number of select if it is derived table */
176  uint32_t derived_select_number;
178  bool copy_blobs;
180  /*
181  0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0.
182  If maybe_null !=0, this table is inner w.r.t. some outer join operation,
183  and null_row may be true.
184  */
185  bool maybe_null;
186 
187  /*
188  If true, the current table row is considered to have all columns set to
189  NULL, including columns declared as "not null" (see maybe_null).
190  */
191  bool null_row;
192 
193  bool force_index;
194  bool distinct;
195  bool const_table;
196  bool no_rows;
197  bool key_read;
198  bool no_keyread;
199  /*
200  Placeholder for an open table which prevents other connections
201  from taking name-locks on this table. Typically used with
202  TableShare::version member to take an exclusive name-lock on
203  this table name -- a name lock that not only prevents other
204  threads from opening the table, but also blocks other name
205  locks. This is achieved by:
206  - setting open_placeholder to 1 - this will block other name
207  locks, as wait_for_locked_table_name will be forced to wait,
208  see table_is_used for details.
209  - setting version to 0 - this will force other threads to close
210  the instance of this table and wait (this is the same approach
211  as used for usual name locks).
212  An exclusively name-locked table currently can have no Cursor
213  object associated with it (db_stat is always 0), but please do
214  not rely on that.
215  */
216  bool open_placeholder;
217  bool locked_by_name;
218  bool no_cache;
219  /*
220  To indicate that a non-null value of the auto_increment field
221  was provided by the user or retrieved from the current record.
222  Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode.
223  */
224  bool auto_increment_field_not_null;
225  bool alias_name_used; /* true if table_name is alias */
226 
227  /*
228  The ID of the query that opened and is using this table. Has different
229  meanings depending on the table type.
230 
231  Temporary tables:
232 
233  table->query_id is set to session->query_id for the duration of a statement
234  and is reset to 0 once it is closed by the same statement. A non-zero
235  table->query_id means that a statement is using the table even if it's
236  not the current statement (table is in use by some outer statement).
237 
238  Non-temporary tables:
239 
240  Under pre-locked or LOCK TABLES mode: query_id is set to session->query_id
241  for the duration of a statement and is reset to 0 once it is closed by
242  the same statement. A non-zero query_id is used to control which tables
243  in the list of pre-opened and locked tables are actually being used.
244  */
245  query_id_t query_id;
246 
256 
257  /*
258  If this table has TIMESTAMP field with auto-set property (pointed by
259  timestamp_field member) then this variable indicates during which
260  operations (insert only/on update/in both cases) we should set this
261  field to current timestamp. If there are no such field in this table
262  or we should not automatically set its value during execution of current
263  statement then the variable contains TIMESTAMP_NO_AUTO_SET (i.e. 0).
264 
265  Value of this variable is set for each statement in open_table() and
266  if needed cleared later in statement processing code (see update_query()
267  as example).
268  */
269  timestamp_auto_set_type timestamp_field_type;
270  table_map map;
271 
272  RegInfo reginfo; /* field connections */
273 
274  /*
275  Map of keys that can be used to retrieve all data from this table
276  needed by the query without reading the row.
277  */
278  key_map covering_keys;
279  key_map quick_keys;
280  key_map merge_keys;
281 
282  /*
283  A set of keys that can be used in the query that references this
284  table.
285 
286  All indexes disabled on the table's TableShare (see Table::s) will be
287  subtracted from this set upon instantiation. Thus for any Table t it holds
288  that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we
289  must not introduce any new keys here (see setup_tables).
290 
291  The set is implemented as a bitmap.
292  */
293  key_map keys_in_use_for_query;
294 
295  /* Map of keys that can be used to calculate GROUP BY without sorting */
296  key_map keys_in_use_for_group_by;
297 
298  /* Map of keys that can be used to calculate ORDER BY without sorting */
299  key_map keys_in_use_for_order_by;
300 
301  /*
302  For each key that has quick_keys.test(key) == true: estimate of #records
303  and max #key parts that range access would use.
304  */
305  ha_rows quick_rows[MAX_KEY];
306 
307  /* Bitmaps of key parts that =const for the entire join. */
308  key_part_map const_key_parts[MAX_KEY];
309 
310  uint32_t quick_key_parts[MAX_KEY];
311  uint32_t quick_n_ranges[MAX_KEY];
312 
313 private:
314  memory::Root mem_root;
315 
316  void init_mem_root()
317  {
318  if (not mem_root.alloc_root_inited())
319  mem_root.init(TABLE_ALLOC_BLOCK_SIZE);
320  }
321 public:
322  memory::Root& mem()
323  {
324  init_mem_root();
325  return mem_root;
326  }
327 
328  unsigned char* alloc(size_t arg)
329  {
330  init_mem_root();
331  return mem_root.alloc(arg);
332  }
333 
334  char* strdup(const char* str_arg, size_t len_arg)
335  {
336  init_mem_root();
337  return mem_root.strdup(str_arg, len_arg);
338  }
339 
340  filesort_info sort;
341 
342  Table();
343  virtual ~Table();
344 
345  int report_error(int error);
352  int delete_table(bool free_share= false);
353 
354  void resetTable(Session *session, TableShare *share, uint32_t db_stat_arg);
355 
356  /* SHARE methods */
357  virtual const TableShare *getShare() const= 0; /* Get rid of this long term */
358  virtual TableShare *getMutableShare()= 0; /* Get rid of this long term */
359  virtual bool hasShare() const= 0; /* Get rid of this long term */
360  virtual void setShare(TableShare *new_share)= 0; /* Get rid of this long term */
361 
362  virtual void release(void)= 0;
363 
364  uint32_t sizeKeys() { return getMutableShare()->sizeKeys(); }
365  uint32_t sizeFields() { return getMutableShare()->sizeFields(); }
366  uint32_t getRecordLength() const { return getShare()->getRecordLength(); }
367  uint32_t sizeBlobFields() { return getMutableShare()->blob_fields; }
368  uint32_t *getBlobField() { return &getMutableShare()->blob_field[0]; }
369 
370 public:
371  virtual bool hasVariableWidth() const
372  {
373  return getShare()->hasVariableWidth(); // We should calculate this.
374  }
375 
376  virtual void setVariableWidth(void);
377 
378  Field_blob *getBlobFieldAt(uint32_t arg) const
379  {
380  if (arg < getShare()->blob_fields)
381  return (Field_blob*) field[getShare()->blob_field[arg]]; /*NOTE: Using 'Table.field' NOT SharedTable.field. */
382 
383  return NULL;
384  }
385  inline uint8_t getBlobPtrSize() const { return getShare()->sizeBlobPtr(); }
386  inline uint32_t getNullBytes() const { return getShare()->null_bytes; }
387  inline uint32_t getNullFields() const { return getShare()->null_fields; }
388  inline unsigned char *getDefaultValues() { return getMutableShare()->getDefaultValues(); }
389  inline const char *getSchemaName() const { return getShare()->getSchemaName(); }
390  inline const char *getTableName() const { return getShare()->getTableName(); }
391 
392  inline bool isDatabaseLowByteFirst() const { return getShare()->db_low_byte_first; } /* Portable row format */
393  inline bool isNameLock() const { return open_placeholder; }
394 
395  uint32_t index_flags(uint32_t idx) const;
396 
397  inline plugin::StorageEngine *getEngine() const /* table_type for handler */
398  {
399  return getShare()->getEngine();
400  }
401 
402  Cursor &getCursor() const /* table_type for handler */
403  {
404  assert(cursor);
405  return *cursor;
406  }
407 
408  size_t max_row_length(const unsigned char *data);
409  uint32_t find_shortest_key(const key_map *usable_keys);
410  bool compare_record(Field **ptr);
411  bool records_are_comparable();
412  bool compare_records();
413  /* TODO: the (re)storeRecord's may be able to be further condensed */
414  void storeRecord();
415  void storeRecordAsInsert();
416  void storeRecordAsDefault();
417  void restoreRecord();
418  void restoreRecordAsDefault();
419  void emptyRecord();
420 
421 
422  /* See if this can be blown away */
423  inline uint32_t getDBStat () const { return db_stat; }
424 
441  void fill_item_list(List<Item>&) const;
442  void clear_column_bitmaps(void);
443  void prepare_for_position(void);
444  void mark_columns_used_by_index_no_reset(uint32_t index, boost::dynamic_bitset<>& bitmap);
445  void mark_columns_used_by_index_no_reset(uint32_t index);
446  void mark_columns_used_by_index(uint32_t index);
447  void restore_column_maps_after_mark_index();
448  void mark_auto_increment_column(void);
449  void mark_columns_needed_for_update(void);
450  void mark_columns_needed_for_delete(void);
451  void mark_columns_needed_for_insert(void);
452  void column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
453  boost::dynamic_bitset<>& write_set_arg);
454 
455  void restore_column_map(const boost::dynamic_bitset<>& old);
456 
457  const boost::dynamic_bitset<> use_all_columns(boost::dynamic_bitset<>& map);
458  inline void use_all_columns()
459  {
460  column_bitmaps_set(getMutableShare()->all_set, getMutableShare()->all_set);
461  }
462 
463  inline void default_column_bitmaps()
464  {
465  read_set= &def_read_set;
466  write_set= &def_write_set;
467  }
468 
469  /* Both of the below should go away once we can move this bit to the field objects */
470  inline bool isReadSet(uint32_t index) const
471  {
472  return read_set->test(index);
473  }
474 
475  inline void setReadSet(uint32_t index)
476  {
477  read_set->set(index);
478  }
479 
480  inline void setReadSet()
481  {
482  read_set->set();
483  }
484 
485  inline void clearReadSet(uint32_t index)
486  {
487  read_set->reset(index);
488  }
489 
490  inline void clearReadSet()
491  {
492  read_set->reset();
493  }
494 
495  inline bool isWriteSet(uint32_t index)
496  {
497  return write_set->test(index);
498  }
499 
500  inline void setWriteSet(uint32_t index)
501  {
502  write_set->set(index);
503  }
504 
505  inline void setWriteSet()
506  {
507  write_set->set();
508  }
509 
510  inline void clearWriteSet(uint32_t index)
511  {
512  write_set->reset(index);
513  }
514 
515  inline void clearWriteSet()
516  {
517  write_set->reset();
518  }
519 
520  /* Is table open or should be treated as such by name-locking? */
521  bool is_name_opened() const
522  {
523  return db_stat || open_placeholder;
524  }
525 
526  /*
527  Is this instance of the table should be reopen or represents a name-lock?
528  */
529  bool needs_reopen_or_name_lock() const;
530 
538  void setup_table_map(TableList *table_list, uint32_t tablenr);
539  inline void mark_as_null_row()
540  {
541  null_row= 1;
542  status|= STATUS_NULL_ROW;
543  memset(null_flags, 255, getShare()->null_bytes);
544  }
545 
546  void free_io_cache();
547  void filesort_free_buffers(bool full= false);
548  void intern_close_table();
549 
550  void print_error(int error, myf errflag) const;
551 
556  uint32_t get_dup_key(int error) const
557  {
558  cursor->errkey = (uint32_t) -1;
559  if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
560  error == HA_ERR_FOUND_DUPP_UNIQUE ||
561  error == HA_ERR_DROP_INDEX_FK)
562  cursor->info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
563 
564  return(cursor->errkey);
565  }
566 
567  /*
568  This is a short term fix. Long term we will used the TableIdentifier to do the actual comparison.
569  */
570  bool operator<(const Table &right) const
571  {
572  return getShare()->getCacheKey() < right.getShare()->getCacheKey();
573  }
574 
575  static bool compare(const Table *a, const Table *b)
576  {
577  return *a < *b;
578  }
579 
580  friend std::ostream& operator<<(std::ostream& output, const Table &table)
581  {
582  if (table.getShare())
583  {
584  output << "Table:(";
585  output << table.getShare()->getSchemaName();
586  output << ", ";
587  output << table.getShare()->getTableName();
588  output << ", ";
589  output << table.getShare()->getTableTypeAsString();
590  output << ")";
591  }
592  else
593  {
594  output << "Table:(has no share)";
595  }
596 
597  return output; // for multiple << operators.
598  }
599 
600 public:
601  virtual bool isPlaceHolder(void) const
602  {
603  return false;
604  }
605 };
606 
615 {
616 public:
630  ForeignKeyInfo(lex_string_t *in_foreign_id,
631  lex_string_t *in_referenced_db,
632  lex_string_t *in_referenced_table,
633  lex_string_t *in_update_method,
634  lex_string_t *in_delete_method,
635  lex_string_t *in_referenced_key_name,
636  List<lex_string_t> in_foreign_fields,
637  List<lex_string_t> in_referenced_fields)
638  :
639  foreign_id(in_foreign_id),
640  referenced_db(in_referenced_db),
641  referenced_table(in_referenced_table),
642  update_method(in_update_method),
643  delete_method(in_delete_method),
644  referenced_key_name(in_referenced_key_name),
645  foreign_fields(in_foreign_fields),
646  referenced_fields(in_referenced_fields)
647  {}
648 
654  : foreign_id(NULL), referenced_db(NULL), referenced_table(NULL),
656  {}
657 
664  const lex_string_t *getForeignId() const
665  {
666  return foreign_id;
667  }
668 
676  {
677  return referenced_db;
678  }
679 
687  {
688  return referenced_table;
689  }
690 
698  {
699  return update_method;
700  }
701 
709  {
710  return delete_method;
711  }
712 
720  {
721  return referenced_key_name;
722  }
723 
731  {
732  return foreign_fields;
733  }
734 
742  {
743  return referenced_fields;
744  }
745 private:
778 };
779 
780 #define JOIN_TYPE_LEFT 1
781 #define JOIN_TYPE_RIGHT 2
782 
783 void free_blobs(Table *table);
784 int set_zone(int nr,int min_zone,int max_zone);
785 uint32_t convert_period_to_month(uint32_t period);
786 uint32_t convert_month_to_period(uint32_t month);
787 
788 int test_if_number(char *str,int *res,bool allow_wildcards);
789 void change_byte(unsigned char *,uint,char,char);
790 void change_double_for_sort(double nr,unsigned char *to);
791 int get_quick_record(optimizer::SqlSelect *select);
792 
793 void find_date(char *pos,uint32_t *vek,uint32_t flag);
794 TYPELIB* convert_strings_to_array_type(char** typelibs, char** end);
795 TYPELIB* typelib(memory::Root&, List<String>&);
796 ulong get_form_pos(int file, unsigned char *head, TYPELIB *save_names);
797 void append_unescaped(String *res, const char *pos, uint32_t length);
798 
799 bool check_column_name(const char*);
800 bool check_table_name(str_ref);
801 
802 } /* namespace drizzled */
803 
804 #include <drizzled/table/singular.h>
805 #include <drizzled/table/concurrent.h>
806