diff options
Diffstat (limited to 'sql/item.h')
-rw-r--r-- | sql/item.h | 108 |
1 files changed, 90 insertions, 18 deletions
diff --git a/sql/item.h b/sql/item.h index 8568e89542e..4bad8bf0722 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. 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 @@ -488,8 +488,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}; + XPATH_NODESET, XPATH_NODESET_CMP}; enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE }; @@ -519,6 +518,8 @@ public: int8 marker; uint8 decimals; my_bool maybe_null; /* If item may be null */ + my_bool in_rollup; /* If used in GROUP BY list + of a query with ROLLUP */ my_bool null_value; /* if item is null */ my_bool unsigned_flag; my_bool with_sum_func; @@ -555,10 +556,17 @@ public: Field *make_string_field(TABLE *table); virtual bool fix_fields(THD *, Item **); /* - should be used in case where we are sure that we do not need + This method should be used in case where we are sure that we do not need complete fix_fields() procedure. - */ - inline void quick_fix_field() { fixed= 1; } + Usually this method is used by the optimizer when it has to create a new + item out of other already fixed items. For example, if the optimizer has + to create a new Item_func for an inferred equality whose left and right + parts are already fixed items. In some cases the optimizer cannot use + directly fixed items as the arguments of the created functional item, + but rather uses intermediate type conversion items. Then the method is + supposed to be applied recursively. + */ + virtual inline void quick_fix_field() { fixed= 1; } /* Function returns 1 on overflow and -1 on fatal errors */ int save_in_field_no_warnings(Field *field, bool no_conversions); virtual int save_in_field(Field *field, bool no_conversions); @@ -745,7 +753,11 @@ public: virtual bool val_bool_result() { return val_bool(); } virtual bool is_null_result() { return is_null(); } - /* bit map of tables used by item */ + /* + Bitmap of tables used by item + (note: if you need to check dependencies on individual columns, check out + class Field_enumerator) + */ virtual table_map used_tables() const { return (table_map) 0L; } /* Return table map of tables that can't be NULL tables (tables that are @@ -848,6 +860,7 @@ public: set value of aggregate function in case of no rows for grouping were found */ virtual void no_rows_in_result() {} + virtual void restore_to_before_no_rows_in_result() {} virtual Item *copy_or_same(THD *thd) { return this; } virtual Item *copy_andor_structure(THD *thd) { return this; } virtual Item *real_item() { return this; } @@ -901,8 +914,24 @@ public: 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 find_item_processor(uchar *arg) { return this == (void *) arg; } virtual bool register_field_in_read_map(uchar *arg) { return 0; } + virtual bool enumerate_field_refs_processor(uchar *arg) { return 0; } + virtual bool mark_as_eliminated_processor(uchar *arg) { return 0; } + + /* To call bool function for all arguments */ + struct bool_func_call_args + { + Item *original_func_item; + void (Item::*bool_function)(); + }; + bool call_bool_func_processor(uchar *org_item) + { + bool_func_call_args *info= (bool_func_call_args*) org_item; + /* Avoid recursion, as walk also calls for original item */ + if (info->original_func_item != this) + (this->*(info->bool_function))(); + return FALSE; + } /* Check if a partition function is allowed SYNOPSIS @@ -992,6 +1021,8 @@ public: return FALSE; } + virtual bool check_inner_refs_processor(uchar *arg) { return FALSE; } + /* For SP local variable returns pointer to Item representing its current value and pointer to current Item otherwise. @@ -1053,6 +1084,30 @@ public: }; +/* + Class to be used to enumerate all field references in an item tree. + Suggested usage: + + class My_enumerator : public Field_enumerator + { + virtual void visit_field() { ... your actions ...} + } + + My_enumerator enumerator; + item->walk(Item::enumerate_field_refs_processor, ...,(uchar*)&enumerator); + + This is similar to Visitor pattern. +*/ + +class Field_enumerator +{ +public: + virtual void visit_field(Field *field)= 0; + virtual ~Field_enumerator() {}; /* purecov: inspected */ + Field_enumerator() {} /* Remove gcc warning */ +}; + + class sp_head; @@ -1522,6 +1577,7 @@ public: 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;} + bool enumerate_field_refs_processor(uchar *arg); void cleanup(); bool result_as_longlong() { @@ -2060,9 +2116,9 @@ public: class Item_partition_func_safe_string: public Item_string { public: - Item_partition_func_safe_string(const char *name, uint length, + Item_partition_func_safe_string(const char *name_arg, uint length, CHARSET_INFO *cs= NULL): - Item_string(name, length, cs) + Item_string(name_arg, length, cs) {} }; @@ -2082,8 +2138,8 @@ public: class Item_blob :public Item_partition_func_safe_string { public: - Item_blob(const char *name, uint length) : - Item_partition_func_safe_string(name, length, &my_charset_bin) + Item_blob(const char *name_arg, uint length) : + Item_partition_func_safe_string(name_arg, length, &my_charset_bin) { max_length= length; } enum Type type() const { return TYPE_HOLDER; } enum_field_types field_type() const { return MYSQL_TYPE_BLOB; } @@ -2111,8 +2167,8 @@ 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, longlong value= 0) - :Item_int(name_arg, value, length), int_field_type(field_type_arg) + enum_field_types field_type_arg, longlong value_arg= 0) + :Item_int(name_arg, value_arg, length), int_field_type(field_type_arg) { unsigned_flag=1; } @@ -2269,6 +2325,10 @@ public: if (!depended_from) (*ref)->update_used_tables(); } + bool const_item() const + { + return (*ref)->const_item(); + } table_map not_null_tables() const { return (*ref)->not_null_tables(); } void set_result_field(Field *field) { result_field= field; } bool is_result_field() { return 1; } @@ -2285,6 +2345,14 @@ public: return (*ref)->walk(processor, walk_subquery, arg) || (this->*processor)(arg); } + void no_rows_in_result() + { + (*ref)->no_rows_in_result(); + } + void restore_to_before_no_rows_in_result() + { + (*ref)->restore_to_before_no_rows_in_result(); + } virtual void print(String *str, enum_query_type query_type); bool result_as_longlong() { @@ -2417,12 +2485,13 @@ public: of the outer select. */ bool found_in_select_list; + bool found_in_group_by; Item_outer_ref(Name_resolution_context *context_arg, Item_field *outer_field_arg) :Item_direct_ref(context_arg, 0, outer_field_arg->table_name, outer_field_arg->field_name), outer_ref(outer_field_arg), in_sum_func(0), - found_in_select_list(0) + found_in_select_list(0), found_in_group_by(0) { ref= &outer_ref; set_properties(); @@ -2433,7 +2502,7 @@ public: bool alias_name_used_arg) :Item_direct_ref(context_arg, item, table_name_arg, field_name_arg, alias_name_used_arg), - outer_ref(0), in_sum_func(0), found_in_select_list(1) + outer_ref(0), in_sum_func(0), found_in_select_list(1), found_in_group_by(0) {} void save_in_result_field(bool no_conversions) { @@ -2444,7 +2513,9 @@ 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); }; @@ -2845,7 +2916,8 @@ public: { return Item_field::save_in_field(field_arg, no_conversions); } - /* + enum Type type() const { return INSERT_VALUE_ITEM; } + /* We use RAND_TABLE_BIT to prevent Item_insert_value from being treated as a constant and precalculated before execution */ @@ -3044,7 +3116,7 @@ public: Item_cache(field_type_arg), value(0) {} virtual void store(Item *item){ Item_cache::store(item); } - void store(Item *item, longlong val_arg); + void store_longlong(Item *item, longlong val_arg); double val_real(); longlong val_int(); String* val_str(String *str); |