summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h454
1 files changed, 349 insertions, 105 deletions
diff --git a/sql/item.h b/sql/item.h
index 250bb3f67ef..be343e25d3f 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -113,7 +113,6 @@ public:
}
};
-
/*************************************************************************/
/*
A framework to easily handle different return types for hybrid items
@@ -378,6 +377,35 @@ public:
}
};
+
+/*
+ This enum is used to report information about monotonicity of function
+ represented by Item* tree.
+ Monotonicity is defined only for Item* trees that represent table
+ partitioning expressions (i.e. have no subselects/user vars/PS parameters
+ etc etc). An Item* tree is assumed to have the same monotonicity properties
+ as its correspoinding function F:
+
+ [signed] longlong F(field1, field2, ...) {
+ put values of field_i into table record buffer;
+ return item->val_int();
+ }
+
+ NOTE
+ At the moment function monotonicity is not well defined (and so may be
+ incorrect) for Item trees with parameters/return types that are different
+ from INT_RESULT, may be NULL, or are unsigned.
+ It will be possible to address this issue once the related partitioning bugs
+ (BUG#16002, BUG#15447, BUG#13436) are fixed.
+*/
+
+typedef enum monotonicity_info
+{
+ NON_MONOTONIC, /* none of the below holds */
+ MONOTONIC_INCREASING, /* F() is unary and (x < y) => (F(x) <= F(y)) */
+ MONOTONIC_STRICT_INCREASING /* F() is unary and (x < y) => (F(x) < F(y)) */
+} enum_monotonicity_info;
+
/*************************************************************************/
class sp_rcontext;
@@ -418,7 +446,7 @@ public:
};
-typedef bool (Item::*Item_processor) (byte *arg);
+typedef bool (Item::*Item_processor) (uchar *arg);
/*
Analyzer function
SYNOPSIS
@@ -430,8 +458,8 @@ typedef bool (Item::*Item_processor) (byte *arg);
FALSE Don't do it
*/
-typedef bool (Item::*Item_analyzer) (byte **argp);
-typedef Item* (Item::*Item_transformer) (byte *arg);
+typedef bool (Item::*Item_analyzer) (uchar **argp);
+typedef Item* (Item::*Item_transformer) (uchar *arg);
typedef void (*Cond_traverser) (const Item *item, void *arg);
@@ -440,9 +468,9 @@ class Item {
void operator=(Item &);
public:
static void *operator new(size_t size) throw ()
- { return (void*) sql_alloc((uint) size); }
+ { return sql_alloc(size); }
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
- { return (void*) alloc_root(mem_root, (uint) size); }
+ { return alloc_root(mem_root, size); }
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
@@ -453,6 +481,7 @@ public:
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM,
+ XPATH_NODESET, XPATH_NODESET_CMP,
VIEW_FIXER_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -467,9 +496,9 @@ public:
save_in_field
*/
String str_value;
- my_string name; /* Name from select */
+ char * name; /* Name from select */
/* Original item name (if it was renamed)*/
- my_string orig_name;
+ char * orig_name;
Item *next;
uint32 max_length;
uint name_length; /* Length of name */
@@ -527,8 +556,55 @@ public:
virtual bool eq(const Item *, bool binary_cmp) const;
virtual Item_result result_type() const { return REAL_RESULT; }
virtual Item_result cast_to_int_type() const { return result_type(); }
+ virtual enum_field_types string_field_type() const;
virtual enum_field_types field_type() const;
virtual enum Type type() const =0;
+
+ /*
+ Return information about function monotonicity. See comment for
+ enum_monotonicity_info for details. This function can only be called
+ after fix_fields() call.
+ */
+ virtual enum_monotonicity_info get_monotonicity_info() const
+ { return NON_MONOTONIC; }
+
+ /*
+ Convert "func_arg $CMP$ const" half-interval into "FUNC(func_arg) $CMP2$ const2"
+
+ SYNOPSIS
+ val_int_endpoint()
+ left_endp FALSE <=> The interval is "x < const" or "x <= const"
+ TRUE <=> The interval is "x > const" or "x >= const"
+
+ incl_endp IN TRUE <=> the comparison is '<' or '>'
+ FALSE <=> the comparison is '<=' or '>='
+ OUT The same but for the "F(x) $CMP$ F(const)" comparison
+
+ DESCRIPTION
+ This function is defined only for unary monotonic functions. The caller
+ supplies the source half-interval
+
+ x $CMP$ const
+
+ The value of const is supplied implicitly as the value this item's
+ argument, the form of $CMP$ comparison is specified through the
+ function's arguments. The calle returns the result interval
+
+ F(x) $CMP2$ F(const)
+
+ passing back F(const) as the return value, and the form of $CMP2$
+ through the out parameter. NULL values are assumed to be comparable and
+ be less than any non-NULL values.
+
+ RETURN
+ The output range bound, which equal to the value of val_int()
+ - If the value of the function is NULL then the bound is the
+ smallest possible value of LONGLONG_MIN
+ */
+ virtual longlong val_int_endpoint(bool left_endp, bool *incl_endp)
+ { DBUG_ASSERT(0); return 0; }
+
+
/* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
/*
Return double precision floating point representation of item.
@@ -619,6 +695,7 @@ public:
TRUE value is true (not equal to 0)
*/
virtual bool val_bool();
+ virtual String *val_nodeset(String*) { return 0; }
/* Helper functions, see item_sum.cc */
String *val_string_from_real(String *str);
String *val_string_from_int(String *str);
@@ -691,20 +768,24 @@ public:
*/
virtual bool const_during_execution() const
{ return (used_tables() & ~PARAM_TABLE_BIT) == 0; }
- /*
- This is an essential method for correct functioning of VIEWS.
- To save a view in an .frm file we need its unequivocal
- definition in SQL that takes into account sql_mode and
- environmental settings. Currently such definition is restored
- by traversing through the parsed tree of a view and
- print()'ing SQL syntax of every node to a String buffer. This
- method is used to print the SQL definition of an item. The
- second use of this method is for EXPLAIN EXTENDED, to print
- the SQL of a query after all optimizations of the parsed tree
- have been done.
- */
- virtual void print(String *str_arg) { str_arg->append(full_name()); }
- void print_item_w_name(String *);
+
+ /**
+ This method is used for to:
+ - to generate a view definition query (SELECT-statement);
+ - to generate a SQL-query for EXPLAIN EXTENDED;
+ - to generate a SQL-query to be shown in INFORMATION_SCHEMA;
+ - debug.
+
+ For more information about view definition query, INFORMATION_SCHEMA
+ query and why they should be generated from the Item-tree, @see
+ mysql_register_view().
+ */
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(full_name());
+ }
+
+ void print_item_w_name(String *, enum_query_type query_type);
virtual void update_used_tables() {}
virtual void split_sum_func(THD *thd, Item **ref_pointer_array,
List<Item> &fields) {}
@@ -760,12 +841,12 @@ public:
static CHARSET_INFO *default_charset();
virtual CHARSET_INFO *compare_collation() { return NULL; }
- virtual bool walk(Item_processor processor, byte *arg)
+ virtual bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
{
return (this->*processor)(arg);
}
- virtual Item* transform(Item_transformer transformer, byte *arg);
+ virtual Item* transform(Item_transformer transformer, uchar *arg);
/*
This function performs a generic "compilation" of the Item tree.
@@ -783,8 +864,8 @@ public:
i.e. analysis is performed top-down while transformation is done
bottom-up.
*/
- virtual Item* compile(Item_analyzer analyzer, byte **arg_p,
- Item_transformer transformer, byte *arg_t)
+ virtual Item* compile(Item_analyzer analyzer, uchar **arg_p,
+ Item_transformer transformer, uchar *arg_t)
{
if ((this->*analyzer) (arg_p))
return ((this->*transformer) (arg_t));
@@ -797,24 +878,77 @@ public:
(*traverser)(this, arg);
}
- virtual bool remove_dependence_processor(byte * arg) { return 0; }
- virtual bool remove_fixed(byte * arg) { fixed= 0; return 0; }
- virtual bool cleanup_processor(byte *arg);
- virtual bool collect_item_field_processor(byte * arg) { return 0; }
- virtual bool find_item_in_field_list_processor(byte *arg) { return 0; }
- virtual bool change_context_processor(byte *context) { return 0; }
- virtual bool reset_query_id_processor(byte *query_id_arg) { return 0; }
- virtual bool is_expensive_processor(byte *arg) { return 0; }
- virtual bool subst_argument_checker(byte **arg)
+ 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);
+ virtual bool collect_item_field_processor(uchar * arg) { return 0; }
+ virtual bool find_item_in_field_list_processor(uchar *arg) { return 0; }
+ virtual bool change_context_processor(uchar *context) { return 0; }
+ virtual bool reset_query_id_processor(uchar *query_id_arg) { return 0; }
+ virtual bool is_expensive_processor(uchar *arg) { return 0; }
+ virtual bool register_field_in_read_map(uchar *arg) { return 0; }
+ /*
+ Check if a partition function is allowed
+ SYNOPSIS
+ check_partition_func_processor()
+ int_arg Ignored
+ RETURN VALUE
+ TRUE Partition function not accepted
+ FALSE Partition function accepted
+
+ DESCRIPTION
+ check_partition_func_processor is used to check if a partition function
+ uses an allowed function. An allowed function will always ensure that
+ X=Y guarantees that also part_function(X)=part_function(Y) where X is
+ a set of partition fields and so is Y. The problems comes mainly from
+ character sets where two equal strings can be quite unequal. E.g. the
+ german character for double s is equal to 2 s.
+
+ The default is that an item is not allowed
+ in a partition function. Allowed functions
+ can never depend on server version, they cannot depend on anything
+ related to the environment. They can also only depend on a set of
+ fields in the table itself. They cannot depend on other tables and
+ cannot contain any queries and cannot contain udf's or similar.
+ If a new Item class is defined and it inherits from a class that is
+ allowed in a partition function then it is very important to consider
+ whether this should be inherited to the new class. If not the function
+ below should be defined in the new Item class.
+
+ The general behaviour is that most integer functions are allowed.
+ If the partition function contains any multi-byte collations then
+ the function check_part_func_fields will report an error on the
+ partition function independent of what functions are used. So the
+ only character sets allowed are single character collation and
+ even for those only a limited set of functions are allowed. The
+ problem with multi-byte collations is that almost every string
+ function has the ability to change things such that two strings
+ that are equal will not be equal after manipulated by a string
+ function. E.g. two strings one contains a double s, there is a
+ special german character that is equal to two s. Now assume a
+ string function removes one character at this place, then in
+ one the double s will be removed and in the other there will
+ still be one s remaining and the strings are no longer equal
+ and thus the partition function will not sort equal strings into
+ the same partitions.
+
+ So the check if a partition function is valid is two steps. First
+ check that the field types are valid, next check that the partition
+ function is valid. The current set of partition functions valid
+ assumes that there are no multi-byte collations amongst the partition
+ fields.
+ */
+ virtual bool check_partition_func_processor(uchar *bool_arg) { return TRUE;}
+ virtual bool subst_argument_checker(uchar **arg)
{
if (*arg)
*arg= NULL;
return TRUE;
}
- virtual Item *equal_fields_propagator(byte * arg) { return this; }
- virtual bool set_no_const_sub(byte *arg) { return FALSE; }
- virtual Item *replace_equal_field(byte * arg) { return this; }
+ virtual Item *equal_fields_propagator(uchar * arg) { return this; }
+ virtual bool set_no_const_sub(uchar *arg) { return FALSE; }
+ virtual Item *replace_equal_field(uchar * arg) { return this; }
/*
For SP local variable returns pointer to Item representing its
@@ -839,11 +973,11 @@ public:
// used in row subselects to get value of elements
virtual void bring_value() {}
- Field *tmp_table_field_from_field_type(TABLE *table);
+ Field *tmp_table_field_from_field_type(TABLE *table, bool fixed_length);
virtual Item_field *filed_for_view_update() { return 0; }
virtual Item *neg_transformer(THD *thd) { return NULL; }
- virtual Item *update_value_transformer(byte *select_arg) { return this; }
+ virtual Item *update_value_transformer(uchar *select_arg) { return this; }
virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
void delete_self()
{
@@ -1021,7 +1155,7 @@ public:
const Item *this_item() const;
Item **this_item_addr(THD *thd, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
public:
inline const LEX_STRING *my_name() const;
@@ -1074,7 +1208,7 @@ inline Item_result Item_splocal::result_type() const
class Item_case_expr :public Item_sp_variable
{
public:
- Item_case_expr(int case_expr_id);
+ Item_case_expr(uint case_expr_id);
public:
Item *this_item();
@@ -1090,10 +1224,10 @@ public:
Item_case_expr can not occur in views, so here it is only for debug
purposes.
*/
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
private:
- int m_case_expr_id;
+ uint m_case_expr_id;
};
/*****************************************************************************
@@ -1141,7 +1275,7 @@ public:
String *val_str(String *sp);
my_decimal *val_decimal(my_decimal *);
bool is_null();
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_result result_type() const
{
@@ -1178,6 +1312,7 @@ public:
Item_num() {} /* 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;}
};
#define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -1221,9 +1356,9 @@ public:
Item_ident(THD *thd, Item_ident *item);
const char *full_name() const;
void cleanup();
- bool remove_dependence_processor(byte * arg);
- void print(String *str);
- virtual bool change_context_processor(byte *cntx)
+ bool remove_dependence_processor(uchar * arg);
+ virtual void print(String *str, enum_query_type query_type);
+ virtual bool change_context_processor(uchar *cntx)
{ context= (Name_resolution_context *)cntx; return FALSE; }
friend bool insert_fields(THD *thd, Name_resolution_context *context,
const char *db_name,
@@ -1320,6 +1455,11 @@ public:
{
return field->type();
}
+ enum_monotonicity_info get_monotonicity_info() const
+ {
+ return MONOTONIC_STRICT_INCREASING;
+ }
+ 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);
@@ -1328,31 +1468,26 @@ public:
bool is_null() { return field->is_null(); }
void update_null_value();
Item *get_tmp_table_item(THD *thd);
- bool collect_item_field_processor(byte * arg);
- bool find_item_in_field_list_processor(byte *arg);
- bool reset_query_id_processor(byte *arg)
- {
- field->query_id= *((query_id_t *) arg);
- if (result_field)
- result_field->query_id= field->query_id;
- return 0;
- }
+ bool collect_item_field_processor(uchar * arg);
+ bool find_item_in_field_list_processor(uchar *arg);
+ bool register_field_in_read_map(uchar *arg);
+ bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
void cleanup();
bool result_as_longlong()
{
return field->can_be_compared_as_longlong();
}
Item_equal *find_item_equal(COND_EQUAL *cond_equal);
- bool subst_argument_checker(byte **arg);
- Item *equal_fields_propagator(byte *arg);
- bool set_no_const_sub(byte *arg);
- Item *replace_equal_field(byte *arg);
+ bool subst_argument_checker(uchar **arg);
+ Item *equal_fields_propagator(uchar *arg);
+ bool set_no_const_sub(uchar *arg);
+ Item *replace_equal_field(uchar *arg);
inline uint32 max_disp_length() { return field->max_display_length(); }
Item_field *filed_for_view_update() { return this; }
Item *safe_charset_converter(CHARSET_INFO *tocs);
int fix_outer_field(THD *thd, Field **field, Item **reference);
- virtual Item *update_value_transformer(byte *select_arg);
- void print(String *str);
+ virtual Item *update_value_transformer(uchar *select_arg);
+ virtual void print(String *str, enum_query_type query_type);
Field::geometry_type get_geometry_type() const
{
DBUG_ASSERT(field_type() == MYSQL_TYPE_GEOMETRY);
@@ -1388,8 +1523,14 @@ public:
bool basic_const_item() const { return 1; }
Item *clone_item() { return new Item_null(name); }
bool is_null() { return 1; }
- void print(String *str) { str->append(STRING_WITH_LEN("NULL")); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(STRING_WITH_LEN("NULL"));
+ }
+
Item *safe_charset_converter(CHARSET_INFO *tocs);
+ bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
};
class Item_null_result :public Item_null
@@ -1402,6 +1543,7 @@ public:
{
save_in_field(result_field, no_conversions);
}
+ bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
};
/* Item represents one placeholder ('?') of prepared statement */
@@ -1518,7 +1660,7 @@ public:
*/
virtual table_map used_tables() const
{ return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool is_null()
{ DBUG_ASSERT(state != NO_VALUE); return state == NULL_VALUE; }
bool basic_const_item() const;
@@ -1542,6 +1684,7 @@ public:
bool eq(const Item *item, bool binary_cmp) const;
/** Item is a argument to a limit clause. */
bool limit_clause_param;
+ void set_param_type_and_swap_value(Item_param *from);
};
@@ -1571,11 +1714,12 @@ public:
int save_in_field(Field *field, bool no_conversions);
bool basic_const_item() const { return 1; }
Item *clone_item() { return new Item_int(name,value,max_length); }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_num *neg() { value= -value; return this; }
uint decimal_precision() const
{ return (uint)(max_length - test(value < 0)); }
bool eq(const Item *, bool binary_cmp) const;
+ bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
};
@@ -1590,9 +1734,10 @@ public:
String *val_str(String*);
Item *clone_item() { return new Item_uint(name, value, max_length); }
int save_in_field(Field *field, bool no_conversions);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_num *neg ();
uint decimal_precision() const { return max_length; }
+ bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
};
@@ -1608,7 +1753,7 @@ public:
Item_decimal(my_decimal *value_par);
Item_decimal(longlong val, bool unsig);
Item_decimal(double val, int precision, int scale);
- Item_decimal(const char *bin, int precision, int scale);
+ Item_decimal(const uchar *bin, int precision, int scale);
enum Type type() const { return DECIMAL_ITEM; }
enum Item_result result_type () const { return DECIMAL_RESULT; }
@@ -1623,7 +1768,7 @@ public:
{
return new Item_decimal(name, &decimal_value, decimals, max_length);
}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
Item_num *neg()
{
my_decimal_neg(&decimal_value);
@@ -1633,6 +1778,7 @@ public:
uint decimal_precision() const { return decimal_value.precision(); }
bool eq(const Item *, bool binary_cmp) const;
void set_decimal_value(my_decimal *value_par);
+ bool check_partition_func_processor(uchar *bool_arg) { return FALSE;}
};
@@ -1651,8 +1797,11 @@ public:
max_length=length;
fixed= 1;
}
- Item_float(double value_par) :presentation(0), value(value_par) { fixed= 1; }
-
+ Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par)
+ {
+ decimals= (uint8) decimal_par;
+ fixed= 1;
+ }
int save_in_field(Field *field, bool no_conversions);
enum Type type() const { return REAL_ITEM; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
@@ -1676,7 +1825,7 @@ public:
Item *clone_item()
{ return new Item_float(name, value, decimals, max_length); }
Item_num *neg() { value= -value; return this; }
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool eq(const Item *, bool binary_cmp) const;
};
@@ -1689,7 +1838,12 @@ public:
uint length)
:Item_float(NullS, val_arg, decimal_par, length), func_name(str)
{}
- void print(String *str) { str->append(func_name); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(func_name);
+ }
+
Item *safe_charset_converter(CHARSET_INFO *tocs);
};
@@ -1700,6 +1854,7 @@ public:
Item_string(const char *str,uint length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
uint repertoire= MY_REPERTOIRE_UNICODE30)
+ : m_cs_specified(FALSE)
{
str_value.set_or_copy_aligned(str, length, cs);
collation.set(cs, dv, repertoire);
@@ -1707,7 +1862,7 @@ public:
We have to have a different max_length than 'length' here to
ensure that we get the right length if we do use the item
to create a new table. In this case max_length must be the maximum
- number of chars for a string of this type because we in create_field::
+ number of chars for a string of this type because we in Create_field::
divide the max_length with mbmaxlen).
*/
max_length= str_value.numchars()*cs->mbmaxlen;
@@ -1718,6 +1873,7 @@ public:
}
/* Just create an item and do not fill string representation */
Item_string(CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE)
+ : m_cs_specified(FALSE)
{
collation.set(cs, dv);
max_length= 0;
@@ -1728,6 +1884,7 @@ public:
Item_string(const char *name_par, const char *str, uint length,
CHARSET_INFO *cs, Derivation dv= DERIVATION_COERCIBLE,
uint repertoire= MY_REPERTOIRE_UNICODE30)
+ : m_cs_specified(FALSE)
{
str_value.set_or_copy_aligned(str, length, cs);
collation.set(cs, dv, repertoire);
@@ -1777,7 +1934,50 @@ public:
str_value.append(str, length);
max_length= str_value.numchars() * collation.collation->mbmaxlen;
}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
+ bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
+
+ /**
+ Return TRUE if character-set-introducer was explicitly specified in the
+ original query for this item (text literal).
+
+ This operation is to be called from Item_string::print(). The idea is
+ that when a query is generated (re-constructed) from the Item-tree,
+ character-set-introducers should appear only for those literals, where
+ they were explicitly specified by the user. Otherwise, that may lead to
+ loss collation information (character set introducers implies default
+ collation for the literal).
+
+ Basically, that makes sense only for views and hopefully will be gone
+ one day when we start using original query as a view definition.
+
+ @return This operation returns the value of m_cs_specified attribute.
+ @retval TRUE if character set introducer was explicitly specified in
+ the original query.
+ @retval FALSE otherwise.
+ */
+ inline bool is_cs_specified() const
+ {
+ return m_cs_specified;
+ }
+
+ /**
+ Set the value of m_cs_specified attribute.
+
+ m_cs_specified attribute shows whether character-set-introducer was
+ explicitly specified in the original query for this text literal or
+ not. The attribute makes sense (is used) only for views.
+
+ This operation is to be called from the parser during parsing an input
+ query.
+ */
+ inline void set_cs_specified(bool cs_specified)
+ {
+ m_cs_specified= cs_specified;
+ }
+
+private:
+ bool m_cs_specified;
};
@@ -1791,43 +1991,73 @@ public:
:Item_string(NullS, str, length, cs, dv), func_name(name_par)
{}
Item *safe_charset_converter(CHARSET_INFO *tocs);
- void print(String *str) { str->append(func_name); }
+
+ virtual inline void print(String *str, enum_query_type query_type)
+ {
+ str->append(func_name);
+ }
+
+ bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
};
/* for show tables */
+class Item_partition_func_safe_string: public Item_string
+{
+public:
+ Item_partition_func_safe_string(const char *name, uint length,
+ CHARSET_INFO *cs= NULL):
+ Item_string(name, length, cs)
+ {}
+};
+
+
+class Item_return_date_time :public Item_partition_func_safe_string
+{
+ enum_field_types date_time_field_type;
+public:
+ Item_return_date_time(const char *name_arg, enum_field_types field_type_arg)
+ :Item_partition_func_safe_string(name_arg, 0, &my_charset_bin),
+ date_time_field_type(field_type_arg)
+ { }
+ enum_field_types field_type() const { return date_time_field_type; }
+};
-class Item_datetime :public Item_string
+
+class Item_blob :public Item_partition_func_safe_string
{
public:
- Item_datetime(const char *item_name): Item_string(item_name,"",0,
- &my_charset_bin)
- { max_length=19;}
- enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+ Item_blob(const char *name, uint length) :
+ Item_partition_func_safe_string(name, length, &my_charset_bin)
+ { max_length= length; }
+ enum Type type() const { return TYPE_HOLDER; }
+ enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
};
+
/**
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
the client.
*/
-class Item_empty_string :public Item_string
+class Item_empty_string :public Item_partition_func_safe_string
{
public:
Item_empty_string(const char *header,uint length, CHARSET_INFO *cs= NULL) :
- Item_string("",0, cs ? cs : &my_charset_utf8_general_ci)
+ Item_partition_func_safe_string("",0, cs ? cs : &my_charset_utf8_general_ci)
{ name=(char*) header; max_length= length * collation.collation->mbmaxlen; }
void make_field(Send_field *field);
};
+
class Item_return_int :public Item_int
{
enum_field_types int_field_type;
public:
Item_return_int(const char *name_arg, uint length,
- enum_field_types field_type_arg)
- :Item_int(name_arg, 0, length), int_field_type(field_type_arg)
+ enum_field_types field_type_arg, longlong value= 0)
+ :Item_int(name_arg, value, length), int_field_type(field_type_arg)
{
unsigned_flag=1;
}
@@ -1854,9 +2084,10 @@ public:
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; }
- void print(String *str);
+ 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;}
};
@@ -1972,9 +2203,9 @@ public:
{
return ref ? (*ref)->real_item() : this;
}
- bool walk(Item_processor processor, byte *arg)
- { return (*ref)->walk(processor, arg); }
- void print(String *str);
+ bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
+ { return (*ref)->walk(processor, walk_subquery, arg); }
+ virtual void print(String *str, enum_query_type query_type);
bool result_as_longlong()
{
return (*ref)->result_as_longlong();
@@ -2150,7 +2381,7 @@ public:
my_decimal *val_decimal(my_decimal *);
bool val_bool();
bool get_date(MYSQL_TIME *ltime, uint fuzzydate);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
/*
we add RAND_TABLE_BIT to prevent moving this item from HAVING to WHERE
*/
@@ -2188,7 +2419,7 @@ public:
virtual Item *real_item() { return ref; }
};
-
+#ifdef MYSQL_SERVER
#include "gstream.h"
#include "spatial.h"
#include "item_sum.h"
@@ -2198,8 +2429,9 @@ public:
#include "item_strfunc.h"
#include "item_geofunc.h"
#include "item_timefunc.h"
-#include "item_uniq.h"
#include "item_subselect.h"
+#include "item_xmlfunc.h"
+#endif
class Item_copy_string :public Item
{
@@ -2296,7 +2528,7 @@ public:
class Cached_item_field :public Cached_item
{
- char *buff;
+ uchar *buff;
Field *field;
uint length;
@@ -2304,7 +2536,7 @@ public:
Cached_item_field(Item_field *item)
{
field= item->field;
- buff= (char*) sql_calloc(length=field->pack_length());
+ buff= (uchar*) sql_calloc(length=field->pack_length());
}
bool cmp(void);
};
@@ -2324,17 +2556,17 @@ public:
enum Type type() const { return DEFAULT_VALUE_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
int save_in_field(Field *field_arg, bool no_conversions);
table_map used_tables() const { return (table_map)0L; }
- bool walk(Item_processor processor, byte *args)
+ bool walk(Item_processor processor, bool walk_subquery, uchar *args)
{
- return arg->walk(processor, args) ||
+ return arg->walk(processor, walk_subquery, args) ||
(this->*processor)(args);
}
- Item *transform(Item_transformer transformer, byte *args);
+ Item *transform(Item_transformer transformer, uchar *args);
};
/*
@@ -2357,7 +2589,7 @@ public:
arg(a) {}
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
int save_in_field(Field *field_arg, bool no_conversions)
{
return Item_field::save_in_field(field_arg, no_conversions);
@@ -2368,9 +2600,9 @@ public:
*/
table_map used_tables() const { return RAND_TABLE_BIT; }
- bool walk(Item_processor processor, byte *args)
+ bool walk(Item_processor processor, bool walk_subquery, uchar *args)
{
- return arg->walk(processor, args) ||
+ return arg->walk(processor, walk_subquery, args) ||
(this->*processor)(args);
}
};
@@ -2428,7 +2660,7 @@ public:
enum Type type() const { return TRIGGER_FIELD_ITEM; }
bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, Item **);
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
table_map used_tables() const { return (table_map)0L; }
Field *get_tmp_table_field() { return 0; }
Item *copy_or_same(THD *thd) { return this; }
@@ -2484,10 +2716,19 @@ protected:
For all other uses of Item_cache, cached_field doesn't matter.
*/
Field *cached_field;
+ enum enum_field_types cached_field_type;
public:
- Item_cache(): example(0), used_table_map(0), cached_field(0)
+ Item_cache():
+ example(0), used_table_map(0), cached_field(0), cached_field_type(MYSQL_TYPE_STRING)
{
- fixed= 1; null_value= 1;
+ 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)
+ {
+ fixed= 1;
+ null_value= 1;
}
void set_used_tables(table_map map) { used_table_map= map; }
@@ -2506,10 +2747,11 @@ public:
};
virtual void store(Item *)= 0;
enum Type type() const { return CACHE_ITEM; }
+ enum_field_types field_type() const { return cached_field_type; }
static Item_cache* get_cache(const Item *item);
table_map used_tables() const { return used_table_map; }
virtual void keep_array() {}
- void print(String *str);
+ virtual void print(String *str, enum_query_type query_type);
bool eq_def(Field *field)
{
return cached_field ? cached_field->eq_def (field) : FALSE;
@@ -2527,6 +2769,8 @@ protected:
longlong value;
public:
Item_cache_int(): Item_cache(), value(0) {}
+ Item_cache_int(enum_field_types field_type_arg):
+ Item_cache(field_type_arg), value(0) {}
void store(Item *item);
void store(Item *item, longlong val_arg);