summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h582
1 files changed, 480 insertions, 102 deletions
diff --git a/sql/item.h b/sql/item.h
index 33296b619db..ed50605ef7b 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1,5 +1,9 @@
+#ifndef SQL_ITEM_INCLUDED
+#define SQL_ITEM_INCLUDED
+
/* Copyright (c) 2000, 2013, Oracle and/or its affiliates.
- Copyright (c) 2009, 2013, Monty Program Ab.
+ Copyright (c) 2009, 2013 Monty Program Ab.
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
@@ -18,11 +22,18 @@
#pragma interface /* gcc class implementation */
#endif
+#include "sql_priv.h" /* STRING_BUFFER_USUAL_SIZE */
+#include "unireg.h"
+#include "sql_const.h" /* RAND_TABLE_BIT, MAX_FIELD_NAME */
+#include "unireg.h" // REQUIRED: for other includes
+#include "thr_malloc.h" /* sql_calloc */
+#include "field.h" /* Derivation */
+
C_MODE_START
#include <ma_dyncol.h>
C_MODE_END
-inline
+static inline
bool trace_unsupported_func(const char *where, const char *processor_name)
{
char buff[64];
@@ -33,17 +44,18 @@ bool trace_unsupported_func(const char *where, const char *processor_name)
DBUG_RETURN(TRUE);
}
-inline
+static inline
bool trace_unsupported_by_check_vcol_func_processor(const char *where)
{
return trace_unsupported_func(where, "check_vcol_func_processor");
}
-
class Protocol;
struct TABLE_LIST;
void item_init(void); /* Init item functions */
class Item_field;
+class user_var_entry;
+
static inline uint32
char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
@@ -63,6 +75,8 @@ char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
(i.e. constant).
MY_COLL_ALLOW_CONV - allow any kind of conversion
(combination of the above two)
+ MY_COLL_ALLOW_NUMERIC_CONV - if all items were numbers, convert to
+ @@character_set_connection
MY_COLL_DISALLOW_NONE - don't allow return DERIVATION_NONE
(e.g. when aggregating for comparison)
MY_COLL_CMP_CONV - combination of MY_COLL_ALLOW_CONV
@@ -71,9 +85,11 @@ char_to_byte_length_safe(uint32 char_length_arg, uint32 mbmaxlen_arg)
#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_NUMERIC_CONV 8
+
+#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:
@@ -118,6 +134,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;
@@ -132,6 +154,7 @@ public:
{
switch(derivation)
{
+ case DERIVATION_NUMERIC: return "NUMERIC";
case DERIVATION_IGNORABLE: return "IGNORABLE";
case DERIVATION_COERCIBLE: return "COERCIBLE";
case DERIVATION_IMPLICIT: return "IMPLICIT";
@@ -309,6 +332,8 @@ struct Name_resolution_context: Sql_alloc
*/
TABLE_LIST *last_name_resolution_table;
+ /* Cache first_name_resolution_table in setup_natural_join_row_types */
+ TABLE_LIST *natural_join_first_table;
/*
SELECT_LEX item belong to, in case of merged VIEW it can differ from
SELECT_LEX where item was created, so we can't use table_list/field_list
@@ -496,6 +521,11 @@ public:
TRUE if error has occured.
*/
virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it)= 0;
+
+ virtual void set_out_param_info(Send_field *info) {}
+
+ virtual const Send_field *get_out_param_info() const
+ { return NULL; }
};
@@ -589,6 +619,10 @@ public:
@see Query_arena::free_list
*/
Item *next;
+ /*
+ The maximum value length in characters multiplied by collation->mbmaxlen.
+ Almost always it's the maximum value length in bytes.
+ */
uint32 max_length;
/*
TODO: convert name and name_length fields into LEX_STRING to keep them in
@@ -641,7 +675,7 @@ public:
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual void cleanup();
virtual void make_field(Send_field *field);
- Field *make_string_field(TABLE *table);
+ virtual Field *make_string_field(TABLE *table);
virtual bool fix_fields(THD *, Item **);
/*
Fix after some tables has been pulled out. Basically re-calculate all
@@ -793,6 +827,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);
+
/*
Returns the val_str() value converted to the given character set.
*/
@@ -990,11 +1095,11 @@ public:
/* Called for items that really have to be split */
void split_sum_func2(THD *thd, Item **ref_pointer_array, List<Item> &fields,
Item **ref, bool skip_registered);
- virtual bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool get_time(MYSQL_TIME *ltime)
{ return get_date(ltime, TIME_TIME_ONLY); }
bool get_seconds(ulonglong *sec, ulong *sec_part);
- virtual bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
+ virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
{ return get_date(ltime,fuzzydate); }
/*
The method allows to determine nullness of a complex expression
@@ -1042,6 +1147,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);
@@ -1079,6 +1194,15 @@ public:
(*traverser)(this, arg);
}
+ /*
+ This is used to get the most recent version of any function in
+ an item tree. The version is the version where a MySQL function
+ was introduced in. So any function which is added should use
+ this function and set the int_arg to maximum of the input data
+ and their own version info.
+ */
+ virtual bool intro_version(uchar *int_arg) { return 0; }
+
virtual bool remove_dependence_processor(uchar * arg) { return 0; }
virtual bool remove_fixed(uchar * arg) { fixed= 0; return 0; }
virtual bool cleanup_processor(uchar *arg);
@@ -1124,6 +1248,10 @@ public:
is passed as uchar *arg.
*/
virtual bool register_field_in_bitmap(uchar *arg) { return 0; }
+
+ bool cache_const_expr_analyzer(uchar **arg);
+ Item* cache_const_expr_transformer(uchar *arg);
+
/*
Check if a partition function is allowed
SYNOPSIS
@@ -1317,22 +1445,33 @@ public:
{
return 0;
}
+ /**
+ Check whether this and the given item has compatible comparison context.
+ Used by the equality propagation. See Item_field::equal_fields_propagator.
- /*
+ @return
+ TRUE if the context is the same
+ FALSE otherwise.
+ */
+ inline bool has_compatible_context(Item *item) const
+ {
+ return cmp_context == IMPOSSIBLE_RESULT || item->cmp_context == cmp_context;
+ }
+ /**
Test whether an expression is expensive to compute. Used during
optimization to avoid computing expensive expressions during this
phase. Also used to force temp tables when sorting on expensive
functions.
- TODO:
+ @todo
Normally we should have a method:
cost Item::execution_cost(),
where 'cost' is either 'double' or some structure of various cost
parameters.
- NOTE
- This function is now used to prevent evaluation of materialized IN
- subquery predicates before it is allowed. grep for
- DontEvaluateMaterializedSubqueryTooEarly to see the uses.
+ @note
+ This function is now used to prevent evaluation of expensive subquery
+ predicates during the optimization phase. It also prevents evaluation
+ of predicates that are not computable at this moment.
*/
virtual bool is_expensive()
{
@@ -1344,13 +1483,31 @@ 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; }
+ bool too_big_for_varchar() const
+ { return max_char_length() > CONVERT_IF_BIGGER_TO_BLOB; }
+ void fix_length_and_charset(uint32 max_char_length_arg, CHARSET_INFO *cs)
+ {
+ max_length= char_to_byte_length_safe(max_char_length_arg, cs->mbmaxlen);
+ collation.collation= cs;
+ }
void fix_char_length(uint32 max_char_length_arg)
{
max_length= char_to_byte_length_safe(max_char_length_arg,
collation.collation->mbmaxlen);
}
+ /*
+ Return TRUE if the item points to a column of an outer-joined table.
+ */
+ virtual bool is_outer_field() const { DBUG_ASSERT(fixed); return FALSE; }
+
+ /**
+ Checks if this item or any of its decendents contains a subquery.
+ */
+ virtual bool has_subquery() const { return with_subselect; }
+
Item* set_expr_cache(THD *thd);
- virtual Item *get_cached_item() { return NULL; }
virtual Item_equal *get_item_equal() { return NULL; }
virtual void set_item_equal(Item_equal *item_eq) {};
@@ -1384,11 +1541,6 @@ public:
virtual void get_cache_parameters(List<Item> &parameters) { };
virtual void mark_as_condition_AND_part(TABLE_LIST *embedding) {};
-
- /**
- Checks if this item or any of its decendents contains a subquery.
- */
- virtual bool has_subquery() const { return with_subselect; }
};
@@ -1424,10 +1576,8 @@ public:
Field_enumerator() {} /* Remove gcc warning */
};
-
class sp_head;
-
class Item_basic_constant :public Item
{
table_map used_table_map;
@@ -1543,6 +1693,13 @@ class Item_splocal :public Item_sp_variable,
Item_result m_result_type;
enum_field_types m_field_type;
public:
+ /*
+ If this variable is a parameter in LIMIT clause.
+ Used only during NAME_CONST substitution, to not append
+ NAME_CONST to the resulting query and thus not break
+ the slave.
+ */
+ bool limit_clause_param;
/*
Position of this reference to SP variable in the statement (the
statement itself is in sp_instr_stmt::m_query).
@@ -1728,12 +1885,44 @@ 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 |
+ MY_COLL_ALLOW_NUMERIC_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);
+}
+inline bool
+agg_item_charsets_for_string_result_with_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_ALLOW_NUMERIC_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;}
@@ -1829,6 +2018,8 @@ public:
String *val_str(String *str) { return field->val_str(str); }
my_decimal *val_decimal(my_decimal *dec) { return field->val_decimal(dec); }
void make_field(Send_field *tmp_field);
+ CHARSET_INFO *charset_for_protocol(void) const
+ { return field->charset_for_protocol(); }
};
@@ -1907,8 +2098,8 @@ public:
longlong val_int_endpoint(bool left_endp, bool *incl_endp);
Field *get_tmp_table_field() { return result_field; }
Field *tmp_table_field(TABLE *t_arg) { return result_field; }
- bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
- bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool get_date_result(MYSQL_TIME *ltime,ulonglong fuzzydate);
bool is_null() { return field->is_null(); }
void update_null_value();
void update_table_bitmaps()
@@ -1958,11 +2149,18 @@ public:
int fix_outer_field(THD *thd, Field **field, Item **reference);
virtual Item *update_value_transformer(uchar *select_arg);
virtual void print(String *str, enum_query_type query_type);
+ bool is_outer_field() const
+ {
+ DBUG_ASSERT(fixed);
+ return field->table->pos_in_table_list->outer_join;
+ }
Field::geometry_type get_geometry_type() const
{
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;
@@ -2023,7 +2221,8 @@ public:
/* Item represents one placeholder ('?') of prepared statement */
-class Item_param :public Item
+class Item_param :public Item,
+ private Settable_routine_parameter
{
char cnvbuf[MAX_FIELD_WIDTH];
String cnvstr;
@@ -2104,13 +2303,14 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal*);
String *val_str(String*);
- bool get_date(MYSQL_TIME *tm, uint fuzzydate);
+ bool get_date(MYSQL_TIME *tm, ulonglong fuzzydate);
int save_in_field(Field *field, bool no_conversions);
void set_null();
void set_int(longlong i, uint32 max_length_arg);
void set_double(double i);
void set_decimal(const char *str, ulong length);
+ void set_decimal(const my_decimal *dv);
bool set_str(const char *str, ulong length);
bool set_longdata(const char *str, ulong length);
void set_time(MYSQL_TIME *tm, timestamp_type type, uint32 max_length_arg);
@@ -2161,6 +2361,24 @@ public:
bool limit_clause_param;
void set_param_type_and_swap_value(Item_param *from);
+private:
+ virtual inline Settable_routine_parameter *
+ get_settable_routine_parameter()
+ {
+ return this;
+ }
+
+ virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+ virtual void set_out_param_info(Send_field *info);
+
+public:
+ virtual const Send_field *get_out_param_info() const;
+
+ virtual void make_field(Send_field *field);
+
+private:
+ Send_field *m_out_param_info;
};
@@ -2481,7 +2699,7 @@ double_from_string_with_check(CHARSET_INFO *cs, const char *cptr,
class Item_static_string_func :public Item_string
{
const char *func_name;
- public:
+public:
Item_static_string_func(const char *name_par, const char *str, uint length,
CHARSET_INFO *cs,
Derivation dv= DERIVATION_COERCIBLE)
@@ -2543,7 +2761,7 @@ public:
/**
Item_empty_string -- is a utility class to put an item into List<Item>
- which is then used in protocol.send_fields() when sending SHOW output to
+ which is then used in protocol.send_result_set_metadata() when sending SHOW output to
the client.
*/
@@ -2571,36 +2789,112 @@ public:
};
-class Item_hex_string: public Item_basic_constant
+/**
+ Item_hex_constant -- a common class for hex literals: X'HHHH' and 0xHHHH
+*/
+class Item_hex_constant: public Item_basic_constant
{
+private:
+ void hex_string_init(const char *str, uint str_length);
public:
- Item_hex_string();
- Item_hex_string(const char *str,uint str_length);
+ Item_hex_constant()
+ {
+ hex_string_init("", 0);
+ }
+ Item_hex_constant(const char *str, uint str_length)
+ {
+ hex_string_init(str, str_length);
+ }
enum Type type() const { return VARBIN_ITEM; }
+ enum Item_result result_type () const { return STRING_RESULT; }
+ enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
+ virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
+ bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+ bool check_vcol_func_processor(uchar *arg) { return FALSE;}
+ bool basic_const_item() const { return 1; }
+ bool eq(const Item *item, bool binary_cmp) const;
+ String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
+};
+
+
+/**
+ Item_hex_hybrid -- is a class implementing 0xHHHH literals, e.g.:
+ SELECT 0x3132;
+ They can behave as numbers and as strings depending on context.
+*/
+class Item_hex_hybrid: public Item_hex_constant
+{
+public:
+ Item_hex_hybrid(): Item_hex_constant() {}
+ Item_hex_hybrid(const char *str, uint str_length):
+ Item_hex_constant(str, str_length) {}
double val_real()
{
DBUG_ASSERT(fixed == 1);
- return (double) (ulonglong) Item_hex_string::val_int();
+ return (double) (ulonglong) Item_hex_hybrid::val_int();
}
longlong val_int();
- bool basic_const_item() const { return 1; }
- String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
- my_decimal *val_decimal(my_decimal *);
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ ulonglong value= (ulonglong) Item_hex_hybrid::val_int();
+ int2my_decimal(E_DEC_FATAL_ERROR, value, TRUE, decimal_value);
+ return decimal_value;
+ }
int save_in_field(Field *field, bool no_conversions);
- enum Item_result result_type () const { return STRING_RESULT; }
enum Item_result cast_to_int_type() const { return INT_RESULT; }
- enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
- virtual void print(String *str, enum_query_type query_type);
- bool eq(const Item *item, bool binary_cmp) const;
- virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
- bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
- bool check_vcol_func_processor(uchar *arg) { return FALSE;}
-private:
- void hex_string_init(const char *str, uint str_length);
+ void print(String *str, enum_query_type query_type);
+};
+
+
+/**
+ Item_hex_string -- is a class implementing X'HHHH' literals, e.g.:
+ SELECT X'3132';
+ Unlike Item_hex_hybrid, X'HHHH' literals behave as strings in all contexts.
+ X'HHHH' are also used in replication of string constants in case of
+ "dangerous" charsets (sjis, cp932, big5, gbk) who can have backslash (0x5C)
+ as the second byte of a multi-byte character, so using '\' escaping for
+ these charsets is not desirable.
+*/
+class Item_hex_string: public Item_hex_constant
+{
+public:
+ Item_hex_string(): Item_hex_constant() {}
+ Item_hex_string(const char *str, uint str_length):
+ Item_hex_constant(str, str_length) {}
+ longlong val_int()
+ {
+ DBUG_ASSERT(fixed == 1);
+ return longlong_from_string_with_check(str_value.charset(),
+ str_value.ptr(),
+ str_value.ptr()+
+ str_value.length());
+ }
+ double val_real()
+ {
+ DBUG_ASSERT(fixed == 1);
+ return double_from_string_with_check(str_value.charset(),
+ str_value.ptr(),
+ str_value.ptr() +
+ str_value.length());
+ }
+ my_decimal *val_decimal(my_decimal *decimal_value)
+ {
+ return val_decimal_from_string(decimal_value);
+ }
+ int save_in_field(Field *field, bool no_conversions)
+ {
+ field->set_notnull();
+ return field->store(str_value.ptr(), str_value.length(),
+ collation.collation);
+ }
+ enum Item_result cast_to_int_type() const { return STRING_RESULT; }
+ void print(String *str, enum_query_type query_type);
};
-class Item_bin_string: public Item_hex_string
+class Item_bin_string: public Item_hex_hybrid
{
public:
Item_bin_string(const char *str,uint str_length);
@@ -2701,7 +2995,7 @@ public:
bool val_bool();
String *val_str(String* tmp);
bool is_null();
- bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
double val_result();
longlong val_int_result();
String *str_result(String* tmp);
@@ -2797,6 +3091,13 @@ public:
{
return trace_unsupported_by_check_vcol_func_processor("ref");
}
+ bool basic_const_item() const { return ref && (*ref)->basic_const_item(); }
+ bool is_outer_field() const
+ {
+ DBUG_ASSERT(fixed);
+ DBUG_ASSERT(ref);
+ return (*ref)->is_outer_field();
+ }
/**
Checks if the item tree that ref points to contains a subquery.
@@ -2838,7 +3139,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool is_null();
- bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
virtual Ref_Type ref_type() { return DIRECT_REF; }
};
@@ -2876,9 +3177,8 @@ public:
};
-class Expression_cache;
class Item_cache;
-
+class Expression_cache;
/**
The objects of this class can store its values in an expression cache.
@@ -2927,13 +3227,8 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool is_null();
- bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
- bool send(Protocol *protocol, String *buffer)
- {
- if (result_field)
- return protocol->store(result_field);
- return Item::send(protocol, buffer);
- }
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
+ bool send(Protocol *protocol, String *buffer);
void save_org_in_field(Field *field)
{
save_val(field);
@@ -3121,7 +3416,7 @@ public:
else
return Item_direct_ref::is_null();
}
- bool get_date(MYSQL_TIME *ltime, uint fuzzydate)
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
if (check_null_ref())
{
@@ -3130,12 +3425,7 @@ public:
}
return Item_direct_ref::get_date(ltime, fuzzydate);
}
- bool send(Protocol *protocol, String *buffer)
- {
- if (check_null_ref())
- return protocol->store_null();
- return Item_direct_ref::send(protocol, buffer);
- }
+ bool send(Protocol *protocol, String *buffer);
void save_org_in_field(Field *field)
{
if (check_null_ref())
@@ -3212,7 +3502,6 @@ public:
return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
}
table_map not_null_tables() const { return 0; }
-
virtual Ref_Type ref_type() { return OUTER_REF; }
bool check_inner_refs_processor(uchar * arg);
};
@@ -3246,7 +3535,7 @@ public:
String* val_str(String* s);
my_decimal *val_decimal(my_decimal *);
bool val_bool();
- bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
virtual void print(String *str, enum_query_type query_type);
table_map used_tables() const;
};
@@ -3289,6 +3578,7 @@ public:
#include "item_timefunc.h"
#include "item_subselect.h"
#include "item_xmlfunc.h"
+#include "item_create.h"
#endif
/**
@@ -3346,6 +3636,8 @@ protected:
cached_field_type= item->field_type();
cached_result_type= item->result_type();
unsigned_flag= item->unsigned_flag;
+ fixed= item->fixed;
+ collation.set(item->collation);
}
public:
@@ -3647,6 +3939,7 @@ public:
return arg->walk(processor, walk_subquery, args) ||
(this->*processor)(args);
}
+ bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
bool check_vcol_func_processor(uchar *arg)
{
return trace_unsupported_by_check_vcol_func_processor("values");
@@ -3654,18 +3947,6 @@ public:
};
-/*
- We need this two enums here instead of sql_lex.h because
- at least one of them is used by Item_trigger_field interface.
-
- Time when trigger is invoked (i.e. before or after row actually
- inserted/updated/deleted).
-*/
-enum trg_action_time_type
-{
- TRG_ACTION_BEFORE= 0, TRG_ACTION_AFTER= 1, TRG_ACTION_MAX
-};
-
class Table_triggers_list;
/*
@@ -3757,7 +4038,7 @@ private:
/**
@todo
Implement the is_null() method for this class. Currently calling is_null()
- on any Item_cache object resolves to Item::is_null(), which reutns FALSE
+ on any Item_cache object resolves to Item::is_null(), which returns FALSE
for any value.
*/
@@ -3783,7 +4064,8 @@ 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;
@@ -3791,7 +4073,8 @@ public:
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;
@@ -3832,20 +4115,24 @@ public:
{
return trace_unsupported_by_check_vcol_func_processor("cache");
}
-
- /**
- If this item caches a field value, return pointer to underlying field.
-
- @return Pointer to field, or NULL if this is not a cache for a field value.
- */
- Field* field() { return cached_field; }
+ /**
+ Check if saved item has a non-NULL value.
+ Will cache value of saved item if not already done.
+ @return TRUE if cached value is non-NULL.
+ */
+ bool has_value()
+ {
+ return (value_cached || cache_value()) && !null_value;
+ }
virtual void store(Item *item);
virtual bool cache_value()= 0;
+ bool basic_const_item() const
+ { return test(example && example->basic_const_item());}
+ virtual void clear() { null_value= TRUE; value_cached= FALSE; }
bool is_null() { return null_value; }
virtual bool is_expensive()
{
- DBUG_ASSERT(example);
if (value_cached)
return false;
return example->is_expensive();
@@ -3858,6 +4145,12 @@ public:
return example->is_expensive_processor(arg);
}
virtual void set_null();
+ bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
+ {
+ if (example && example->walk(processor, walk_subquery, arg))
+ return TRUE;
+ return (this->*processor)(arg);
+ }
};
@@ -3884,21 +4177,16 @@ public:
class Item_cache_temporal: public Item_cache_int
{
public:
- Item_cache_temporal(enum_field_types field_type_arg):
- Item_cache_int(field_type_arg)
- {
- if (mysql_type_to_time_type(cached_field_type) == MYSQL_TIMESTAMP_ERROR)
- cached_field_type= MYSQL_TYPE_DATETIME;
- }
-
+ Item_cache_temporal(enum_field_types field_type_arg);
String* val_str(String *str);
my_decimal *val_decimal(my_decimal *);
longlong val_int();
longlong val_temporal_packed();
double val_real();
bool cache_value();
- bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
int save_in_field(Field *field, bool no_conversions);
+ Item_result cmp_type() const { return TIME_RESULT; }
void store_packed(longlong val_arg, Item *example);
/*
Having a clone_item method tells optimizer that this object
@@ -3913,6 +4201,7 @@ public:
}
};
+
class Item_cache_real: public Item_cache
{
double value;
@@ -3953,12 +4242,13 @@ 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())
- {}
+ {
+ collation.set(const_cast<DTCollation&>(item->collation));
+ }
double val_real();
longlong val_int();
String* val_str(String *);
@@ -4088,3 +4378,91 @@ 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);
+
+extern const String my_null_string;
+
+/**
+ Interface for Item iterator
+*/
+
+class Item_iterator
+{
+public:
+ /**
+ Shall set this iterator to the position before the first item
+
+ @note
+ This method also may perform some other initialization actions like
+ allocation of certain resources.
+ */
+ virtual void open()= 0;
+ /**
+ Shall return the next Item (or NULL if there is no next item) and
+ move pointer to position after it.
+ */
+ virtual Item *next()= 0;
+ /**
+ Shall force iterator to free resources (if it holds them)
+
+ @note
+ One should not use the iterator without open() call after close()
+ */
+ virtual void close()= 0;
+
+ virtual ~Item_iterator() {}
+};
+
+
+/**
+ Item iterator over List_iterator_fast for Item references
+*/
+
+class Item_iterator_ref_list: public Item_iterator
+{
+ List_iterator<Item*> list;
+public:
+ Item_iterator_ref_list(List_iterator<Item*> &arg_list):
+ list(arg_list) {}
+ void open() { list.rewind(); }
+ Item *next() { return *(list++); }
+ void close() {}
+};
+
+
+/**
+ Item iterator over List_iterator_fast for Items
+*/
+
+class Item_iterator_list: public Item_iterator
+{
+ List_iterator<Item> list;
+public:
+ Item_iterator_list(List_iterator<Item> &arg_list):
+ list(arg_list) {}
+ void open() { list.rewind(); }
+ Item *next() { return (list++); }
+ void close() {}
+};
+
+
+/**
+ Item iterator over Item interface for rows
+*/
+
+class Item_iterator_row: public Item_iterator
+{
+ Item *base_item;
+ uint current;
+public:
+ Item_iterator_row(Item *base) : base_item(base), current(0) {}
+ void open() { current= 0; }
+ Item *next()
+ {
+ if (current >= base_item->cols())
+ return NULL;
+ return base_item->element_index(current++);
+ }
+ void close() {}
+};
+
+#endif /* SQL_ITEM_INCLUDED */