summaryrefslogtreecommitdiff
path: root/sql/field.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/field.h')
-rw-r--r--sql/field.h128
1 files changed, 98 insertions, 30 deletions
diff --git a/sql/field.h b/sql/field.h
index a7718df604a..0282deb9a3d 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -635,6 +635,48 @@ private:
{ return 0; }
protected:
+ static void handle_int16(uchar *to, const uchar *from,
+ bool low_byte_first_from, bool low_byte_first_to)
+ {
+ int16 val;
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_from)
+ val = sint2korr(from);
+ else
+#endif
+ shortget(val, from);
+
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_to)
+ int2store(to, val);
+ else
+#endif
+ shortstore(to, val);
+ }
+
+ static void handle_int24(uchar *to, const uchar *from,
+ bool low_byte_first_from, bool low_byte_first_to)
+ {
+ int32 val;
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_from)
+ val = sint3korr(from);
+ else
+#endif
+ val= (from[0] << 16) + (from[1] << 8) + from[2];
+
+#ifdef WORDS_BIGENDIAN
+ if (low_byte_first_to)
+ int2store(to, val);
+ else
+#endif
+ {
+ to[0]= 0xFF & (val >> 16);
+ to[1]= 0xFF & (val >> 8);
+ to[2]= 0xFF & val;
+ }
+ }
+
/*
Helper function to pack()/unpack() int32 values
*/
@@ -679,6 +721,32 @@ protected:
longlongstore(to, val);
}
+ uchar *pack_int16(uchar *to, const uchar *from, bool low_byte_first_to)
+ {
+ handle_int16(to, from, table->s->db_low_byte_first, low_byte_first_to);
+ return to + sizeof(int16);
+ }
+
+ const uchar *unpack_int16(uchar* to, const uchar *from,
+ bool low_byte_first_from)
+ {
+ handle_int16(to, from, low_byte_first_from, table->s->db_low_byte_first);
+ return from + sizeof(int16);
+ }
+
+ uchar *pack_int24(uchar *to, const uchar *from, bool low_byte_first_to)
+ {
+ handle_int24(to, from, table->s->db_low_byte_first, low_byte_first_to);
+ return to + 3;
+ }
+
+ const uchar *unpack_int24(uchar* to, const uchar *from,
+ bool low_byte_first_from)
+ {
+ handle_int24(to, from, low_byte_first_from, table->s->db_low_byte_first);
+ return from + 3;
+ }
+
uchar *pack_int32(uchar *to, const uchar *from, bool low_byte_first_to)
{
handle_int32(to, from, table->s->db_low_byte_first, low_byte_first_to);
@@ -759,6 +827,17 @@ public:
uchar null_bit_arg, utype unireg_check_arg,
const char *field_name_arg, CHARSET_INFO *charset);
Item_result result_type () const { return STRING_RESULT; }
+ /*
+ match_collation_to_optimize_range() is to distinguish in
+ range optimizer (see opt_range.cc) between real string types:
+ CHAR, VARCHAR, TEXT
+ and the other string-alike types with result_type() == STRING_RESULT:
+ DATE, TIME, DATETIME, TIMESTAMP
+ We need it to decide whether to test if collation of the operation
+ matches collation of the field (needed only for real string types).
+ QQ: shouldn't DATE/TIME types have their own XXX_RESULT types eventually?
+ */
+ virtual bool match_collation_to_optimize_range() const=0;
uint decimals() const { return NOT_FIXED_DEC; }
int store(double nr);
int store(longlong nr, bool unsigned_val)=0;
@@ -999,41 +1078,13 @@ public:
virtual uchar *pack(uchar* to, const uchar *from,
uint max_length, bool low_byte_first)
{
- int16 val;
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return to + sizeof(val);
+ return pack_int16(to, from, low_byte_first);
}
virtual const uchar *unpack(uchar* to, const uchar *from,
uint param_data, bool low_byte_first)
{
- int16 val;
-#ifdef WORDS_BIGENDIAN
- if (low_byte_first)
- val = sint2korr(from);
- else
-#endif
- shortget(val, from);
-
-#ifdef WORDS_BIGENDIAN
- if (table->s->db_low_byte_first)
- int2store(to, val);
- else
-#endif
- shortstore(to, val);
- return from + sizeof(val);
+ return unpack_int16(to, from, low_byte_first);
}
};
@@ -1268,6 +1319,7 @@ public:
unireg_check_arg, field_name_arg, cs)
{}
enum_field_types type() const { return MYSQL_TYPE_NULL;}
+ bool match_collation_to_optimize_range() const { return FALSE; }
int store(const char *to, uint length, CHARSET_INFO *cs)
{ null[0]=1; return 0; }
int store(double nr) { null[0]=1; return 0; }
@@ -1297,6 +1349,7 @@ public:
Field_timestamp(bool maybe_null_arg, const char *field_name_arg,
CHARSET_INFO *cs);
enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;}
+ bool match_collation_to_optimize_range() const { return FALSE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
@@ -1401,6 +1454,7 @@ public:
:Field_str((uchar*) 0, MAX_DATE_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) { flags|= BINARY_FLAG; }
enum_field_types type() const { return MYSQL_TYPE_DATE;}
+ bool match_collation_to_optimize_range() const { return FALSE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
@@ -1450,6 +1504,7 @@ public:
NONE, field_name_arg, cs) { flags|= BINARY_FLAG; }
enum_field_types type() const { return MYSQL_TYPE_DATE;}
enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; }
+ bool match_collation_to_optimize_range() const { return FALSE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
@@ -1489,6 +1544,7 @@ public:
:Field_str((uchar*) 0,8, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) { flags|= BINARY_FLAG; }
enum_field_types type() const { return MYSQL_TYPE_TIME;}
+ bool match_collation_to_optimize_range() const { return FALSE; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Derivation derivation(void) const { return DERIVATION_NUMERIC; }
@@ -1528,6 +1584,7 @@ public:
:Field_str((uchar*) 0, MAX_DATETIME_WIDTH, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, cs) { flags|= BINARY_FLAG; }
enum_field_types type() const { return MYSQL_TYPE_DATETIME;}
+ bool match_collation_to_optimize_range() const { return FALSE; }
#ifdef HAVE_LONG_LONG
enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; }
#endif
@@ -1596,6 +1653,7 @@ public:
orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR ?
MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING);
}
+ bool match_collation_to_optimize_range() const { return TRUE; }
enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
bool zero_pack() const { return 0; }
@@ -1676,6 +1734,7 @@ public:
}
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
+ bool match_collation_to_optimize_range() const { return TRUE; }
enum ha_base_keytype key_type() const;
uint row_pack_length() { return field_length; }
bool zero_pack() const { return 0; }
@@ -1771,6 +1830,7 @@ public:
:Field_longstr((uchar*) 0, 0, (uchar*) "", 0, NONE, "temp", system_charset_info),
packlength(packlength_arg) {}
enum_field_types type() const { return MYSQL_TYPE_BLOB;}
+ bool match_collation_to_optimize_range() const { return TRUE; }
enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
int store(const char *to,uint length,CHARSET_INFO *charset);
@@ -1920,6 +1980,7 @@ public:
{ geom_type= geom_type_arg; }
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; }
+ bool match_collation_to_optimize_range() const { return FALSE; }
void sql_type(String &str) const;
int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr);
@@ -1951,6 +2012,7 @@ public:
}
Field *new_field(MEM_ROOT *root, TABLE *new_table, bool keep_type);
enum_field_types type() const { return MYSQL_TYPE_STRING; }
+ bool match_collation_to_optimize_range() const { return FALSE; }
enum Item_result cmp_type () const { return INT_RESULT; }
enum Item_result cast_to_int_type () const { return INT_RESULT; }
enum ha_base_keytype key_type() const;
@@ -1976,6 +2038,12 @@ public:
bool has_charset(void) const { return TRUE; }
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
+
+ virtual uchar *pack(uchar *to, const uchar *from,
+ uint max_length, bool low_byte_first);
+ virtual const uchar *unpack(uchar *to, const uchar *from,
+ uint param_data, bool low_byte_first);
+
private:
int do_save_field_metadata(uchar *first_byte);
uint is_equal(Create_field *new_field);