summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-03-24 18:03:44 +0300
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-03-24 18:03:44 +0300
commitd95c1e3b470506c7df6dfce3fe6dc7e5b46930ee (patch)
tree9f13d4fcc3ac732dc94fe2cae446f6f8c2b4e02b /sql/item.h
parentabc6846d5b1df4846c4ffc03f4c93c82f874dd96 (diff)
parentae715642f46d4ed9ea8b5dd9b5cc9f3cace7f437 (diff)
downloadmariadb-git-d95c1e3b470506c7df6dfce3fe6dc7e5b46930ee.tar.gz
Manual merge of mysql-trunk into mysql-trunk-merge.
Conflicts: Text conflict in client/mysqlbinlog.cc Text conflict in mysql-test/Makefile.am Text conflict in mysql-test/collections/default.daily Text conflict in mysql-test/r/mysqlbinlog_row_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_typeconv_innodb.result Text conflict in mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test Text conflict in mysql-test/suite/rpl/t/rpl_row_create_table.test Text conflict in mysql-test/suite/rpl/t/rpl_slave_skip.test Text conflict in mysql-test/suite/rpl/t/rpl_typeconv_innodb.test Text conflict in mysys/charset.c Text conflict in sql/field.cc Text conflict in sql/field.h Text conflict in sql/item.h Text conflict in sql/item_func.cc Text conflict in sql/log.cc Text conflict in sql/log_event.cc Text conflict in sql/log_event_old.cc Text conflict in sql/mysqld.cc Text conflict in sql/rpl_utility.cc Text conflict in sql/rpl_utility.h Text conflict in sql/set_var.cc Text conflict in sql/share/Makefile.am Text conflict in sql/sql_delete.cc Text conflict in sql/sql_plugin.cc Text conflict in sql/sql_select.cc Text conflict in sql/sql_table.cc Text conflict in storage/example/ha_example.h Text conflict in storage/federated/ha_federated.cc Text conflict in storage/myisammrg/ha_myisammrg.cc Text conflict in storage/myisammrg/myrg_open.c
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h181
1 files changed, 171 insertions, 10 deletions
diff --git a/sql/item.h b/sql/item.h
index 9ca94064bd7..5d811b50bbc 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -44,9 +44,10 @@ class Item_field;
#define MY_COLL_ALLOW_SUPERSET_CONV 1
#define MY_COLL_ALLOW_COERCIBLE_CONV 2
-#define MY_COLL_ALLOW_CONV 3
#define MY_COLL_DISALLOW_NONE 4
-#define MY_COLL_CMP_CONV 7
+
+#define MY_COLL_ALLOW_CONV (MY_COLL_ALLOW_SUPERSET_CONV | MY_COLL_ALLOW_COERCIBLE_CONV)
+#define MY_COLL_CMP_CONV (MY_COLL_ALLOW_CONV | MY_COLL_DISALLOW_NONE)
class DTCollation {
public:
@@ -91,6 +92,12 @@ public:
derivation= derivation_arg;
repertoire= repertoire_arg;
}
+ void set_numeric()
+ {
+ collation= &my_charset_numeric;
+ derivation= DERIVATION_NUMERIC;
+ repertoire= MY_REPERTOIRE_NUMERIC;
+ }
void set(CHARSET_INFO *collation_arg)
{
collation= collation_arg;
@@ -105,6 +112,7 @@ public:
{
switch(derivation)
{
+ case DERIVATION_NUMERIC: return "NUMERIC";
case DERIVATION_IGNORABLE: return "IGNORABLE";
case DERIVATION_COERCIBLE: return "COERCIBLE";
case DERIVATION_IMPLICIT: return "IMPLICIT";
@@ -690,6 +698,77 @@ public:
If value is not null null_value flag will be reset to FALSE.
*/
virtual String *val_str(String *str)=0;
+
+ /*
+ Returns string representation of this item in ASCII format.
+
+ SYNOPSIS
+ val_str_ascii()
+ str - similar to val_str();
+
+ NOTE
+ This method is introduced for performance optimization purposes.
+
+ 1. val_str() result of some Items in string context
+ depends on @@character_set_results.
+ @@character_set_results can be set to a "real multibyte" character
+ set like UCS2, UTF16, UTF32. (We'll use only UTF32 in the examples
+ below for convenience.)
+
+ So the default string result of such functions
+ in these circumstances is real multi-byte character set, like UTF32.
+
+ For example, all numbers in string context
+ return result in @@character_set_results:
+
+ SELECT CONCAT(20010101); -> UTF32
+
+ We do sprintf() first (to get ASCII representation)
+ and then convert to UTF32;
+
+ So these kind "data sources" can use ASCII representation
+ internally, but return multi-byte data only because
+ @@character_set_results wants so.
+ Therefore, conversion from ASCII to UTF32 is applied internally.
+
+
+ 2. Some other functions need in fact ASCII input.
+
+ For example,
+ inet_aton(), GeometryFromText(), Convert_TZ(), GET_FORMAT().
+
+ Similar, fields of certain type, like DATE, TIME,
+ when you insert string data into them, expect in fact ASCII input.
+ If they get non-ASCII input, for example UTF32, they
+ convert input from UTF32 to ASCII, and then use ASCII
+ representation to do further processing.
+
+
+ 3. Now imagine we pass result of a data source of the first type
+ to a data destination of the second type.
+
+ What happens:
+ a. data source converts data from ASCII to UTF32, because
+ @@character_set_results wants so and passes the result to
+ data destination.
+ b. data destination gets UTF32 string.
+ c. data destination converts UTF32 string to ASCII,
+ because it needs ASCII representation to be able to handle data
+ correctly.
+
+ As a result we get two steps of unnecessary conversion:
+ From ASCII to UTF32, then from UTF32 to ASCII.
+
+ A better way to handle these situations is to pass ASCII
+ representation directly from the source to the destination.
+
+ This is why val_str_ascii() introduced.
+
+ RETURN
+ Similar to val_str()
+ */
+ virtual String *val_str_ascii(String *str);
+
/*
Return decimal representation of item with fixed point.
@@ -864,6 +943,16 @@ public:
static CHARSET_INFO *default_charset();
virtual CHARSET_INFO *compare_collation() { return NULL; }
+ /*
+ For backward compatibility, to make numeric
+ data types return "binary" charset in client-side metadata.
+ */
+ virtual CHARSET_INFO *charset_for_protocol(void) const
+ {
+ return result_type() == STRING_RESULT ? collation.collation :
+ &my_charset_bin;
+ };
+
virtual bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
{
return (this->*processor)(arg);
@@ -920,6 +1009,9 @@ public:
virtual bool is_expensive_processor(uchar *arg) { return 0; }
virtual bool find_item_processor(uchar *arg) { return this == (void *) arg; }
virtual bool register_field_in_read_map(uchar *arg) { return 0; }
+
+ virtual bool cache_const_expr_analyzer(uchar **arg);
+ virtual Item* cache_const_expr_transformer(uchar *arg);
/*
Check if a partition function is allowed
SYNOPSIS
@@ -1067,6 +1159,20 @@ public:
{ return Field::GEOM_GEOMETRY; };
String *check_well_formed_result(String *str, bool send_error= 0);
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
+ uint32 max_char_length() const
+ { return max_length / collation.collation->mbmaxlen; }
+ void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs)
+ {
+ max_length= max_char_length_arg * cs->mbmaxlen;
+ collation.collation= cs;
+ }
+ void fix_char_length(uint32 max_char_length_arg)
+ { max_length= max_char_length_arg * collation.collation->mbmaxlen; }
+ void fix_length_and_charset_datetime(uint32 max_char_length_arg)
+ {
+ collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII);
+ fix_char_length(max_char_length_arg);
+ }
};
@@ -1369,12 +1475,30 @@ bool agg_item_set_converter(DTCollation &coll, const char *fname,
Item **args, uint nargs, uint flags, int item_sep);
bool agg_item_charsets(DTCollation &c, const char *name,
Item **items, uint nitems, uint flags, int item_sep);
-
+inline bool
+agg_item_charsets_for_string_result(DTCollation &c, const char *name,
+ Item **items, uint nitems,
+ int item_sep= 1)
+{
+ uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
+ MY_COLL_ALLOW_COERCIBLE_CONV;
+ return agg_item_charsets(c, name, items, nitems, flags, item_sep);
+}
+inline bool
+agg_item_charsets_for_comparison(DTCollation &c, const char *name,
+ Item **items, uint nitems,
+ int item_sep= 1)
+{
+ uint flags= MY_COLL_ALLOW_SUPERSET_CONV |
+ MY_COLL_ALLOW_COERCIBLE_CONV |
+ MY_COLL_DISALLOW_NONE;
+ return agg_item_charsets(c, name, items, nitems, flags, item_sep);
+}
class Item_num: public Item_basic_constant
{
public:
- Item_num() {} /* Remove gcc warning */
+ Item_num() { collation.set_numeric(); } /* Remove gcc warning */
virtual Item_num *neg()= 0;
Item *safe_charset_converter(CHARSET_INFO *tocs);
bool check_partition_func_processor(uchar *int_arg) { return FALSE;}
@@ -1560,6 +1684,8 @@ public:
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
return field->get_geometry_type();
}
+ CHARSET_INFO *charset_for_protocol(void) const
+ { return field->charset_for_protocol(); }
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
@@ -2363,6 +2489,7 @@ public:
DBUG_ASSERT(fixed);
return (*ref)->get_time(ltime);
}
+ bool basic_const_item() { return (*ref)->basic_const_item(); }
};
@@ -3013,14 +3140,16 @@ protected:
bool value_cached;
public:
Item_cache():
- example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING),
+ example(0), used_table_map(0), cached_field(0),
+ cached_field_type(MYSQL_TYPE_STRING),
value_cached(0)
{
fixed= 1;
null_value= 1;
}
Item_cache(enum_field_types field_type_arg):
- example(0), used_table_map(0), cached_field(0), cached_field_type(field_type_arg),
+ example(0), used_table_map(0), cached_field(0),
+ cached_field_type(field_type_arg),
value_cached(0)
{
fixed= 1;
@@ -3058,6 +3187,8 @@ public:
}
virtual void store(Item *item);
virtual bool cache_value()= 0;
+ bool basic_const_item() const
+ { return test(example && example->basic_const_item());}
};
@@ -3123,10 +3254,9 @@ class Item_cache_str: public Item_cache
public:
Item_cache_str(const Item *item) :
- Item_cache(), value(0),
+ Item_cache(item->field_type()), value(0),
is_varbinary(item->type() == FIELD_ITEM &&
- ((const Item_field *) item)->field->type() ==
- MYSQL_TYPE_VARCHAR &&
+ cached_field_type == MYSQL_TYPE_VARCHAR &&
!((const Item_field *) item)->field->has_charset())
{}
double val_real();
@@ -3209,6 +3339,38 @@ public:
};
+class Item_cache_datetime: public Item_cache
+{
+protected:
+ String str_value;
+ ulonglong int_value;
+ bool str_value_cached;
+public:
+ Item_cache_datetime(enum_field_types field_type_arg):
+ Item_cache(field_type_arg), int_value(0), str_value_cached(0)
+ {
+ cmp_context= STRING_RESULT;
+ }
+
+ void store(Item *item, longlong val_arg);
+ double val_real();
+ longlong val_int();
+ String* val_str(String *str);
+ my_decimal *val_decimal(my_decimal *);
+ enum Item_result result_type() const { return STRING_RESULT; }
+ bool result_as_longlong() { return TRUE; }
+ /*
+ In order to avoid INT <-> STRING conversion of a DATETIME value
+ two cache_value functions are introduced. One (cache_value) caches STRING
+ value, another (cache_value_int) - INT value. Thus this cache item
+ completely relies on the ability of the underlying item to do the
+ correct conversion.
+ */
+ bool cache_value_int();
+ bool cache_value();
+};
+
+
/*
Item_type_holder used to store type. name, length of Item for UNIONS &
derived tables.
@@ -3256,5 +3418,4 @@ extern Cached_item *new_Cached_item(THD *thd, Item *item);
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item);
extern int stored_field_cmp_to_item(THD *thd, Field *field, Item *item);
-
#endif /* ITEM_INCLUDED */