Drizzled Public API Documentation

field.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 /*
00021   Because of the function new_field() all field classes that have static
00022   variables must declare the size_of() member function.
00023 */
00024 
00025 
00026 
00027 #pragma once
00028 
00029 #include <drizzled/common_fwd.h>
00030 #include <drizzled/sql_error.h>
00031 #include <drizzled/type/decimal.h>
00032 #include <drizzled/key_map.h>
00033 #include <drizzled/sql_list.h>
00034 #include <drizzled/structs.h>
00035 #include <drizzled/charset.h>
00036 #include <drizzled/item_result.h>
00037 
00038 #include <string>
00039 #include <vector>
00040 
00041 #include <drizzled/visibility.h>
00042 
00043 namespace drizzled {
00044 
00045 #define DATETIME_DEC                     6
00046 #define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE FLOATING_POINT_BUFFER
00047 
00048 #define ASSERT_COLUMN_MARKED_FOR_READ assert(getTable() && (not getTable()->read_set || isReadSet()))
00049 #define ASSERT_COLUMN_MARKED_FOR_WRITE assert(getTable() && (not getTable()->write_set || isWriteSet()))
00050 
00051 const uint32_t max_field_size= (uint32_t) 4294967295U;
00052 
00053 int field_conv(Field *to,Field *from);
00054 
00068 class DRIZZLED_API Field : boost::noncopyable
00069 {
00070 public:
00071   unsigned char *ptr; 
00072   unsigned char *null_ptr; 
00080 private:
00081   Table *table;
00082 
00083 public:
00084   Table *getTable()
00085   {
00086     assert(table);
00087     return table;
00088   }
00089 
00090   Table *getTable() const
00091   {
00092     assert(table);
00093     return table;
00094   }
00095 
00096   void setTable(Table *table_arg)
00097   {
00098     table= table_arg;
00099   }
00100 
00101   Table *orig_table; 
00102   const char *field_name; 
00103   str_ref comment; 
00106   key_map key_start;
00107   key_map part_of_key;
00108   key_map part_of_key_not_clustered;
00109   key_map part_of_sortkey;
00110 
00111   /*
00112     We use three additional unireg types for TIMESTAMP for hysterical
00113     raisins and limitations in the MySQL FRM file format.
00114 
00115     A good TODO is to clean this up as we can support just about
00116     anything in the table proto message now.
00117   */
00118   enum utype
00119   {
00120     NONE,
00121     NEXT_NUMBER,
00122     TIMESTAMP_OLD_FIELD,
00123     TIMESTAMP_DN_FIELD,
00124     TIMESTAMP_UN_FIELD,
00125     TIMESTAMP_DNUN_FIELD
00126   };
00127 
00128   utype unireg_check;
00129   uint32_t field_length; 
00130   uint32_t flags;
00131 
00132   bool isUnsigned() const
00133   {
00134     return flags & UNSIGNED_FLAG;
00135   }
00136 
00137 private:
00138   uint16_t field_index; 
00140 public:
00141 
00142   uint16_t position() const
00143   {
00144     return field_index;
00145   }
00146 
00147   void setPosition(uint32_t arg)
00148   {
00149     field_index= arg;
00150   }
00151 
00152   unsigned char null_bit; 
00161   bool is_created_from_null_item;
00162 
00163   static void *operator new(size_t size);
00164   static void *operator new(size_t size, memory::Root *mem_root);
00165   static void operator delete(void *, size_t)
00166   { }
00167   static void operator delete(void *, memory::Root *)
00168   { }
00169 
00170   Field(unsigned char *ptr_arg,
00171         uint32_t length_arg,
00172         unsigned char *null_ptr_arg,
00173         unsigned char null_bit_arg,
00174         utype unireg_check_arg,
00175         const char *field_name_arg);
00176   virtual ~Field() {}
00177 
00178   bool hasDefault() const
00179   {
00180     return not (flags & NO_DEFAULT_VALUE_FLAG);
00181   }
00182 
00183   /* Store functions returns 1 on overflow and -1 on fatal error */
00184   virtual int store(const char *to,
00185                     uint32_t length,
00186                     const charset_info_st * const cs)=0;
00187   virtual int store(double nr)=0;
00188   virtual int store(int64_t nr, bool unsigned_val)=0;
00189   virtual int store_decimal(const type::Decimal *d)=0;
00190   int store_and_check(enum_check_fields check_level,
00191                       const char *to,
00192                       uint32_t length,
00193                       const charset_info_st * const cs);
00200   virtual int store_time(type::Time &ltime, type::timestamp_t t_type);
00201   virtual double val_real() const=0;
00202   virtual int64_t val_int() const =0;
00203   virtual type::Decimal *val_decimal(type::Decimal *) const;
00204   String *val_str_internal(String *str) const
00205   {
00206     return val_str(str, str);
00207   }
00208 
00209   /*
00210      val_str(buf1, buf2) gets two buffers and should use them as follows:
00211      if it needs a temp buffer to convert result to string - use buf1
00212        example Field_tiny::val_str()
00213      if the value exists as a string already - use buf2
00214        example Field_varstring::val_str() (???)
00215      consequently, buf2 may be created as 'String buf;' - no memory
00216      will be allocated for it. buf1 will be allocated to hold a
00217      value if it's too small. Using allocated buffer for buf2 may result in
00218      an unnecessary free (and later, may be an alloc).
00219      This trickery is used to decrease a number of malloc calls.
00220   */
00221   virtual String *val_str(String*, String *) const =0;
00222 
00223   /*
00224    str_needs_quotes() returns true if the value returned by val_str() needs
00225    to be quoted when used in constructing an SQL query.
00226   */
00227   virtual bool str_needs_quotes() { return false; }
00228   virtual Item_result result_type () const=0;
00229   virtual Item_result cmp_type () const { return result_type(); }
00230   virtual Item_result cast_to_int_type () const { return result_type(); }
00231 
00245   static bool type_can_have_key_part(enum_field_types);
00255   static enum_field_types field_type_merge(enum_field_types, enum_field_types);
00256 
00265   static Item_result result_merge_type(enum_field_types);
00266 
00267   virtual bool eq(Field *field);
00276   virtual bool eq_def(Field *field);
00277 
00278   virtual bool is_timestamp() const
00279   {
00280     return false;
00281   }
00282 
00288   virtual uint32_t pack_length() const;
00289 
00295   virtual uint32_t pack_length_in_rec() const;
00296 
00301   virtual uint32_t data_length();
00307   virtual uint32_t used_length();
00308   virtual uint32_t sort_length() const;
00309 
00316   virtual uint32_t max_data_length() const;
00317   virtual int reset(void);
00318   virtual void reset_fields();
00319   virtual void set_default();
00320   virtual bool binary() const;
00321   virtual bool zero_pack() const;
00322   virtual enum ha_base_keytype key_type() const;
00323   virtual uint32_t key_length() const;
00324   virtual enum_field_types type() const =0;
00325   virtual enum_field_types real_type() const;
00326   virtual int cmp_max(const unsigned char *a, const unsigned char *b, uint32_t max_len);
00327   virtual int cmp(const unsigned char *,const unsigned char *)=0;
00328   int cmp_internal(const unsigned char *str) { return cmp(ptr,str); }
00329   virtual int cmp_binary(const unsigned char *a,const unsigned char *b,
00330                          uint32_t max_length=UINT32_MAX);
00331   virtual int cmp_offset(uint32_t row_offset);
00332   virtual int cmp_binary_offset(uint32_t row_offset);
00333   virtual int key_cmp(const unsigned char *a,const unsigned char *b);
00334   virtual int key_cmp(const unsigned char *str, uint32_t length);
00335   virtual uint32_t decimals() const;
00336 
00337   // For new field
00338   virtual uint32_t size_of() const =0;
00339 
00340   bool is_null(ptrdiff_t row_offset= 0) const;
00341   bool is_real_null(ptrdiff_t row_offset= 0) const;
00342   bool is_null_in_record(const unsigned char *record) const;
00343   bool is_null_in_record_with_offset(ptrdiff_t offset) const;
00344   void set_null(ptrdiff_t row_offset= 0);
00345   void set_notnull(ptrdiff_t row_offset= 0);
00346   bool maybe_null(void) const;
00347   bool real_maybe_null(void) const;
00348 
00349   virtual void make_field(SendField *);
00350   virtual void sort_string(unsigned char *buff,uint32_t length)=0;
00351   virtual bool optimize_range(uint32_t idx, uint32_t part);
00359   virtual bool can_be_compared_as_int64_t() const
00360   {
00361     return false;
00362   }
00363   virtual void free() {}
00364   virtual Field *new_field(memory::Root*, Table*, bool keep_type);
00365   virtual Field *new_key_field(memory::Root *root, Table *new_table,
00366                                unsigned char *new_ptr,
00367                                unsigned char *new_null_ptr,
00368                                uint32_t new_null_bit);
00370   Field* clone(memory::Root*, Table*);
00371   void move_field(unsigned char *ptr_arg,unsigned char *null_ptr_arg,unsigned char null_bit_arg)
00372   {
00373     ptr= ptr_arg;
00374     null_ptr= null_ptr_arg;
00375     null_bit= null_bit_arg;
00376   }
00377   void move_field(unsigned char *ptr_arg) { ptr=ptr_arg; }
00378   virtual void move_field_offset(ptrdiff_t ptr_diff)
00379   {
00380     ptr= ADD_TO_PTR(ptr,ptr_diff, unsigned char*);
00381     if (null_ptr)
00382       null_ptr= ADD_TO_PTR(null_ptr,ptr_diff,unsigned char*);
00383   }
00384   virtual void get_image(unsigned char *buff, uint32_t length, const charset_info_st * const)
00385   {
00386     memcpy(buff,ptr,length);
00387   }
00388   virtual void get_image(std::basic_string<unsigned char> &buff, uint32_t length, const charset_info_st * const)
00389   {
00390     buff.append(ptr,length);
00391   }
00392   virtual void set_image(const unsigned char *buff,uint32_t length, const charset_info_st * const)
00393   {
00394     memcpy(ptr,buff,length);
00395   }
00396 
00421   virtual uint32_t get_key_image(unsigned char *buff, uint32_t length)
00422   {
00423     get_image(buff, length, &my_charset_bin);
00424     return length;
00425   }
00426   virtual uint32_t get_key_image(std::basic_string<unsigned char> &buff, uint32_t length)
00427   {
00428     get_image(buff, length, &my_charset_bin);
00429     return length;
00430   }
00431   virtual void set_key_image(const unsigned char *buff,uint32_t length)
00432   {
00433     set_image(buff,length, &my_charset_bin);
00434   }
00435   int64_t val_int_offset(uint32_t row_offset)
00436   {
00437     ptr+=row_offset;
00438     int64_t tmp=val_int();
00439     ptr-=row_offset;
00440     return tmp;
00441   }
00442 
00443   int64_t val_int_internal(const unsigned char *new_ptr)
00444   {
00445     unsigned char *old_ptr= ptr;
00446     ptr= const_cast<unsigned char*>(new_ptr);
00447     int64_t return_value= val_int();
00448     ptr= old_ptr;
00449     return return_value;
00450   }
00451 
00452   String *val_str_internal(String *str, const unsigned char *new_ptr)
00453   {
00454     unsigned char *old_ptr= ptr;
00455     ptr= const_cast<unsigned char*>(new_ptr);
00456     val_str_internal(str);
00457     ptr= old_ptr;
00458     return str;
00459   }
00460 
00498   virtual unsigned char *pack(unsigned char *to,
00499                               const unsigned char *from,
00500                               uint32_t max_length,
00501                               bool low_byte_first);
00502 
00503   unsigned char *pack(unsigned char *to, const unsigned char *from);
00504 
00535   virtual const unsigned char *unpack(unsigned char* to,
00536                                       const unsigned char *from,
00537                                       uint32_t param_data,
00538                                       bool low_byte_first);
00543   const unsigned char *unpack(unsigned char* to,
00544                               const unsigned char *from);
00545 
00546   virtual unsigned char *pack_key(unsigned char* to,
00547                                   const unsigned char *from,
00548                                   uint32_t max_length,
00549                                   bool low_byte_first)
00550   {
00551     return pack(to, from, max_length, low_byte_first);
00552   }
00553   virtual const unsigned char *unpack_key(unsigned char* to,
00554                                           const unsigned char *from,
00555                                           uint32_t max_length,
00556                                           bool low_byte_first)
00557   {
00558     return unpack(to, from, max_length, low_byte_first);
00559   }
00560   virtual uint32_t max_packed_col_length(uint32_t max_length)
00561   {
00562     return max_length;
00563   }
00564 
00565   uint32_t offset(const unsigned char *record)
00566   {
00567     return (uint32_t) (ptr - record);
00568   }
00569   void copy_from_tmp(int offset);
00570   uint32_t fill_cache_field(CacheField *copy);
00571   virtual bool get_date(type::Time &ltime,uint32_t fuzzydate) const;
00572   virtual bool get_time(type::Time &ltime) const;
00573   virtual const charset_info_st *charset(void) const { return &my_charset_bin; }
00574   virtual const charset_info_st *sort_charset(void) const { return charset(); }
00575   virtual bool has_charset(void) const { return false; }
00576   virtual void set_charset(const charset_info_st * const)
00577   {}
00578   virtual enum Derivation derivation(void) const
00579   {
00580     return DERIVATION_IMPLICIT;
00581   }
00582   virtual void set_derivation(enum Derivation)
00583   {}
00603   bool set_warning(DRIZZLE_ERROR::enum_warning_level,
00604                    drizzled::error_t code,
00605                    int cuted_increment);
00621   void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level,
00622                             drizzled::error_t code,
00623                             const char *str,
00624                             uint32_t str_len,
00625                             type::timestamp_t ts_type,
00626                             int cuted_increment);
00641   void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level,
00642                             drizzled::error_t code,
00643                             int64_t nr,
00644                             type::timestamp_t ts_type,
00645                             int cuted_increment);
00659   void set_datetime_warning(DRIZZLE_ERROR::enum_warning_level,
00660                             const drizzled::error_t code,
00661                             double nr,
00662                             type::timestamp_t ts_type);
00663   bool check_overflow(int op_result)
00664   {
00665     return (op_result == E_DEC_OVERFLOW);
00666   }
00679   int warn_if_overflow(int op_result);
00680   void init(Table *table_arg);
00681 
00682   /* maximum possible display length */
00683   virtual uint32_t max_display_length()= 0;
00684 
00685   virtual uint32_t is_equal(CreateField *new_field);
00697   int64_t convert_decimal2int64_t(const type::Decimal *val,
00698                                   bool unsigned_flag,
00699                                   int *err);
00700   /* The max. number of characters */
00701   uint32_t char_length() const
00702   {
00703     return field_length / charset()->mbmaxlen;
00704   }
00705 
00706   enum column_format_type column_format() const
00707   {
00708     return (enum column_format_type)
00709       ((flags >> COLUMN_FORMAT_FLAGS) & COLUMN_FORMAT_MASK);
00710   }
00711 
00712   /* Hash value */
00713   virtual void hash(uint32_t *nr, uint32_t *nr2) const;
00714   friend bool reopen_table(Session *,Table *,bool);
00715 
00716   friend class CopyField;
00717   friend class Item_avg_field;
00718   friend class Item_std_field;
00719   friend class Item_sum_num;
00720   friend class Item_sum_sum;
00721   friend class Item_sum_str;
00722   friend class Item_sum_count;
00723   friend class Item_sum_avg;
00724   friend class Item_sum_std;
00725   friend class Item_sum_min;
00726   friend class Item_sum_max;
00727   friend class Item_func_group_concat;
00728 
00729   bool isReadSet() const;
00730   bool isWriteSet();
00731   void setReadSet(bool arg= true);
00732   void setWriteSet(bool arg= true);
00733 
00734 protected:
00735 
00736   void pack_num(uint64_t arg, unsigned char *destination= NULL);
00737   void pack_num(uint32_t arg, unsigned char *destination= NULL);
00738   uint64_t unpack_num(uint64_t &destination, const unsigned char *arg= NULL) const;
00739   uint32_t unpack_num(uint32_t &destination, const unsigned char *arg= NULL) const;
00740 };
00741 
00742 namespace field {
00743 
00744 inline bool isDateTime(const enum_field_types &arg)
00745 {
00746   switch (arg)
00747   {
00748   case DRIZZLE_TYPE_DATE:
00749   case DRIZZLE_TYPE_DATETIME:
00750   case DRIZZLE_TYPE_MICROTIME:
00751   case DRIZZLE_TYPE_TIME:
00752   case DRIZZLE_TYPE_TIMESTAMP:
00753     return true;
00754 
00755   case DRIZZLE_TYPE_BLOB:
00756   case DRIZZLE_TYPE_BOOLEAN:
00757   case DRIZZLE_TYPE_DECIMAL:
00758   case DRIZZLE_TYPE_DOUBLE:
00759   case DRIZZLE_TYPE_ENUM:
00760   case DRIZZLE_TYPE_LONG:
00761   case DRIZZLE_TYPE_LONGLONG:
00762   case DRIZZLE_TYPE_NULL:
00763   case DRIZZLE_TYPE_UUID:
00764   case DRIZZLE_TYPE_IPV6:
00765   case DRIZZLE_TYPE_VARCHAR:
00766     return false;
00767   }
00768 
00769   assert(0);
00770   abort();
00771 }
00772 
00773 } // namespace field
00774 
00775 std::ostream& operator<<(std::ostream& output, const Field &field);
00776 
00785 class SendField
00786 {
00787 public:
00788   const char *db_name;
00789   const char *table_name;
00790   const char *org_table_name;
00791   const char *col_name;
00792   const char *org_col_name;
00793   uint32_t length;
00794   uint32_t charsetnr;
00795   uint32_t flags;
00796   uint32_t decimals;
00797   enum_field_types type;
00798 };
00799 
00800 uint32_t pack_length_to_packflag(uint32_t type);
00801 uint32_t calc_pack_length(enum_field_types type,uint32_t length);
00802 int set_field_to_null(Field *field);
00803 int set_field_to_null_with_conversions(Field *field, bool no_conversions);
00804 
00818 bool test_if_important_data(const charset_info_st * const cs,
00819                             const char *str,
00820                             const char *strend);
00821 
00822 } /* namespace drizzled */
00823