summaryrefslogtreecommitdiff
path: root/sql/field.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/field.h')
-rw-r--r--sql/field.h770
1 files changed, 533 insertions, 237 deletions
diff --git a/sql/field.h b/sql/field.h
index 14f14afdaf7..bfdb06984af 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -31,6 +31,7 @@
#include "my_decimal.h" /* my_decimal */
#include "sql_error.h" /* Sql_condition */
#include "compat56.h"
+#include "sql_type.h" /* Type_std_attributes */
class Send_field;
class Copy_field;
@@ -364,24 +365,25 @@ public:
Subst_constraint m_subst_constraint;
/*
Comparison type.
- Impostant only when ANY_SUBSTS.
+ Important only when ANY_SUBSTS.
*/
- Item_result m_compare_type;
+ const Type_handler *m_compare_handler;
/*
Collation of the comparison operation.
Important only when ANY_SUBST.
*/
CHARSET_INFO *m_compare_collation;
public:
- Context(Subst_constraint subst, Item_result type, CHARSET_INFO *cs)
+ Context(Subst_constraint subst, const Type_handler *h, CHARSET_INFO *cs)
:m_subst_constraint(subst),
- m_compare_type(type),
- m_compare_collation(cs) { }
+ m_compare_handler(h),
+ m_compare_collation(cs)
+ { DBUG_ASSERT(h == h->type_handler_for_comparison()); }
Subst_constraint subst_constraint() const { return m_subst_constraint; }
- Item_result compare_type() const
+ const Type_handler *compare_type_handler() const
{
DBUG_ASSERT(m_subst_constraint == ANY_SUBST);
- return m_compare_type;
+ return m_compare_handler;
}
CHARSET_INFO *compare_collation() const
{
@@ -393,35 +395,21 @@ public:
{ // Use this to request only exact value, no invariants.
public:
Context_identity()
- :Context(IDENTITY_SUBST, STRING_RESULT, &my_charset_bin) { }
+ :Context(IDENTITY_SUBST, &type_handler_long_blob, &my_charset_bin) { }
};
class Context_boolean: public Context
{ // Use this when an item is [a part of] a boolean expression
public:
- Context_boolean() :Context(ANY_SUBST, INT_RESULT, &my_charset_bin) { }
+ Context_boolean()
+ :Context(ANY_SUBST, &type_handler_longlong, &my_charset_bin) { }
};
};
-enum Derivation
-{
- DERIVATION_IGNORABLE= 6,
- DERIVATION_NUMERIC= 5,
- DERIVATION_COERCIBLE= 4,
- DERIVATION_SYSCONST= 3,
- DERIVATION_IMPLICIT= 2,
- DERIVATION_NONE= 1,
- DERIVATION_EXPLICIT= 0
-};
-
-
#define STORAGE_TYPE_MASK 7
#define COLUMN_FORMAT_MASK 7
#define COLUMN_FORMAT_SHIFT 3
-#define my_charset_numeric my_charset_latin1
-#define MY_REPERTOIRE_NUMERIC MY_REPERTOIRE_ASCII
-
/* The length of the header part for each virtual column in the .frm file */
#define FRM_VCOL_OLD_HEADER_SIZE(b) (3 + MY_TEST(b))
#define FRM_VCOL_NEW_BASE_SIZE 16
@@ -474,16 +462,6 @@ inline bool is_temporal_type_with_date(enum_field_types type)
/**
- Recognizer for concrete data type (called real_type for some reason),
- returning true if it is one of the TIMESTAMP types.
-*/
-inline bool is_timestamp_type(enum_field_types type)
-{
- return type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_TIMESTAMP2;
-}
-
-
-/**
Convert temporal real types as retuned by field->real_type()
to field type as returned by field->type().
@@ -539,27 +517,6 @@ inline bool is_temporal_type(enum_field_types type)
}
-/**
- Tests if field type is temporal and has time part,
- i.e. represents TIME, DATETIME or TIMESTAMP types in SQL.
-
- @param type Field type, as returned by field->type().
- @retval true If field type is temporal type with time part.
- @retval false If field type is not temporal type with time part.
-*/
-inline bool is_temporal_type_with_time(enum_field_types type)
-{
- switch (type)
- {
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_TIMESTAMP:
- return true;
- default:
- return false;
- }
-}
-
enum enum_vcol_info_type
{
VCOL_GENERATED_VIRTUAL, VCOL_GENERATED_STORED,
@@ -629,7 +586,7 @@ public:
bool stored_in_db;
bool utf8; /* Already in utf8 */
Item *expr;
- LEX_STRING name; /* Name of constraint */
+ LEX_CSTRING name; /* Name of constraint */
uint flags;
Virtual_column_info()
@@ -721,12 +678,12 @@ public:
*/
TABLE *table; // Pointer for table
TABLE *orig_table; // Pointer to original table
- const char * const *table_name;
- const char *field_name;
+ const char * const *table_name; // Pointer to alias in TABLE
+ LEX_CSTRING field_name;
+ LEX_CSTRING comment;
/** reference to the list of options or NULL */
engine_option_value *option_list;
ha_field_option_struct *option_struct; /* structure with parsed options */
- LEX_STRING comment;
/* Field is part of the following keys */
key_map key_start, part_of_key, part_of_key_not_clustered;
@@ -815,8 +772,20 @@ public:
Field(uchar *ptr_arg,uint32 length_arg,uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg);
+ const LEX_CSTRING *field_name_arg);
virtual ~Field() {}
+
+ DTCollation dtcollation() const
+ {
+ return DTCollation(charset(), derivation(), repertoire());
+ }
+ Type_std_attributes type_std_attributes() const
+ {
+ return Type_std_attributes(field_length, decimals(),
+ MY_TEST(flags & UNSIGNED_FLAG),
+ dtcollation());
+ }
+
/**
Convenience definition of a copy function returned by
Field::get_copy_func()
@@ -847,6 +816,8 @@ public:
enum_check_fields check_level);
int store(const LEX_STRING *ls, CHARSET_INFO *cs)
{ return store(ls->str, ls->length, cs); }
+ int store(const LEX_CSTRING *ls, CHARSET_INFO *cs)
+ { return store(ls->str, ls->length, cs); }
virtual double val_real(void)=0;
virtual longlong val_int(void)=0;
virtual bool val_bool(void)= 0;
@@ -872,11 +843,15 @@ public:
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(); }
- static bool type_can_have_key_part(enum_field_types);
+ Item_result result_type () const
+ {
+ return type_handler()->result_type();
+ }
+ Item_result cmp_type () const
+ {
+ return type_handler()->cmp_type();
+ }
static enum_field_types field_type_merge(enum_field_types, enum_field_types);
- static Item_result result_merge_type(enum_field_types);
virtual bool eq(Field *field)
{
return (ptr == field->ptr && null_ptr == field->null_ptr &&
@@ -989,8 +964,15 @@ public:
virtual bool zero_pack() const { return 1; }
virtual enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
virtual uint32 key_length() const { return pack_length(); }
- virtual enum_field_types type() const =0;
- virtual enum_field_types real_type() const { return type(); }
+ virtual const Type_handler *type_handler() const= 0;
+ virtual enum_field_types type() const
+ {
+ return type_handler()->field_type();
+ }
+ virtual enum_field_types real_type() const
+ {
+ return type_handler()->real_field_type();
+ }
virtual enum_field_types binlog_type() const
{
/*
@@ -1307,6 +1289,7 @@ public:
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool get_time(MYSQL_TIME *ltime) { return get_date(ltime, TIME_TIME_ONLY); }
+ virtual TYPELIB *get_typelib() const { return NULL; }
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
virtual CHARSET_INFO *charset_for_protocol(void) const
{ return binary() ? &my_charset_bin : charset(); }
@@ -1315,9 +1298,6 @@ public:
virtual enum Derivation derivation(void) const
{ return DERIVATION_IMPLICIT; }
virtual uint repertoire(void) const { return MY_REPERTOIRE_UNICODE30; }
- virtual void set_derivation(enum Derivation derivation_arg,
- uint repertoire_arg)
- { }
virtual int set_time() { return 1; }
bool set_warning(Sql_condition::enum_warning_level, unsigned int code,
int cuted_increment) const;
@@ -1330,7 +1310,7 @@ protected:
{
return set_warning(Sql_condition::WARN_LEVEL_NOTE, code, cuted_increment);
}
- void set_datetime_warning(Sql_condition::enum_warning_level, uint code,
+ void set_datetime_warning(Sql_condition::enum_warning_level, uint code,
const ErrConv *str, timestamp_type ts_type,
int cuted_increment) const;
void set_datetime_warning(uint code,
@@ -1546,7 +1526,7 @@ protected:
return to + size;
}
- const uchar *unpack_int(uchar* to, const uchar *from,
+ const uchar *unpack_int(uchar* to, const uchar *from,
const uchar *from_end, size_t size)
{
if (from + size > from_end)
@@ -1605,9 +1585,8 @@ public:
bool zerofill,unsigned_flag; // Purify cannot handle bit fields
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,
+ const LEX_CSTRING *field_name_arg,
uint8 dec_arg, bool zero_arg, bool unsigned_arg);
- enum Item_result result_type () const { return INT_RESULT; }
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
uint repertoire(void) const { return MY_REPERTOIRE_NUMERIC; }
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
@@ -1669,8 +1648,8 @@ public:
const Item_equal *item_equal);
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, CHARSET_INFO *charset);
- Item_result result_type () const { return STRING_RESULT; }
+ const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation);
uint decimals() const { return NOT_FIXED_DEC; }
int save_in_field(Field *to) { return save_in_field_str(to); }
bool memcpy_field_possible(const Field *from) const
@@ -1690,12 +1669,6 @@ public:
uint repertoire(void) const { return field_repertoire; }
CHARSET_INFO *charset(void) const { return field_charset; }
enum Derivation derivation(void) const { return field_derivation; }
- void set_derivation(enum Derivation derivation_arg,
- uint repertoire_arg)
- {
- field_derivation= derivation_arg;
- field_repertoire= repertoire_arg;
- }
bool binary() const { return field_charset == &my_charset_bin; }
uint32 max_display_length() { return field_length; }
friend class Create_field;
@@ -1737,9 +1710,10 @@ protected:
public:
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, CHARSET_INFO *charset_arg)
+ const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
- field_name_arg, charset_arg)
+ field_name_arg, collation)
{}
int store_decimal(const my_decimal *d);
@@ -1772,13 +1746,12 @@ public:
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,
+ const LEX_CSTRING *field_name_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, dec_arg, zero_arg, unsigned_arg),
not_fixed(dec_arg >= FLOATING_POINT_DECIMALS)
{}
- Item_result result_type () const { return REAL_RESULT; }
Copy_func *get_copy_func(const Field *from) const
{
return do_field_real;
@@ -1809,13 +1782,13 @@ class Field_decimal :public Field_real {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
dec_arg, zero_arg, unsigned_arg)
{}
- enum_field_types type() const { return MYSQL_TYPE_DECIMAL;}
+ const Type_handler *type_handler() const { return &type_handler_olddecimal; }
enum ha_base_keytype key_type() const
{ return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; }
Copy_func *get_copy_func(const Field *from) const
@@ -1857,14 +1830,11 @@ public:
*/
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,
+ enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_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, uint8 dec_arg,
- bool unsigned_arg);
- enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;}
+ const Type_handler *type_handler() const { return &type_handler_newdecimal; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; }
- Item_result result_type () const { return DECIMAL_RESULT; }
Copy_func *get_copy_func(const Field *from) const
{
// if (from->real_type() == MYSQL_TYPE_BIT) // QQ: why?
@@ -1914,7 +1884,6 @@ public:
uint16 mflags, int *order_var);
uint is_equal(Create_field *new_field);
virtual const uchar *unpack(uchar* to, const uchar *from, const uchar *from_end, uint param_data);
- static Field *create_from_item(MEM_ROOT *root, Item *);
Item *get_equal_const_item(THD *thd, const Context &ctx, Item *const_item);
};
@@ -1923,13 +1892,13 @@ class Field_tiny :public Field_num {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
0, zero_arg,unsigned_arg)
{}
- enum_field_types type() const { return MYSQL_TYPE_TINY;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -1967,18 +1936,19 @@ class Field_short :public Field_num {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
0, zero_arg,unsigned_arg)
{}
- Field_short(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
+ Field_short(uint32 len_arg,bool maybe_null_arg,
+ const LEX_CSTRING *field_name_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_field_types type() const { return MYSQL_TYPE_SHORT;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -2007,13 +1977,13 @@ class Field_medium :public Field_num {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
0, zero_arg,unsigned_arg)
{}
- enum_field_types type() const { return MYSQL_TYPE_INT24;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -2041,18 +2011,19 @@ class Field_long :public Field_num {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
0, zero_arg,unsigned_arg)
{}
- Field_long(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
+ Field_long(uint32 len_arg,bool maybe_null_arg,
+ const LEX_CSTRING *field_name_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_field_types type() const { return MYSQL_TYPE_LONG;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -2086,19 +2057,19 @@ class Field_longlong :public Field_num {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
0, zero_arg,unsigned_arg)
{}
Field_longlong(uint32 len_arg,bool maybe_null_arg,
- const char *field_name_arg,
- bool unsigned_arg)
+ const LEX_CSTRING *field_name_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_field_types type() const { return MYSQL_TYPE_LONGLONG;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -2135,7 +2106,7 @@ class Field_float :public Field_real {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
@@ -2144,15 +2115,15 @@ public:
if (dec_arg >= FLOATING_POINT_DECIMALS)
dec_arg= NOT_FIXED_DEC;
}
- Field_float(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
- uint8 dec_arg)
+ Field_float(uint32 len_arg, bool maybe_null_arg,
+ const LEX_CSTRING *field_name_arg, uint8 dec_arg)
:Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0,
NONE, field_name_arg, dec_arg, 0, 0)
{
if (dec_arg >= FLOATING_POINT_DECIMALS)
dec_arg= NOT_FIXED_DEC;
}
- enum_field_types type() const { return MYSQL_TYPE_FLOAT;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -2176,7 +2147,7 @@ class Field_double :public Field_real {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_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,
@@ -2185,15 +2156,16 @@ public:
if (dec_arg >= FLOATING_POINT_DECIMALS)
dec_arg= NOT_FIXED_DEC;
}
- Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
- uint8 dec_arg)
+ Field_double(uint32 len_arg, bool maybe_null_arg,
+ const LEX_CSTRING *field_name_arg, uint8 dec_arg)
:Field_real((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "" : 0, (uint) 0,
NONE, field_name_arg, dec_arg, 0, 0)
{
if (dec_arg >= FLOATING_POINT_DECIMALS)
dec_arg= NOT_FIXED_DEC;
}
- Field_double(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg,
+ Field_double(uint32 len_arg, bool maybe_null_arg,
+ const LEX_CSTRING *field_name_arg,
uint8 dec_arg, 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)
@@ -2202,7 +2174,7 @@ public:
if (dec_arg >= FLOATING_POINT_DECIMALS)
dec_arg= NOT_FIXED_DEC;
}
- enum_field_types type() const { return MYSQL_TYPE_DOUBLE;}
+ const Type_handler *type_handler() const { return &type_handler_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);
@@ -2234,12 +2206,12 @@ class Field_null :public Field_str {
static uchar null[1];
public:
Field_null(uchar *ptr_arg, uint32 len_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation)
:Field_str(ptr_arg, len_arg, null, 1,
- unireg_check_arg, field_name_arg, cs)
+ unireg_check_arg, field_name_arg, collation)
{}
- enum_field_types type() const { return MYSQL_TYPE_NULL;}
+ const Type_handler *type_handler() const { return &type_handler_null; }
Copy_func *get_copy_func(const Field *from) const
{
return do_field_string;
@@ -2285,11 +2257,10 @@ protected:
public:
Field_temporal(uchar *ptr_arg,uint32 len_arg, uchar *null_ptr_arg,
uchar null_bit_arg, utype unireg_check_arg,
- const char *field_name_arg)
+ const LEX_CSTRING *field_name_arg)
:Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg)
{ flags|= BINARY_FLAG; }
- Item_result result_type () const { return STRING_RESULT; }
int store_hex_hybrid(const char *str, uint length)
{
return store(str, length, &my_charset_bin);
@@ -2310,7 +2281,6 @@ public:
CHARSET_INFO *charset(void) const { return &my_charset_numeric; }
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
bool binary() const { return true; }
- enum Item_result cmp_type () const { return TIME_RESULT; }
bool val_bool() { return val_real() != 0e0; }
uint is_equal(Create_field *new_field);
bool eq_def(const Field *field) const
@@ -2364,7 +2334,7 @@ public:
Field_temporal_with_date(uchar *ptr_arg, uint32 len_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
utype unireg_check_arg,
- const char *field_name_arg)
+ const LEX_CSTRING *field_name_arg)
:Field_temporal(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg)
{}
@@ -2384,9 +2354,10 @@ protected:
public:
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,
+ enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share);
- enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
+ const Type_handler *type_handler() const { return &type_handler_timestamp; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr);
@@ -2453,7 +2424,7 @@ public:
Field_timestamp_with_dec(uchar *ptr_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg,
- const char *field_name_arg,
+ const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share, uint dec_arg) :
Field_timestamp(ptr_arg,
MAX_DATETIME_WIDTH + dec_arg + MY_TEST(dec_arg), null_ptr_arg,
@@ -2483,11 +2454,15 @@ public:
class Field_timestamp_hires :public Field_timestamp_with_dec {
+ uint sec_part_bytes(uint dec) const
+ {
+ return Type_handler_timestamp::sec_part_bytes(dec);
+ }
public:
Field_timestamp_hires(uchar *ptr_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg,
- const char *field_name_arg,
+ const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share, uint dec_arg) :
Field_timestamp_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, share, dec_arg)
@@ -2497,7 +2472,7 @@ public:
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
void store_TIME(my_time_t timestamp, ulong sec_part);
int cmp(const uchar *,const uchar *);
- uint32 pack_length() const;
+ uint32 pack_length() const { return 4 + sec_part_bytes(dec); }
uint size_of() const { return sizeof(*this); }
};
@@ -2515,12 +2490,12 @@ public:
Field_timestampf(uchar *ptr_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
enum utype unireg_check_arg,
- const char *field_name_arg,
+ const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share, uint dec_arg) :
Field_timestamp_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, share, dec_arg)
{}
- enum_field_types real_type() const { return MYSQL_TYPE_TIMESTAMP2; }
+ const Type_handler *type_handler() const { return &type_handler_timestamp2; }
enum_field_types binlog_type() const { return MYSQL_TYPE_TIMESTAMP2; }
uint32 pack_length() const
{
@@ -2547,18 +2522,23 @@ class Field_year :public Field_tiny {
public:
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)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg)
:Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, 1, 1)
{}
- enum_field_types type() const { return MYSQL_TYPE_YEAR;}
+ const Type_handler *type_handler() const { return &type_handler_year; }
Copy_func *get_copy_func(const Field *from) const
{
if (eq_def(from))
return get_identical_copy_func();
switch (from->cmp_type()) {
case STRING_RESULT:
+ {
+ const Type_handler *handler= from->type_handler();
+ if (handler == &type_handler_enum || handler == &type_handler_set)
+ return do_field_int;
return do_field_string;
+ }
case TIME_RESULT:
return do_field_temporal;
case DECIMAL_RESULT:
@@ -2593,10 +2573,10 @@ class Field_date :public Field_temporal_with_date {
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
public:
Field_date(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg)
:Field_temporal_with_date(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg) {}
- enum_field_types type() const { return MYSQL_TYPE_DATE;}
+ const Type_handler *type_handler() const { return &type_handler_date; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
@@ -2628,12 +2608,11 @@ class Field_newdate :public Field_temporal_with_date {
bool get_TIME(MYSQL_TIME *ltime, const uchar *pos, ulonglong fuzzydate) const;
public:
Field_newdate(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg)
:Field_temporal_with_date(ptr_arg, MAX_DATE_WIDTH, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg)
{}
- enum_field_types type() const { return MYSQL_TYPE_DATE;}
- enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; }
+ const Type_handler *type_handler() const { return &type_handler_newdate; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; }
double val_real(void);
@@ -2667,11 +2646,13 @@ protected:
public:
Field_time(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg,
- const char *field_name_arg)
+ const LEX_CSTRING *field_name_arg)
:Field_temporal(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg), curdays(0)
{}
- enum_field_types type() const { return MYSQL_TYPE_TIME;}
+ bool can_be_substituted_to_equal_item(const Context &ctx,
+ const Item_equal *item_equal);
+ const Type_handler *type_handler() const { return &type_handler_time; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
Copy_func *get_copy_func(const Field *from) const
{
@@ -2719,7 +2700,8 @@ protected:
uint dec;
public:
Field_time_with_dec(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
+ enum utype unireg_check_arg,
+ const LEX_CSTRING *field_name_arg,
uint dec_arg)
:Field_time(ptr_arg, MIN_TIME_WIDTH + dec_arg + MY_TEST(dec_arg),
null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg),
@@ -2743,7 +2725,7 @@ class Field_time_hires :public Field_time_with_dec {
void store_TIME(MYSQL_TIME *ltime);
public:
Field_time_hires(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
uint dec_arg)
:Field_time_with_dec(ptr_arg, null_ptr_arg,
null_bit_arg, unireg_check_arg, field_name_arg,
@@ -2757,7 +2739,7 @@ public:
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
- uint32 pack_length() const;
+ uint32 pack_length() const { return Type_handler_time::hires_bytes(dec); }
uint size_of() const { return sizeof(*this); }
};
@@ -2774,7 +2756,7 @@ class Field_timef :public Field_time_with_dec {
}
public:
Field_timef(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
uint dec_arg)
:Field_time_with_dec(ptr_arg, null_ptr_arg,
null_bit_arg, unireg_check_arg, field_name_arg,
@@ -2782,7 +2764,7 @@ public:
{
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
}
- enum_field_types real_type() const { return MYSQL_TYPE_TIME2; }
+ const Type_handler *type_handler() const { return &type_handler_time2; }
enum_field_types binlog_type() const { return MYSQL_TYPE_TIME2; }
uint32 pack_length() const
{
@@ -2816,7 +2798,7 @@ class Field_datetime :public Field_temporal_with_date {
public:
Field_datetime(uchar *ptr_arg, uint length_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg,
- const char *field_name_arg)
+ const LEX_CSTRING *field_name_arg)
:Field_temporal_with_date(ptr_arg, length_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg)
{
@@ -2824,7 +2806,7 @@ public:
unireg_check == TIMESTAMP_DNUN_FIELD)
flags|= ON_UPDATE_NOW_FLAG;
}
- enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
+ const Type_handler *type_handler() const { return &type_handler_datetime; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
double val_real(void);
longlong val_int(void);
@@ -2873,7 +2855,7 @@ protected:
public:
Field_datetime_with_dec(uchar *ptr_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg,
- const char *field_name_arg, uint dec_arg)
+ const LEX_CSTRING *field_name_arg, uint dec_arg)
:Field_datetime(ptr_arg, MAX_DATETIME_WIDTH + dec_arg + MY_TEST(dec_arg),
null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg), dec(dec_arg)
@@ -2909,14 +2891,14 @@ class Field_datetime_hires :public Field_datetime_with_dec {
public:
Field_datetime_hires(uchar *ptr_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg,
- const char *field_name_arg, uint dec_arg)
+ const LEX_CSTRING *field_name_arg, uint dec_arg)
:Field_datetime_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, dec_arg)
{
DBUG_ASSERT(dec);
}
int cmp(const uchar *,const uchar *);
- uint32 pack_length() const;
+ uint32 pack_length() const { return Type_handler_datetime::hires_bytes(dec); }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{ return Field_datetime_hires::get_TIME(ltime, ptr, fuzzydate); }
uint size_of() const { return sizeof(*this); }
@@ -2937,11 +2919,11 @@ class Field_datetimef :public Field_datetime_with_dec {
public:
Field_datetimef(uchar *ptr_arg, uchar *null_ptr_arg,
uchar null_bit_arg, enum utype unireg_check_arg,
- const char *field_name_arg, uint dec_arg)
+ const LEX_CSTRING *field_name_arg, uint dec_arg)
:Field_datetime_with_dec(ptr_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, dec_arg)
{}
- enum_field_types real_type() const { return MYSQL_TYPE_DATETIME2; }
+ const Type_handler *type_handler() const { return &type_handler_datetime2; }
enum_field_types binlog_type() const { return MYSQL_TYPE_DATETIME2; }
uint32 pack_length() const
{
@@ -2967,7 +2949,8 @@ public:
static inline Field_timestamp *
new_Field_timestamp(MEM_ROOT *root,uchar *ptr, uchar *null_ptr, uchar null_bit,
- enum Field::utype unireg_check, const char *field_name,
+ enum Field::utype unireg_check,
+ const LEX_CSTRING *field_name,
TABLE_SHARE *share, uint dec)
{
if (dec==0)
@@ -2983,7 +2966,7 @@ new_Field_timestamp(MEM_ROOT *root,uchar *ptr, uchar *null_ptr, uchar null_bit,
static inline Field_time *
new_Field_time(MEM_ROOT *root, uchar *ptr, uchar *null_ptr, uchar null_bit,
- enum Field::utype unireg_check, const char *field_name,
+ enum Field::utype unireg_check, const LEX_CSTRING *field_name,
uint dec)
{
if (dec == 0)
@@ -2999,7 +2982,7 @@ new_Field_time(MEM_ROOT *root, uchar *ptr, uchar *null_ptr, uchar null_bit,
static inline Field_datetime *
new_Field_datetime(MEM_ROOT *root, uchar *ptr, uchar *null_ptr, uchar null_bit,
enum Field::utype unireg_check,
- const char *field_name, uint dec)
+ const LEX_CSTRING *field_name, uint dec)
{
if (dec == 0)
return new (root)
@@ -3018,28 +3001,35 @@ class Field_string :public Field_longstr {
public:
Warn_filter_string(const THD *thd, const Field_string *field);
};
+ bool is_var_string() const
+ {
+ return can_alter_field_type &&
+ orig_table &&
+ (orig_table->s->db_create_options & HA_OPTION_PACK_RECORD) &&
+ field_length >= 4 &&
+ orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR;
+ }
public:
bool can_alter_field_type;
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,
- CHARSET_INFO *cs)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation)
:Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs),
+ unireg_check_arg, field_name_arg, collation),
can_alter_field_type(1) {};
- Field_string(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
+ Field_string(uint32 len_arg,bool maybe_null_arg,
+ const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation)
:Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs),
+ NONE, field_name_arg, collation),
can_alter_field_type(1) {};
- enum_field_types type() const
+ const Type_handler *type_handler() const
{
- return ((can_alter_field_type && orig_table &&
- orig_table->s->db_create_options & HA_OPTION_PACK_RECORD &&
- field_length >= 4) &&
- orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR ?
- MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING);
+ if (is_var_string())
+ return &type_handler_var_string;
+ return &type_handler_string;
}
enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
@@ -3081,7 +3071,6 @@ public:
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 MYSQL_TYPE_STRING; }
bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
@@ -3111,25 +3100,25 @@ public:
Field_varstring(uchar *ptr_arg,
uint32 len_arg, uint length_bytes_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- TABLE_SHARE *share, CHARSET_INFO *cs)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
+ TABLE_SHARE *share, const DTCollation &collation)
:Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, cs),
+ unireg_check_arg, field_name_arg, collation),
length_bytes(length_bytes_arg)
{
share->varchar_fields++;
}
Field_varstring(uint32 len_arg,bool maybe_null_arg,
- const char *field_name_arg,
- TABLE_SHARE *share, CHARSET_INFO *cs)
+ const LEX_CSTRING *field_name_arg,
+ TABLE_SHARE *share, const DTCollation &collation)
:Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs),
+ NONE, field_name_arg, collation),
length_bytes(len_arg < 256 ? 1 :2)
{
share->varchar_fields++;
}
- enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
+ const Type_handler *type_handler() const { return &type_handler_varchar; }
enum ha_base_keytype key_type() const;
uint row_pack_length() const { return field_length; }
bool zero_pack() const { return 0; }
@@ -3173,7 +3162,6 @@ public:
uint max_packed_col_length(uint max_length);
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 *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
@@ -3188,6 +3176,8 @@ private:
};
+extern LEX_CSTRING temp_lex_str;
+
class Field_blob :public Field_longstr {
protected:
/**
@@ -3210,20 +3200,22 @@ protected:
static void do_conv_blob(Copy_field *copy);
public:
Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
- TABLE_SHARE *share, uint blob_pack_length, CHARSET_INFO *cs);
- Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs)
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
+ TABLE_SHARE *share, uint blob_pack_length,
+ const DTCollation &collation);
+ Field_blob(uint32 len_arg,bool maybe_null_arg, const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation)
:Field_longstr((uchar*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs),
+ NONE, field_name_arg, collation),
packlength(4)
{
flags|= BLOB_FLAG;
}
- Field_blob(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- CHARSET_INFO *cs, bool set_packlength)
+ Field_blob(uint32 len_arg,bool maybe_null_arg,
+ const LEX_CSTRING *field_name_arg,
+ const DTCollation &collation, bool set_packlength)
:Field_longstr((uchar*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0, 0,
- NONE, field_name_arg, cs)
+ NONE, field_name_arg, collation)
{
flags|= BLOB_FLAG;
packlength= 4;
@@ -3235,10 +3227,27 @@ public:
}
}
Field_blob(uint32 packlength_arg)
- :Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, "temp", system_charset_info),
+ :Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, &temp_lex_str,
+ system_charset_info),
packlength(packlength_arg) {}
+ const Type_handler *type_handler() const;
/* Note that the default copy constructor is used, in clone() */
- enum_field_types type() const { return MYSQL_TYPE_BLOB;}
+ enum_field_types type() const
+ {
+ /*
+ We cannot return type_handler()->field_type() here.
+ Some pieces of the code (e.g. in engines) rely on the fact
+ that Field::type(), Field::real_type() and Item_field::field_type()
+ return MYSQL_TYPE_BLOB for all blob variants.
+ We should eventually fix all such code pieces to expect
+ all BLOB type codes.
+ */
+ return MYSQL_TYPE_BLOB;
+ }
+ enum_field_types real_type() const
+ {
+ return MYSQL_TYPE_BLOB;
+ }
enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
Copy_func *get_copy_func(const Field *from) const
@@ -3417,18 +3426,25 @@ public:
enum storage_type storage;
Field_geom(uchar *ptr_arg, uchar *null_ptr_arg, uint null_bit_arg,
- enum utype unireg_check_arg, const char *field_name_arg,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
TABLE_SHARE *share, uint blob_pack_length,
enum geometry_type geom_type_arg, uint field_srid)
- :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
+ :Field_blob(ptr_arg, null_ptr_arg, null_bit_arg, unireg_check_arg,
field_name_arg, share, blob_pack_length, &my_charset_bin)
{ geom_type= geom_type_arg; srid= field_srid; }
- Field_geom(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg,
- 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; srid= 0; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
- enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
+ const Type_handler *type_handler() const
+ {
+ return &type_handler_geometry;
+ }
+ enum_field_types type() const
+ {
+ return MYSQL_TYPE_GEOMETRY;
+ }
+ enum_field_types real_type() const
+ {
+ return MYSQL_TYPE_GEOMETRY;
+ }
bool can_optimize_range(const Item_bool_func *cond,
const Item *item,
bool is_eq_func) const;
@@ -3474,19 +3490,18 @@ public:
TYPELIB *typelib;
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
uint packlength_arg,
TYPELIB *typelib_arg,
- CHARSET_INFO *charset_arg)
+ const DTCollation &collation)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
- unireg_check_arg, field_name_arg, charset_arg),
+ unireg_check_arg, field_name_arg, collation),
packlength(packlength_arg),typelib(typelib_arg)
{
flags|=ENUM_FLAG;
}
Field *make_new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
- enum_field_types type() const { return MYSQL_TYPE_STRING; }
- enum Item_result cmp_type () const { return INT_RESULT; }
+ const Type_handler *type_handler() const { return &type_handler_enum; }
enum ha_base_keytype key_type() const;
Copy_func *get_copy_func(const Field *from) const
{
@@ -3527,7 +3542,6 @@ public:
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 MYSQL_TYPE_ENUM; }
uint pack_length_from_metadata(uint field_metadata)
{ return (field_metadata & 0x00ff); }
uint row_pack_length() const { return pack_length(); }
@@ -3538,6 +3552,7 @@ public:
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
uint decimals() const { return 0; }
+ TYPELIB *get_typelib() const { return typelib; }
virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
virtual const uchar *unpack(uchar *to, const uchar *from,
@@ -3557,6 +3572,9 @@ public:
*/
return false;
}
+ bool can_optimize_range(const Item_bool_func *cond,
+ const Item *item,
+ bool is_eq_func) const;
private:
int do_save_field_metadata(uchar *first_byte);
uint is_equal(Create_field *new_field);
@@ -3567,14 +3585,14 @@ class Field_set :public Field_enum {
public:
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,
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg,
uint32 packlength_arg,
- TYPELIB *typelib_arg, CHARSET_INFO *charset_arg)
+ TYPELIB *typelib_arg, const DTCollation &collation)
:Field_enum(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg,
packlength_arg,
- typelib_arg,charset_arg),
- empty_set_string("", 0, charset_arg)
+ typelib_arg, collation),
+ empty_set_string("", 0, collation.collation)
{
flags=(flags & ~ENUM_FLAG) | SET_FLAG;
}
@@ -3587,7 +3605,7 @@ public:
String *val_str(String*,String *);
void sql_type(String &str) const;
uint size_of() const { return sizeof(*this); }
- enum_field_types real_type() const { return MYSQL_TYPE_SET; }
+ const Type_handler *type_handler() const { return &type_handler_set; }
bool has_charset(void) const { return TRUE; }
private:
const String empty_set_string;
@@ -3616,14 +3634,13 @@ public:
uint bytes_in_rec;
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);
- enum_field_types type() const { return MYSQL_TYPE_BIT; }
+ enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg);
+ const Type_handler *type_handler() const { return &type_handler_bit; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
uint32 key_length() const { return (uint32) (field_length + 7) / 8; }
uint32 max_data_length() const { return (field_length + 7) / 8; }
uint32 max_display_length() { return field_length; }
uint size_of() const { return sizeof(*this); }
- Item_result result_type () const { return INT_RESULT; }
int reset(void) {
bzero(ptr, bytes_in_rec);
if (bit_ptr && (bit_len > 0)) // reset odd bits among null bits
@@ -3752,7 +3769,7 @@ class Field_bit_as_char: public Field_bit {
public:
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);
+ enum utype unireg_check_arg, const LEX_CSTRING *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);
@@ -3763,28 +3780,68 @@ public:
};
-extern const LEX_STRING null_lex_str;
-
+extern const LEX_CSTRING null_clex_str;
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
uchar *ptr, uint32 field_length,
uchar *null_pos, uchar null_bit,
- uint pack_flag, enum_field_types field_type,
+ uint pack_flag, const Type_handler *handler,
CHARSET_INFO *cs,
Field::geometry_type geom_type, uint srid,
Field::utype unireg_check,
- TYPELIB *interval, const char *field_name);
+ TYPELIB *interval, const LEX_CSTRING *field_name);
/*
Create field class for CREATE TABLE
*/
-class Column_definition: public Sql_alloc
+class Column_definition: public Sql_alloc,
+ public Type_handler_hybrid_field_type
{
+ /**
+ Create "interval" from "interval_list".
+ @param mem_root - memory root to create the TYPELIB
+ instance and its values on
+ @param reuse_interval_list_values - determines if TYPELIB can reuse strings
+ from interval_list, or should always
+ allocate a copy on mem_root, even if
+ character set conversion is not needed
+ @retval false on success
+ @retval true on error (bad values, or EOM)
+ */
+ bool create_interval_from_interval_list(MEM_ROOT *mem_root,
+ bool reuse_interval_list_values);
+
+ /*
+ Calculate TYPELIB (set or enum) max and total lengths
+
+ @param cs charset+collation pair of the interval
+ @param max_length length of the longest item
+ @param tot_length sum of the item lengths
+
+ After this method call:
+ - ENUM uses max_length
+ - SET uses tot_length.
+ */
+ void calculate_interval_lengths(uint32 *max_length, uint32 *tot_length)
+ {
+ const char **pos;
+ uint *len;
+ *max_length= *tot_length= 0;
+ for (pos= interval->type_names, len= interval->type_lengths;
+ *pos ; pos++, len++)
+ {
+ size_t length= charset->cset->numchars(charset, *pos, *pos + *len);
+ *tot_length+= length;
+ set_if_bigger(*max_length, (uint32)length);
+ }
+ }
+ bool prepare_stage1_check_typelib_default();
+ bool prepare_stage1_convert_default(THD *, MEM_ROOT *, CHARSET_INFO *to);
+ const Type_handler *field_type() const; // Prevent using this
public:
- const char *field_name;
- LEX_STRING comment; // Comment for field
+ LEX_CSTRING field_name;
+ LEX_CSTRING comment; // Comment for field
Item *on_update; // ON UPDATE NOW()
- enum enum_field_types sql_type;
/*
At various stages in execution this can be length of field in bytes or
max number of characters.
@@ -3816,19 +3873,111 @@ public:
*default_value, // Default value
*check_constraint; // Check constraint
- Column_definition():
- comment(null_lex_str),
- on_update(0), sql_type(MYSQL_TYPE_NULL),
+ Column_definition()
+ :Type_handler_hybrid_field_type(&type_handler_null),
+ comment(null_clex_str),
+ on_update(NULL), length(0), decimals(0),
flags(0), pack_length(0), key_length(0), unireg_check(Field::NONE),
- interval(0), srid(0), geom_type(Field::GEOM_GEOMETRY),
- option_list(NULL),
+ interval(0), charset(&my_charset_bin),
+ srid(0), geom_type(Field::GEOM_GEOMETRY),
+ option_list(NULL), pack_flag(0),
vcol_info(0), default_value(0), check_constraint(0)
{
interval_list.empty();
}
-
Column_definition(THD *thd, Field *field, Field *orig_field);
- void create_length_to_internal_length(void);
+ void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs);
+ void create_length_to_internal_length_null()
+ {
+ DBUG_ASSERT(length == 0);
+ key_length= pack_length= 0;
+ }
+ void create_length_to_internal_length_simple()
+ {
+ key_length= pack_length= type_handler()->calc_pack_length(length);
+ }
+ void create_length_to_internal_length_string()
+ {
+ length*= charset->mbmaxlen;
+ key_length= length;
+ pack_length= type_handler()->calc_pack_length(length);
+ }
+ void create_length_to_internal_length_typelib()
+ {
+ /* Pack_length already calculated in sql_parse.cc */
+ length*= charset->mbmaxlen;
+ key_length= pack_length;
+ }
+ void create_length_to_internal_length_bit();
+ void create_length_to_internal_length_newdecimal();
+
+ /**
+ Prepare a SET/ENUM field.
+ Create "interval" from "interval_list" if needed, and adjust "length".
+ @param mem_root - Memory root to allocate TYPELIB and
+ its values on
+ @param reuse_interval_list_values - determines if TYPELIB can reuse value
+ buffers from interval_list, or should
+ always allocate a copy on mem_root,
+ even if character set conversion
+ is not needed
+ */
+ bool prepare_interval_field(MEM_ROOT *mem_root,
+ bool reuse_interval_list_values);
+
+ void prepare_interval_field_calc_length()
+ {
+ uint32 field_length, dummy;
+ if (real_field_type() == MYSQL_TYPE_SET)
+ {
+ calculate_interval_lengths(&dummy, &field_length);
+ length= field_length + (interval->count - 1);
+ }
+ else /* MYSQL_TYPE_ENUM */
+ {
+ calculate_interval_lengths(&field_length, &dummy);
+ length= field_length;
+ }
+ set_if_smaller(length, MAX_FIELD_WIDTH - 1);
+ }
+
+ bool prepare_blob_field(THD *thd);
+
+ bool sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root);
+
+ bool prepare_stage1(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+ bool prepare_stage1_typelib(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+ bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+ bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+
+ void redefine_stage1_common(const Column_definition *dup_field,
+ const handler *file,
+ const Schema_specification_st *schema);
+ bool redefine_stage1(const Column_definition *dup_field, const handler *file,
+ const Schema_specification_st *schema)
+ {
+ const Type_handler *handler= dup_field->type_handler();
+ return handler->Column_definition_redefine_stage1(this, dup_field,
+ file, schema);
+ }
+ bool prepare_stage2(handler *handler, ulonglong table_flags);
+ bool prepare_stage2_blob(handler *handler,
+ ulonglong table_flags, uint field_flags);
+ bool prepare_stage2_varchar(ulonglong table_flags);
+ bool prepare_stage2_typelib(const char *type_name, uint field_flags,
+ uint *dup_val_count);
+ uint pack_flag_numeric(uint dec) const;
+ uint sign_length() const { return flags & UNSIGNED_FLAG ? 0 : 1; }
+ bool check_length(uint mysql_errno, uint max_allowed_length) const;
+ bool fix_attributes_real(uint default_length);
+ bool fix_attributes_int(uint default_length);
+ bool fix_attributes_decimal();
+ bool fix_attributes_temporal_with_time(uint int_part_length);
+ bool fix_attributes_bit();
bool check(THD *thd);
@@ -3853,16 +4002,16 @@ public:
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
uchar *ptr, uchar *null_pos, uchar null_bit,
- const char *field_name_arg) const
+ const LEX_CSTRING *field_name_arg) const
{
return ::make_field(share, mem_root, ptr,
(uint32)length, null_pos, null_bit,
- pack_flag, sql_type, charset,
+ pack_flag, type_handler(), charset,
geom_type, srid, unireg_check, interval,
field_name_arg);
}
Field *make_field(TABLE_SHARE *share, MEM_ROOT *mem_root,
- const char *field_name_arg)
+ const LEX_CSTRING *field_name_arg)
{
return make_field(share, mem_root, (uchar *) 0, (uchar *) "", 0,
field_name_arg);
@@ -3875,14 +4024,158 @@ public:
return unireg_check == Field::TIMESTAMP_DN_FIELD
|| unireg_check == Field::TIMESTAMP_DNUN_FIELD;
}
+
+ // Replace the entire value by another definition
+ void set_column_definition(const Column_definition *def)
+ {
+ *this= *def;
+ }
+};
+
+
+/**
+ List of ROW element definitions, e.g.:
+ DECLARE a ROW(a INT,b VARCHAR(10))
+*/
+class Row_definition_list: public List<class Spvar_definition>
+{
+public:
+ inline bool eq_name(const Spvar_definition *def, const LEX_CSTRING *name) const;
+ /**
+ Find a ROW field by name.
+ @param [IN] name - the name
+ @param [OUT] offset - if the ROW field found, its offset it returned here
+ @retval NULL - the ROW field was not found
+ @retval !NULL - the pointer to the found ROW field
+ */
+ Spvar_definition *find_row_field_by_name(const LEX_CSTRING *name, uint *offset) const
+ {
+ // Cast-off the "const" qualifier
+ List_iterator<Spvar_definition> it(*((List<Spvar_definition>*)this));
+ Spvar_definition *def;
+ for (*offset= 0; (def= it++); (*offset)++)
+ {
+ if (eq_name(def, name))
+ return def;
+ }
+ return 0;
+ }
+};
+
+
+/**
+ This class is used during a stored routine or a trigger execution,
+ at sp_rcontext::create() time.
+ Currently it can represent:
+ - variables with explicit data types: DECLARE a INT;
+ - variables with data type references: DECLARE a t1.a%TYPE;
+ - ROW type variables
+
+ Notes:
+ - Scalar variables have m_field_definitions==NULL.
+ - ROW variables are defined as having MYSQL_TYPE_NULL,
+ with a non-empty m_field_definitions.
+
+ Data type references to other object types will be added soon, e.g.:
+ - DECLARE a table_name%ROWTYPE;
+ - DECLARE a cursor_name%ROWTYPE;
+ - DECLARE a record_name%TYPE;
+ - DECLARE a variable_name%TYPE;
+*/
+class Spvar_definition: public Column_definition
+{
+ class Qualified_column_ident *m_column_type_ref; // for %TYPE
+ class Table_ident *m_table_rowtype_ref; // for table%ROWTYPE
+ bool m_cursor_rowtype_ref; // for cursor%ROWTYPE
+ Row_definition_list *m_row_field_definitions; // for ROW
+public:
+ Spvar_definition()
+ :m_column_type_ref(NULL),
+ m_table_rowtype_ref(NULL),
+ m_cursor_rowtype_ref(false),
+ m_row_field_definitions(NULL)
+ { }
+ Spvar_definition(THD *thd, Field *field)
+ :Column_definition(thd, field, NULL),
+ m_column_type_ref(NULL),
+ m_table_rowtype_ref(NULL),
+ m_cursor_rowtype_ref(false),
+ m_row_field_definitions(NULL)
+ { }
+ const Type_handler *type_handler() const
+ {
+ return is_row() || is_table_rowtype_ref() || is_cursor_rowtype_ref() ?
+ &type_handler_row :
+ Type_handler_hybrid_field_type::type_handler();
+ }
+ bool is_column_type_ref() const { return m_column_type_ref != 0; }
+ bool is_table_rowtype_ref() const { return m_table_rowtype_ref != 0; }
+ bool is_cursor_rowtype_ref() const { return m_cursor_rowtype_ref; }
+ class Qualified_column_ident *column_type_ref() const
+ {
+ return m_column_type_ref;
+ }
+ void set_column_type_ref(class Qualified_column_ident *ref)
+ {
+ m_column_type_ref= ref;
+ }
+
+ class Table_ident *table_rowtype_ref() const
+ {
+ return m_table_rowtype_ref;
+ }
+ void set_table_rowtype_ref(class Table_ident *ref)
+ {
+ m_table_rowtype_ref= ref;
+ }
+ void set_cursor_rowtype_ref(bool ref)
+ {
+ m_cursor_rowtype_ref= ref;
+ }
+
+ /*
+ Find a ROW field by name.
+ See Row_field_list::find_row_field_by_name() for details.
+ */
+ Spvar_definition *find_row_field_by_name(const LEX_CSTRING *name, uint *offset) const
+ {
+ DBUG_ASSERT(m_row_field_definitions);
+ return m_row_field_definitions->find_row_field_by_name(name, offset);
+ }
+ uint is_row() const
+ {
+ return m_row_field_definitions != NULL;
+ }
+ // Check if "this" defines a ROW variable with n elements
+ uint is_row(uint n) const
+ {
+ return m_row_field_definitions != NULL &&
+ m_row_field_definitions->elements == n;
+ }
+ Row_definition_list *row_field_definitions() const
+ {
+ return m_row_field_definitions;
+ }
+ void set_row_field_definitions(Row_definition_list *list)
+ {
+ m_row_field_definitions= list;
+ }
+
};
+inline bool Row_definition_list::eq_name(const Spvar_definition *def,
+ const LEX_CSTRING *name) const
+{
+ return def->field_name.length == name->length && my_strcasecmp(system_charset_info, def->field_name.str, name->str) == 0;
+}
+
+
class Create_field :public Column_definition
{
public:
- const char *change; // If done with alter table
- const char *after; // Put column after this one
+ LEX_CSTRING change; // If done with alter table
+ LEX_CSTRING after; // Put column after this one
Field *field; // For alter table
TYPELIB *save_interval; // Temporary copy for the above
// Used only for UCS2 intervals
@@ -3894,16 +4187,20 @@ public:
bool create_if_not_exists; // Used in ALTER TABLE IF NOT EXISTS
Create_field():
- Column_definition(), change(0), after(0),
+ Column_definition(),
field(0), option_struct(NULL),
create_if_not_exists(false)
- { }
+ {
+ change= after= null_clex_str;
+ }
Create_field(THD *thd, Field *old_field, Field *orig_field):
Column_definition(thd, old_field, orig_field),
- change(old_field->field_name), after(0),
+ change(old_field->field_name),
field(old_field), option_struct(old_field->option_struct),
create_if_not_exists(false)
- { }
+ {
+ after= null_clex_str;
+ }
/* Used to make a clone of this object for ALTER/CREATE TABLE */
Create_field *clone(MEM_ROOT *mem_root) const;
};
@@ -3917,9 +4214,9 @@ class Send_field :public Sql_alloc {
public:
const char *db_name;
const char *table_name,*org_table_name;
- const char *col_name,*org_col_name;
+ LEX_CSTRING col_name, org_col_name;
ulong length;
- uint charsetnr, flags, decimals;
+ uint flags, decimals;
enum_field_types type;
Send_field() {}
};
@@ -3967,11 +4264,10 @@ public:
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);
int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions);
int convert_null_to_field_value_or_error(Field *field);
-bool check_expression(Virtual_column_info *vcol, const char *name,
+bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
enum_vcol_info_type type);
/*