summaryrefslogtreecommitdiff
path: root/sql/field.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/field.h')
-rw-r--r--sql/field.h513
1 files changed, 329 insertions, 184 deletions
diff --git a/sql/field.h b/sql/field.h
index 5a1ab163266..f4c8c5a9955 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -27,26 +27,62 @@
#define NOT_FIXED_DEC 31
class Send_field;
+class Protocol;
struct st_cache_field;
void field_conv(Field *to,Field *from);
-class Field {
+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 delete(void *ptr_arg, size_t size) {} /*lint -e715 */
+ static void operator delete(void *ptr_arg, size_t size) {
+#ifdef PEDANTIC_SAFEMALLOC
+ bfill(ptr_arg, size, 0x8F);
+#endif
+ }
char *ptr; // Position to field in record
uchar *null_ptr; // Byte where null_bit is
struct st_table *table; // Pointer for table
+ struct st_table *orig_table; // Pointer to original table
const char *table_name,*field_name;
+ LEX_STRING comment;
ulong 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_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
+ NOW() as default and on update value for such fields but unable to hold
+ this info anywhere except unireg_check field. This issue will be resolved
+ in more clean way with transition to new text based .frm format.
+ See also comment for Field_timestamp::Field_timestamp().
+ */
enum utype { NONE,DATE,SHIELD,NOEMPTY,CASEUP,PNR,BGNR,PGNR,YES,NO,REL,
CHECK,EMPTY,UNKNOWN_FIELD,CASEDN,NEXT_NUMBER,INTERVAL_FIELD,
- BIT_FIELD, TIMESTAMP_FIELD,CAPITALIZE,BLOB_FIELD};
+ BIT_FIELD, TIMESTAMP_OLD_FIELD, CAPITALIZE, BLOB_FIELD,
+ TIMESTAMP_DN_FIELD, TIMESTAMP_UN_FIELD, TIMESTAMP_DNUN_FIELD};
+ enum geometry_type
+ {
+ GEOM_GEOMETRY = 0, GEOM_POINT = 1, GEOM_LINESTRING = 2, GEOM_POLYGON = 3,
+ GEOM_MULTIPOINT = 4, GEOM_MULTILINESTRING = 5, GEOM_MULTIPOLYGON = 6,
+ GEOM_GEOMETRYCOLLECTION = 7
+ };
+ enum imagetype { itRAW, itMBR};
+ enum field_cast_enum
+ {
+ FIELD_CAST_STOP, FIELD_CAST_DECIMAL, FIELD_CAST_TINY, FIELD_CAST_SHORT,
+ FIELD_CAST_MEDIUM, FIELD_CAST_LONG, FIELD_CAST_LONGLONG,
+ FIELD_CAST_FLOAT, FIELD_CAST_DOUBLE,
+ FIELD_CAST_NULL,
+ FIELD_CAST_TIMESTAMP, FIELD_CAST_YEAR, FIELD_CAST_DATE, FIELD_CAST_NEWDATE,
+ FIELD_CAST_TIME, FIELD_CAST_DATETIME,
+ FIELD_CAST_STRING, FIELD_CAST_VARSTRING, FIELD_CAST_BLOB,
+ FIELD_CAST_GEOM, FIELD_CAST_ENUM, FIELD_CAST_SET
+ };
+
utype unireg_check;
uint32 field_length; // Length of field
uint16 flags;
@@ -56,12 +92,26 @@ public:
utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg);
virtual ~Field() {}
- virtual void store(const char *to,uint length)=0;
- virtual void store(double nr)=0;
- virtual void store(longlong nr)=0;
+ /* 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(double nr)=0;
+ virtual int store(longlong nr)=0;
virtual void store_time(TIME *ltime,timestamp_type t_type);
virtual double val_real(void)=0;
virtual longlong val_int(void)=0;
+ inline String *val_str(String *str) { return val_str(str, str); }
+ /*
+ val_str(buf1, buf2) gets two buffers and should use them as follows:
+ if it needs a temp buffer to convert result to string - use buf1
+ example Field_tiny::val_str()
+ if the value exists as a string already - use buf2
+ example Field_string::val_str()
+ consequently, buf2 may be created as 'String buf;' - no memory
+ will be allocated for it. buf1 will be allocated to hold a
+ value if it's too small. Using allocated buffer for buf2 may result in
+ an unnecessary free (and later, may be an alloc).
+ This trickery is used to decrease a number of malloc calls.
+ */
virtual String *val_str(String*,String *)=0;
virtual Item_result result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); }
@@ -72,7 +122,7 @@ public:
virtual void reset_fields() {}
virtual void set_default()
{
- my_ptrdiff_t offset = (my_ptrdiff_t) (table->record[2] -
+ my_ptrdiff_t offset = (my_ptrdiff_t) (table->default_values -
table->record[0]);
memcpy(ptr, ptr + offset, pack_length());
if (null_ptr)
@@ -109,6 +159,13 @@ public:
{ return null_ptr ? (null_ptr[row_offset] & null_bit ? 1 : 0) : table->null_row; }
inline bool is_real_null(uint 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])] &
+ null_bit);
+ }
inline void set_null(int row_offset=0)
{ if (null_ptr) null_ptr[row_offset]|= null_bit; }
inline void set_notnull(int row_offset=0)
@@ -119,6 +176,7 @@ public:
virtual void sort_string(char *buff,uint length)=0;
virtual bool optimize_range(uint idx);
virtual bool store_for_compare() { return 0; }
+ virtual void free() {}
Field *new_field(MEM_ROOT *root, struct st_table *new_table)
{
Field *tmp= (Field*) memdup_root(root,(char*) this,size_of());
@@ -126,10 +184,16 @@ public:
{
if (tmp->table->maybe_null)
tmp->flags&= ~NOT_NULL_FLAG;
- tmp->table=new_table;
- tmp->key_start=tmp->part_of_key=tmp->part_of_sortkey=0;
+ tmp->table= new_table;
+ tmp->key_start.init(0);
+ tmp->part_of_key.init(0);
+ tmp->part_of_sortkey.init(0);
tmp->unireg_check=Field::NONE;
- tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG | ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
+ tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
+ ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
+#ifdef PROBABLY_WRONG
+ tmp->table_name= new_table->table_name;
+#endif
tmp->reset_fields();
}
return tmp;
@@ -145,21 +209,15 @@ public:
if (null_ptr)
null_ptr=ADD_TO_PTR(null_ptr,ptr_diff,uchar*);
}
- inline void get_image(char *buff,uint length)
+ inline void get_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(buff,ptr,length); }
- inline void set_image(char *buff,uint length)
+ inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(ptr,buff,length); }
- virtual void get_key_image(char *buff,uint length)
- { get_image(buff,length); }
- virtual void set_key_image(char *buff,uint length)
- { set_image(buff,length); }
- inline int cmp_image(char *buff,uint length)
- {
- if (binary())
- return memcmp(ptr,buff,length);
- else
- return my_casecmp(ptr,buff,length);
- }
+ virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs,
+ imagetype type)
+ { get_image(buff,length,cs); }
+ virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs)
+ { set_image(buff,length,cs); }
inline longlong val_int_offset(uint row_offset)
{
ptr+=row_offset;
@@ -167,7 +225,7 @@ public:
ptr-=row_offset;
return tmp;
}
- bool send(THD *thd, String *packet);
+ virtual bool send_binary(Protocol *protocol);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{
uint32 length=pack_length();
@@ -201,8 +259,14 @@ public:
uint offset(); // Should be inline ...
void copy_from_tmp(int offset);
uint fill_cache_field(struct st_cache_field *copy);
- virtual bool get_date(TIME *ltime,bool fuzzydate);
+ virtual bool get_date(TIME *ltime,uint fuzzydate);
virtual bool get_time(TIME *ltime);
+ virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
+ virtual bool has_charset(void) const { return FALSE; }
+ virtual void set_charset(CHARSET_INFO *charset) { }
+ void set_warning(const unsigned int level, const unsigned int code);
+ virtual field_cast_enum field_cast_type()= 0;
+ bool field_cast_compatible(field_cast_enum type);
friend bool reopen_table(THD *,struct st_table *,bool);
friend int cre_myisam(my_string name, register TABLE *form, uint options,
ulonglong auto_increment_value);
@@ -217,6 +281,7 @@ public:
friend class Item_sum_std;
friend class Item_sum_min;
friend class Item_sum_max;
+ friend class Item_func_group_concat;
};
@@ -250,19 +315,28 @@ public:
class Field_str :public Field {
+protected:
+ CHARSET_INFO *field_charset;
public:
Field_str(char *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)
+ struct st_table *table_arg,CHARSET_INFO *charset)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg)
- {}
+ {
+ field_charset=charset;
+ if (charset->state & MY_CS_BINSORT)
+ flags|=BINARY_FLAG;
+ }
Item_result result_type () const { return STRING_RESULT; }
uint decimals() const { return NOT_FIXED_DEC; }
- friend class create_field;
void make_field(Send_field *);
uint size_of() const { return sizeof(*this); }
+ CHARSET_INFO *charset(void) const { return field_charset; }
+ void set_charset(CHARSET_INFO *charset) { field_charset=charset; }
+ bool binary() const { return field_charset->state & MY_CS_BINSORT ? 1 : 0; }
+ friend class create_field;
};
@@ -279,11 +353,11 @@ public:
{}
enum_field_types type() const { return FIELD_TYPE_DECIMAL;}
enum ha_base_keytype key_type() const
- { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
+ { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
void reset(void);
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -292,6 +366,7 @@ public:
void overflow(bool negative);
bool zero_pack() const { return 0; }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_DECIMAL; }
};
@@ -310,17 +385,19 @@ public:
enum_field_types type() const { return FIELD_TYPE_TINY;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 1; }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_TINY; }
};
@@ -335,21 +412,28 @@ public:
unireg_check_arg, field_name_arg, table_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)
+ {}
enum Item_result result_type () const { return INT_RESULT; }
enum_field_types type() const { return FIELD_TYPE_SHORT;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;}
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 2; }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_SHORT; }
};
@@ -368,17 +452,19 @@ public:
enum_field_types type() const { return FIELD_TYPE_INT24;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_MEDIUM; }
};
@@ -402,17 +488,19 @@ public:
enum_field_types type() const { return FIELD_TYPE_LONG;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_LONG; }
};
@@ -438,18 +526,20 @@ public:
enum_field_types type() const { return FIELD_TYPE_LONGLONG;}
enum ha_base_keytype key_type() const
{ return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 8; }
void sql_type(String &str) const;
bool store_for_compare() { return 1; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_LONGLONG; }
};
#endif
@@ -464,19 +554,26 @@ public:
unireg_check_arg, field_name_arg, table_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_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
+ NONE, field_name_arg, table_arg,dec_arg,0,0)
+ {}
enum_field_types type() const { return FIELD_TYPE_FLOAT;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { bzero(ptr,sizeof(float)); }
double val_real(void);
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);
uint32 pack_length() const { return sizeof(float); }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_FLOAT; }
};
@@ -498,17 +595,19 @@ public:
{}
enum_field_types type() const { return FIELD_TYPE_DOUBLE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { bzero(ptr,sizeof(double)); }
double val_real(void);
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);
uint32 pack_length() const { return sizeof(double); }
void sql_type(String &str) const;
+ field_cast_enum field_cast_type() { return FIELD_CAST_DOUBLE; }
};
@@ -519,14 +618,15 @@ class Field_null :public Field_str {
public:
Field_null(char *ptr_arg, uint32 len_arg,
enum utype unireg_check_arg, const char *field_name_arg,
- struct st_table *table_arg)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, len_arg, null, 1,
- unireg_check_arg, field_name_arg, table_arg)
+ unireg_check_arg, field_name_arg, table_arg, cs)
{}
enum_field_types type() const { return FIELD_TYPE_NULL;}
- void store(const char *to, uint length) { null[0]=1; }
- void store(double nr) { null[0]=1; }
- void store(longlong nr) { null[0]=1; }
+ int store(const char *to, uint length, CHARSET_INFO *cs)
+ { null[0]=1; return 0; }
+ int store(double nr) { null[0]=1; return 0; }
+ int store(longlong nr) { null[0]=1; return 0; }
void reset(void) {}
double val_real(void) { return 0.0;}
longlong val_int(void) { return 0;}
@@ -535,26 +635,29 @@ public:
int cmp(const char *a, const char *b) { return 0;}
void sort_string(char *buff, uint length) {}
uint32 pack_length() const { return 0; }
- void sql_type(String &str) const { str.set("null",4); }
+ void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
+ field_cast_enum field_cast_type() { return FIELD_CAST_NULL; }
};
-class Field_timestamp :public Field_num {
+class Field_timestamp :public Field_str {
public:
Field_timestamp(char *ptr_arg, uint32 len_arg,
enum utype unireg_check_arg, const char *field_name_arg,
- struct st_table *table_arg);
- enum Item_result result_type () const;
+ struct st_table *table_arg,
+ CHARSET_INFO *cs);
enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ enum Item_result cmp_type () const { return INT_RESULT; }
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 4; }
@@ -564,7 +667,8 @@ public:
void set_time();
virtual void set_default()
{
- if (table->timestamp_field == this)
+ if (table->timestamp_field == this &&
+ unireg_check != TIMESTAMP_UN_FIELD)
set_time();
else
Field::set_default();
@@ -579,10 +683,10 @@ public:
longget(tmp,ptr);
return tmp;
}
- void fill_and_store(char *from,uint len);
- bool get_date(TIME *ltime,bool fuzzydate);
+ bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
- void make_field(Send_field *field);
+ field_cast_enum field_cast_type() { return FIELD_CAST_TIMESTAMP; }
+ void set_timestamp_offsets();
};
@@ -596,14 +700,16 @@ public:
unireg_check_arg, field_name_arg, table_arg, 1, 1)
{}
enum_field_types type() const { return FIELD_TYPE_YEAR;}
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
+ bool send_binary(Protocol *protocol);
void sql_type(String &str) const;
bool store_for_compare() { return 1; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_YEAR; }
};
@@ -611,60 +717,64 @@ class Field_date :public Field_str {
public:
Field_date(char *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)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, table_arg)
+ unireg_check_arg, field_name_arg, table_arg, cs)
{}
Field_date(bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_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) {}
+ NONE, field_name_arg, table_arg, cs) {}
enum_field_types type() const { return FIELD_TYPE_DATE;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
enum Item_result cmp_type () const { return INT_RESULT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 4; }
void sql_type(String &str) const;
bool store_for_compare() { return 1; }
bool zero_pack() const { return 1; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_DATE; }
};
class Field_newdate :public Field_str {
public:
Field_newdate(char *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)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, table_arg)
+ unireg_check_arg, field_name_arg, table_arg, cs)
{}
enum_field_types type() const { return FIELD_TYPE_DATE;}
enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void store_time(TIME *ltime,timestamp_type type);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 3; }
void sql_type(String &str) const;
bool store_for_compare() { return 1; }
bool zero_pack() const { return 1; }
- bool get_date(TIME *ltime,bool fuzzydate);
+ bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
+ field_cast_enum field_cast_type() { return FIELD_CAST_NEWDATE; }
};
@@ -672,25 +782,26 @@ class Field_time :public Field_str {
public:
Field_time(char *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)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, 8, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, table_arg)
+ unireg_check_arg, field_name_arg, table_arg, cs)
{}
Field_time(bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_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) {}
+ NONE, field_name_arg, table_arg, cs) {}
enum_field_types type() const { return FIELD_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
bool get_date(TIME *ltime,bool fuzzydate);
+ bool send_binary(Protocol *protocol);
bool get_time(TIME *ltime);
int cmp(const char *,const char*);
void sort_string(char *buff,uint length);
@@ -698,6 +809,7 @@ public:
void sql_type(String &str) const;
bool store_for_compare() { return 1; }
bool zero_pack() const { return 1; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_TIME; }
};
@@ -705,61 +817,52 @@ class Field_datetime :public Field_str {
public:
Field_datetime(char *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)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, 19, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, table_arg)
+ unireg_check_arg, field_name_arg, table_arg, cs)
{}
Field_datetime(bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_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) {}
+ NONE, field_name_arg, table_arg, cs) {}
enum_field_types type() const { return FIELD_TYPE_DATETIME;}
#ifdef HAVE_LONG_LONG
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
#endif
enum Item_result cmp_type () const { return INT_RESULT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void store_time(TIME *ltime,timestamp_type type);
void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; }
double val_real(void);
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);
uint32 pack_length() const { return 8; }
void sql_type(String &str) const;
bool store_for_compare() { return 1; }
bool zero_pack() const { return 1; }
- bool get_date(TIME *ltime,bool fuzzydate);
+ bool get_date(TIME *ltime,uint fuzzydate);
bool get_time(TIME *ltime);
+ field_cast_enum field_cast_type() { return FIELD_CAST_DATETIME; }
};
class Field_string :public Field_str {
- bool binary_flag;
public:
Field_string(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,bool binary_arg)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, table_arg),
- binary_flag(binary_arg)
- {
- if (binary_arg)
- flags|=BINARY_FLAG;
- }
+ unireg_check_arg, field_name_arg, table_arg,cs) {};
Field_string(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg, bool binary_arg)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, table_arg),
- binary_flag(binary_arg)
- {
- if (binary_arg)
- flags|=BINARY_FLAG;
- }
+ NONE, field_name_arg, table_arg, cs) {};
enum_field_types type() const
{
@@ -768,13 +871,12 @@ public:
FIELD_TYPE_VAR_STRING : FIELD_TYPE_STRING);
}
enum ha_base_keytype key_type() const
- { return binary_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
+ { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
bool zero_pack() const { return 0; }
- bool binary() const { return binary_flag; }
- void reset(void) { bfill(ptr,field_length,' '); }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); }
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -789,50 +891,45 @@ public:
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; }
+ bool has_charset(void) const
+ { return charset() == &my_charset_bin ? FALSE : TRUE; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_STRING; }
};
class Field_varstring :public Field_str {
- bool binary_flag;
public:
Field_varstring(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,bool binary_arg)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, table_arg),
- binary_flag(binary_arg)
- {
- if (binary_arg)
- flags|= BINARY_FLAG;
- }
+ unireg_check_arg, field_name_arg, table_arg, cs)
+ {}
Field_varstring(uint32 len_arg,bool maybe_null_arg,
const char *field_name_arg,
- struct st_table *table_arg, bool binary_arg)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, table_arg),
- binary_flag(binary_arg)
- {
- if (binary_arg)
- flags|=BINARY_FLAG;
- }
+ NONE, field_name_arg, table_arg, cs)
+ {}
enum_field_types type() const { return FIELD_TYPE_VAR_STRING; }
enum ha_base_keytype key_type() const
- { return binary_flag ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
+ { return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
bool zero_pack() const { return 0; }
- bool binary() const { return binary_flag; }
void reset(void) { bzero(ptr,field_length+2); }
uint32 pack_length() const { return (uint32) field_length+2; }
uint32 key_length() const { return (uint32) field_length; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
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);
+ void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
+ void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
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);
@@ -842,34 +939,35 @@ public:
uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); }
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
+ bool has_charset(void) const
+ { return charset() == &my_charset_bin ? FALSE : TRUE; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; }
};
class Field_blob :public Field_str {
+protected:
uint packlength;
String value; // For temporaries
- bool binary_flag;
public:
Field_blob(char *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,
- bool binary_arg);
+ CHARSET_INFO *cs);
Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- struct st_table *table_arg, bool binary_arg)
+ struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
- NONE, field_name_arg, table_arg),
- packlength(3),binary_flag(binary_arg)
- {
- flags|= BLOB_FLAG;
- if (binary_arg)
- flags|= BINARY_FLAG;
- }
+ NONE, field_name_arg, table_arg, cs),
+ packlength(4)
+ {
+ flags|= BLOB_FLAG;
+ }
enum_field_types type() const { return FIELD_TYPE_BLOB;}
enum ha_base_keytype key_type() const
- { return binary_flag ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ { return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
@@ -884,13 +982,16 @@ public:
void sort_string(char *buff,uint length);
uint32 pack_length() const
{ return (uint32) (packlength+table->blob_ptr_size); }
+ inline uint32 max_data_length() const
+ {
+ return (uint32) (((ulonglong) 1 << (packlength*8)) -1);
+ }
void reset(void) { bzero(ptr, packlength+sizeof(char*)); }
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);
- bool binary() const { return binary_flag; }
inline void get_ptr(char **str)
{
memcpy_fixed(str,ptr+packlength,sizeof(char*));
@@ -905,13 +1006,13 @@ public:
store_length(length);
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
}
- void get_key_image(char *buff,uint length);
- void set_key_image(char *buff,uint length);
+ void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
+ void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
void sql_type(String &str) const;
inline bool copy()
{ char *tmp;
get_ptr(&tmp);
- if (value.copy(tmp,get_length()))
+ if (value.copy(tmp,get_length(),charset()))
{
Field_blob::reset();
return 1;
@@ -927,12 +1028,44 @@ public:
int pack_cmp(const char *b, uint key_length);
uint packed_col_length(const char *col_ptr, uint length);
uint max_packed_col_length(uint max_length);
- inline void free() { value.free(); }
+ void free() { value.free(); }
inline void clear_temporary() { bzero((char*) &value,sizeof(value)); }
friend void 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; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_BLOB; }
};
+#ifdef HAVE_SPATIAL
+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,
+ enum utype unireg_check_arg, const char *field_name_arg,
+ struct st_table *table_arg,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)
+ { 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)
+ { geom_type= geom_type_arg; }
+ enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
+ enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
+ void sql_type(String &str) const;
+ int store(const char *to, uint length, CHARSET_INFO *charset);
+ int store(double nr) { return 1; }
+ int store(longlong nr) { return 1; }
+
+ void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
+ void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
+ field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; }
+};
+#endif /*HAVE_SPATIAL*/
class Field_enum :public Field_str {
protected:
@@ -943,9 +1076,10 @@ public:
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)
+ 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),
+ unireg_check_arg, field_name_arg, table_arg, charset_arg),
packlength(packlength_arg),typelib(typelib_arg)
{
flags|=ENUM_FLAG;
@@ -953,9 +1087,9 @@ public:
enum_field_types type() const { return FIELD_TYPE_STRING; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
- void store(const char *to,uint length);
- void store(double nr);
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr);
+ int store(longlong nr);
void reset() { bzero(ptr,packlength); }
double val_real(void);
longlong val_int(void);
@@ -969,8 +1103,9 @@ public:
enum_field_types real_type() const { return FIELD_TYPE_ENUM; }
virtual bool zero_pack() const { return 0; }
bool optimize_range(uint idx) { return 0; }
- bool binary() const { return 0; }
bool eq_def(Field *field);
+ bool has_charset(void) const { return TRUE; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_ENUM; }
};
@@ -980,21 +1115,23 @@ public:
uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg,uint32 packlength_arg,
- TYPELIB *typelib_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)
+ typelib_arg,charset_arg)
{
flags=(flags & ~ENUM_FLAG) | SET_FLAG;
}
- void store(const char *to,uint length);
- void store(double nr) { Field_set::store((longlong) nr); }
- void store(longlong nr);
+ int store(const char *to,uint length,CHARSET_INFO *charset);
+ int store(double nr) { return Field_set::store((longlong) nr); }
+ int store(longlong nr);
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; }
+ bool has_charset(void) const { return TRUE; }
+ field_cast_enum field_cast_type() { return FIELD_CAST_SET; }
};
@@ -1007,18 +1144,22 @@ public:
const char *field_name;
const char *change; // If done with alter table
const char *after; // Put column after this one
+ LEX_STRING comment; // Comment for field
Item *def; // Default value
enum enum_field_types sql_type;
uint32 length;
uint decimals,flags,pack_length;
Field::utype unireg_check;
TYPELIB *interval; // Which interval to use
+ CHARSET_INFO *charset;
+ Field::geometry_type geom_type;
Field *field; // For alter table
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);
+ void create_length_to_internal_length(void);
};
@@ -1028,8 +1169,11 @@ public:
class Send_field {
public:
- const char *table_name,*col_name;
- uint length,flags,decimals;
+ const char *db_name;
+ const char *table_name,*org_table_name;
+ const char *col_name,*org_col_name;
+ ulong length;
+ uint charsetnr, flags, decimals;
enum_field_types type;
Send_field() {}
};
@@ -1061,25 +1205,25 @@ public:
Field *make_field(char *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit,
- uint pack_flag,
- enum_field_types field_type,
+ 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);
uint pack_length_to_packflag(uint type);
uint32 calc_pack_length(enum_field_types type,uint32 length);
-bool set_field_to_null(Field *field);
-bool set_field_to_null_with_conversions(Field *field, bool no_conversions);
-uint find_enum(TYPELIB *typelib,const char *x, uint length);
-ulonglong find_set(TYPELIB *typelib,const char *x, uint length);
-bool test_if_int(const char *str,int length);
+int set_field_to_null(Field *field);
+int set_field_to_null_with_conversions(Field *field, bool no_conversions);
+bool test_if_int(const char *str, int length, const char *int_end,
+ CHARSET_INFO *cs);
/*
The following are for the interface with the .frm file
*/
#define FIELDFLAG_DECIMAL 1
-#define FIELDFLAG_BINARY 1 // Shares same flag
+#define FIELDFLAG_BINARY 1 // Shares same flag
#define FIELDFLAG_NUMBER 2
#define FIELDFLAG_ZEROFILL 4
#define FIELDFLAG_PACK 120 // Bits used for packing
@@ -1087,6 +1231,7 @@ bool test_if_int(const char *str,int length);
#define FIELDFLAG_BITFIELD 512 // mangled with dec!
#define FIELDFLAG_BLOB 1024 // mangled with dec!
#define FIELDFLAG_GEOM 2048
+
#define FIELDFLAG_LEFT_FULLSCREEN 8192
#define FIELDFLAG_RIGHT_FULLSCREEN 16384
#define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output
@@ -1109,8 +1254,8 @@ bool test_if_int(const char *str,int length);
#define f_packtype(x) (((x) >> FIELDFLAG_PACK_SHIFT) & 15)
#define f_decimals(x) ((uint8) (((x) >> FIELDFLAG_DEC_SHIFT) & FIELDFLAG_MAX_DEC))
#define f_is_alpha(x) (!f_is_num(x))
-#define f_is_binary(x) ((x) & FIELDFLAG_BINARY)
-#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL)
+#define f_is_binary(x) ((x) & FIELDFLAG_BINARY) // 4.0- compatibility
+#define f_is_enum(x) ((x) & FIELDFLAG_INTERVAL)
#define f_is_bitfield(x) ((x) & FIELDFLAG_BITFIELD)
#define f_is_blob(x) (((x) & (FIELDFLAG_BLOB | FIELDFLAG_NUMBER)) == FIELDFLAG_BLOB)
#define f_is_geom(x) ((x) & FIELDFLAG_GEOM)