diff options
Diffstat (limited to 'sql/field.h')
-rw-r--r-- | sql/field.h | 829 |
1 files changed, 494 insertions, 335 deletions
diff --git a/sql/field.h b/sql/field.h index 4fcdb50f8c7..1861a5d6e6f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -28,6 +28,7 @@ class Send_field; class Protocol; +class Create_field; struct st_cache_field; int field_conv(Field *to,Field *from); @@ -47,10 +48,10 @@ class Field Field(const Item &); /* Prevent use of these */ void operator=(Field &); public: - static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } + static void *operator new(size_t size) {return sql_alloc(size); } static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); } - char *ptr; // Position to field in record + uchar *ptr; // Position to field in record uchar *null_ptr; // Byte where null_bit is /* Note that you can use table->in_use as replacement for current_thd member @@ -60,9 +61,9 @@ public: struct st_table *orig_table; // Pointer to original table const char **table_name, *field_name; LEX_STRING comment; - query_id_t query_id; // For quick test of used fields /* Field is part of the following keys */ - key_map key_start,part_of_key,part_of_sortkey; + key_map key_start, part_of_key, part_of_key_not_clustered; + key_map part_of_sortkey; /* We use three additional unireg types for TIMESTAMP to overcome limitation of current binary format of .frm file. We'd like to be able to support @@ -85,20 +86,22 @@ public: utype unireg_check; uint32 field_length; // Length of field - uint field_index; // field number in fields array - uint16 flags; + uint32 flags; + uint16 field_index; // field number in fields array uchar null_bit; // Bit used to test null bit - Field(char *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,uchar null_bit_arg, - utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg); + Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg, + uchar null_bit_arg, utype unireg_check_arg, + const char *field_name_arg); virtual ~Field() {} /* Store functions returns 1 on overflow and -1 on fatal error */ - virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0; + virtual int store(const char *to, uint length,CHARSET_INFO *cs)=0; virtual int store(double nr)=0; virtual int store(longlong nr, bool unsigned_val)=0; virtual int store_decimal(const my_decimal *d)=0; virtual int store_time(MYSQL_TIME *ltime, timestamp_type t_type); + int store(const char *to, uint length, CHARSET_INFO *cs, + enum_check_fields check_level); virtual double val_real(void)=0; virtual longlong val_int(void)=0; virtual my_decimal *val_decimal(my_decimal *); @@ -117,6 +120,11 @@ public: */ virtual String *val_str(String*,String *)=0; String *val_int_as_str(String *val_buffer, my_bool unsigned_flag); + /* + str_needs_quotes() returns TRUE if the value returned by val_str() needs + to be quoted when used in constructing an SQL query. + */ + virtual bool str_needs_quotes() { return FALSE; } virtual Item_result result_type () const=0; virtual Item_result cmp_type () const { return result_type(); } virtual Item_result cast_to_int_type () const { return result_type(); } @@ -147,7 +155,7 @@ public: /* data_length() return the "real size" of the data in memory. */ - virtual uint32 data_length(const char *from) { return pack_length(); } + virtual uint32 data_length() { return pack_length(); } virtual uint32 sort_length() const { return pack_length(); } virtual int reset(void) { bzero(ptr,pack_length()); return 0; } virtual void reset_fields() {} @@ -166,18 +174,20 @@ public: virtual uint32 key_length() const { return pack_length(); } virtual enum_field_types type() const =0; virtual enum_field_types real_type() const { return type(); } - inline int cmp(const char *str) { return cmp(ptr,str); } - virtual int cmp(const char *,const char *)=0; - virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L) + inline int cmp(const uchar *str) { return cmp(ptr,str); } + virtual int cmp_max(const uchar *a, const uchar *b, uint max_len) + { return cmp(a, b); } + virtual int cmp(const uchar *,const uchar *)=0; + virtual int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L) { return memcmp(a,b,pack_length()); } virtual int cmp_offset(uint row_offset) { return cmp(ptr,ptr+row_offset); } virtual int cmp_binary_offset(uint row_offset) { return cmp_binary(ptr, ptr+row_offset); }; - virtual int key_cmp(const byte *a,const byte *b) - { return cmp((char*) a,(char*) b); } - virtual int key_cmp(const byte *str, uint length) - { return cmp(ptr,(char*) str); } + virtual int key_cmp(const uchar *a,const uchar *b) + { return cmp(a, b); } + virtual int key_cmp(const uchar *str, uint length) + { return cmp(ptr,str); } virtual uint decimals() const { return 0; } /* Caller beware: sql_type can change str.Ptr, so check @@ -186,25 +196,58 @@ public: */ virtual void sql_type(String &str) const =0; virtual uint size_of() const =0; // For new field - inline bool is_null(uint row_offset=0) + inline bool is_null(my_ptrdiff_t row_offset= 0) { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; } - inline bool is_real_null(uint row_offset=0) + inline bool is_real_null(my_ptrdiff_t row_offset= 0) { return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : 0; } inline bool is_null_in_record(const uchar *record) { if (!null_ptr) return 0; - return test(record[(uint) (null_ptr - (uchar*) table->record[0])] & + return test(record[(uint) (null_ptr -table->record[0])] & null_bit); } - inline void set_null(int row_offset=0) + inline bool is_null_in_record_with_offset(my_ptrdiff_t offset) + { + if (!null_ptr) + return 0; + return test(null_ptr[offset] & null_bit); + } + inline void set_null(my_ptrdiff_t row_offset= 0) { if (null_ptr) null_ptr[row_offset]|= null_bit; } - inline void set_notnull(int row_offset=0) + inline void set_notnull(my_ptrdiff_t row_offset= 0) { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; } inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; } inline bool real_maybe_null(void) { return null_ptr != 0; } + + enum { + LAST_NULL_BYTE_UNDEF= 0 + }; + + /* + Find the position of the last null byte for the field. + + SYNOPSIS + last_null_byte() + + DESCRIPTION + Return a pointer to the last byte of the null bytes where the + field conceptually is placed. + + RETURN VALUE + The position of the last null byte relative to the beginning of + the record. If the field does not use any bits of the null + bytes, the value 0 (LAST_NULL_BYTE_UNDEF) is returned. + */ + size_t last_null_byte() const { + size_t bytes= do_last_null_byte(); + DBUG_PRINT("debug", ("last_null_byte() ==> %ld", (long) bytes)); + DBUG_ASSERT(bytes <= table->s->null_bytes); + return bytes; + } + virtual void make_field(Send_field *); - virtual void sort_string(char *buff,uint length)=0; + virtual void sort_string(uchar *buff,uint length)=0; virtual bool optimize_range(uint idx, uint part); /* This should be true for fields which, when compared with constant @@ -218,22 +261,23 @@ public: virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type); virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table, - char *new_ptr, uchar *new_null_ptr, + uchar *new_ptr, uchar *new_null_ptr, uint new_null_bit); - inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg) + Field *clone(MEM_ROOT *mem_root, struct st_table *new_table); + inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg) { ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg; } - inline void move_field(char *ptr_arg) { ptr=ptr_arg; } - virtual inline void move_field(my_ptrdiff_t ptr_diff) + inline void move_field(uchar *ptr_arg) { ptr=ptr_arg; } + virtual void move_field_offset(my_ptrdiff_t ptr_diff) { - ptr=ADD_TO_PTR(ptr,ptr_diff,char*); + ptr=ADD_TO_PTR(ptr,ptr_diff, uchar*); if (null_ptr) null_ptr=ADD_TO_PTR(null_ptr,ptr_diff,uchar*); } - virtual void get_image(char *buff, uint length, CHARSET_INFO *cs) + virtual void get_image(uchar *buff, uint length, CHARSET_INFO *cs) { memcpy(buff,ptr,length); } - virtual void set_image(char *buff,uint length, CHARSET_INFO *cs) + virtual void set_image(const uchar *buff,uint length, CHARSET_INFO *cs) { memcpy(ptr,buff,length); } @@ -263,12 +307,12 @@ public: Number of copied bytes (excluding padded zero bytes -- see above). */ - virtual uint get_key_image(char *buff, uint length, imagetype type) + virtual uint get_key_image(uchar *buff, uint length, imagetype type) { get_image(buff, length, &my_charset_bin); return length; } - virtual void set_key_image(char *buff,uint length) + virtual void set_key_image(const uchar *buff,uint length) { set_image(buff,length, &my_charset_bin); } inline longlong val_int_offset(uint row_offset) { @@ -277,53 +321,66 @@ public: ptr-=row_offset; return tmp; } - - inline String *val_str(String *str, char *new_ptr) + inline longlong val_int(const uchar *new_ptr) + { + uchar *old_ptr= ptr; + longlong return_value; + ptr= (uchar*) new_ptr; + return_value= val_int(); + ptr= old_ptr; + return return_value; + } + inline String *val_str(String *str, const uchar *new_ptr) { - char *old_ptr= ptr; - ptr= new_ptr; + uchar *old_ptr= ptr; + ptr= (uchar*) new_ptr; val_str(str); ptr= old_ptr; return str; } virtual bool send_binary(Protocol *protocol); - virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0) + virtual uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0) { uint32 length=pack_length(); memcpy(to,from,length); return to+length; } - virtual const char *unpack(char* to, const char *from) + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); + virtual const uchar *unpack(uchar* to, const uchar *from) { uint length=pack_length(); memcpy(to,from,length); return from+length; } - virtual char *pack_key(char* to, const char *from, uint max_length) + virtual uchar *pack_key(uchar* to, const uchar *from, uint max_length) { return pack(to,from,max_length); } - virtual char *pack_key_from_key_image(char* to, const char *from, + virtual uchar *pack_key_from_key_image(uchar* to, const uchar *from, uint max_length) { return pack(to,from,max_length); } - virtual const char *unpack_key(char* to, const char *from, uint max_length) + virtual const uchar *unpack_key(uchar* to, const uchar *from, + uint max_length) { return unpack(to,from); } - virtual uint packed_col_length(const char *to, uint length) + virtual uint packed_col_length(const uchar *to, uint length) { return length;} virtual uint max_packed_col_length(uint max_length) { return max_length;} - virtual int pack_cmp(const char *a,const char *b, uint key_length_arg, + virtual int pack_cmp(const uchar *a,const uchar *b, uint key_length_arg, my_bool insert_or_update) { return cmp(a,b); } - virtual int pack_cmp(const char *b, uint key_length_arg, + virtual int pack_cmp(const uchar *b, uint key_length_arg, my_bool insert_or_update) { return cmp(ptr,b); } - uint offset(); // Should be inline ... + uint offset(uchar *record) + { + return (uint) (ptr - record); + } void copy_from_tmp(int offset); uint fill_cache_field(struct st_cache_field *copy); virtual bool get_date(MYSQL_TIME *ltime,uint fuzzydate); @@ -350,8 +407,16 @@ public: return (op_result == E_DEC_OVERFLOW); } int warn_if_overflow(int op_result); + void init(TABLE *table_arg) + { + orig_table= table= table_arg; + table_name= &table_arg->alias; + } + /* maximum possible display length */ virtual uint32 max_display_length()= 0; + + virtual uint is_equal(Create_field *new_field); /* convert decimal to longlong with overflow check */ longlong convert_decimal2longlong(const my_decimal *val, bool unsigned_flag, int *err); @@ -360,14 +425,17 @@ public: { return field_length / charset()->mbmaxlen; } + virtual geometry_type get_geometry_type() { /* shouldn't get here. */ DBUG_ASSERT(0); return GEOM_GEOMETRY; } + /* Hash value */ + virtual void hash(ulong *nr, ulong *nr2); friend bool reopen_table(THD *,struct st_table *,bool); - friend int cre_myisam(my_string name, register TABLE *form, uint options, + friend int cre_myisam(char * name, register TABLE *form, uint options, ulonglong auto_increment_value); friend class Copy_field; friend class Item_avg_field; @@ -381,6 +449,20 @@ public: friend class Item_sum_min; friend class Item_sum_max; friend class Item_func_group_concat; + +private: + /* + Primitive for implementing last_null_byte(). + + SYNOPSIS + do_last_null_byte() + + DESCRIPTION + Primitive for the implementation of the last_null_byte() + function. This represents the inheritance interface and can be + overridden by subclasses. + */ + virtual size_t do_last_null_byte() const; }; @@ -388,21 +470,21 @@ class Field_num :public Field { public: const uint8 dec; bool zerofill,unsigned_flag; // Purify cannot handle bit fields - Field_num(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, + Field_num(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg, bool zero_arg, bool unsigned_arg); Item_result result_type () const { return REAL_RESULT; } void prepend_zeros(String *value); void add_zerofill_and_unsigned(String &res) const; - friend class create_field; + friend class Create_field; void make_field(Send_field *); uint decimals() const { return (uint) dec; } uint size_of() const { return sizeof(*this); } bool eq_def(Field *field); int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); + uint is_equal(Create_field *new_field); int check_int(CHARSET_INFO *cs, const char *str, int length, const char *int_end, int error); bool get_int(CHARSET_INFO *cs, const char *from, uint len, @@ -416,10 +498,9 @@ protected: CHARSET_INFO *field_charset; enum Derivation field_derivation; public: - Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, + Field_str(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, - const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *charset); + const char *field_name_arg, CHARSET_INFO *charset); Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } int store(double nr); @@ -434,8 +515,11 @@ public: { field_derivation= derivation_arg; } bool binary() const { return field_charset == &my_charset_bin; } uint32 max_display_length() { return field_length; } - friend class create_field; + friend class Create_field; my_decimal *val_decimal(my_decimal *); + virtual bool str_needs_quotes() { return TRUE; } + bool compare_str_field_flags(Create_field *new_field, uint32 flags); + uint is_equal(Create_field *new_field); }; @@ -444,12 +528,11 @@ public: class Field_longstr :public Field_str { public: - Field_longstr(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_longstr(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, - const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *charset_arg) + const char *field_name_arg, CHARSET_INFO *charset_arg) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, - field_name_arg, table_arg, charset_arg) + field_name_arg, charset_arg) {} int store_decimal(const my_decimal *d); @@ -460,17 +543,14 @@ class Field_real :public Field_num { public: my_bool not_fixed; - Field_real(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_real(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg, bool zero_arg, bool unsigned_arg) :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, - field_name_arg, table_arg, dec_arg, zero_arg, unsigned_arg), + field_name_arg, dec_arg, zero_arg, unsigned_arg), not_fixed(dec_arg >= NOT_FIXED_DEC) {} - - int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); int truncate(double *nr, double max_length); @@ -481,16 +561,15 @@ public: class Field_decimal :public Field_real { public: - Field_decimal(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_decimal(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg,bool zero_arg,bool unsigned_arg) :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) {} - enum_field_types type() const { return FIELD_TYPE_DECIMAL;} + enum_field_types type() const { return MYSQL_TYPE_DECIMAL;} enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } int reset(void); @@ -500,8 +579,8 @@ public: double val_real(void); longlong val_int(void); String *val_str(String*,String *); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); void overflow(bool negative); bool zero_pack() const { return 0; } void sql_type(String &str) const; @@ -520,16 +599,14 @@ public: So for example we need to count length from precision handling CREATE TABLE ( DECIMAL(x,y)) */ - Field_new_decimal(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_new_decimal(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg, bool zero_arg, bool unsigned_arg); Field_new_decimal(uint32 len_arg, bool maybe_null_arg, - const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg, + const char *field_name_arg, uint8 dec_arg, bool unsigned_arg); - enum_field_types type() const { return FIELD_TYPE_NEWDECIMAL;} + enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } Item_result result_type () const { return DECIMAL_RESULT; } int reset(void); @@ -544,29 +621,30 @@ public: longlong val_int(void); my_decimal *val_decimal(my_decimal *); String *val_str(String*, String *); - int cmp(const char *, const char*); - void sort_string(char *buff, uint length); + int cmp(const uchar *, const uchar *); + void sort_string(uchar *buff, uint length); bool zero_pack() const { return 0; } void sql_type(String &str) const; uint32 max_display_length() { return field_length; } uint size_of() const { return sizeof(*this); } uint32 pack_length() const { return (uint32) bin_size; } + uint is_equal(Create_field *new_field); + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); }; class Field_tiny :public Field_num { public: - Field_tiny(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_tiny(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, bool zero_arg, bool unsigned_arg) :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, 0, zero_arg,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_TINY;} + enum_field_types type() const { return MYSQL_TYPE_TINY;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -577,8 +655,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 1; } void sql_type(String &str) const; uint32 max_display_length() { return 4; } @@ -587,22 +665,21 @@ public: class Field_short :public Field_num { public: - Field_short(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_short(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, bool zero_arg, bool unsigned_arg) :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, 0, zero_arg,unsigned_arg) {} Field_short(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg,bool unsigned_arg) - :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,unsigned_arg) + bool unsigned_arg) + :Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg, 0, 0, unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_SHORT;} + enum_field_types type() const { return MYSQL_TYPE_SHORT;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} int store(const char *to,uint length,CHARSET_INFO *charset); @@ -613,8 +690,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 2; } void sql_type(String &str) const; uint32 max_display_length() { return 6; } @@ -623,17 +700,16 @@ public: class Field_medium :public Field_num { public: - Field_medium(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_medium(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, bool zero_arg, bool unsigned_arg) :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, 0, zero_arg,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_INT24;} + enum_field_types type() const { return MYSQL_TYPE_INT24;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -644,8 +720,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; uint32 max_display_length() { return 8; } @@ -654,22 +730,21 @@ public: class Field_long :public Field_num { public: - Field_long(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_long(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, bool zero_arg, bool unsigned_arg) :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, 0, zero_arg,unsigned_arg) {} Field_long(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg,bool unsigned_arg) - :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,unsigned_arg) + bool unsigned_arg) + :Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_LONG;} + enum_field_types type() const { return MYSQL_TYPE_LONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -680,8 +755,8 @@ public: longlong val_int(void); bool send_binary(Protocol *protocol); String *val_str(String*,String *); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; uint32 max_display_length() { return MY_INT32_NUM_DECIMAL_DIGITS; } @@ -691,23 +766,22 @@ public: #ifdef HAVE_LONG_LONG class Field_longlong :public Field_num { public: - Field_longlong(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_longlong(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, bool zero_arg, bool unsigned_arg) :Field_num(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, 0, zero_arg,unsigned_arg) {} Field_longlong(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, bool unsigned_arg) - :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,unsigned_arg) + bool unsigned_arg) + :Field_num((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_LONGLONG;} + enum_field_types type() const { return MYSQL_TYPE_LONGLONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -722,8 +796,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; bool can_be_compared_as_longlong() const { return TRUE; } @@ -734,21 +808,20 @@ public: class Field_float :public Field_real { public: - Field_float(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_float(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg,bool zero_arg,bool unsigned_arg) :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) {} Field_float(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg) - :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0, - NONE, field_name_arg, table_arg, dec_arg, 0, 0) + uint8 dec_arg) + :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0, + NONE, field_name_arg, dec_arg, 0, 0) {} - enum_field_types type() const { return FIELD_TYPE_FLOAT;} + enum_field_types type() const { return MYSQL_TYPE_FLOAT;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); @@ -758,8 +831,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(float); } void sql_type(String &str) const; }; @@ -767,26 +840,25 @@ public: class Field_double :public Field_real { public: - Field_double(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_double(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg,bool zero_arg,bool unsigned_arg) :Field_real(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, + unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) {} Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg) - :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, - NONE, field_name_arg, table_arg, dec_arg, 0, 0) + uint8 dec_arg) + :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, + NONE, field_name_arg, dec_arg, 0, 0) {} Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, uint8 dec_arg, my_bool not_fixed_arg) - :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, - NONE, field_name_arg, table_arg, dec_arg, 0, 0) + uint8 dec_arg, my_bool not_fixed_arg) + :Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0, + NONE, field_name_arg, dec_arg, 0, 0) {not_fixed= not_fixed_arg; } - enum_field_types type() const { return FIELD_TYPE_DOUBLE;} + enum_field_types type() const { return MYSQL_TYPE_DOUBLE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); @@ -796,8 +868,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return sizeof(double); } void sql_type(String &str) const; }; @@ -808,13 +880,13 @@ public: class Field_null :public Field_str { static uchar null[1]; public: - Field_null(char *ptr_arg, uint32 len_arg, + Field_null(uchar *ptr_arg, uint32 len_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + CHARSET_INFO *cs) :Field_str(ptr_arg, len_arg, null, 1, - unireg_check_arg, field_name_arg, table_arg, cs) + unireg_check_arg, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_NULL;} + enum_field_types type() const { return MYSQL_TYPE_NULL;} int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } int store(double nr) { null[0]=1; return 0; } @@ -826,8 +898,8 @@ public: my_decimal *val_decimal(my_decimal *) { return 0; } String *val_str(String *value,String *value2) { value2->length(0); return value2;} - int cmp(const char *a, const char *b) { return 0;} - void sort_string(char *buff, uint length) {} + int cmp(const uchar *a, const uchar *b) { return 0;} + void sort_string(uchar *buff, uint length) {} uint32 pack_length() const { return 0; } void sql_type(String &str) const; uint size_of() const { return sizeof(*this); } @@ -837,14 +909,13 @@ public: class Field_timestamp :public Field_str { public: - Field_timestamp(char *ptr_arg, uint32 len_arg, + Field_timestamp(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, - CHARSET_INFO *cs); + TABLE_SHARE *share, CHARSET_INFO *cs); Field_timestamp(bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs); - enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} + CHARSET_INFO *cs); + enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -855,8 +926,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; bool can_be_compared_as_longlong() const { return TRUE; } @@ -891,14 +962,13 @@ public: class Field_year :public Field_tiny { public: - Field_year(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_year(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, - enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg) + enum utype unireg_check_arg, const char *field_name_arg) :Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, 1, 1) + unireg_check_arg, field_name_arg, 1, 1) {} - enum_field_types type() const { return FIELD_TYPE_YEAR;} + enum_field_types type() const { return MYSQL_TYPE_YEAR;} int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -913,17 +983,17 @@ public: class Field_date :public Field_str { public: - Field_date(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + CHARSET_INFO *cs) :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, cs) + unireg_check_arg, field_name_arg, cs) {} Field_date(bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_DATE;} + CHARSET_INFO *cs) + :Field_str((uchar*) 0,10, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg, cs) {} + enum_field_types type() const { return MYSQL_TYPE_DATE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -934,24 +1004,25 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 4; } void sql_type(String &str) const; bool can_be_compared_as_longlong() const { return TRUE; } bool zero_pack() const { return 1; } }; + class Field_newdate :public Field_str { public: - Field_newdate(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + Field_newdate(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + CHARSET_INFO *cs) :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, cs) + unireg_check_arg, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_DATE;} - enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; } + enum_field_types type() const { return MYSQL_TYPE_DATE;} + enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; } enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -963,8 +1034,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; bool can_be_compared_as_longlong() const { return TRUE; } @@ -976,17 +1047,17 @@ public: class Field_time :public Field_str { public: - Field_time(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + Field_time(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + CHARSET_INFO *cs) :Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, cs) + unireg_check_arg, field_name_arg, cs) {} Field_time(bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_str((char*) 0,8, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_TIME;} + CHARSET_INFO *cs) + :Field_str((uchar*) 0,8, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg, cs) {} + enum_field_types type() const { return MYSQL_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } int store_time(MYSQL_TIME *ltime, timestamp_type type); @@ -1000,8 +1071,8 @@ public: bool get_date(MYSQL_TIME *ltime, uint fuzzydate); bool send_binary(Protocol *protocol); bool get_time(MYSQL_TIME *ltime); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 3; } void sql_type(String &str) const; bool can_be_compared_as_longlong() const { return TRUE; } @@ -1011,17 +1082,17 @@ public: class Field_datetime :public Field_str { public: - Field_datetime(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + Field_datetime(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + CHARSET_INFO *cs) :Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, cs) + unireg_check_arg, field_name_arg, cs) {} Field_datetime(bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_str((char*) 0,19, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_DATETIME;} + CHARSET_INFO *cs) + :Field_str((uchar*) 0,19, maybe_null_arg ? (uchar*) "": 0,0, + NONE, field_name_arg, cs) {} + enum_field_types type() const { return MYSQL_TYPE_DATETIME;} #ifdef HAVE_LONG_LONG enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } #endif @@ -1040,8 +1111,8 @@ public: longlong val_int(void); String *val_str(String*,String *); bool send_binary(Protocol *protocol); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return 8; } void sql_type(String &str) const; bool can_be_compared_as_longlong() const { return TRUE; } @@ -1054,17 +1125,17 @@ public: class Field_string :public Field_longstr { public: bool can_alter_field_type; - Field_string(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg, + Field_string(uchar *ptr_arg, uint32 len_arg,uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + CHARSET_INFO *cs) :Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, cs), + unireg_check_arg, field_name_arg, cs), can_alter_field_type(1) {}; Field_string(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_longstr((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0, - NONE, field_name_arg, table_arg, cs), + CHARSET_INFO *cs) + :Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0, + NONE, field_name_arg, cs), can_alter_field_type(1) {}; enum_field_types type() const @@ -1080,7 +1151,7 @@ public: bool zero_pack() const { return 0; } int reset(void) { - charset()->cset->fill(charset(),ptr,field_length, + charset()->cset->fill(charset(),(char*) ptr, field_length, (has_charset() ? ' ' : 0)); return 0; } @@ -1091,22 +1162,23 @@ public: longlong val_int(void); String *val_str(String*,String *); my_decimal *val_decimal(my_decimal *); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); void sql_type(String &str) const; - char *pack(char *to, const char *from, uint max_length=~(uint) 0); - const char *unpack(char* to, const char *from); - int pack_cmp(const char *a,const char *b,uint key_length, + uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); + const uchar *unpack(uchar* to, const uchar *from); + int pack_cmp(const uchar *a,const uchar *b,uint key_length, my_bool insert_or_update); - int pack_cmp(const char *b,uint key_length,my_bool insert_or_update); - uint packed_col_length(const char *to, uint length); + int pack_cmp(const uchar *b,uint key_length,my_bool insert_or_update); + uint packed_col_length(const uchar *to, uint length); uint max_packed_col_length(uint max_length); uint size_of() const { return sizeof(*this); } - enum_field_types real_type() const { return FIELD_TYPE_STRING; } + enum_field_types real_type() const { return MYSQL_TYPE_STRING; } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type); - virtual uint get_key_image(char *buff,uint length, imagetype type); + virtual uint get_key_image(uchar *buff,uint length, imagetype type); }; @@ -1119,28 +1191,25 @@ public: static const uint MAX_SIZE; /* Store number of bytes used to store length (1 or 2) */ uint32 length_bytes; - Field_varstring(char *ptr_arg, + Field_varstring(uchar *ptr_arg, uint32 len_arg, uint length_bytes_arg, - uchar *null_ptr_arg, - uchar null_bit_arg, + uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) + TABLE_SHARE *share, CHARSET_INFO *cs) :Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, cs), + unireg_check_arg, field_name_arg, cs), length_bytes(length_bytes_arg) { - if (table) - table->s->varchar_fields++; + share->varchar_fields++; } Field_varstring(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_longstr((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0, - NONE, field_name_arg, table_arg, cs), + TABLE_SHARE *share, CHARSET_INFO *cs) + :Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0, + NONE, field_name_arg, cs), length_bytes(len_arg < 256 ? 1 :2) { - if (table) - table->s->varchar_fields++; + share->varchar_fields++; } enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } @@ -1161,33 +1230,41 @@ public: longlong val_int(void); String *val_str(String*,String *); my_decimal *val_decimal(my_decimal *); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); - uint get_key_image(char *buff,uint length, imagetype type); - void set_key_image(char *buff,uint length); + int cmp_max(const uchar *, const uchar *, uint max_length); + int cmp(const uchar *a,const uchar *b) + { + return cmp_max(a, b, ~0L); + } + void sort_string(uchar *buff,uint length); + uint get_key_image(uchar *buff,uint length, imagetype type); + void set_key_image(const uchar *buff,uint length); void sql_type(String &str) const; - char *pack(char *to, const char *from, uint max_length=~(uint) 0); - char *pack_key(char *to, const char *from, uint max_length); - char *pack_key_from_key_image(char* to, const char *from, uint max_length); - const char *unpack(char* to, const char *from); - const char *unpack_key(char* to, const char *from, uint max_length); - int pack_cmp(const char *a, const char *b, uint key_length, + uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); + uchar *pack_key(uchar *to, const uchar *from, uint max_length); + uchar *pack_key_from_key_image(uchar* to, const uchar *from, + uint max_length); + virtual const uchar *unpack(uchar* to, const uchar *from, uint param_data); + const uchar *unpack(uchar* to, const uchar *from); + const uchar *unpack_key(uchar* to, const uchar *from, uint max_length); + int pack_cmp(const uchar *a, const uchar *b, uint key_length, my_bool insert_or_update); - int pack_cmp(const char *b, uint key_length,my_bool insert_or_update); - int cmp_binary(const char *a,const char *b, uint32 max_length=~0L); - int key_cmp(const byte *,const byte*); - int key_cmp(const byte *str, uint length); - uint packed_col_length(const char *to, uint length); + int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update); + int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L); + int key_cmp(const uchar *,const uchar*); + int key_cmp(const uchar *str, uint length); + uint packed_col_length(const uchar *to, uint length); uint max_packed_col_length(uint max_length); - uint32 data_length(const char *from); + uint32 data_length(); uint size_of() const { return sizeof(*this); } enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type); Field *new_key_field(MEM_ROOT *root, struct st_table *new_table, - char *new_ptr, uchar *new_null_ptr, + uchar *new_ptr, uchar *new_null_ptr, uint new_null_bit); + uint is_equal(Create_field *new_field); + void hash(ulong *nr, ulong *nr2); }; @@ -1196,22 +1273,21 @@ protected: uint packlength; String value; // For temporaries public: - Field_blob(char *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, + Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,uint blob_pack_length, - CHARSET_INFO *cs); + TABLE_SHARE *share, uint blob_pack_length, CHARSET_INFO *cs); Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs) - :Field_longstr((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0, - NONE, field_name_arg, table_arg, cs), + CHARSET_INFO *cs) + :Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0, + NONE, field_name_arg, cs), packlength(4) { flags|= BLOB_FLAG; } Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, CHARSET_INFO *cs, bool set_packlength) - :Field_longstr((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0, - NONE, field_name_arg, table_arg, cs) + CHARSET_INFO *cs, bool set_packlength) + :Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0, + NONE, field_name_arg, cs) { flags|= BLOB_FLAG; packlength= 4; @@ -1223,7 +1299,10 @@ public: l_char_length <= 16777215 ? 3 : 4; } } - enum_field_types type() const { return FIELD_TYPE_BLOB;} + Field_blob(uint32 packlength_arg) + :Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, "temp", system_charset_info), + packlength(packlength_arg) {} + enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -1233,72 +1312,124 @@ public: longlong val_int(void); String *val_str(String*,String *); my_decimal *val_decimal(my_decimal *); - int cmp(const char *,const char*); - int cmp(const char *a, uint32 a_length, const char *b, uint32 b_length); - int cmp_binary(const char *a,const char *b, uint32 max_length=~0L); - int key_cmp(const byte *,const byte*); - int key_cmp(const byte *str, uint length); + int cmp_max(const uchar *, const uchar *, uint max_length); + int cmp(const uchar *a,const uchar *b) + { return cmp_max(a, b, ~0L); } + int cmp(const uchar *a, uint32 a_length, const uchar *b, uint32 b_length); + int cmp_binary(const uchar *a,const uchar *b, uint32 max_length=~0L); + int key_cmp(const uchar *,const uchar*); + int key_cmp(const uchar *str, uint length); uint32 key_length() const { return 0; } - void sort_string(char *buff,uint length); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return (uint32) (packlength+table->s->blob_ptr_size); } + + /** + Return the packed length without the pointer size added. + + This is used to determine the size of the actual data in the row + buffer. + + @retval The length of the raw data itself without the pointer. + */ + uint32 pack_length_no_ptr() const + { return (uint32) (packlength); } uint32 sort_length() const; inline uint32 max_data_length() const { return (uint32) (((ulonglong) 1 << (packlength*8)) -1); } - int reset(void) { bzero(ptr, packlength+sizeof(char*)); return 0; } - void reset_fields() { bzero((char*) &value,sizeof(value)); } - void store_length(uint32 number); - inline uint32 get_length(uint row_offset=0) - { return get_length(ptr+row_offset); } - uint32 get_length(const char *ptr); - void put_length(char *pos, uint32 length); - inline void get_ptr(char **str) + int reset(void) { bzero(ptr, packlength+sizeof(uchar*)); return 0; } + void reset_fields() { bzero((uchar*) &value,sizeof(value)); } +#ifndef WORDS_BIGENDIAN + static +#endif + void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number, bool low_byte_first); + void store_length(uchar *i_ptr, uint i_packlength, uint32 i_number) + { + store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first); + } + inline void store_length(uint32 number) + { + store_length(ptr, packlength, number); + } + + /** + Return the packed length plus the length of the data. + + This is used to determine the size of the data plus the + packed length portion in the row data. + + @retval The length in the row plus the size of the data. + */ + uint32 get_packed_size(const uchar *ptr_arg, bool low_byte_first) + {return packlength + get_length(ptr_arg, low_byte_first);} + + inline uint32 get_length(uint row_offset= 0) + { return get_length(ptr+row_offset, table->s->db_low_byte_first); } + uint32 get_length(const uchar *ptr, bool low_byte_first); + uint32 get_length(const uchar *ptr_arg) + { return get_length(ptr_arg, table->s->db_low_byte_first); } + void put_length(uchar *pos, uint32 length); + inline void get_ptr(uchar **str) + { + memcpy_fixed((uchar*) str,ptr+packlength,sizeof(uchar*)); + } + inline void get_ptr(uchar **str, uint row_offset) { - memcpy_fixed(str,ptr+packlength,sizeof(char*)); + memcpy_fixed((uchar*) str,ptr+packlength+row_offset,sizeof(char*)); } - inline void set_ptr(char *length,char *data) + inline void set_ptr(uchar *length, uchar *data) { memcpy(ptr,length,packlength); memcpy_fixed(ptr+packlength,&data,sizeof(char*)); } - inline void set_ptr(uint32 length,char *data) + void set_ptr_offset(my_ptrdiff_t ptr_diff, uint32 length, uchar *data) { - store_length(length); - memcpy_fixed(ptr+packlength,&data,sizeof(char*)); + uchar *ptr_ofs= ADD_TO_PTR(ptr,ptr_diff,uchar*); + store_length(ptr_ofs, packlength, length); + memcpy_fixed(ptr_ofs+packlength,&data,sizeof(char*)); + } + inline void set_ptr(uint32 length, uchar *data) + { + set_ptr_offset(0, length, data); } - uint get_key_image(char *buff,uint length, imagetype type); - void set_key_image(char *buff,uint length); + uint get_key_image(uchar *buff,uint length, imagetype type); + void set_key_image(const uchar *buff,uint length); void sql_type(String &str) const; inline bool copy() - { char *tmp; + { + uchar *tmp; get_ptr(&tmp); - if (value.copy(tmp,get_length(),charset())) + if (value.copy((char*) tmp, get_length(), charset())) { Field_blob::reset(); return 1; } - tmp=(char*) value.ptr(); memcpy_fixed(ptr+packlength,&tmp,sizeof(char*)); + tmp=(uchar*) value.ptr(); + memcpy_fixed(ptr+packlength,&tmp,sizeof(char*)); return 0; } - char *pack(char *to, const char *from, uint max_length= ~(uint) 0); - char *pack_key(char *to, const char *from, uint max_length); - char *pack_key_from_key_image(char* to, const char *from, uint max_length); - const char *unpack(char *to, const char *from); - const char *unpack_key(char* to, const char *from, uint max_length); - int pack_cmp(const char *a, const char *b, uint key_length, + uchar *pack(uchar *to, const uchar *from, uint max_length= ~(uint) 0); + uchar *pack_key(uchar *to, const uchar *from, uint max_length); + uchar *pack_key_from_key_image(uchar* to, const uchar *from, + uint max_length); + virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); + const uchar *unpack(uchar *to, const uchar *from); + const uchar *unpack_key(uchar* to, const uchar *from, uint max_length); + int pack_cmp(const uchar *a, const uchar *b, uint key_length, my_bool insert_or_update); - int pack_cmp(const char *b, uint key_length,my_bool insert_or_update); - uint packed_col_length(const char *col_ptr, uint length); + int pack_cmp(const uchar *b, uint key_length,my_bool insert_or_update); + uint packed_col_length(const uchar *col_ptr, uint length); uint max_packed_col_length(uint max_length); void free() { value.free(); } - inline void clear_temporary() { bzero((char*) &value,sizeof(value)); } + inline void clear_temporary() { bzero((uchar*) &value,sizeof(value)); } friend int field_conv(Field *to,Field *from); uint size_of() const { return sizeof(*this); } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } uint32 max_display_length(); + uint is_equal(Create_field *new_field); }; @@ -1307,26 +1438,25 @@ class Field_geom :public Field_blob { public: enum geometry_type geom_type; - Field_geom(char *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg, + Field_geom(uchar *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,uint blob_pack_length, + TABLE_SHARE *share, uint blob_pack_length, enum geometry_type geom_type_arg) :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, - field_name_arg, table_arg, blob_pack_length,&my_charset_bin) + field_name_arg, share, blob_pack_length, &my_charset_bin) { geom_type= geom_type_arg; } Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg, enum geometry_type geom_type_arg) - :Field_blob(len_arg, maybe_null_arg, field_name_arg, - table_arg, &my_charset_bin) + TABLE_SHARE *share, enum geometry_type geom_type_arg) + :Field_blob(len_arg, maybe_null_arg, field_name_arg, &my_charset_bin) { geom_type= geom_type_arg; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; } - enum_field_types type() const { return FIELD_TYPE_GEOMETRY; } + enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; } void sql_type(String &str) const; int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); int store_decimal(const my_decimal *); - uint get_key_image(char *buff,uint length,imagetype type); + uint get_key_image(uchar *buff,uint length,imagetype type); uint size_of() const { return sizeof(*this); } int reset(void) { return !maybe_null() || Field_blob::reset(); } geometry_type get_geometry_type() { return geom_type; }; @@ -1339,37 +1469,36 @@ protected: uint packlength; public: TYPELIB *typelib; - Field_enum(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, - uchar null_bit_arg, - enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,uint packlength_arg, - TYPELIB *typelib_arg, - CHARSET_INFO *charset_arg) + Field_enum(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + uchar null_bit_arg, + enum utype unireg_check_arg, const char *field_name_arg, + uint packlength_arg, + TYPELIB *typelib_arg, + CHARSET_INFO *charset_arg) :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg, charset_arg), + unireg_check_arg, field_name_arg, charset_arg), packlength(packlength_arg),typelib(typelib_arg) { flags|=ENUM_FLAG; } Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type); - enum_field_types type() const { return FIELD_TYPE_STRING; } + enum_field_types type() const { return MYSQL_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum Item_result cast_to_int_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - int reset() { bzero(ptr,packlength); return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); - int cmp(const char *,const char*); - void sort_string(char *buff,uint length); + int cmp(const uchar *,const uchar *); + void sort_string(uchar *buff,uint length); uint32 pack_length() const { return (uint32) packlength; } void store_type(ulonglong value); void sql_type(String &str) const; uint size_of() const { return sizeof(*this); } - enum_field_types real_type() const { return FIELD_TYPE_ENUM; } + enum_field_types real_type() const { return MYSQL_TYPE_ENUM; } virtual bool zero_pack() const { return 0; } bool optimize_range(uint idx, uint part) { return 0; } bool eq_def(Field *field); @@ -1381,15 +1510,15 @@ public: class Field_set :public Field_enum { public: - Field_set(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_set(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg,uint32 packlength_arg, + uint32 packlength_arg, TYPELIB *typelib_arg, CHARSET_INFO *charset_arg) :Field_enum(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, - table_arg, packlength_arg, - typelib_arg,charset_arg) + packlength_arg, + typelib_arg,charset_arg) { flags=(flags & ~ENUM_FLAG) | SET_FLAG; } @@ -1399,22 +1528,35 @@ public: virtual bool zero_pack() const { return 1; } String *val_str(String*,String *); void sql_type(String &str) const; - enum_field_types real_type() const { return FIELD_TYPE_SET; } + enum_field_types real_type() const { return MYSQL_TYPE_SET; } bool has_charset(void) const { return TRUE; } }; +/* + Note: + To use Field_bit::cmp_binary() you need to copy the bits stored in + the beginning of the record (the NULL bytes) to each memory you + want to compare (where the arguments point). + + This is the reason: + - Field_bit::cmp_binary() is only implemented in the base class + (Field::cmp_binary()). + - Field::cmp_binary() currenly use pack_length() to calculate how + long the data is. + - pack_length() includes size of the bits stored in the NULL bytes + of the record. +*/ class Field_bit :public Field { public: uchar *bit_ptr; // position in record where 'uneven' bits store uchar bit_ofs; // offset to 'uneven' high bits uint bit_len; // number of 'uneven' high bits uint bytes_in_rec; - Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_bit(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, - enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg); - enum_field_types type() const { return FIELD_TYPE_BIT; } + enum utype unireg_check_arg, const char *field_name_arg); + enum_field_types type() const { return MYSQL_TYPE_BIT; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; } uint32 key_length() const { return (uint32) (field_length + 7) / 8; } uint32 max_display_length() { return field_length; } @@ -1428,40 +1570,40 @@ public: double val_real(void); longlong val_int(void); String *val_str(String*, String *); + virtual bool str_needs_quotes() { return TRUE; } my_decimal *val_decimal(my_decimal *); - int cmp(const char *a, const char *b) + int cmp(const uchar *a, const uchar *b) { DBUG_ASSERT(ptr == a); return Field_bit::key_cmp((const byte *) b, bytes_in_rec+test(bit_len)); } - int key_cmp(const byte *a, const byte *b) - { return cmp_binary((char *) a, (char *) b); } - int key_cmp(const byte *str, uint length); - int cmp_offset(uint row_offset); int cmp_binary_offset(uint row_offset) { return cmp_offset(row_offset); } - void get_image(char *buff, uint length, CHARSET_INFO *cs) + int cmp_max(const uchar *a, const uchar *b, uint max_length); + int key_cmp(const uchar *a, const uchar *b) + { return cmp_binary((uchar *) a, (uchar *) b); } + int key_cmp(const uchar *str, uint length); + int cmp_offset(uint row_offset); + void get_image(uchar *buff, uint length, CHARSET_INFO *cs) { get_key_image(buff, length, itRAW); } - void set_image(char *buff,uint length, CHARSET_INFO *cs) + void set_image(const uchar *buff,uint length, CHARSET_INFO *cs) { Field_bit::store(buff, length, cs); } - uint get_key_image(char *buff, uint length, imagetype type); - void set_key_image(char *buff, uint length) - { Field_bit::store(buff, length, &my_charset_bin); } - void sort_string(char *buff, uint length) + uint get_key_image(uchar *buff, uint length, imagetype type); + void set_key_image(const uchar *buff, uint length) + { Field_bit::store((char*) buff, length, &my_charset_bin); } + void sort_string(uchar *buff, uint length) { get_key_image(buff, length, itRAW); } uint32 pack_length() const { return (uint32) (field_length + 7) / 8; } uint32 pack_length_in_rec() const { return bytes_in_rec; } void sql_type(String &str) const; - char *pack(char *to, const char *from, uint max_length=~(uint) 0); - const char *unpack(char* to, const char *from); + uchar *pack(uchar *to, const uchar *from, uint max_length=~(uint) 0); + virtual const uchar *unpack(uchar *to, const uchar *from, uint param_data); + const uchar *unpack(uchar* to, const uchar *from); + virtual void set_default(); + Field *new_key_field(MEM_ROOT *root, struct st_table *new_table, - char *new_ptr, uchar *new_null_ptr, + uchar *new_ptr, uchar *new_null_ptr, uint new_null_bit); - inline void move_field(my_ptrdiff_t ptr_diff) - { - Field::move_field(ptr_diff); - bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*); - } void set_bit_ptr(uchar *bit_ptr_arg, uchar bit_ofs_arg) { bit_ptr= bit_ptr_arg; @@ -1474,15 +1616,30 @@ public: bit_ptr == ((Field_bit *)field)->bit_ptr && bit_ofs == ((Field_bit *)field)->bit_ofs); } + uint is_equal(Create_field *new_field); + void move_field_offset(my_ptrdiff_t ptr_diff) + { + Field::move_field_offset(ptr_diff); + bit_ptr= ADD_TO_PTR(bit_ptr, ptr_diff, uchar*); + } + +private: + virtual size_t do_last_null_byte() const; }; +/** + BIT field represented as chars for non-MyISAM tables. + + @todo The inheritance relationship is backwards since Field_bit is + an extended version of Field_bit_as_char and not the other way + around. Hence, we should refactor it to fix the hierarchy order. + */ class Field_bit_as_char: public Field_bit { public: - Field_bit_as_char(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, + Field_bit_as_char(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, - enum utype unireg_check_arg, const char *field_name_arg, - struct st_table *table_arg); + enum utype unireg_check_arg, const char *field_name_arg); enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } uint size_of() const { return sizeof(*this); } int store(const char *to, uint length, CHARSET_INFO *charset); @@ -1497,7 +1654,7 @@ public: Create field class for CREATE TABLE */ -class create_field :public Sql_alloc +class Create_field :public Sql_alloc { public: const char *field_name; @@ -1528,8 +1685,11 @@ public: uint8 row,col,sc_length,interval_id; // For rea_create_table uint offset,pack_flag; - create_field() :after(0) {} - create_field(Field *field, Field *orig_field); + Create_field() :after(0) {} + Create_field(Field *field, Field *orig_field); + /* Used to make a clone of this object for ALTER/CREATE TABLE */ + Create_field *clone(MEM_ROOT *mem_root) const + { return new (mem_root) Create_field(*this); } void create_length_to_internal_length(void); /* Init for a tmp table field. To be extended if need be. */ @@ -1568,7 +1728,7 @@ class Send_field { class Copy_field :public Sql_alloc { void (*get_copy_func(Field *to,Field *from))(Copy_field *); public: - char *from_ptr,*to_ptr; + uchar *from_ptr,*to_ptr; uchar *from_null_ptr,*to_null_ptr; my_bool *null_row; uint from_bit,to_bit; @@ -1579,20 +1739,19 @@ public: Copy_field() {} ~Copy_field() {} void set(Field *to,Field *from,bool save); // Field to field - void set(char *to,Field *from); // Field to string + void set(uchar *to,Field *from); // Field to string void (*do_copy)(Copy_field *); void (*do_copy2)(Copy_field *); // Used to handle null values }; -Field *make_field(char *ptr, uint32 field_length, +Field *make_field(TABLE_SHARE *share, uchar *ptr, uint32 field_length, uchar *null_pos, uchar null_bit, uint pack_flag, enum_field_types field_type, CHARSET_INFO *cs, Field::geometry_type geom_type, Field::utype unireg_check, - TYPELIB *interval, const char *field_name, - struct st_table *table); + TYPELIB *interval, const char *field_name); uint pack_length_to_packflag(uint type); enum_field_types get_blob_type_from_length(ulong length); uint32 calc_pack_length(enum_field_types type,uint32 length); |