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 #pragma once
00022 
00023 #include <string>
00024 #include <boost/dynamic_bitset.hpp>
00025 
00026 #include <drizzled/order.h>
00027 #include <drizzled/filesort_info.h>
00028 #include <drizzled/natural_join_column.h>
00029 #include <drizzled/field_iterator.h>
00030 #include <drizzled/cursor.h>
00031 #include <drizzled/lex_string.h>
00032 #include <drizzled/table/instance.h>
00033 #include <drizzled/atomics.h>
00034 
00035 #include <drizzled/visibility.h>
00036 
00037 namespace drizzled {
00038 
00043 class DRIZZLED_API Table 
00044 {
00045   Field **field; 
00047 public:
00048   Field **getFields() const
00049   {
00050     return field;
00051   }
00052 
00053   Field *getField(uint32_t arg) const
00054   {
00055     return field[arg];
00056   }
00057 
00058   void setFields(Field **arg)
00059   {
00060     field= arg;
00061   }
00062 
00063   void setFieldAt(Field *arg, uint32_t arg_pos)
00064   {
00065     field[arg_pos]= arg;
00066   }
00067 
00068   Cursor *cursor; 
00070 private:
00071   Table *next;
00072 
00073 public:
00074   Table *getNext() const
00075   {
00076     return next;
00077   }
00078 
00079   Table **getNextPtr()
00080   {
00081     return &next;
00082   }
00083 
00084   void setNext(Table *arg)
00085   {
00086     next= arg;
00087   }
00088 
00089   void unlink()
00090   {
00091     getNext()->setPrev(getPrev());    /* remove from used chain */
00092     getPrev()->setNext(getNext());
00093   }
00094 
00095 private:
00096   Table *prev;
00097 public:
00098   Table *getPrev() const
00099   {
00100     return prev;
00101   }
00102 
00103   Table **getPrevPtr()
00104   {
00105     return &prev;
00106   }
00107 
00108   void setPrev(Table *arg)
00109   {
00110     prev= arg;
00111   }
00112 
00113   boost::dynamic_bitset<> *read_set; /* Active column sets */
00114   boost::dynamic_bitset<> *write_set; /* Active column sets */
00115 
00116   uint32_t tablenr;
00117   uint32_t db_stat; 
00119   boost::dynamic_bitset<> def_read_set; 
00120   boost::dynamic_bitset<> def_write_set; 
00121   boost::dynamic_bitset<> tmp_set; /* Not sure about this... */
00122 
00123   Session *in_use; 
00124   Session *getSession()
00125   {
00126     return in_use;
00127   }
00128 
00129   unsigned char *getInsertRecord() const
00130   {
00131     return record[0];
00132   }
00133 
00134   unsigned char *getUpdateRecord()
00135   {
00136     return record[1];
00137   }
00138 
00139   unsigned char *record[2]; 
00140   std::vector<unsigned char> insert_values; /* used by INSERT ... UPDATE */
00141   KeyInfo  *key_info; 
00142   Field *next_number_field; 
00143   Field *found_next_number_field; 
00144   field::Epoch *timestamp_field; 
00146   TableList *pos_in_table_list; /* Element referring to this table */
00147   Order *group;
00148   
00149   const char *getAlias() const
00150   {
00151     return _alias.c_str();
00152   }
00153 
00154   void clearAlias()
00155   {
00156     _alias.clear();
00157   }
00158 
00159   void setAlias(const char *arg)
00160   {
00161     _alias= arg;
00162   }
00163 
00164 private:
00165   std::string _alias; 
00166 public:
00167 
00168   unsigned char *null_flags;
00169 
00170   uint32_t lock_position; 
00171   uint32_t lock_data_start; 
00172   uint32_t lock_count; 
00173   uint32_t used_fields;
00174   uint32_t status; /* What's in getInsertRecord() */
00175   /* number of select if it is derived table */
00176   uint32_t derived_select_number;
00177   int current_lock; 
00178   bool copy_blobs; 
00180   /*
00181     0 or JOIN_TYPE_{LEFT|RIGHT}. Currently this is only compared to 0.
00182     If maybe_null !=0, this table is inner w.r.t. some outer join operation,
00183     and null_row may be true.
00184   */
00185   bool maybe_null;
00186 
00187   /*
00188     If true, the current table row is considered to have all columns set to
00189     NULL, including columns declared as "not null" (see maybe_null).
00190   */
00191   bool null_row;
00192 
00193   bool force_index;
00194   bool distinct;
00195   bool const_table;
00196   bool no_rows;
00197   bool key_read;
00198   bool no_keyread;
00199   /*
00200     Placeholder for an open table which prevents other connections
00201     from taking name-locks on this table. Typically used with
00202     TableShare::version member to take an exclusive name-lock on
00203     this table name -- a name lock that not only prevents other
00204     threads from opening the table, but also blocks other name
00205     locks. This is achieved by:
00206     - setting open_placeholder to 1 - this will block other name
00207       locks, as wait_for_locked_table_name will be forced to wait,
00208       see table_is_used for details.
00209     - setting version to 0 - this will force other threads to close
00210       the instance of this table and wait (this is the same approach
00211       as used for usual name locks).
00212     An exclusively name-locked table currently can have no Cursor
00213     object associated with it (db_stat is always 0), but please do
00214     not rely on that.
00215   */
00216   bool open_placeholder;
00217   bool locked_by_name;
00218   bool no_cache;
00219   /*
00220     To indicate that a non-null value of the auto_increment field
00221     was provided by the user or retrieved from the current record.
00222     Used only in the MODE_NO_AUTO_VALUE_ON_ZERO mode.
00223   */
00224   bool auto_increment_field_not_null;
00225   bool alias_name_used; /* true if table_name is alias */
00226 
00227   /*
00228    The ID of the query that opened and is using this table. Has different
00229    meanings depending on the table type.
00230 
00231    Temporary tables:
00232 
00233    table->query_id is set to session->query_id for the duration of a statement
00234    and is reset to 0 once it is closed by the same statement. A non-zero
00235    table->query_id means that a statement is using the table even if it's
00236    not the current statement (table is in use by some outer statement).
00237 
00238    Non-temporary tables:
00239 
00240    Under pre-locked or LOCK TABLES mode: query_id is set to session->query_id
00241    for the duration of a statement and is reset to 0 once it is closed by
00242    the same statement. A non-zero query_id is used to control which tables
00243    in the list of pre-opened and locked tables are actually being used.
00244   */
00245   query_id_t query_id;
00246 
00255   ha_rows quick_condition_rows;
00256 
00257   /*
00258     If this table has TIMESTAMP field with auto-set property (pointed by
00259     timestamp_field member) then this variable indicates during which
00260     operations (insert only/on update/in both cases) we should set this
00261     field to current timestamp. If there are no such field in this table
00262     or we should not automatically set its value during execution of current
00263     statement then the variable contains TIMESTAMP_NO_AUTO_SET (i.e. 0).
00264 
00265     Value of this variable is set for each statement in open_table() and
00266     if needed cleared later in statement processing code (see update_query()
00267     as example).
00268   */
00269   timestamp_auto_set_type timestamp_field_type;
00270   table_map map; 
00271 
00272   RegInfo reginfo; /* field connections */
00273 
00274   /*
00275     Map of keys that can be used to retrieve all data from this table
00276     needed by the query without reading the row.
00277   */
00278   key_map covering_keys;
00279   key_map quick_keys;
00280   key_map merge_keys;
00281 
00282   /*
00283     A set of keys that can be used in the query that references this
00284     table.
00285 
00286     All indexes disabled on the table's TableShare (see Table::s) will be
00287     subtracted from this set upon instantiation. Thus for any Table t it holds
00288     that t.keys_in_use_for_query is a subset of t.s.keys_in_use. Generally we
00289     must not introduce any new keys here (see setup_tables).
00290 
00291     The set is implemented as a bitmap.
00292   */
00293   key_map keys_in_use_for_query;
00294 
00295   /* Map of keys that can be used to calculate GROUP BY without sorting */
00296   key_map keys_in_use_for_group_by;
00297 
00298   /* Map of keys that can be used to calculate ORDER BY without sorting */
00299   key_map keys_in_use_for_order_by;
00300 
00301   /*
00302     For each key that has quick_keys.test(key) == true: estimate of #records
00303     and max #key parts that range access would use.
00304   */
00305   ha_rows quick_rows[MAX_KEY];
00306 
00307   /* Bitmaps of key parts that =const for the entire join. */
00308   key_part_map  const_key_parts[MAX_KEY];
00309 
00310   uint32_t quick_key_parts[MAX_KEY];
00311   uint32_t quick_n_ranges[MAX_KEY];
00312 
00313 private:
00314   memory::Root mem_root;
00315 
00316   void init_mem_root()
00317   {
00318     if (not mem_root.alloc_root_inited())
00319       mem_root.init(TABLE_ALLOC_BLOCK_SIZE);
00320   }
00321 public:
00322   memory::Root& mem()
00323   {
00324     init_mem_root();
00325     return mem_root;
00326   }
00327 
00328   unsigned char* alloc(size_t arg)
00329   {
00330     init_mem_root();
00331     return mem_root.alloc(arg);
00332   }
00333 
00334   char* strdup(const char* str_arg, size_t len_arg)
00335   {
00336     init_mem_root();
00337     return mem_root.strdup(str_arg, len_arg);
00338   }
00339 
00340   filesort_info sort;
00341 
00342   Table();
00343   virtual ~Table();
00344 
00345   int report_error(int error);
00352   int delete_table(bool free_share= false);
00353 
00354   void resetTable(Session *session, TableShare *share, uint32_t db_stat_arg);
00355 
00356   /* SHARE methods */
00357   virtual const TableShare *getShare() const= 0; /* Get rid of this long term */
00358   virtual TableShare *getMutableShare()= 0; /* Get rid of this long term */
00359   virtual bool hasShare() const= 0; /* Get rid of this long term */
00360   virtual void setShare(TableShare *new_share)= 0; /* Get rid of this long term */
00361 
00362   virtual void release(void)= 0;
00363 
00364   uint32_t sizeKeys() { return getMutableShare()->sizeKeys(); }
00365   uint32_t sizeFields() { return getMutableShare()->sizeFields(); }
00366   uint32_t getRecordLength() const { return getShare()->getRecordLength(); }
00367   uint32_t sizeBlobFields() { return getMutableShare()->blob_fields; }
00368   uint32_t *getBlobField() { return &getMutableShare()->blob_field[0]; }
00369 
00370 public:
00371   virtual bool hasVariableWidth() const
00372   {
00373     return getShare()->hasVariableWidth(); // We should calculate this.
00374   }
00375 
00376   virtual void setVariableWidth(void);
00377 
00378   Field_blob *getBlobFieldAt(uint32_t arg) const
00379   {
00380     if (arg < getShare()->blob_fields)
00381       return (Field_blob*) field[getShare()->blob_field[arg]]; /*NOTE: Using 'Table.field' NOT SharedTable.field. */
00382 
00383     return NULL;
00384   }
00385   inline uint8_t getBlobPtrSize() const { return getShare()->sizeBlobPtr(); }
00386   inline uint32_t getNullBytes() const { return getShare()->null_bytes; }
00387   inline uint32_t getNullFields() const { return getShare()->null_fields; }
00388   inline unsigned char *getDefaultValues() { return  getMutableShare()->getDefaultValues(); }
00389   inline const char *getSchemaName()  const { return getShare()->getSchemaName(); }
00390   inline const char *getTableName()  const { return getShare()->getTableName(); }
00391 
00392   inline bool isDatabaseLowByteFirst() const { return getShare()->db_low_byte_first; } /* Portable row format */
00393   inline bool isNameLock() const { return open_placeholder; }
00394 
00395   uint32_t index_flags(uint32_t idx) const;
00396 
00397   inline plugin::StorageEngine *getEngine() const   /* table_type for handler */
00398   {
00399     return getShare()->getEngine();
00400   }
00401 
00402   Cursor &getCursor() const /* table_type for handler */
00403   {
00404     assert(cursor);
00405     return *cursor;
00406   }
00407 
00408   size_t max_row_length(const unsigned char *data);
00409   uint32_t find_shortest_key(const key_map *usable_keys);
00410   bool compare_record(Field **ptr);
00411   bool records_are_comparable();
00412   bool compare_records();
00413   /* TODO: the (re)storeRecord's may be able to be further condensed */
00414   void storeRecord();
00415   void storeRecordAsInsert();
00416   void storeRecordAsDefault();
00417   void restoreRecord();
00418   void restoreRecordAsDefault();
00419   void emptyRecord();
00420 
00421 
00422   /* See if this can be blown away */
00423   inline uint32_t getDBStat () const { return db_stat; }
00424 
00441   void fill_item_list(List<Item>&) const;
00442   void clear_column_bitmaps(void);
00443   void prepare_for_position(void);
00444   void mark_columns_used_by_index_no_reset(uint32_t index, boost::dynamic_bitset<>& bitmap);
00445   void mark_columns_used_by_index_no_reset(uint32_t index);
00446   void mark_columns_used_by_index(uint32_t index);
00447   void restore_column_maps_after_mark_index();
00448   void mark_auto_increment_column(void);
00449   void mark_columns_needed_for_update(void);
00450   void mark_columns_needed_for_delete(void);
00451   void mark_columns_needed_for_insert(void);
00452   void column_bitmaps_set(boost::dynamic_bitset<>& read_set_arg,
00453                           boost::dynamic_bitset<>& write_set_arg);
00454 
00455   void restore_column_map(const boost::dynamic_bitset<>& old);
00456 
00457   const boost::dynamic_bitset<> use_all_columns(boost::dynamic_bitset<>& map);
00458   inline void use_all_columns()
00459   {
00460     column_bitmaps_set(getMutableShare()->all_set, getMutableShare()->all_set);
00461   }
00462 
00463   inline void default_column_bitmaps()
00464   {
00465     read_set= &def_read_set;
00466     write_set= &def_write_set;
00467   }
00468 
00469   /* Both of the below should go away once we can move this bit to the field objects */
00470   inline bool isReadSet(uint32_t index) const
00471   {
00472     return read_set->test(index);
00473   }
00474 
00475   inline void setReadSet(uint32_t index)
00476   {
00477     read_set->set(index);
00478   }
00479 
00480   inline void setReadSet()
00481   {
00482     read_set->set();
00483   }
00484 
00485   inline void clearReadSet(uint32_t index)
00486   {
00487     read_set->reset(index);
00488   }
00489 
00490   inline void clearReadSet()
00491   {
00492     read_set->reset();
00493   }
00494 
00495   inline bool isWriteSet(uint32_t index)
00496   {
00497     return write_set->test(index);
00498   }
00499 
00500   inline void setWriteSet(uint32_t index)
00501   {
00502     write_set->set(index);
00503   }
00504 
00505   inline void setWriteSet()
00506   {
00507     write_set->set();
00508   }
00509 
00510   inline void clearWriteSet(uint32_t index)
00511   {
00512     write_set->reset(index);
00513   }
00514 
00515   inline void clearWriteSet()
00516   {
00517     write_set->reset();
00518   }
00519 
00520   /* Is table open or should be treated as such by name-locking? */
00521   bool is_name_opened() const
00522   {
00523     return db_stat || open_placeholder;
00524   }
00525 
00526   /*
00527     Is this instance of the table should be reopen or represents a name-lock?
00528   */
00529   bool needs_reopen_or_name_lock() const;
00530 
00538   void setup_table_map(TableList *table_list, uint32_t tablenr);
00539   inline void mark_as_null_row()
00540   {
00541     null_row= 1;
00542     status|= STATUS_NULL_ROW;
00543     memset(null_flags, 255, getShare()->null_bytes);
00544   }
00545 
00546   void free_io_cache();
00547   void filesort_free_buffers(bool full= false);
00548   void intern_close_table();
00549 
00550   void print_error(int error, myf errflag) const;
00551 
00556   uint32_t get_dup_key(int error) const
00557   {
00558     cursor->errkey  = (uint32_t) -1;
00559     if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
00560         error == HA_ERR_FOUND_DUPP_UNIQUE ||
00561         error == HA_ERR_DROP_INDEX_FK)
00562       cursor->info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
00563 
00564     return(cursor->errkey);
00565   }
00566 
00567   /*
00568     This is a short term fix. Long term we will used the TableIdentifier to do the actual comparison.
00569   */
00570   bool operator<(const Table &right) const
00571   {
00572     return getShare()->getCacheKey() < right.getShare()->getCacheKey();
00573   }
00574 
00575   static bool compare(const Table *a, const Table *b)
00576   {
00577     return *a < *b;
00578   }
00579 
00580   friend std::ostream& operator<<(std::ostream& output, const Table &table)
00581   {
00582     if (table.getShare())
00583     {
00584       output << "Table:(";
00585       output << table.getShare()->getSchemaName();
00586       output << ", ";
00587       output <<  table.getShare()->getTableName();
00588       output << ", ";
00589       output <<  table.getShare()->getTableTypeAsString();
00590       output << ")";
00591     }
00592     else
00593     {
00594       output << "Table:(has no share)";
00595     }
00596 
00597     return output;  // for multiple << operators.
00598   }
00599 
00600 public:
00601   virtual bool isPlaceHolder(void) const
00602   {
00603     return false;
00604   }
00605 };
00606 
00614 class ForeignKeyInfo
00615 {
00616 public:
00630     ForeignKeyInfo(lex_string_t *in_foreign_id,
00631                    lex_string_t *in_referenced_db,
00632                    lex_string_t *in_referenced_table,
00633                    lex_string_t *in_update_method,
00634                    lex_string_t *in_delete_method,
00635                    lex_string_t *in_referenced_key_name,
00636                    List<lex_string_t> in_foreign_fields,
00637                    List<lex_string_t> in_referenced_fields)
00638     :
00639       foreign_id(in_foreign_id),
00640       referenced_db(in_referenced_db),
00641       referenced_table(in_referenced_table),
00642       update_method(in_update_method),
00643       delete_method(in_delete_method),
00644       referenced_key_name(in_referenced_key_name),
00645       foreign_fields(in_foreign_fields),
00646       referenced_fields(in_referenced_fields)
00647     {}
00648 
00653     ForeignKeyInfo()
00654     : foreign_id(NULL), referenced_db(NULL), referenced_table(NULL),
00655       update_method(NULL), delete_method(NULL), referenced_key_name(NULL)
00656     {}
00657 
00664     const lex_string_t *getForeignId() const
00665     {
00666         return foreign_id;
00667     }
00668 
00675     const lex_string_t *getReferencedDb() const
00676     {
00677         return referenced_db;
00678     }
00679 
00686     const lex_string_t *getReferencedTable() const
00687     {
00688         return referenced_table;
00689     }
00690 
00697     const lex_string_t *getUpdateMethod() const
00698     {
00699         return update_method;
00700     }
00701 
00708     const lex_string_t *getDeleteMethod() const
00709     {
00710         return delete_method;
00711     }
00712 
00719     const lex_string_t *getReferencedKeyName() const
00720     {
00721         return referenced_key_name;
00722     }
00723 
00730     const List<lex_string_t> &getForeignFields() const
00731     {
00732         return foreign_fields;
00733     }
00734 
00741     const List<lex_string_t> &getReferencedFields() const
00742     {
00743         return referenced_fields;
00744     }
00745 private:
00749     lex_string_t *foreign_id;
00753     lex_string_t *referenced_db;
00757     lex_string_t *referenced_table;
00761     lex_string_t *update_method;
00765     lex_string_t *delete_method;
00769     lex_string_t *referenced_key_name;
00773     List<lex_string_t> foreign_fields;
00777     List<lex_string_t> referenced_fields;
00778 };
00779 
00780 #define JOIN_TYPE_LEFT  1
00781 #define JOIN_TYPE_RIGHT 2
00782 
00783 void free_blobs(Table *table);
00784 int set_zone(int nr,int min_zone,int max_zone);
00785 uint32_t convert_period_to_month(uint32_t period);
00786 uint32_t convert_month_to_period(uint32_t month);
00787 
00788 int test_if_number(char *str,int *res,bool allow_wildcards);
00789 void change_byte(unsigned char *,uint,char,char);
00790 void change_double_for_sort(double nr,unsigned char *to);
00791 int get_quick_record(optimizer::SqlSelect *select);
00792 
00793 void find_date(char *pos,uint32_t *vek,uint32_t flag);
00794 TYPELIB* convert_strings_to_array_type(char** typelibs, char** end);
00795 TYPELIB* typelib(memory::Root&, List<String>&);
00796 ulong get_form_pos(int file, unsigned char *head, TYPELIB *save_names);
00797 void append_unescaped(String *res, const char *pos, uint32_t length);
00798 
00799 bool check_column_name(const char*);
00800 bool check_table_name(str_ref);
00801 
00802 } /* namespace drizzled */
00803 
00804 #include <drizzled/table/singular.h>
00805 #include <drizzled/table/concurrent.h>
00806