diff options
Diffstat (limited to 'sql/item.h')
-rw-r--r-- | sql/item.h | 292 |
1 files changed, 267 insertions, 25 deletions
diff --git a/sql/item.h b/sql/item.h index 5dd49d9c6b2..fb2948a9149 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1,8 +1,8 @@ #ifndef SQL_ITEM_INCLUDED #define SQL_ITEM_INCLUDED -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009, 2013 Monty Program Ab +/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. + 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 @@ -15,7 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifdef USE_PRAGMA_INTERFACE @@ -384,6 +384,12 @@ struct Name_resolution_context: Sql_alloc { (*error_processor)(thd, error_processor_data); } + st_select_lex *outer_select() + { + return (outer_context ? + outer_context->select_lex : + NULL); + } }; @@ -548,11 +554,21 @@ typedef bool (Item::*Item_analyzer) (uchar **argp); typedef Item* (Item::*Item_transformer) (uchar *arg); typedef void (*Cond_traverser) (const Item *item, void *arg); +struct st_cond_statistic; + +struct find_selective_predicates_list_processor_data +{ + TABLE *table; + List<st_cond_statistic> list; +}; + class Item_equal; class COND_EQUAL; class st_select_lex_unit; +class Item_func_not; + class Item { Item(const Item &); /* Prevent use of these */ void operator=(Item &); @@ -583,7 +599,8 @@ public: SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER, PARAM_ITEM, TRIGGER_FIELD_ITEM, DECIMAL_ITEM, XPATH_NODESET, XPATH_NODESET_CMP, - VIEW_FIXER_ITEM, EXPR_CACHE_ITEM}; + VIEW_FIXER_ITEM, EXPR_CACHE_ITEM, + DATE_ITEM}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; @@ -940,7 +957,9 @@ public: my_decimal *val_decimal_from_date(my_decimal *decimal_value); my_decimal *val_decimal_from_time(my_decimal *decimal_value); longlong val_int_from_decimal(); + longlong val_int_from_date(); double val_real_from_decimal(); + double val_real_from_date(); int save_time_in_field(Field *field); int save_date_in_field(Field *field); @@ -1041,7 +1060,7 @@ public: Item **ref, bool skip_registered); virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); bool get_time(MYSQL_TIME *ltime) - { return get_date(ltime, TIME_TIME_ONLY | TIME_FUZZY_DATE | TIME_INVALID_DATES); } + { return get_date(ltime, TIME_TIME_ONLY | TIME_INVALID_DATES); } bool get_seconds(ulonglong *sec, ulong *sec_part); virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate) { return get_date(ltime,fuzzydate); } @@ -1097,8 +1116,8 @@ public: */ virtual CHARSET_INFO *charset_for_protocol(void) const { - return result_type() == STRING_RESULT ? collation.collation : - &my_charset_bin; + return cmp_type() == STRING_RESULT ? collation.collation : + &my_charset_bin; }; virtual bool walk(Item_processor processor, bool walk_subquery, uchar *arg) @@ -1106,6 +1125,11 @@ public: return (this->*processor)(arg); } + virtual bool walk_top_and(Item_processor processor, uchar *arg) + { + return (this->*processor)(arg); + } + virtual Item* transform(Item_transformer transformer, uchar *arg); /* @@ -1153,6 +1177,7 @@ public: virtual bool collect_item_field_processor(uchar * arg) { return 0; } virtual bool add_field_to_set_processor(uchar * arg) { return 0; } virtual bool find_item_in_field_list_processor(uchar *arg) { return 0; } + virtual bool find_item_processor(uchar *arg); 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; } @@ -1167,9 +1192,12 @@ public: virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; } virtual bool is_subquery_processor (uchar *opt_arg) { return 0; } virtual bool limit_index_condition_pushdown_processor(uchar *opt_arg) - { + { return FALSE; } + virtual bool exists2in_processor(uchar *opt_arg) { return 0; } + virtual bool find_selective_predicates_list_processor(uchar *opt_arg) + { return 0; } /* To call bool function for all arguments */ struct bool_func_call_args @@ -1186,6 +1214,7 @@ public: return FALSE; } + /* The next function differs from the previous one that a bitmap to be updated is passed as uchar *arg. @@ -1315,7 +1344,9 @@ public: List<Item> *parameters; /* unit from which we count nest_level */ st_select_lex_unit *nest_level_base; + uint count; int nest_level; + bool collect; }; /** Collect outer references @@ -1444,6 +1475,12 @@ public: 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_equal *get_item_equal() { return NULL; } @@ -1478,6 +1515,15 @@ public: virtual void get_cache_parameters(List<Item> ¶meters) { }; virtual void mark_as_condition_AND_part(TABLE_LIST *embedding) {}; + + /* how much position should be reserved for Exists2In transformation */ + virtual uint exists2in_reserved_items() { return 0; }; + + /** + Inform the item that it is located under a NOT, which is a top-level item. + */ + virtual void under_not(Item_func_not * upper + __attribute__((unused))) {}; }; @@ -2724,41 +2770,221 @@ 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); + 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_hybrid +{ +public: + Item_bin_string(const char *str,uint str_length); +}; + + +class Item_temporal_literal :public Item_basic_constant +{ + //sql_mode= current_thd->variables.sql_mode & + // (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE); +protected: + MYSQL_TIME cached_time; +public: + /** + Constructor for Item_date_literal. + @param ltime DATE value. + */ + Item_temporal_literal(MYSQL_TIME *ltime) :Item_basic_constant() + { + collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); + decimals= 0; + cached_time= *ltime; + } + Item_temporal_literal(MYSQL_TIME *ltime, uint dec_arg) :Item_basic_constant() + { + collation.set(&my_charset_numeric, DERIVATION_NUMERIC, MY_REPERTOIRE_ASCII); + decimals= dec_arg; + cached_time= *ltime; + } + bool basic_const_item() const { return true; } + bool const_item() const { return true; } + enum Type type() const { return DATE_ITEM; } bool eq(const Item *item, bool binary_cmp) const; - virtual Item *safe_charset_converter(CHARSET_INFO *tocs); + enum Item_result result_type () const { return STRING_RESULT; } + Item_result cmp_type() const { return TIME_RESULT; } + 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); + + String *val_str(String *str) + { return val_string_from_date(str); } + longlong val_int() + { return val_int_from_date(); } + double val_real() + { return val_real_from_date(); } + my_decimal *val_decimal(my_decimal *decimal_value) + { return val_decimal_from_date(decimal_value); } + Field *tmp_table_field(TABLE *table) + { return tmp_table_field_from_field_type(table, 0); } + int save_in_field(Field *field, bool no_conversions) + { return save_date_in_field(field); } }; -class Item_bin_string: public Item_hex_string +/** + DATE'2010-01-01' +*/ +class Item_date_literal: public Item_temporal_literal { public: - Item_bin_string(const char *str,uint str_length); + Item_date_literal(MYSQL_TIME *ltime) + :Item_temporal_literal(ltime) + { + max_length= MAX_DATE_WIDTH; + fixed= 1; + } + enum_field_types field_type() const { return MYSQL_TYPE_DATE; } + void print(String *str, enum_query_type query_type); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); +}; + + +/** + TIME'10:10:10' +*/ +class Item_time_literal: public Item_temporal_literal +{ +public: + Item_time_literal(MYSQL_TIME *ltime, uint dec_arg) + :Item_temporal_literal(ltime, dec_arg) + { + max_length= MIN_TIME_WIDTH + (decimals ? decimals + 1 : 0); + fixed= 1; + } + enum_field_types field_type() const { return MYSQL_TYPE_TIME; } + void print(String *str, enum_query_type query_type); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); +}; + + +/** + TIMESTAMP'2001-01-01 10:20:30' +*/ +class Item_datetime_literal: public Item_temporal_literal +{ +public: + Item_datetime_literal(MYSQL_TIME *ltime, uint dec_arg) + :Item_temporal_literal(ltime, dec_arg) + { + max_length= MAX_DATETIME_WIDTH + (decimals ? decimals + 1 : 0); + fixed= 1; + } + enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; } + void print(String *str, enum_query_type query_type); + bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date); }; + + class Item_result_field :public Item /* Item with result field */ { public: @@ -2957,6 +3183,14 @@ public: DBUG_ASSERT(ref); return (*ref)->is_outer_field(); } + + /** + Checks if the item tree that ref points to contains a subquery. + */ + virtual bool has_subquery() const + { + return (*ref)->has_subquery(); + } }; @@ -2983,6 +3217,13 @@ public: alias_name_used_arg) {} + bool fix_fields(THD *thd, Item **it) + { + if ((!(*ref)->fixed && (*ref)->fix_fields(thd, ref)) || + (*ref)->check_cols(1)) + return TRUE; + return Item_ref::fix_fields(thd, it); + } void save_val(Field *to); double val_real(); longlong val_int(); @@ -3202,7 +3443,7 @@ public: bool subst_argument_checker(uchar **arg); Item *equal_fields_propagator(uchar *arg); Item *replace_equal_field(uchar *arg); - table_map used_tables() const; + table_map used_tables() const; table_map not_null_tables() const; void update_used_tables(); bool walk(Item_processor processor, bool walk_subquery, uchar *arg) @@ -3569,7 +3810,7 @@ public: } virtual longlong val_int() { - return null_value ? LL(0) : cached_value; + return null_value ? 0 : cached_value; } virtual void copy(); }; @@ -4030,6 +4271,7 @@ public: bool cache_value(); 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 |