diff options
Diffstat (limited to 'sql/item.h')
-rw-r--r-- | sql/item.h | 454 |
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); |