Drizzled Public API Documentation

table.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; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 /* Structs that defines the Table */
00022 
00023 
00024 
00025 #pragma once
00026 
00027 #include <string>
00028 #include <boost/dynamic_bitset.hpp>
00029 
00030 #include <drizzled/order.h>
00031 #include <drizzled/filesort_info.h>
00032 #include <drizzled/natural_join_column.h>
00033 #include <drizzled/field_iterator.h>
00034 #include <drizzled/cursor.h>
00035 #include <drizzled/lex_string.h>
00036 #include <drizzled/table/instance.h>
00037 #include <drizzled/atomics.h>
00038 #include <drizzled/query_id.h>
00039 
00040 #include <drizzled/visibility.h>
00041 
00042 namespace drizzled
00043 {
00044 
00045 class COND_EQUAL;
00046 class Field_blob;
00047 class Item;
00048 class Item_subselect;
00049 class SecurityContext;
00050 class Select_Lex;
00051 class Select_Lex_Unit;
00052 class TableList;
00053 namespace field { class Epoch; }
00054 namespace plugin { class StorageEngine; }
00055 
00056 typedef enum enum_table_category TABLE_CATEGORY;
00057 typedef struct st_columndef MI_COLUMNDEF;
00058 
00063 class DRIZZLED_API Table 
00064 {
00065   Field **field; 
00067 public:
00068   Field **getFields() const
00069   {
00070     return field;
00071   }
00072 
00073   Field *getField(uint32_t arg) const
00074   {
00075     return field[arg];
00076   }
00077 
00078   void setFields(Field **arg)
00079   {
00080     field= arg;
00081   }
00082 
00083   void setFieldAt(Field *arg, uint32_t arg_pos)
00084   {
00085     field[arg_pos]= arg;
00086   }
00087 
00088   Cursor *cursor; 
00090 private:
00091   Table *next;
00092 
00093 public:
00094   Table *getNext() const
00095   {
00096     return next;
00097   }
00098 
00099   Table **getNextPtr()
00100   {
00101     return &next;
00102   }
00103 
00104   void setNext(Table *arg)
00105   {
00106     next= arg;
00107   }
00108 
00109   void unlink()
00110   {
00111     getNext()->setPrev(getPrev());    /* remove from used chain */
00112     getPrev()->setNext(getNext());
00113   }
00114 
00115 private:
00116   Table *prev;
00117 public:
00118   Table *getPrev() const
00119   {
00120     return prev;
00121   }
00122 
00123   Table **getPrevPtr()
00124   {
00125     return &prev;
00126   }
00127 
00128   void setPrev(Table *arg)
00129   {
00130     prev= arg;
00131   }
00132 
00133   boost::dynamic_bitset<> *read_set; /* Active column sets */
00134   boost::dynamic_bitset<> *write_set; /* Active column sets */
00135 
00136   uint32_t tablenr;
00137   uint32_t db_stat; 
00139   boost::dynamic_bitset<> def_read_set; 
00140   boost::dynamic_bitset<> def_write_set; 
00141   boost::dynamic_bitset<> tmp_set; /* Not sure about this... */
00142 
00143   Session *in_use; 
00144   Session *getSession()
00145   {
00146     return in_use;
00147   }
00148 
00149   unsigned char *getInsertRecord() const
00150   {
00151     return record[0];
00152   }
00153 
00154   unsigned char *getUpdateRecord()
00155   {
00156     return record[1];
00157   }
00158 
00159   unsigned char *record[2]; 
00160   std::vector<unsigned char> insert_values; /* used by INSERT ... UPDATE */
00161   KeyInfo  *key_info; 
00162   Field *next_number_field; 
00163   Field *found_next_number_field; 
00164   field::Epoch *timestamp_field; 
00166   TableList *pos_in_table_list; /* Element referring to this table */
00167   Order *group;
00168   
00169   const char *getAlias() const
00170   {
00171     return _alias.c_str();
00172   }
00173 
00174   void clearAlias()
00175   {
00176     _alias.clear();
00177   }
00178 
00179   void setAlias(const char *arg)
00180   {
00181     _alias= arg;
00182   }
00183 
00184 private:
00185   std::string _alias; 
00186 public:
00187 
00188   unsigned char *null_flags;
00189 
00190   uint32_t lock_position; 
00191   uint32_t lock_data_start; 
00192   uint32_t lock_count; 
00193   uint32_t used_fields;
00194   uint32_t status; /* What's in getInsertRecord() */
00195   /* number of select if it is derived table */
00196   uint32_t derived_select_number;
00197   int current_lock; 
00198   bool copy_blobs; 
00200   /*
00201     0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0.
00202     If maybe_null !=0, this table is inner w.r.t. some outer join operation,
00203     and null_row may be true.
00204   */
00205   bool maybe_null;
00206 
00207   /*
00208     If true, the current table row is considered to have all columns set to
00209     NULL, including columns declared as "not null" (see maybe_null).
00210   */
00211   bool null_row;
00212 
00213   bool force_index;
00214   bool distinct;
00215   bool const_table;
00216   bool no_rows;
00217   bool key_read;
00218   bool no_keyread;
00219   /*
00220     Placeholder for an open table which prevents other connections
00221     from taking name-locks on this table. Typically used with
00222     TableShare::version member to take an exclusive name-lock on
00223     this table name -- a name lock that not only prevents other
00224     threads from opening the table, but also blocks other name
00225     locks. This is achieved by:
00226     - setting open_placeholder to 1 - this will block other name
00227       locks, as wait_for_locked_table_name will be forced to wait,
00228       see table_is_used for details.
00229     - setting version to 0 - this will force other threads to close
00230       the instance of this table and wait (this is the same approach
00231       as used for usual name locks).
00232     An exclusively name-locked table currently can have no Cursor
00233     object associated with it (db_stat is always 0), but please do
00234     not rely on that.
00235   */
00236   bool open_placeholder;
00237   bool locked_by_name;
00238   bool no_cache;
00239   /*
00240     To indicate that a non-null value of the auto_increment field
00241     was provided by the user or retrieved from the current record.
00242     Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode.
00243   */
00244   bool auto_increment_field_not_null;
00245   bool alias_name_used; /* true if table_name is alias */
00246 
00247   /*
00248    The ID of the query that opened and is using this table. Has different
00249    meanings depending on the table type.
00250 
00251    Temporary tables:
00252 
00253    table->query_id is set to session->query_id for the duration of a statement
00254    and is reset to 0 once it is closed by the same statement. A non-zero
00255    table->query_id means that a statement is using the table even if it's
00256    not the current statement (table is in use by some outer statement).
00257 
00258    Non-temporary tables:
00259 
00260    Under pre-locked or LOCK TABLES mode: query_id is set to session->query_id
00261    for the duration of a statement and is reset to 0 once it is closed by
00262    the same statement. A non-zero query_id is used to control which tables
00263    in the list of pre-opened and locked tables are actually being used.
00264   */
00265   query_id_t query_id;
00266 
00275   ha_rows quick_condition_rows;
00276 
00277   /*
00278     If this table has TIMESTAMP field with auto-set property (pointed by
00279     timestamp_field member) then this variable indicates during which
00280     operations (insert only/on update/in both cases) we should set this
00281     field to current timestamp. If there are no such field in this table
00282     or we should not automatically set its value during execution of current
00283     statement then the variable contains TIMESTAMP_NO_AUTO_SET (i.e. 0).
00284 
00285     Value of this variable is set for each statement in open_table() and
00286     if needed cleared later in statement processing code (see update_query()
00287     as example).
00288   */
00289   timestamp_auto_set_type timestamp_field_type;
00290   table_map map; 
00291 
00292   RegInfo reginfo; /* field connections */
00293 
00294   /*
00295     Map of keys that can be used to retrieve all data from this table
00296     needed by the query without reading the row.
00297   */
00298   key_map covering_keys;
00299   key_map quick_keys;
00300   key_map merge_keys;
00301 
00302   /*
00303     A set of keys that can be used in the query that references this
00304     table.
00305 
00306     All indexes disabled on the table's TableShare (see Table::s) will be
00307     subtracted from this set upon instantiation. Thus for any Table t it holds
00308     that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we
00309     must not introduce any new keys here (see setup_tables).
00310 
00311     The set is implemented as a bitmap.
00312   */
00313   key_map keys_in_use_for_query;
00314 
00315   /* Map of keys that can be used to calculate GROUP BY without sorting */
00316   key_map keys_in_use_for_group_by;
00317 
00318   /* Map of keys that can be used to calculate ORDER BY without sorting */
00319   key_map keys_in_use_for_order_by;
00320 
00321   /*
00322     For each key that has quick_keys.test(key) == true: estimate of #records
00323     and max #key parts that range access would use.
00324   */
00325   ha_rows quick_rows[MAX_KEY];
00326 
00327   /* Bitmaps of key parts that =const for the entire join. */
00328   key_part_map  const_key_parts[MAX_KEY];
00329 
00330   uint32_t quick_key_parts[MAX_KEY];
00331   uint32_t quick_n_ranges[MAX_KEY];
00332 
00333 private:
00334   memory::Root mem_root;
00335 
00336   void init_mem_root()
00337   {
00338     init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
00339   }
00340 public:
00341   memory::Root *getMemRoot()
00342   {
00343     if (not mem_root.alloc_root_inited())
00344     {
00345       init_mem_root();
00346     }
00347 
00348     return &mem_root;
00349   }
00350 
00351   void *alloc_root(size_t arg)
00352   {
00353     if (not mem_root.alloc_root_inited())
00354     {
00355       init_mem_root();
00356     }
00357 
00358     return mem_root.alloc_root(arg);
00359   }
00360 
00361   char *strmake_root(const char *str_arg, size_t len_arg)
00362   {
00363     if (not mem_root.alloc_root_inited())
00364     {
00365       init_mem_root();
00366     }
00367 
00368     return mem_root.strmake_root(str_arg, len_arg);
00369   }
00370 
00371   filesort_info sort;
00372 
00373   Table();
00374   virtual ~Table();
00375 
00376   int report_error(int error);
00383   int delete_table(bool free_share= false);
00384 
00385   void resetTable(Session *session, TableShare *share, uint32_t db_stat_arg);
00386 
00387   /* SHARE methods */
00388   virtual const TableShare *getShare() const= 0; /* Get rid of this long term */
00389   virtual TableShare *getMutableShare()= 0; /* Get rid of this long term */
00390   virtual bool hasShare() const= 0; /* Get rid of this long term */
00391   virtual void setShare(TableShare *new_share)= 0; /* Get rid of this long term */
00392 
00393   virtual void release(void)= 0;
00394 
00395   uint32_t sizeKeys() { return getMutableShare()->sizeKeys(); }
00396   uint32_t sizeFields() { return getMutableShare()->sizeFields(); }
00397   uint32_t getRecordLength() const { return getShare()->getRecordLength(); }
00398   uint32_t sizeBlobFields() { return getMutableShare()->blob_fields; }
00399   uint32_t *getBlobField() { return &getMutableShare()->blob_field[0]; }
00400 
00401 public:
00402   virtual bool hasVariableWidth() const
00403   {
00404     return getShare()->hasVariableWidth(); // We should calculate this.
00405   }
00406 
00407   virtual void setVariableWidth(void);
00408 
00409   Field_blob *getBlobFieldAt(uint32_t arg) const
00410   {
00411     if (arg < getShare()->blob_fields)
00412       return (Field_blob*) field[getShare()->blob_field[arg]]; /*NOTE: Using 'Table.field' NOT SharedTable.field. */
00413 
00414     return NULL;
00415   }
00416   inline uint8_t getBlobPtrSize() const { return getShare()->sizeBlobPtr(); }
00417   inline uint32_t getNullBytes() const { return getShare()->null_bytes; }
00418   inline uint32_t getNullFields() const { return getShare()->null_fields; }
00419   inline unsigned char *getDefaultValues() { return  getMutableShare()->getDefaultValues(); }
00420   inline const char *getSchemaName()  const { return getShare()->getSchemaName(); }
00421   inline const char *getTableName()  const { return getShare()->getTableName(); }
00422 
00423   inline bool isDatabaseLowByteFirst() const { return getShare()->db_low_byte_first; } /* Portable row format */
00424   inline bool isNameLock() const { return open_placeholder; }
00425 
00426   uint32_t index_flags(uint32_t idx) const;
00427 
00428   inline plugin::StorageEngine *getEngine() const   /* table_type for handler */
00429   {
00430     return getShare()->getEngine();
00431   }
00432 
00433   Cursor &getCursor() const /* table_type for handler */
00434   {
00435     assert(cursor);
00436     return *cursor;
00437   }
00438 
00439   size_t max_row_length(const unsigned char *data);
00440   uint32_t find_shortest_key(const key_map *usable_keys);
00441   bool compare_record(Field **ptr);
00442   bool records_are_comparable();
00443   bool compare_records();
00444   /* TODO: the (re)storeRecord's may be able to be further condensed */
00445   void storeRecord();
00446   void storeRecordAsInsert();
00447   void storeRecordAsDefault();
00448   void restoreRecord();
00449   void restoreRecordAsDefault();
00450   void emptyRecord();
00451 
00452 
00453   /* See if this can be blown away */
00454   inline uint32_t getDBStat () { return db_stat; }
00455   inline uint32_t setDBStat () { return db_stat; }
00472   bool fill_item_list(List<Item> *item_list) const;
00473   void clear_column_bitmaps(void);
00474   void prepare_for_position(void);
00475   void mark_columns_used_by_index_no_reset(uint32_t index, boost::dynamic_bitset<>& bitmap);
00476   void mark_columns_used_by_index_no_reset(uint32_t index);
00477   void mark_columns_used_by_index(uint32_t index);
00478   void restore_column_maps_after_mark_index();
00479   void mark_auto_increment_column(void);
00480   void mark_columns_needed_for_update(void);
00481   void mark_columns_needed_for_delete(void);
00482   void mark_columns_needed_for_insert(void);
00483   void column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
00484                           boost::dynamic_bitset<>& write_set_arg);
00485 
00486   void restore_column_map(const boost::dynamic_bitset<>& old);
00487 
00488   const boost::dynamic_bitset<> use_all_columns(boost::dynamic_bitset<>& map);
00489   inline void use_all_columns()
00490   {
00491     column_bitmaps_set(getMutableShare()->all_set, getMutableShare()->all_set);
00492   }
00493 
00494   inline void default_column_bitmaps()
00495   {
00496     read_set= &def_read_set;
00497     write_set= &def_write_set;
00498   }
00499 
00500   /* Both of the below should go away once we can move this bit to the field objects */
00501   inline bool isReadSet(uint32_t index) const
00502   {
00503     return read_set->test(index);
00504   }
00505 
00506   inline void setReadSet(uint32_t index)
00507   {
00508     read_set->set(index);
00509   }
00510 
00511   inline void setReadSet()
00512   {
00513     read_set->set();
00514   }
00515 
00516   inline void clearReadSet(uint32_t index)
00517   {
00518     read_set->reset(index);
00519   }
00520 
00521   inline void clearReadSet()
00522   {
00523     read_set->reset();
00524   }
00525 
00526   inline bool isWriteSet(uint32_t index)
00527   {
00528     return write_set->test(index);
00529   }
00530 
00531   inline void setWriteSet(uint32_t index)
00532   {
00533     write_set->set(index);
00534   }
00535 
00536   inline void setWriteSet()
00537   {
00538     write_set->set();
00539   }
00540 
00541   inline void clearWriteSet(uint32_t index)
00542   {
00543     write_set->reset(index);
00544   }
00545 
00546   inline void clearWriteSet()
00547   {
00548     write_set->reset();
00549   }
00550 
00551   /* Is table open or should be treated as such by name-locking? */
00552   inline bool is_name_opened()
00553   {
00554     return db_stat || open_placeholder;
00555   }
00556 
00557   /*
00558     Is this instance of the table should be reopen or represents a name-lock?
00559   */
00560   bool needs_reopen_or_name_lock() const;
00561 
00569   void setup_table_map(TableList *table_list, uint32_t tablenr);
00570   inline void mark_as_null_row()
00571   {
00572     null_row= 1;
00573     status|= STATUS_NULL_ROW;
00574     memset(null_flags, 255, getShare()->null_bytes);
00575   }
00576 
00577   void free_io_cache();
00578   void filesort_free_buffers(bool full= false);
00579   void intern_close_table();
00580 
00581   void print_error(int error, myf errflag) const;
00582 
00587   uint32_t get_dup_key(int error) const
00588   {
00589     cursor->errkey  = (uint32_t) -1;
00590     if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
00591         error == HA_ERR_FOUND_DUPP_UNIQUE ||
00592         error == HA_ERR_DROP_INDEX_FK)
00593       cursor->info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
00594 
00595     return(cursor->errkey);
00596   }
00597 
00598   /*
00599     This is a short term fix. Long term we will used the TableIdentifier to do the actual comparison.
00600   */
00601   bool operator<(const Table &right) const
00602   {
00603     return getShare()->getCacheKey() < right.getShare()->getCacheKey();
00604   }
00605 
00606   static bool compare(const Table *a, const Table *b)
00607   {
00608     return *a < *b;
00609   }
00610 
00611   friend std::ostream& operator<<(std::ostream& output, const Table &table)
00612   {
00613     if (table.getShare())
00614     {
00615       output << "Table:(";
00616       output << table.getShare()->getSchemaName();
00617       output << ", ";
00618       output <<  table.getShare()->getTableName();
00619       output << ", ";
00620       output <<  table.getShare()->getTableTypeAsString();
00621       output << ")";
00622     }
00623     else
00624     {
00625       output << "Table:(has no share)";
00626     }
00627 
00628     return output;  // for multiple << operators.
00629   }
00630 
00631 public:
00632   virtual bool isPlaceHolder(void) const
00633   {
00634     return false;
00635   }
00636 };
00637 
00645 class ForeignKeyInfo
00646 {
00647 public:
00661     ForeignKeyInfo(LEX_STRING *in_foreign_id,
00662                    LEX_STRING *in_referenced_db,
00663                    LEX_STRING *in_referenced_table,
00664                    LEX_STRING *in_update_method,
00665                    LEX_STRING *in_delete_method,
00666                    LEX_STRING *in_referenced_key_name,
00667                    List<LEX_STRING> in_foreign_fields,
00668                    List<LEX_STRING> in_referenced_fields)
00669     :
00670       foreign_id(in_foreign_id),
00671       referenced_db(in_referenced_db),
00672       referenced_table(in_referenced_table),
00673       update_method(in_update_method),
00674       delete_method(in_delete_method),
00675       referenced_key_name(in_referenced_key_name),
00676       foreign_fields(in_foreign_fields),
00677       referenced_fields(in_referenced_fields)
00678     {}
00679 
00684     ForeignKeyInfo()
00685     : foreign_id(NULL), referenced_db(NULL), referenced_table(NULL),
00686       update_method(NULL), delete_method(NULL), referenced_key_name(NULL)
00687     {}
00688 
00695     const LEX_STRING *getForeignId() const
00696     {
00697         return foreign_id;
00698     }
00699 
00706     const LEX_STRING *getReferencedDb() const
00707     {
00708         return referenced_db;
00709     }
00710 
00717     const LEX_STRING *getReferencedTable() const
00718     {
00719         return referenced_table;
00720     }
00721 
00728     const LEX_STRING *getUpdateMethod() const
00729     {
00730         return update_method;
00731     }
00732 
00739     const LEX_STRING *getDeleteMethod() const
00740     {
00741         return delete_method;
00742     }
00743 
00750     const LEX_STRING *getReferencedKeyName() const
00751     {
00752         return referenced_key_name;
00753     }
00754 
00761     const List<LEX_STRING> &getForeignFields() const
00762     {
00763         return foreign_fields;
00764     }
00765 
00772     const List<LEX_STRING> &getReferencedFields() const
00773     {
00774         return referenced_fields;
00775     }
00776 private:
00780     LEX_STRING *foreign_id;
00784     LEX_STRING *referenced_db;
00788     LEX_STRING *referenced_table;
00792     LEX_STRING *update_method;
00796     LEX_STRING *delete_method;
00800     LEX_STRING *referenced_key_name;
00804     List<LEX_STRING> foreign_fields;
00808     List<LEX_STRING> referenced_fields;
00809 };
00810 
00811 class TableList;
00812 
00813 #define JOIN_TYPE_LEFT  1
00814 #define JOIN_TYPE_RIGHT 2
00815 
00816 struct st_lex;
00817 class select_union;
00818 class Tmp_Table_Param;
00819 
00820 void free_blobs(Table *table);
00821 int set_zone(int nr,int min_zone,int max_zone);
00822 uint32_t convert_period_to_month(uint32_t period);
00823 uint32_t convert_month_to_period(uint32_t month);
00824 
00825 int test_if_number(char *str,int *res,bool allow_wildcards);
00826 void change_byte(unsigned char *,uint,char,char);
00827 
00828 namespace optimizer { class SqlSelect; }
00829 
00830 void change_double_for_sort(double nr,unsigned char *to);
00831 int get_quick_record(optimizer::SqlSelect *select);
00832 
00833 void find_date(char *pos,uint32_t *vek,uint32_t flag);
00834 TYPELIB *convert_strings_to_array_type(char * *typelibs, char * *end);
00835 TYPELIB *typelib(memory::Root *mem_root, List<String> &strings);
00836 ulong get_form_pos(int file, unsigned char *head, TYPELIB *save_names);
00837 void append_unescaped(String *res, const char *pos, uint32_t length);
00838 
00839 DRIZZLED_API int rename_file_ext(const char * from,const char * to,const char * ext);
00840 bool check_column_name(const char *name);
00841 bool check_table_name(const char *name, uint32_t length);
00842 
00843 } /* namespace drizzled */
00844 
00845 #include <drizzled/table/singular.h>
00846 #include <drizzled/table/concurrent.h>
00847