#include "mysql_priv.h"#include "sql_select.h"#include "sql_cursor.h"#include <m_ctype.h>#include <hash.h>#include <ft_global.h>Include dependency graph for sql_select.cc:

Go to the source code of this file.
Classes | |
| struct | key_field_t |
| class | COND_CMP |
Defines | |
| #define | KEY_OPTIMIZE_EXISTS 1 |
| #define | KEY_OPTIMIZE_REF_OR_NULL 2 |
| #define | FT_KEYPART (MAX_REF_PARTS+10) |
| #define | STRING_TOTAL_LENGTH_TO_PACK_ROWS 128 |
| #define | AVG_STRING_LENGTH_TO_PACK_ROWS 64 |
| #define | RATIO_TO_PACK_ROWS 2 |
| #define | MIN_STRING_LENGTH_TO_PACK_ROWS 10 |
Typedefs | |
| typedef key_field_t | KEY_FIELD |
Functions | |
| static void | optimize_keyuse (JOIN *join, DYNAMIC_ARRAY *keyuse_array) |
| static bool | make_join_statistics (JOIN *join, TABLE_LIST *leaves, COND *conds, DYNAMIC_ARRAY *keyuse) |
| static bool | update_ref_and_keys (THD *thd, DYNAMIC_ARRAY *keyuse, JOIN_TAB *join_tab, uint tables, COND *conds, COND_EQUAL *cond_equal, table_map table_map, SELECT_LEX *select_lex) |
| static int | sort_keyuse (KEYUSE *a, KEYUSE *b) |
| static void | set_position (JOIN *join, uint index, JOIN_TAB *table, KEYUSE *key) |
| static bool | create_ref_for_key (JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, table_map used_tables) |
| static void | choose_plan (JOIN *join, table_map join_tables) |
| static void | best_access_path (JOIN *join, JOIN_TAB *s, THD *thd, table_map remaining_tables, uint idx, double record_count, double read_time) |
| static void | optimize_straight_join (JOIN *join, table_map join_tables) |
| static void | greedy_search (JOIN *join, table_map remaining_tables, uint depth, uint prune_level) |
| static void | best_extension_by_limited_search (JOIN *join, table_map remaining_tables, uint idx, double record_count, double read_time, uint depth, uint prune_level) |
| static uint | determine_search_depth (JOIN *join) |
| static int | join_tab_cmp (const void *ptr1, const void *ptr2) |
| static int | join_tab_cmp_straight (const void *ptr1, const void *ptr2) |
| static void | find_best (JOIN *join, table_map rest_tables, uint index, double record_count, double read_time) |
| static uint | cache_record_length (JOIN *join, uint index) |
| static double | prev_record_reads (JOIN *join, table_map found_ref) |
| static bool | get_best_combination (JOIN *join) |
| static store_key * | get_store_key (THD *thd, KEYUSE *keyuse, table_map used_tables, KEY_PART_INFO *key_part, char *key_buff, uint maybe_null) |
| static bool | make_simple_join (JOIN *join, TABLE *tmp_table) |
| static void | make_outerjoin_info (JOIN *join) |
| static bool | make_join_select (JOIN *join, SQL_SELECT *select, COND *item) |
| static void | make_join_readinfo (JOIN *join, uint options) |
| static bool | only_eq_ref_tables (JOIN *join, ORDER *order, table_map tables) |
| static void | update_depend_map (JOIN *join) |
| static void | update_depend_map (JOIN *join, ORDER *order) |
| static ORDER * | remove_const (JOIN *join, ORDER *first_order, COND *cond, bool change_list, bool *simple_order) |
| static int | return_zero_rows (JOIN *join, select_result *res, TABLE_LIST *tables, List< Item > &fields, bool send_row, uint select_options, const char *info, Item *having) |
| static COND * | build_equal_items (THD *thd, COND *cond, COND_EQUAL *inherited, List< TABLE_LIST > *join_list, COND_EQUAL **cond_equal_ref) |
| static COND * | substitute_for_best_equal_field (COND *cond, COND_EQUAL *cond_equal, void *table_join_idx) |
| static COND * | simplify_joins (JOIN *join, List< TABLE_LIST > *join_list, COND *conds, bool top) |
| static bool | check_interleaving_with_nj (JOIN_TAB *last, JOIN_TAB *next) |
| static void | restore_prev_nj_state (JOIN_TAB *last) |
| static void | reset_nj_counters (List< TABLE_LIST > *join_list) |
| static uint | build_bitmap_for_nested_joins (List< TABLE_LIST > *join_list, uint first_unused) |
| static COND * | optimize_cond (JOIN *join, COND *conds, List< TABLE_LIST > *join_list, Item::cond_result *cond_value) |
| static bool | resolve_nested_join (TABLE_LIST *table) |
| static bool | const_expression_in_where (COND *conds, Item *item, Item **comp_item) |
| static bool | open_tmp_table (TABLE *table) |
| static bool | create_myisam_tmp_table (TABLE *table, TMP_TABLE_PARAM *param, ulong options) |
| static int | do_select (JOIN *join, List< Item > *fields, TABLE *tmp_table, Procedure *proc) |
| static enum_nested_loop_state | evaluate_join_record (JOIN *join, JOIN_TAB *join_tab, int error, my_bool *report_error) |
| static enum_nested_loop_state | evaluate_null_complemented_join_record (JOIN *join, JOIN_TAB *join_tab) |
| static enum_nested_loop_state | flush_cached_records (JOIN *join, JOIN_TAB *join_tab, bool skip_last) |
| static enum_nested_loop_state | end_send (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| static enum_nested_loop_state | end_send_group (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| static enum_nested_loop_state | end_write (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| static enum_nested_loop_state | end_update (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| static enum_nested_loop_state | end_unique_update (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| static enum_nested_loop_state | end_write_group (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| static int | test_if_group_changed (List< Cached_item > &list) |
| static int | join_read_const_table (JOIN_TAB *tab, POSITION *pos) |
| static int | join_read_system (JOIN_TAB *tab) |
| static int | join_read_const (JOIN_TAB *tab) |
| static int | join_read_key (JOIN_TAB *tab) |
| static int | join_read_always_key (JOIN_TAB *tab) |
| static int | join_read_last_key (JOIN_TAB *tab) |
| static int | join_no_more_records (READ_RECORD *info) |
| static int | join_read_next (READ_RECORD *info) |
| static int | join_init_quick_read_record (JOIN_TAB *tab) |
| static int | test_if_quick_select (JOIN_TAB *tab) |
| static int | join_init_read_record (JOIN_TAB *tab) |
| static int | join_read_first (JOIN_TAB *tab) |
| static int | join_read_next_same (READ_RECORD *info) |
| static int | join_read_last (JOIN_TAB *tab) |
| static int | join_read_prev_same (READ_RECORD *info) |
| static int | join_read_prev (READ_RECORD *info) |
| static int | join_ft_read_first (JOIN_TAB *tab) |
| static int | join_ft_read_next (READ_RECORD *info) |
| static int | join_read_always_key_or_null (JOIN_TAB *tab) |
| static int | join_read_next_same_or_null (READ_RECORD *info) |
| static COND * | make_cond_for_table (COND *cond, table_map table, table_map used_table) |
| static Item * | part_of_refkey (TABLE *form, Field *field) |
| uint | find_shortest_key (TABLE *table, const key_map *usable_keys) |
| static bool | test_if_skip_sort_order (JOIN_TAB *tab, ORDER *order, ha_rows select_limit, bool no_changes) |
| static bool | list_contains_unique_index (TABLE *table, bool(*find_func)(Field *, void *), void *data) |
| static bool | find_field_in_item_list (Field *field, void *data) |
| static bool | find_field_in_order_list (Field *field, void *data) |
| static int | create_sort_index (THD *thd, JOIN *join, ORDER *order, ha_rows filesort_limit, ha_rows select_limit) |
| static int | remove_duplicates (JOIN *join, TABLE *entry, List< Item > &fields, Item *having) |
| static int | remove_dup_with_compare (THD *thd, TABLE *entry, Field **field, ulong offset, Item *having) |
| static int | remove_dup_with_hash_index (THD *thd, TABLE *table, uint field_count, Field **first_field, ulong key_length, Item *having) |
| static int | join_init_cache (THD *thd, JOIN_TAB *tables, uint table_count) |
| static ulong | used_blob_length (CACHE_FIELD **ptr) |
| static bool | store_record_in_cache (JOIN_CACHE *cache) |
| static void | reset_cache_read (JOIN_CACHE *cache) |
| static void | reset_cache_write (JOIN_CACHE *cache) |
| static void | read_cached_record (JOIN_TAB *tab) |
| static bool | cmp_buffer_with_ref (JOIN_TAB *tab) |
| static bool | setup_new_fields (THD *thd, List< Item > &fields, List< Item > &all_fields, ORDER *new_order) |
| static ORDER * | create_distinct_group (THD *thd, Item **ref_pointer_array, ORDER *order, List< Item > &fields, bool *all_order_by_fields_used) |
| static bool | test_if_subpart (ORDER *a, ORDER *b) |
| static TABLE * | get_sort_by_table (ORDER *a, ORDER *b, TABLE_LIST *tables) |
| static void | calc_group_buffer (JOIN *join, ORDER *group) |
| static bool | make_group_fields (JOIN *main_join, JOIN *curr_join) |
| static bool | alloc_group_fields (JOIN *join, ORDER *group) |
| static bool | change_to_use_tmp_fields (THD *thd, Item **ref_pointer_array, List< Item > &new_list1, List< Item > &new_list2, uint elements, List< Item > &items) |
| static bool | change_refs_to_tmp_fields (THD *thd, Item **ref_pointer_array, List< Item > &new_list1, List< Item > &new_list2, uint elements, List< Item > &items) |
| static void | init_tmptable_sum_functions (Item_sum **func) |
| static void | update_tmptable_sum_func (Item_sum **func, TABLE *tmp_table) |
| static void | copy_sum_funcs (Item_sum **func_ptr, Item_sum **end) |
| static bool | add_ref_to_table_cond (THD *thd, JOIN_TAB *join_tab) |
| static bool | setup_sum_funcs (THD *thd, Item_sum **func_ptr) |
| static bool | init_sum_functions (Item_sum **func, Item_sum **end) |
| static bool | update_sum_func (Item_sum **func) |
| static void | select_describe (JOIN *join, bool need_tmp_table, bool need_order, bool distinct, const char *message=NullS) |
| static Item * | remove_additional_cond (Item *conds) |
| static void | add_group_and_distinct_keys (JOIN *join, JOIN_TAB *join_tab) |
| bool | handle_select (THD *thd, LEX *lex, select_result *result, ulong setup_tables_done_option) |
| int | setup_without_group (THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, TABLE_LIST *leaves, List< Item > &fields, List< Item > &all_fields, COND **conds, ORDER *order, ORDER *group, bool *hidden_group_fields) |
| bool | mysql_select (THD *thd, Item ***rref_pointer_array, TABLE_LIST *tables, uint wild_num, List< Item > &fields, COND *conds, uint og_num, ORDER *order, ORDER *group, Item *having, ORDER *proc_param, ulong select_options, select_result *result, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex) |
| static ha_rows | get_quick_record_count (THD *thd, SQL_SELECT *select, TABLE *table, const key_map *keys, ha_rows limit) |
| static KEY_FIELD * | merge_key_fields (KEY_FIELD *start, KEY_FIELD *new_fields, KEY_FIELD *end, uint and_level) |
| static void | add_key_field (KEY_FIELD **key_fields, uint and_level, Item_func *cond, Field *field, bool eq_func, Item **value, uint num_values, table_map usable_tables) |
| static void | add_key_equal_fields (KEY_FIELD **key_fields, uint and_level, Item_func *cond, Item_field *field_item, bool eq_func, Item **val, uint num_values, table_map usable_tables) |
| static void | add_key_fields (KEY_FIELD **key_fields, uint *and_level, COND *cond, table_map usable_tables) |
| static uint | max_part_bit (key_part_map bits) |
| static void | add_key_part (DYNAMIC_ARRAY *keyuse_array, KEY_FIELD *key_field) |
| static void | add_ft_keys (DYNAMIC_ARRAY *keyuse_array, JOIN_TAB *stat, COND *cond, table_map usable_tables) |
| static void | add_key_fields_for_nj (TABLE_LIST *nested_join_table, KEY_FIELD **end, uint *and_level) |
| static void | calc_used_field_length (THD *thd, JOIN_TAB *join_tab) |
| bool | store_val_in_field (Field *field, Item *item, enum_check_fields check_flag) |
| void | add_cond_and_fix (Item **e1, Item *e2) |
| static void | add_not_null_conds (JOIN *join) |
| static COND * | add_found_match_trig_cond (JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab) |
| bool | error_if_full_join (JOIN *join) |
| static bool | eq_ref_table (JOIN *join, ORDER *start_order, JOIN_TAB *tab) |
| static void | clear_tables (JOIN *join) |
| Item_equal * | find_item_equal (COND_EQUAL *cond_equal, Field *field, bool *inherited_fl) |
| static bool | check_equality (Item *item, COND_EQUAL *cond_equal) |
| static COND * | build_equal_items_for_cond (COND *cond, COND_EQUAL *inherited) |
| static int | compare_fields_by_table_order (Item_field *field1, Item_field *field2, void *table_join_idx) |
| static Item * | eliminate_item_equal (COND *cond, COND_EQUAL *upper_levels, Item_equal *item_equal) |
| static void | update_const_equal_items (COND *cond, JOIN_TAB *tab) |
| static void | change_cond_ref_to_const (THD *thd, I_List< COND_CMP > *save_list, Item *and_father, Item *cond, Item *field, Item *value) |
| static void | propagate_cond_constants (THD *thd, I_List< COND_CMP > *save_list, COND *and_father, COND *cond) |
| COND * | remove_eq_conds (THD *thd, COND *cond, Item::cond_result *cond_value) |
| Field * | create_tmp_field_from_field (THD *thd, Field *org_field, const char *name, TABLE *table, Item_field *item, uint convert_blob_length) |
| static Field * | create_tmp_field_from_item (THD *thd, Item *item, TABLE *table, Item ***copy_func, bool modify_item, uint convert_blob_length) |
| Field * | create_tmp_field_for_schema (THD *thd, Item *item, TABLE *table) |
| Field * | create_tmp_field (THD *thd, TABLE *table, Item *item, Item::Type type, Item ***copy_func, Field **from_field, Field **default_field, bool group, bool modify_item, bool table_cant_handle_bit_fields, bool make_copy_field, uint convert_blob_length) |
| void | setup_tmp_table_column_bitmaps (TABLE *table, byte *bitmaps) |
| TABLE * | create_tmp_table (THD *thd, TMP_TABLE_PARAM *param, List< Item > &fields, ORDER *group, bool distinct, bool save_sum_fields, ulonglong select_options, ha_rows rows_limit, char *table_alias) |
| TABLE * | create_virtual_tmp_table (THD *thd, List< create_field > &field_list) |
| void | free_tmp_table (THD *thd, TABLE *entry) |
| bool | create_myisam_from_heap (THD *thd, TABLE *table, TMP_TABLE_PARAM *param, int error, bool ignore_last_dupp_key_error) |
| Next_select_func | setup_end_select_func (JOIN *join) |
| enum_nested_loop_state | sub_select_cache (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| enum_nested_loop_state | sub_select (JOIN *join, JOIN_TAB *join_tab, bool end_of_records) |
| int | report_error (TABLE *table, int error) |
| int | safe_index_read (JOIN_TAB *tab) |
| static int | join_no_more_records (READ_RECORD *info __attribute__((unused))) |
| static enum_nested_loop_state | end_send (JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), bool end_of_records) |
| static enum_nested_loop_state | end_send_group (JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), bool end_of_records) |
| static enum_nested_loop_state | end_write (JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), bool end_of_records) |
| static enum_nested_loop_state | end_update (JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), bool end_of_records) |
| static enum_nested_loop_state | end_unique_update (JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), bool end_of_records) |
| static enum_nested_loop_state | end_write_group (JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), bool end_of_records) |
| static bool | test_if_ref (Item_field *left_item, Item *right_item) |
| static int | test_if_order_by_key (ORDER *order, TABLE *table, uint idx, uint *used_key_parts) |
| bool | is_subkey (KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part, KEY_PART_INFO *ref_key_part_end) |
| static uint | test_if_subkey (ORDER *order, TABLE *table, uint ref, uint ref_key_parts, const key_map *usable_keys) |
| static bool | compare_record (TABLE *table, Field **ptr) |
| static bool | copy_blobs (Field **ptr) |
| static void | free_blobs (Field **ptr) |
| SORT_FIELD * | make_unireg_sortorder (ORDER *order, uint *length) |
| bool | cp_buffer_from_ref (THD *thd, TABLE *table, TABLE_REF *ref) |
| static bool | find_order_in_list (THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, ORDER *order, List< Item > &fields, List< Item > &all_fields, bool is_group_field) |
| int | setup_order (THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, List< Item > &fields, List< Item > &all_fields, ORDER *order) |
| int | setup_group (THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, List< Item > &fields, List< Item > &all_fields, ORDER *order, bool *hidden_group_fields) |
| void | count_field_types (TMP_TABLE_PARAM *param, List< Item > &fields, bool reset_with_sum_func) |
| bool | setup_copy_fields (THD *thd, TMP_TABLE_PARAM *param, Item **ref_pointer_array, List< Item > &res_selected_fields, List< Item > &res_all_fields, uint elements, List< Item > &all_fields) |
| void | copy_fields (TMP_TABLE_PARAM *param) |
| static void | update_tmptable_sum_func (Item_sum **func_ptr, TABLE *tmp_table __attribute__((unused))) |
| void | copy_funcs (Item **func_ptr) |
| void | free_underlaid_joins (THD *thd, SELECT_LEX *select) |
| static bool | change_group_ref (THD *thd, Item_func *expr, ORDER *group_list, bool *changed) |
| bool | mysql_explain_union (THD *thd, SELECT_LEX_UNIT *unit, select_result *result) |
| static void | print_join (THD *thd, String *str, List< TABLE_LIST > *tables) |
Variables | |
| const char * | join_type_str [] |
| #define AVG_STRING_LENGTH_TO_PACK_ROWS 64 |
| #define FT_KEYPART (MAX_REF_PARTS+10) |
Definition at line 2982 of file sql_select.cc.
Referenced by add_ft_keys(), best_access_path(), and create_ref_for_key().
| #define KEY_OPTIMIZE_EXISTS 1 |
Definition at line 2450 of file sql_select.cc.
Referenced by add_key_field(), add_key_part(), and merge_key_fields().
| #define KEY_OPTIMIZE_REF_OR_NULL 2 |
Definition at line 2451 of file sql_select.cc.
Referenced by add_key_part(), best_access_path(), create_ref_for_key(), merge_key_fields(), and sort_keyuse().
| #define MIN_STRING_LENGTH_TO_PACK_ROWS 10 |
| #define RATIO_TO_PACK_ROWS 2 |
| #define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128 |
| typedef struct key_field_t KEY_FIELD |
Definition at line 4992 of file sql_select.cc.
References Item::quick_fix_field().
Referenced by add_not_null_conds().
04993 { 04994 if (*e1) 04995 { 04996 Item *res; 04997 if ((res= new Item_cond_and(*e1, e2))) 04998 { 04999 *e1= res; 05000 res->quick_fix_field(); 05001 } 05002 } 05003 else 05004 *e1= e2; 05005 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static COND* add_found_match_trig_cond | ( | JOIN_TAB * | tab, | |
| COND * | cond, | |||
| JOIN_TAB * | root_tab | |||
| ) | [static] |
Definition at line 5127 of file sql_select.cc.
References cond, DBUG_ASSERT, st_join_table::first_upper, st_join_table::found, Item::quick_fix_field(), and Item::update_used_tables().
05128 { 05129 COND *tmp; 05130 DBUG_ASSERT(cond != 0); 05131 if (tab == root_tab) 05132 return cond; 05133 if ((tmp= add_found_match_trig_cond(tab->first_upper, cond, root_tab))) 05134 tmp= new Item_func_trig_cond(tmp, &tab->found); 05135 if (tmp) 05136 { 05137 tmp->quick_fix_field(); 05138 tmp->update_used_tables(); 05139 } 05140 return tmp; 05141 }
Here is the call graph for this function:

| static void add_ft_keys | ( | DYNAMIC_ARRAY * | keyuse_array, | |
| JOIN_TAB * | stat, | |||
| COND * | cond, | |||
| table_map | usable_tables | |||
| ) | [static] |
Definition at line 2985 of file sql_select.cc.
References cond, Item_func::COND_AND_FUNC, Item::COND_ITEM, Item_func::const_item(), Item_func::FT_FUNC, FT_KEYPART, func, Item::FUNC_ITEM, Item_func::functype(), Item_func::GE_FUNC, Item_func::GT_FUNC, insert_dynamic(), keyuse_t::key, Item_func_match::key, Item_func::key_item(), keyuse_t::keypart, keyuse_t::keypart_map, Item_func::LE_FUNC, Item_func::LT_FUNC, st_table::map, NO_SUCH_KEY, NULL, keyuse_t::optimize, keyuse_t::table, Item_func_match::table, Item_func::type(), Item::used_tables(), keyuse_t::used_tables, keyuse_t::val, Item::val_real(), and VOID.
Referenced by update_ref_and_keys().
02987 { 02988 Item_func_match *cond_func=NULL; 02989 02990 if (!cond) 02991 return; 02992 02993 if (cond->type() == Item::FUNC_ITEM) 02994 { 02995 Item_func *func=(Item_func *)cond; 02996 Item_func::Functype functype= func->functype(); 02997 if (functype == Item_func::FT_FUNC) 02998 cond_func=(Item_func_match *)cond; 02999 else if (func->arg_count == 2) 03000 { 03001 Item_func *arg0=(Item_func *)(func->arguments()[0]), 03002 *arg1=(Item_func *)(func->arguments()[1]); 03003 if (arg1->const_item() && 03004 ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) || 03005 (functype == Item_func::GT_FUNC && arg1->val_real() >=0)) && 03006 arg0->type() == Item::FUNC_ITEM && 03007 arg0->functype() == Item_func::FT_FUNC) 03008 cond_func=(Item_func_match *) arg0; 03009 else if (arg0->const_item() && 03010 ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) || 03011 (functype == Item_func::LT_FUNC && arg0->val_real() >=0)) && 03012 arg1->type() == Item::FUNC_ITEM && 03013 arg1->functype() == Item_func::FT_FUNC) 03014 cond_func=(Item_func_match *) arg1; 03015 } 03016 } 03017 else if (cond->type() == Item::COND_ITEM) 03018 { 03019 List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); 03020 03021 if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) 03022 { 03023 Item *item; 03024 while ((item=li++)) 03025 add_ft_keys(keyuse_array,stat,item,usable_tables); 03026 } 03027 } 03028 03029 if (!cond_func || cond_func->key == NO_SUCH_KEY || 03030 !(usable_tables & cond_func->table->map)) 03031 return; 03032 03033 KEYUSE keyuse; 03034 keyuse.table= cond_func->table; 03035 keyuse.val = cond_func; 03036 keyuse.key = cond_func->key; 03037 keyuse.keypart= FT_KEYPART; 03038 keyuse.used_tables=cond_func->key_item()->used_tables(); 03039 keyuse.optimize= 0; 03040 keyuse.keypart_map= 0; 03041 VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); 03042 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3321 of file sql_select.cc.
References Item::collect_item_field_processor(), st_join_table::const_keys, base_list::elements, Item_field::field, JOIN::fields_list, JOIN::group_list, Bitmap< 64 >::intersect(), Bitmap< 64 >::is_clear_all(), st_order::item, Bitmap< 64 >::merge(), st_order::next, Field::part_of_key, JOIN::select_distinct, and Item::walk().
03322 { 03323 List<Item_field> indexed_fields; 03324 List_iterator<Item_field> indexed_fields_it(indexed_fields); 03325 ORDER *cur_group; 03326 Item_field *cur_item; 03327 key_map possible_keys(0); 03328 03329 if (join->group_list) 03330 { /* Collect all query fields referenced in the GROUP clause. */ 03331 for (cur_group= join->group_list; cur_group; cur_group= cur_group->next) 03332 (*cur_group->item)->walk(&Item::collect_item_field_processor, 0, 03333 (byte*) &indexed_fields); 03334 } 03335 else if (join->select_distinct) 03336 { /* Collect all query fields referenced in the SELECT clause. */ 03337 List<Item> &select_items= join->fields_list; 03338 List_iterator<Item> select_items_it(select_items); 03339 Item *item; 03340 while ((item= select_items_it++)) 03341 item->walk(&Item::collect_item_field_processor, 0, 03342 (byte*) &indexed_fields); 03343 } 03344 else 03345 return; 03346 03347 if (indexed_fields.elements == 0) 03348 return; 03349 03350 /* Intersect the keys of all group fields. */ 03351 cur_item= indexed_fields_it++; 03352 possible_keys.merge(cur_item->field->part_of_key); 03353 while ((cur_item= indexed_fields_it++)) 03354 { 03355 possible_keys.intersect(cur_item->field->part_of_key); 03356 } 03357 03358 if (!possible_keys.is_clear_all()) 03359 join_tab->const_keys.merge(possible_keys); 03360 }
Here is the call graph for this function:

| static void add_key_equal_fields | ( | KEY_FIELD ** | key_fields, | |
| uint | and_level, | |||
| Item_func * | cond, | |||
| Item_field * | field_item, | |||
| bool | eq_func, | |||
| Item ** | val, | |||
| uint | num_values, | |||
| table_map | usable_tables | |||
| ) | [static] |
Definition at line 2759 of file sql_select.cc.
References add_key_field(), cond, Field::eq(), Item_field::field, and Item_field::item_equal.
Referenced by add_key_fields().
02763 { 02764 Field *field= field_item->field; 02765 add_key_field(key_fields, and_level, cond, field, 02766 eq_func, val, num_values, usable_tables); 02767 Item_equal *item_equal= field_item->item_equal; 02768 if (item_equal) 02769 { 02770 /* 02771 Add to the set of possible key values every substitution of 02772 the field for an equal field included into item_equal 02773 */ 02774 Item_equal_iterator it(*item_equal); 02775 Item_field *item; 02776 while ((item= it++)) 02777 { 02778 if (!field->eq(item->field)) 02779 { 02780 add_key_field(key_fields, and_level, cond, item->field, 02781 eq_func, val, num_values, usable_tables); 02782 } 02783 } 02784 } 02785 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void add_key_field | ( | KEY_FIELD ** | key_fields, | |
| uint | and_level, | |||
| Item_func * | cond, | |||
| Field * | field, | |||
| bool | eq_func, | |||
| Item ** | value, | |||
| uint | num_values, | |||
| table_map | usable_tables | |||
| ) | [static] |
Definition at line 2599 of file sql_select.cc.
References Item_func::BETWEEN, Field::binary(), BLOB_FLAG, Field::cmp_type(), cond, DBUG_ASSERT, Field::flags, Bitmap< 64 >::intersect(), st_reginfo::join_tab, st_join_table::key_dependent, KEY_OPTIMIZE_EXISTS, Field::key_start, st_join_table::keys, st_table::keys_in_use_for_query, st_table::map, st_table::maybe_null, Bitmap< 64 >::merge(), Item::NULL_ITEM, Field::null_ptr, PART_KEY_FLAG, RAND_TABLE_BIT, st_table::reginfo, Field::result_type(), STRING_RESULT, Field::table, TRUE, and value.
Referenced by add_key_equal_fields(), and add_key_fields().
02602 { 02603 uint exists_optimize= 0; 02604 if (!(field->flags & PART_KEY_FLAG)) 02605 { 02606 // Don't remove column IS NULL on a LEFT JOIN table 02607 if (!eq_func || (*value)->type() != Item::NULL_ITEM || 02608 !field->table->maybe_null || field->null_ptr) 02609 return; // Not a key. Skip it 02610 exists_optimize= KEY_OPTIMIZE_EXISTS; 02611 DBUG_ASSERT(num_values == 1); 02612 } 02613 else 02614 { 02615 table_map used_tables=0; 02616 bool optimizable=0; 02617 for (uint i=0; i<num_values; i++) 02618 { 02619 used_tables|=(value[i])->used_tables(); 02620 if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT))) 02621 optimizable=1; 02622 } 02623 if (!optimizable) 02624 return; 02625 if (!(usable_tables & field->table->map)) 02626 { 02627 if (!eq_func || (*value)->type() != Item::NULL_ITEM || 02628 !field->table->maybe_null || field->null_ptr) 02629 return; // Can't use left join optimize 02630 exists_optimize= KEY_OPTIMIZE_EXISTS; 02631 } 02632 else 02633 { 02634 JOIN_TAB *stat=field->table->reginfo.join_tab; 02635 key_map possible_keys=field->key_start; 02636 possible_keys.intersect(field->table->keys_in_use_for_query); 02637 stat[0].keys.merge(possible_keys); // Add possible keys 02638 02639 /* 02640 Save the following cases: 02641 Field op constant 02642 Field LIKE constant where constant doesn't start with a wildcard 02643 Field = field2 where field2 is in a different table 02644 Field op formula 02645 Field IS NULL 02646 Field IS NOT NULL 02647 Field BETWEEN ... 02648 Field IN ... 02649 */ 02650 stat[0].key_dependent|=used_tables; 02651 02652 bool is_const=1; 02653 for (uint i=0; i<num_values; i++) 02654 { 02655 if (!(is_const&= value[i]->const_item())) 02656 break; 02657 } 02658 if (is_const) 02659 stat[0].const_keys.merge(possible_keys); 02660 /* 02661 We can't always use indexes when comparing a string index to a 02662 number. cmp_type() is checked to allow compare of dates to numbers. 02663 eq_func is NEVER true when num_values > 1 02664 */ 02665 if (!eq_func) 02666 { 02667 /* 02668 Additional optimization: if we're processing 02669 "t.key BETWEEN c1 AND c1" then proceed as if we were processing 02670 "t.key = c1". 02671 TODO: This is a very limited fix. A more generic fix is possible. 02672 There are 2 options: 02673 A) Make equality propagation code be able to handle BETWEEN 02674 (including cases like t1.key BETWEEN t2.key AND t3.key) 02675 B) Make range optimizer to infer additional "t.key = c" equalities 02676 and use them in equality propagation process (see details in 02677 OptimizerKBAndTodo) 02678 */ 02679 if ((cond->functype() != Item_func::BETWEEN) || 02680 ((Item_func_between*) cond)->negated || 02681 !value[0]->eq(value[1], field->binary())) 02682 return; 02683 eq_func= TRUE; 02684 } 02685 02686 if (field->result_type() == STRING_RESULT) 02687 { 02688 if ((*value)->result_type() != STRING_RESULT) 02689 { 02690 if (field->cmp_type() != (*value)->result_type()) 02691 return; 02692 } 02693 else 02694 { 02695 /* 02696 We can't use indexes if the effective collation 02697 of the operation differ from the field collation. 02698 02699 We also cannot use index on a text column, as the column may 02700 contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after 02701 'x' when searching for WHERE col='x ' 02702 */ 02703 if (field->cmp_type() == STRING_RESULT && 02704 (((Field_str*)field)->charset() != cond->compare_collation() || 02705 ((*value)->type() != Item::NULL_ITEM && 02706 (field->flags & BLOB_FLAG) && !field->binary()))) 02707 return; 02708 } 02709 } 02710 } 02711 } 02712 /* 02713 For the moment eq_func is always true. This slot is reserved for future 02714 extensions where we want to remembers other things than just eq comparisons 02715 */ 02716 DBUG_ASSERT(eq_func); 02717 /* Store possible eq field */ 02718 (*key_fields)->field= field; 02719 (*key_fields)->eq_func= eq_func; 02720 (*key_fields)->val= *value; 02721 (*key_fields)->level= and_level; 02722 (*key_fields)->optimize= exists_optimize; 02723 /* 02724 If the condition has form "tbl.keypart = othertbl.field" and 02725 othertbl.field can be NULL, there will be no matches if othertbl.field 02726 has NULL value. 02727 We use null_rejecting in add_not_null_conds() to add 02728 'othertbl.field IS NOT NULL' to tab->select_cond. 02729 */ 02730 (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC) && 02731 ((*value)->type() == Item::FIELD_ITEM) && 02732 ((Item_field*)*value)->field->maybe_null()); 02733 (*key_fields)++; 02734 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void add_key_fields | ( | KEY_FIELD ** | key_fields, | |
| uint * | and_level, | |||
| COND * | cond, | |||
| table_map | usable_tables | |||
| ) | [static] |
Definition at line 2788 of file sql_select.cc.
References add_key_equal_fields(), add_key_field(), Item_func::argument_count(), Item_func::arguments(), cond, Item_func::COND_AND_FUNC, Item::COND_ITEM, DBUG_ASSERT, Field::eq(), Item_func::EQ_FUNC, Item_func::EQUAL_FUNC, Item_field::field, Item::FIELD_ITEM, Item::FUNC_ITEM, Item_func::functype(), Item_equal::get_const(), Item_func::IN_FUNC, Item_func::ISNULL_FUNC, Item_func::key_item(), key_field_t::level, Item_func::LIKE_FUNC, merge_key_fields(), Item_func::NE_FUNC, Item_func::OPTIMIZE_EQUAL, Item_func::OPTIMIZE_KEY, Item_func::OPTIMIZE_NONE, Item_func::OPTIMIZE_NULL, Item_func::OPTIMIZE_OP, OUTER_REF_TABLE_BIT, Item::real_item(), Item_equal_iterator::rewind(), Item_func::select_optimize(), TRUE, Item::type(), unlikely, Item::used_tables(), and Item_func::used_tables().
Referenced by add_key_fields_for_nj(), and update_ref_and_keys().
02790 { 02791 if (cond->type() == Item_func::COND_ITEM) 02792 { 02793 List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); 02794 KEY_FIELD *org_key_fields= *key_fields; 02795 02796 if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) 02797 { 02798 Item *item; 02799 while ((item=li++)) 02800 add_key_fields(key_fields,and_level,item,usable_tables); 02801 for (; org_key_fields != *key_fields ; org_key_fields++) 02802 org_key_fields->level= *and_level; 02803 } 02804 else 02805 { 02806 (*and_level)++; 02807 add_key_fields(key_fields,and_level,li++,usable_tables); 02808 Item *item; 02809 while ((item=li++)) 02810 { 02811 KEY_FIELD *start_key_fields= *key_fields; 02812 (*and_level)++; 02813 add_key_fields(key_fields,and_level,item,usable_tables); 02814 *key_fields=merge_key_fields(org_key_fields,start_key_fields, 02815 *key_fields,++(*and_level)); 02816 } 02817 } 02818 return; 02819 } 02820 /* If item is of type 'field op field/constant' add it to key_fields */ 02821 02822 if (cond->type() != Item::FUNC_ITEM) 02823 return; 02824 Item_func *cond_func= (Item_func*) cond; 02825 switch (cond_func->select_optimize()) { 02826 case Item_func::OPTIMIZE_NONE: 02827 break; 02828 case Item_func::OPTIMIZE_KEY: 02829 { 02830 // BETWEEN, IN, NE 02831 if (cond_func->key_item()->real_item()->type() == Item::FIELD_ITEM && 02832 !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) 02833 { 02834 Item **values= cond_func->arguments()+1; 02835 if (cond_func->functype() == Item_func::NE_FUNC && 02836 cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM && 02837 !(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT)) 02838 values--; 02839 DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC || 02840 cond_func->argument_count() != 2); 02841 add_key_equal_fields(key_fields, *and_level, cond_func, 02842 (Item_field*) (cond_func->key_item()->real_item()), 02843 0, values, 02844 cond_func->argument_count()-1, 02845 usable_tables); 02846 } 02847 break; 02848 } 02849 case Item_func::OPTIMIZE_OP: 02850 { 02851 bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC || 02852 cond_func->functype() == Item_func::EQUAL_FUNC); 02853 02854 if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM && 02855 !(cond_func->arguments()[0]->used_tables() & OUTER_REF_TABLE_BIT)) 02856 { 02857 add_key_equal_fields(key_fields, *and_level, cond_func, 02858 (Item_field*) (cond_func->arguments()[0])->real_item(), 02859 equal_func, 02860 cond_func->arguments()+1, 1, usable_tables); 02861 } 02862 if (cond_func->arguments()[1]->real_item()->type() == Item::FIELD_ITEM && 02863 cond_func->functype() != Item_func::LIKE_FUNC && 02864 !(cond_func->arguments()[1]->used_tables() & OUTER_REF_TABLE_BIT)) 02865 { 02866 add_key_equal_fields(key_fields, *and_level, cond_func, 02867 (Item_field*) (cond_func->arguments()[1])->real_item(), 02868 equal_func, 02869 cond_func->arguments(),1,usable_tables); 02870 } 02871 break; 02872 } 02873 case Item_func::OPTIMIZE_NULL: 02874 /* column_name IS [NOT] NULL */ 02875 if (cond_func->arguments()[0]->real_item()->type() == Item::FIELD_ITEM && 02876 !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) 02877 { 02878 Item *tmp=new Item_null; 02879 if (unlikely(!tmp)) // Should never be true 02880 return; 02881 add_key_equal_fields(key_fields, *and_level, cond_func, 02882 (Item_field*) (cond_func->arguments()[0])->real_item(), 02883 cond_func->functype() == Item_func::ISNULL_FUNC, 02884 &tmp, 1, usable_tables); 02885 } 02886 break; 02887 case Item_func::OPTIMIZE_EQUAL: 02888 Item_equal *item_equal= (Item_equal *) cond; 02889 Item *const_item= item_equal->get_const(); 02890 Item_equal_iterator it(*item_equal); 02891 Item_field *item; 02892 if (const_item) 02893 { 02894 /* 02895 For each field field1 from item_equal consider the equality 02896 field1=const_item as a condition allowing an index access of the table 02897 with field1 by the keys value of field1. 02898 */ 02899 while ((item= it++)) 02900 { 02901 add_key_field(key_fields, *and_level, cond_func, item->field, 02902 TRUE, &const_item, 1, usable_tables); 02903 } 02904 } 02905 else 02906 { 02907 /* 02908 Consider all pairs of different fields included into item_equal. 02909 For each of them (field1, field1) consider the equality 02910 field1=field2 as a condition allowing an index access of the table 02911 with field1 by the keys value of field2. 02912 */ 02913 Item_equal_iterator fi(*item_equal); 02914 while ((item= fi++)) 02915 { 02916 Field *field= item->field; 02917 while ((item= it++)) 02918 { 02919 if (!field->eq(item->field)) 02920 { 02921 add_key_field(key_fields, *and_level, cond_func, field, 02922 TRUE, (Item **) &item, 1, usable_tables); 02923 } 02924 } 02925 it.rewind(); 02926 } 02927 } 02928 break; 02929 } 02930 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void add_key_fields_for_nj | ( | TABLE_LIST * | nested_join_table, | |
| KEY_FIELD ** | end, | |||
| uint * | and_level | |||
| ) | [static] |
Definition at line 3095 of file sql_select.cc.
References add_key_fields(), DBUG_ASSERT, st_nested_join::join_list, st_table::map, st_table_list::nested_join, st_table_list::on_expr, and st_table_list::table.
Referenced by update_ref_and_keys().
03097 { 03098 List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list); 03099 table_map tables= 0; 03100 TABLE_LIST *table; 03101 DBUG_ASSERT(nested_join_table->nested_join); 03102 03103 while ((table= li++)) 03104 { 03105 if (table->nested_join) 03106 add_key_fields_for_nj(table, end, and_level); 03107 else 03108 if (!table->on_expr) 03109 tables |= table->table->map; 03110 } 03111 add_key_fields(end, and_level, nested_join_table->on_expr, tables); 03112 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void add_key_part | ( | DYNAMIC_ARRAY * | keyuse_array, | |
| KEY_FIELD * | key_field | |||
| ) | [static] |
Definition at line 2946 of file sql_select.cc.
References Field::eq(), HA_FULLTEXT, insert_dynamic(), Bitmap< 64 >::is_set(), keyuse_t::key, key, key_field, st_table::key_info, KEY_OPTIMIZE_EXISTS, KEY_OPTIMIZE_REF_OR_NULL, keyuse_t::keypart, keyuse_t::keypart_map, st_table_share::keys, st_table::keys_in_use_for_query, keyuse_t::null_rejecting, keyuse_t::optimize, st_table::s, keyuse_t::table, Field::table, keyuse_t::used_tables, keyuse_t::val, and VOID.
Referenced by update_ref_and_keys().
02947 { 02948 Field *field=key_field->field; 02949 TABLE *form= field->table; 02950 KEYUSE keyuse; 02951 02952 if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS)) 02953 { 02954 for (uint key=0 ; key < form->s->keys ; key++) 02955 { 02956 if (!(form->keys_in_use_for_query.is_set(key))) 02957 continue; 02958 if (form->key_info[key].flags & HA_FULLTEXT) 02959 continue; // ToDo: ft-keys in non-ft queries. SerG 02960 02961 uint key_parts= (uint) form->key_info[key].key_parts; 02962 for (uint part=0 ; part < key_parts ; part++) 02963 { 02964 if (field->eq(form->key_info[key].key_part[part].field)) 02965 { 02966 keyuse.table= field->table; 02967 keyuse.val = key_field->val; 02968 keyuse.key = key; 02969 keyuse.keypart=part; 02970 keyuse.keypart_map= (key_part_map) 1 << part; 02971 keyuse.used_tables=key_field->val->used_tables(); 02972 keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL; 02973 keyuse.null_rejecting= key_field->null_rejecting; 02974 VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); 02975 } 02976 } 02977 } 02978 } 02979 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void add_not_null_conds | ( | JOIN * | join | ) | [static] |
Definition at line 5061 of file sql_select.cc.
References add_cond_and_fix(), st_table::alias, JOIN::const_tables, DBUG_ASSERT, DBUG_ENTER, DBUG_EXECUTE, DBUG_VOID_RETURN, Item_field::field, Item::FIELD_ITEM, st_table_ref::items, st_join_table::join, st_reginfo::join_tab, JOIN::join_tab, JT_REF, JT_REF_OR_NULL, st_table_ref::key_parts, st_table::maybe_null, st_table_ref::null_rejecting, print_where(), st_join_table::ref, st_table::reginfo, st_join_table::select_cond, Field::table, st_join_table::table, JOIN::thd, and st_join_table::type.
Referenced by make_join_select().
05062 { 05063 DBUG_ENTER("add_not_null_conds"); 05064 for (uint i=join->const_tables ; i < join->tables ; i++) 05065 { 05066 JOIN_TAB *tab=join->join_tab+i; 05067 if ((tab->type == JT_REF || tab->type == JT_REF_OR_NULL) && 05068 !tab->table->maybe_null) 05069 { 05070 for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) 05071 { 05072 if (tab->ref.null_rejecting & (1 << keypart)) 05073 { 05074 Item *item= tab->ref.items[keypart]; 05075 Item *notnull; 05076 DBUG_ASSERT(item->type() == Item::FIELD_ITEM); 05077 Item_field *not_null_item= (Item_field*)item; 05078 JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab; 05079 /* 05080 For UPDATE queries such as: 05081 UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1); 05082 not_null_item is the t1.f1, but it's referred_tab is 0. 05083 */ 05084 if (!referred_tab || referred_tab->join != join) 05085 continue; 05086 if (!(notnull= new Item_func_isnotnull(not_null_item))) 05087 DBUG_VOID_RETURN; 05088 /* 05089 We need to do full fix_fields() call here in order to have correct 05090 notnull->const_item(). This is needed e.g. by test_quick_select 05091 when it is called from make_join_select after this function is 05092 called. 05093 */ 05094 if (notnull->fix_fields(join->thd, ¬null)) 05095 DBUG_VOID_RETURN; 05096 DBUG_EXECUTE("where",print_where(notnull, 05097 referred_tab->table->alias);); 05098 add_cond_and_fix(&referred_tab->select_cond, notnull); 05099 } 05100 } 05101 } 05102 } 05103 DBUG_VOID_RETURN; 05104 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 13689 of file sql_select.cc.
References SQL_SELECT::cond, cond, DBUG_ENTER, DBUG_RETURN, FALSE, st_table::field, int(), st_table_ref::items, st_table_ref::key, st_table::key_info, st_table_ref::key_parts, make_select(), st_join_table::ref, st_join_table::select, st_join_table::select_cond, st_join_table::table, TRUE, and value.
13690 { 13691 DBUG_ENTER("add_ref_to_table_cond"); 13692 if (!join_tab->ref.key_parts) 13693 DBUG_RETURN(FALSE); 13694 13695 Item_cond_and *cond=new Item_cond_and(); 13696 TABLE *table=join_tab->table; 13697 int error; 13698 if (!cond) 13699 DBUG_RETURN(TRUE); 13700 13701 for (uint i=0 ; i < join_tab->ref.key_parts ; i++) 13702 { 13703 Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i]. 13704 fieldnr-1]; 13705 Item *value=join_tab->ref.items[i]; 13706 cond->add(new Item_func_equal(new Item_field(field), value)); 13707 } 13708 if (thd->is_fatal_error) 13709 DBUG_RETURN(TRUE); 13710 13711 if (!cond->fixed) 13712 cond->fix_fields(thd, (Item**)&cond); 13713 if (join_tab->select) 13714 { 13715 error=(int) cond->add(join_tab->select->cond); 13716 join_tab->select_cond=join_tab->select->cond=cond; 13717 } 13718 else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0, 13719 &error))) 13720 join_tab->select_cond=cond; 13721 13722 DBUG_RETURN(error ? TRUE : FALSE); 13723 }
Here is the call graph for this function:

Definition at line 13172 of file sql_select.cc.
References FALSE, JOIN::group_fields, st_order::item, new_Cached_item(), st_order::next, List< T >::push_front(), JOIN::sort_and_group, JOIN::thd, and TRUE.
Referenced by make_group_fields().
13173 { 13174 if (group) 13175 { 13176 for (; group ; group=group->next) 13177 { 13178 Cached_item *tmp=new_Cached_item(join->thd, *group->item); 13179 if (!tmp || join->group_fields.push_front(tmp)) 13180 return TRUE; 13181 } 13182 } 13183 join->sort_and_group=1; /* Mark for do_select */ 13184 return FALSE; 13185 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void best_access_path | ( | JOIN * | join, | |
| JOIN_TAB * | s, | |||
| THD * | thd, | |||
| table_map | remaining_tables, | |||
| uint | idx, | |||
| double | record_count, | |||
| double | read_time | |||
| ) | [static] |
Definition at line 3419 of file sql_select.cc.
References ha_statistics::block_size, cache_record_length(), JOIN::const_table_map, JOIN::const_tables, DBL_MAX, DBUG_ENTER, DBUG_VOID_RETURN, st_table::file, st_table::force_index, st_join_table::found_records, FT_KEYPART, HA_NOSAME, HA_NULL_PART_KEY, HA_ONLY_WHOLE_INDEX, handler::ha_table_flags(), HA_TABLE_SCAN_ON_INDEX, QUICK_SELECT_I::index, handler::index_flags(), Bitmap< 64 >::is_clear_all(), Bitmap< 64 >::is_set(), st_position::key, keyuse_t::key, key, st_table::key_info, KEY_OPTIMIZE_REF_OR_NULL, keyinfo, keyuse_t::keypart, keyuse_t::keypart_map, st_join_table::keyuse, st_table::map, MATCHING_ROWS_IN_OTHER_TABLE, st_table_share::max_key_length, max_part_bit(), min, keyuse_t::optimize, JOIN::outer_join, JOIN::positions, PREV_BITS, prev_record_reads(), st_join_table::quick, st_table::quick_condition_rows, st_table::quick_key_parts, st_table::quick_keys, st_table::quick_n_ranges, st_table::quick_rows, st_position::read_time, QUICK_SELECT_I::read_time, st_join_table::read_time, st_join_table::records, records, st_position::records_read, handler::ref_length, keyuse_t::ref_table_rows, rows2double, st_table::s, handler::scan_time(), set_if_bigger, set_if_smaller, JOIN::sort_by_table, handler::stats, st_position::table, keyuse_t::table, st_join_table::table, test, TIME_FOR_COMPARE, JOIN::unit, st_table::used_keys, keyuse_t::used_tables, and st_join_table::worst_seeks.
Referenced by best_extension_by_limited_search(), find_best(), and optimize_straight_join().
03426 { 03427 KEYUSE *best_key= 0; 03428 uint best_max_key_part= 0; 03429 my_bool found_constraint= 0; 03430 double best= DBL_MAX; 03431 double best_time= DBL_MAX; 03432 double records= DBL_MAX; 03433 double tmp; 03434 ha_rows rec; 03435 03436 DBUG_ENTER("best_access_path"); 03437 03438 if (s->keyuse) 03439 { /* Use key if possible */ 03440 TABLE *table= s->table; 03441 KEYUSE *keyuse,*start_key=0; 03442 double best_records= DBL_MAX; 03443 uint max_key_part=0; 03444 03445 /* Test how we can use keys */ 03446 rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key 03447 for (keyuse=s->keyuse ; keyuse->table == table ;) 03448 { 03449 key_part_map found_part= 0; 03450 table_map found_ref= 0; 03451 uint key= keyuse->key; 03452 KEY *keyinfo= table->key_info+key; 03453 bool ft_key= (keyuse->keypart == FT_KEYPART); 03454 /* Bitmap of keyparts where the ref access is over 'keypart=const': */ 03455 key_part_map const_part= 0; 03456 /* The or-null keypart in ref-or-null access: */ 03457 key_part_map ref_or_null_part= 0; 03458 03459 /* Calculate how many key segments of the current key we can use */ 03460 start_key= keyuse; 03461 do 03462 { /* for each keypart */ 03463 uint keypart= keyuse->keypart; 03464 table_map best_part_found_ref= 0; 03465 double best_prev_record_reads= DBL_MAX; 03466 do 03467 { 03468 if (!(remaining_tables & keyuse->used_tables) && 03469 !(ref_or_null_part && (keyuse->optimize & 03470 KEY_OPTIMIZE_REF_OR_NULL))) 03471 { 03472 found_part|= keyuse->keypart_map; 03473 if (!(keyuse->used_tables & ~join->const_table_map)) 03474 const_part|= keyuse->keypart_map; 03475 double tmp= prev_record_reads(join, (found_ref | 03476 keyuse->used_tables)); 03477 if (tmp < best_prev_record_reads) 03478 { 03479 best_part_found_ref= keyuse->used_tables; 03480 best_prev_record_reads= tmp; 03481 } 03482 if (rec > keyuse->ref_table_rows) 03483 rec= keyuse->ref_table_rows; 03484 /* 03485 If there is one 'key_column IS NULL' expression, we can 03486 use this ref_or_null optimisation of this field 03487 */ 03488 if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) 03489 ref_or_null_part |= keyuse->keypart_map; 03490 } 03491 keyuse++; 03492 } while (keyuse->table == table && keyuse->key == key && 03493 keyuse->keypart == keypart); 03494 found_ref|= best_part_found_ref; 03495 } while (keyuse->table == table && keyuse->key == key); 03496 03497 /* 03498 Assume that that each key matches a proportional part of table. 03499 */ 03500 if (!found_part && !ft_key) 03501 continue; // Nothing usable found 03502 03503 if (rec < MATCHING_ROWS_IN_OTHER_TABLE) 03504 rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables 03505 03506 /* 03507 ft-keys require special treatment 03508 */ 03509 if (ft_key) 03510 { 03511 /* 03512 Really, there should be records=0.0 (yes!) 03513 but 1.0 would be probably safer 03514 */ 03515 tmp= prev_record_reads(join, found_ref); 03516 records= 1.0; 03517 } 03518 else 03519 { 03520 found_constraint= 1; 03521 /* 03522 Check if we found full key 03523 */ 03524 if (found_part == PREV_BITS(uint,keyinfo->key_parts) && 03525 !ref_or_null_part) 03526 { /* use eq key */ 03527 max_key_part= (uint) ~0; 03528 if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) 03529 { 03530 tmp = prev_record_reads(join, found_ref); 03531 records=1.0; 03532 } 03533 else 03534 { 03535 if (!found_ref) 03536 { /* We found a const key */ 03537 /* 03538 ReuseRangeEstimateForRef-1: 03539 We get here if we've found a ref(const) (c_i are constants): 03540 "(keypart1=c1) AND ... AND (keypartN=cN)" [ref_const_cond] 03541 03542 If range optimizer was able to construct a "range" 03543 access on this index, then its condition "quick_cond" was 03544 eqivalent to ref_const_cond (*), and we can re-use E(#rows) 03545 from the range optimizer. 03546 03547 Proof of (*): By properties of range and ref optimizers 03548 quick_cond will be equal or tighther than ref_const_cond. 03549 ref_const_cond already covers "smallest" possible interval - 03550 a singlepoint interval over all keyparts. Therefore, 03551 quick_cond is equivalent to ref_const_cond (if it was an 03552 empty interval we wouldn't have got here). 03553 */ 03554 if (table->quick_keys.is_set(key)) 03555 records= (double) table->quick_rows[key]; 03556 else 03557 { 03558 /* quick_range couldn't use key! */ 03559 records= (double) s->records/rec; 03560 } 03561 } 03562 else 03563 { 03564 if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1])) 03565 { /* Prefer longer keys */ 03566 records= 03567 ((double) s->records / (double) rec * 03568 (1.0 + 03569 ((double) (table->s->max_key_length-keyinfo->key_length) / 03570 (double) table->s->max_key_length))); 03571 if (records < 2.0) 03572 records=2.0; /* Can't be as good as a unique */ 03573 } 03574 /* 03575 ReuseRangeEstimateForRef-2: We get here if we could not reuse 03576 E(#rows) from range optimizer. Make another try: 03577 03578 If range optimizer produced E(#rows) for a prefix of the ref 03579 access we're considering, and that E(#rows) is lower then our 03580 current estimate, make an adjustment. The criteria of when we 03581 can make an adjustment is a special case of the criteria used 03582 in ReuseRangeEstimateForRef-3. 03583 */ 03584 if (table->quick_keys.is_set(key) && 03585 const_part & (1 << table->quick_key_parts[key]) && 03586 table->quick_n_ranges[key] == 1 && 03587 records > (double) table->quick_rows[key]) 03588 { 03589 records= (double) table->quick_rows[key]; 03590 } 03591 } 03592 /* Limit the number of matched rows */ 03593 tmp= records; 03594 set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); 03595 if (table->used_keys.is_set(key)) 03596 { 03597 /* we can use only index tree */ 03598 uint keys_per_block= table->file->stats.block_size/2/ 03599 (keyinfo->key_length+table->file->ref_length)+1; 03600 tmp= record_count*(tmp+keys_per_block-1)/keys_per_block; 03601 } 03602 else 03603 tmp= record_count*min(tmp,s->worst_seeks); 03604 } 03605 } 03606 else 03607 { 03608 /* 03609 Use as much key-parts as possible and a uniq key is better 03610 than a not unique key 03611 Set tmp to (previous record count) * (records / combination) 03612 */ 03613 if ((found_part & 1) && 03614 (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) || 03615 found_part == PREV_BITS(uint,keyinfo->key_parts))) 03616 { 03617 max_key_part= max_part_bit(found_part); 03618 /* 03619 ReuseRangeEstimateForRef-3: 03620 We're now considering a ref[or_null] access via 03621 (t.keypart1=e1 AND ... AND t.keypartK=eK) [ OR 03622 (same-as-above but with one cond replaced 03623 with "t.keypart_i IS NULL")] (**) 03624 03625 Try re-using E(#rows) from "range" optimizer: 03626 We can do so if "range" optimizer used the same intervals as 03627 in (**). The intervals used by range optimizer may be not 03628 available at this point (as "range" access might have choosen to 03629 create quick select over another index), so we can't compare 03630 them to (**). We'll make indirect judgements instead. 03631 The sufficient conditions for re-use are: 03632 (C1) All e_i in (**) are constants, i.e. found_ref==FALSE. (if 03633 this is not satisfied we have no way to know which ranges 03634 will be actually scanned by 'ref' until we execute the 03635 join) 03636 (C2) max #key parts in 'range' access == K == max_key_part (this 03637 is apparently a necessary requirement) 03638 03639 We also have a property that "range optimizer produces equal or 03640 tighter set of scan intervals than ref(const) optimizer". Each 03641 of the intervals in (**) are "tightest possible" intervals when 03642 one limits itself to using keyparts 1..K (which we do in #2). 03643 From here it follows that range access used either one, or 03644 both of the (I1) and (I2) intervals: 03645 03646 (t.keypart1=c1 AND ... AND t.keypartK=eK) (I1) 03647 (same-as-above but with one cond replaced 03648 with "t.keypart_i IS NULL") (I2) 03649 03650 The remaining part is to exclude the situation where range 03651 optimizer used one interval while we're considering 03652 ref-or-null and looking for estimate for two intervals. This 03653 is done by last limitation: 03654 03655 (C3) "range optimizer used (have ref_or_null?2:1) intervals" 03656 */ 03657 if (table->quick_keys.is_set(key) && !found_ref && //(C1) 03658 table->quick_key_parts[key] == max_key_part && //(C2) 03659 table->quick_n_ranges[key] == 1+test(ref_or_null_part)) //(C3) 03660 { 03661 tmp= records= (double) table->quick_rows[key]; 03662 } 03663 else 03664 { 03665 /* Check if we have statistic about the distribution */ 03666 if ((records= keyinfo->rec_per_key[max_key_part-1])) 03667 tmp= records; 03668 else 03669 { 03670 /* 03671 Assume that the first key part matches 1% of the file 03672 and that the whole key matches 10 (duplicates) or 1 03673 (unique) records. 03674 Assume also that more key matches proportionally more 03675 records 03676 This gives the formula: 03677 records = (x * (b-a) + a*c-b)/(c-1) 03678 03679 b = records matched by whole key 03680 a = records matched by first key part (1% of all records?) 03681 c = number of key parts in key 03682 x = used key parts (1 <= x <= c) 03683 */ 03684 double rec_per_key; 03685 if (!(rec_per_key=(double) 03686 keyinfo->rec_per_key[keyinfo->key_parts-1])) 03687 rec_per_key=(double) s->records/rec+1; 03688 03689 if (!s->records) 03690 tmp = 0; 03691 else if (rec_per_key/(double) s->records >= 0.01) 03692 tmp = rec_per_key; 03693 else 03694 { 03695 double a=s->records*0.01; 03696 if (keyinfo->key_parts > 1) 03697 tmp= (max_key_part * (rec_per_key - a) + 03698 a*keyinfo->key_parts - rec_per_key)/ 03699 (keyinfo->key_parts-1); 03700 else 03701 tmp= a; 03702 set_if_bigger(tmp,1.0); 03703 } 03704 records = (ulong) tmp; 03705 } 03706 03707 if (ref_or_null_part) 03708 { 03709 /* We need to do two key searches to find key */ 03710 tmp *= 2.0; 03711 records *= 2.0; 03712 } 03713 03714 /* 03715 ReuseRangeEstimateForRef-4: We get here if we could not reuse 03716 E(#rows) from range optimizer. Make another try: 03717 03718 If range optimizer produced E(#rows) for a prefix of the ref 03719 access we're considering, and that E(#rows) is lower then our 03720 current estimate, make the adjustment. 03721 03722 The decision whether we can re-use the estimate from the range 03723 optimizer is the same as in ReuseRangeEstimateForRef-3, 03724 applied to first table->quick_key_parts[key] key parts. 03725 */ 03726 if (table->quick_keys.is_set(key) && 03727 table->quick_key_parts[key] <= max_key_part && 03728 const_part & (1 << table->quick_key_parts[key]) && 03729 table->quick_n_ranges[key] == 1 + test(ref_or_null_part & 03730 const_part) && 03731 records > (double) table->quick_rows[key]) 03732 { 03733 tmp= records= (double) table->quick_rows[key]; 03734 } 03735 } 03736 03737 /* Limit the number of matched rows */ 03738 set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); 03739 if (table->used_keys.is_set(key)) 03740 { 03741 /* we can use only index tree */ 03742 uint keys_per_block= table->file->stats.block_size/2/ 03743 (keyinfo->key_length+table->file->ref_length)+1; 03744 tmp= record_count*(tmp+keys_per_block-1)/keys_per_block; 03745 } 03746 else 03747 tmp= record_count*min(tmp,s->worst_seeks); 03748 } 03749 else 03750 tmp= best_time; // Do nothing 03751 } 03752 } /* not ft_key */ 03753 if (tmp < best_time - records/(double) TIME_FOR_COMPARE) 03754 { 03755 best_time= tmp + records/(double) TIME_FOR_COMPARE; 03756 best= tmp; 03757 best_records= records; 03758 best_key= start_key; 03759 best_max_key_part= max_key_part; 03760 } 03761 } 03762 records= best_records; 03763 } 03764 03765 /* 03766 Don't test table scan if it can't be better. 03767 Prefer key lookup if we would use the same key for scanning. 03768 03769 Don't do a table scan on InnoDB tables, if we can read the used 03770 parts of the row from any of the used index. 03771 This is because table scans uses index and we would not win 03772 anything by using a table scan. 03773 03774 A word for word translation of the below if-statement in psergey's 03775 understanding: we check if we should use table scan if: 03776 (1) The found 'ref' access produces more records than a table scan 03777 (or index scan, or quick select), or 'ref' is more expensive than 03778 any of them. 03779 (2) This doesn't hold: the best way to perform table scan is to to perform 03780 'range' access using index IDX, and the best way to perform 'ref' 03781 access is to use the same index IDX, with the same or more key parts. 03782 (note: it is not clear how this rule is/should be extended to 03783 index_merge quick selects) 03784 (3) See above note about InnoDB. 03785 (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access 03786 path, but there is no quick select) 03787 If the condition in the above brackets holds, then the only possible 03788 "table scan" access method is ALL/index (there is no quick select). 03789 Since we have a 'ref' access path, and FORCE INDEX instructs us to 03790 choose it over ALL/index, there is no need to consider a full table 03791 scan. 03792 */ 03793 if ((records >= s->found_records || best > s->read_time) && // (1) 03794 !(s->quick && best_key && s->quick->index == best_key->key && // (2) 03795 best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2) 03796 !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3) 03797 ! s->table->used_keys.is_clear_all() && best_key) && // (3) 03798 !(s->table->force_index && best_key && !s->quick)) // (4) 03799 { // Check full join 03800 ha_rows rnd_records= s->found_records; 03801 /* 03802 If there is a filtering condition on the table (i.e. ref analyzer found 03803 at least one "table.keyXpartY= exprZ", where exprZ refers only to tables 03804 preceding this table in the join order we're now considering), then 03805 assume that 25% of the rows will be filtered out by this condition. 03806 03807 This heuristic is supposed to force tables used in exprZ to be before 03808 this table in join order. 03809 */ 03810 if (found_constraint) 03811 rnd_records-= rnd_records/4; 03812 03813 /* 03814 If applicable, get a more accurate estimate. Don't use the two 03815 heuristics at once. 03816 */ 03817 if (s->table->quick_condition_rows != s->found_records) 03818 rnd_records= s->table->quick_condition_rows; 03819 03820 /* 03821 Range optimizer never proposes a RANGE if it isn't better 03822 than FULL: so if RANGE is present, it's always preferred to FULL. 03823 Here we estimate its cost. 03824 */ 03825 if (s->quick) 03826 { 03827 /* 03828 For each record we: 03829 - read record range through 'quick' 03830 - skip rows which does not satisfy WHERE constraints 03831 TODO: 03832 We take into account possible use of join cache for ALL/index 03833 access (see first else-branch below), but we don't take it into 03834 account here for range/index_merge access. Find out why this is so. 03835 */ 03836 tmp= record_count * 03837 (s->quick->read_time + 03838 (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE); 03839 } 03840 else 03841 { 03842 /* Estimate cost of reading table. */ 03843 tmp= s->table->file->scan_time(); 03844 if (s->table->map & join->outer_join) // Can't use join cache 03845 { 03846 /* 03847 For each record we have to: 03848 - read the whole table record 03849 - skip rows which does not satisfy join condition 03850 */ 03851 tmp= record_count * 03852 (tmp + 03853 (s->records - rnd_records)/(double) TIME_FOR_COMPARE); 03854 } 03855 else 03856 { 03857 /* We read the table as many times as join buffer becomes full. */ 03858 tmp*= (1.0 + floor((double) cache_record_length(join,idx) * 03859 record_count / 03860 (double) thd->variables.join_buff_size)); 03861 /* 03862 We don't make full cartesian product between rows in the scanned 03863 table and existing records because we skip all rows from the 03864 scanned table, which does not satisfy join condition when 03865 we read the table (see flush_cached_records for details). Here we 03866 take into account cost to read and skip these records. 03867 */ 03868 tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE; 03869 } 03870 } 03871 03872 /* 03873 We estimate the cost of evaluating WHERE clause for found records 03874 as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus 03875 tmp give us total cost of using TABLE SCAN 03876 */ 03877 if (best == DBL_MAX || 03878 (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records < 03879 best + record_count/(double) TIME_FOR_COMPARE*records)) 03880 { 03881 /* 03882 If the table has a range (s->quick is set) make_join_select() 03883 will ensure that this will be used 03884 */ 03885 best= tmp; 03886 records= rows2double(rnd_records); 03887 best_key= 0; 03888 } 03889 } 03890 03891 /* Update the cost information for the current partial plan */ 03892 join->positions[idx].records_read= records; 03893 join->positions[idx].read_time= best; 03894 join->positions[idx].key= best_key; 03895 join->positions[idx].table= s; 03896 03897 if (!best_key && 03898 idx == join->const_tables && 03899 s->table == join->sort_by_table && 03900 join->unit->select_limit_cnt >= records) 03901 join->sort_by_table= (TABLE*) 1; // Must use temporary table 03902 03903 DBUG_VOID_RETURN; 03904 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void best_extension_by_limited_search | ( | JOIN * | join, | |
| table_map | remaining_tables, | |||
| uint | idx, | |||
| double | record_count, | |||
| double | read_time, | |||
| uint | depth, | |||
| uint | prune_level | |||
| ) | [static] |
Definition at line 4391 of file sql_select.cc.
References best_access_path(), JOIN::best_ref, check_interleaving_with_nj(), DBL_MAX, DBUG_ENTER, DBUG_EXECUTE, pos(), JOIN::positions, print_plan(), restore_prev_nj_state(), st_position::table, JOIN::thd, and TIME_FOR_COMPARE.
Referenced by greedy_search().
04398 { 04399 THD *thd= join->thd; 04400 if (thd->killed) // Abort 04401 return; 04402 04403 DBUG_ENTER("best_extension_by_limited_search"); 04404 DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx, 04405 "SOFAR:");); 04406 04407 /* 04408 'join' is a partial plan with lower cost than the best plan so far, 04409 so continue expanding it further with the tables in 'remaining_tables'. 04410 */ 04411 JOIN_TAB *s; 04412 double best_record_count= DBL_MAX; 04413 double best_read_time= DBL_MAX; 04414 04415 DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time, 04416 "part_plan");); 04417 04418 for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++) 04419 { 04420 table_map real_table_bit= s->table->map; 04421 if ((remaining_tables & real_table_bit) && 04422 !(remaining_tables & s->dependent) && 04423 (!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s))) 04424 { 04425 double current_record_count, current_read_time; 04426 04427 /* Find the best access method from 's' to the current partial plan */ 04428 best_access_path(join, s, thd, remaining_tables, idx, 04429 record_count, read_time); 04430 /* Compute the cost of extending the plan with 's' */ 04431 current_record_count= record_count * join->positions[idx].records_read; 04432 current_read_time= read_time + join->positions[idx].read_time; 04433 04434 /* Expand only partial plans with lower cost than the best QEP so far */ 04435 if ((current_read_time + 04436 current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read) 04437 { 04438 DBUG_EXECUTE("opt", print_plan(join, idx+1, 04439 current_record_count, 04440 read_time, 04441 (current_read_time + 04442 current_record_count / 04443 (double) TIME_FOR_COMPARE), 04444 "prune_by_cost");); 04445 restore_prev_nj_state(s); 04446 continue; 04447 } 04448 04449 /* 04450 Prune some less promising partial plans. This heuristic may miss 04451 the optimal QEPs, thus it results in a non-exhaustive search. 04452 */ 04453 if (prune_level == 1) 04454 { 04455 if (best_record_count > current_record_count || 04456 best_read_time > current_read_time || 04457 idx == join->const_tables && // 's' is the first table in the QEP 04458 s->table == join->sort_by_table) 04459 { 04460 if (best_record_count >= current_record_count && 04461 best_read_time >= current_read_time && 04462 /* TODO: What is the reasoning behind this condition? */ 04463 (!(s->key_dependent & remaining_tables) || 04464 join->positions[idx].records_read < 2.0)) 04465 { 04466 best_record_count= current_record_count; 04467 best_read_time= current_read_time; 04468 } 04469 } 04470 else 04471 { 04472 DBUG_EXECUTE("opt", print_plan(join, idx+1, 04473 current_record_count, 04474 read_time, 04475 current_read_time, 04476 "pruned_by_heuristic");); 04477 restore_prev_nj_state(s); 04478 continue; 04479 } 04480 } 04481 04482 if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) ) 04483 { /* Recursively expand the current partial plan */ 04484 swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); 04485 best_extension_by_limited_search(join, 04486 remaining_tables & ~real_table_bit, 04487 idx + 1, 04488 current_record_count, 04489 current_read_time, 04490 search_depth - 1, 04491 prune_level); 04492 if (thd->killed) 04493 DBUG_VOID_RETURN; 04494 swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); 04495 } 04496 else 04497 { /* 04498 'join' is either the best partial QEP with 'search_depth' relations, 04499 or the best complete QEP so far, whichever is smaller. 04500 */ 04501 current_read_time+= current_record_count / (double) TIME_FOR_COMPARE; 04502 if (join->sort_by_table && 04503 join->sort_by_table != 04504 join->positions[join->const_tables].table->table) 04505 /* We have to make a temp table */ 04506 current_read_time+= current_record_count; 04507 if ((search_depth == 1) || (current_read_time < join->best_read)) 04508 { 04509 memcpy((gptr) join->best_positions, (gptr) join->positions, 04510 sizeof(POSITION) * (idx + 1)); 04511 join->best_read= current_read_time - 0.001; 04512 } 04513 DBUG_EXECUTE("opt", print_plan(join, idx+1, 04514 current_record_count, 04515 read_time, 04516 current_read_time, 04517 "full_plan");); 04518 } 04519 restore_prev_nj_state(s); 04520 } 04521 } 04522 DBUG_VOID_RETURN; 04523 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static uint build_bitmap_for_nested_joins | ( | List< TABLE_LIST > * | join_list, | |
| uint | first_unused | |||
| ) | [static] |
Definition at line 7628 of file sql_select.cc.
References DBUG_ENTER, DBUG_RETURN, st_nested_join::join_list, st_table_list::nested_join, and st_nested_join::nj_map.
Referenced by JOIN::optimize().
07630 { 07631 List_iterator<TABLE_LIST> li(*join_list); 07632 TABLE_LIST *table; 07633 DBUG_ENTER("build_bitmap_for_nested_joins"); 07634 while ((table= li++)) 07635 { 07636 NESTED_JOIN *nested_join; 07637 if ((nested_join= table->nested_join)) 07638 { 07639 /* 07640 It is guaranteed by simplify_joins() function that a nested join 07641 that has only one child represents a single table VIEW (and the child 07642 is an underlying table). We don't assign bits to such nested join 07643 structures because 07644 1. it is redundant (a "sequence" of one table cannot be interleaved 07645 with anything) 07646 2. we could run out bits in nested_join_map otherwise. 07647 */ 07648 if (nested_join->join_list.elements != 1) 07649 { 07650 nested_join->nj_map= 1 << first_unused++; 07651 first_unused= build_bitmap_for_nested_joins(&nested_join->join_list, 07652 first_unused); 07653 } 07654 } 07655 } 07656 DBUG_RETURN(first_unused); 07657 }
Here is the caller graph for this function:

| static COND * build_equal_items | ( | THD * | thd, | |
| COND * | cond, | |||
| COND_EQUAL * | inherited, | |||
| List< TABLE_LIST > * | join_list, | |||
| COND_EQUAL ** | cond_equal_ref | |||
| ) | [static] |
Definition at line 6835 of file sql_select.cc.
References build_equal_items_for_cond(), cond, Item_func::COND_AND_FUNC, st_table_list::cond_equal, Item::COND_ITEM, COND_EQUAL::current_level, Item::FUNC_ITEM, st_nested_join::join_list, Item_func::MULT_EQUAL_FUNC, st_table_list::nested_join, NULL, st_table_list::on_expr, List< T >::push_back(), and COND_EQUAL::upper_levels.
Referenced by optimize_cond().
06839 { 06840 COND_EQUAL *cond_equal= 0; 06841 06842 if (cond) 06843 { 06844 cond= build_equal_items_for_cond(cond, inherited); 06845 cond->update_used_tables(); 06846 if (cond->type() == Item::COND_ITEM && 06847 ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) 06848 cond_equal= &((Item_cond_and*) cond)->cond_equal; 06849 else if (cond->type() == Item::FUNC_ITEM && 06850 ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC) 06851 { 06852 cond_equal= new COND_EQUAL; 06853 cond_equal->current_level.push_back((Item_equal *) cond); 06854 } 06855 } 06856 if (cond_equal) 06857 { 06858 cond_equal->upper_levels= inherited; 06859 inherited= cond_equal; 06860 } 06861 *cond_equal_ref= cond_equal; 06862 06863 if (join_list) 06864 { 06865 TABLE_LIST *table; 06866 List_iterator<TABLE_LIST> li(*join_list); 06867 06868 while ((table= li++)) 06869 { 06870 if (table->on_expr) 06871 { 06872 List<TABLE_LIST> *join_list= table->nested_join ? 06873 &table->nested_join->join_list : NULL; 06874 /* 06875 We can modify table->on_expr because its old value will 06876 be restored before re-execution of PS/SP. 06877 */ 06878 table->on_expr= build_equal_items(thd, table->on_expr, inherited, 06879 join_list, &table->cond_equal); 06880 } 06881 } 06882 } 06883 06884 return cond; 06885 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static COND* build_equal_items_for_cond | ( | COND * | cond, | |
| COND_EQUAL * | inherited | |||
| ) | [static] |
Definition at line 6665 of file sql_select.cc.
References args, check_equality(), cond, Item_func::COND_AND_FUNC, Item::COND_ITEM, COND_EQUAL::current_level, Item::equal_fields_propagator(), Item_equal::fix_length_and_dec(), Item::FUNC_ITEM, COND_EQUAL::max_members, Item_equal::members(), List< T >::pop(), List_iterator< T >::remove(), List_iterator< T >::replace(), List_iterator< T >::rewind(), Item_equal::transform(), Item::update_used_tables(), Item_equal::update_used_tables(), and COND_EQUAL::upper_levels.
Referenced by build_equal_items().
06667 { 06668 Item_equal *item_equal; 06669 uint members; 06670 COND_EQUAL cond_equal; 06671 cond_equal.upper_levels= inherited; 06672 06673 if (cond->type() == Item::COND_ITEM) 06674 { 06675 bool and_level= ((Item_cond*) cond)->functype() == 06676 Item_func::COND_AND_FUNC; 06677 List<Item> *args= ((Item_cond*) cond)->argument_list(); 06678 06679 List_iterator<Item> li(*args); 06680 Item *item; 06681 06682 if (and_level) 06683 { 06684 /* 06685 Retrieve all conjucts of this level detecting the equality 06686 that are subject to substitution by multiple equality items and 06687 removing each such predicate from the conjunction after having 06688 found/created a multiple equality whose inference the predicate is. 06689 */ 06690 while ((item= li++)) 06691 { 06692 /* 06693 PS/SP note: we can safely remove a node from AND-OR 06694 structure here because it's restored before each 06695 re-execution of any prepared statement/stored procedure. 06696 */ 06697 if (check_equality(item, &cond_equal)) 06698 li.remove(); 06699 } 06700 06701 List_iterator_fast<Item_equal> it(cond_equal.current_level); 06702 while ((item_equal= it++)) 06703 { 06704 item_equal->fix_length_and_dec(); 06705 item_equal->update_used_tables(); 06706 members= item_equal->members(); 06707 if (cond_equal.max_members < members) 06708 cond_equal.max_members= members; 06709 } 06710 members= cond_equal.max_members; 06711 if (inherited && inherited->max_members < members) 06712 { 06713 do 06714 { 06715 inherited->max_members= members; 06716 inherited= inherited->upper_levels; 06717 } 06718 while (inherited); 06719 } 06720 06721 ((Item_cond_and*)cond)->cond_equal= cond_equal; 06722 inherited= &(((Item_cond_and*)cond)->cond_equal); 06723 } 06724 /* 06725 Make replacement of equality predicates for lower levels 06726 of the condition expression. 06727 */ 06728 li.rewind(); 06729 while ((item= li++)) 06730 { 06731 Item *new_item; 06732 if ((new_item = build_equal_items_for_cond(item, inherited))!= item) 06733 { 06734 /* This replacement happens only for standalone equalities */ 06735 /* 06736 This is ok with PS/SP as the replacement is done for 06737 arguments of an AND/OR item, which are restored for each 06738 execution of PS/SP. 06739 */ 06740 li.replace(new_item); 06741 } 06742 } 06743 if (and_level) 06744 args->concat((List<Item> *)&cond_equal.current_level); 06745 } 06746 else if (cond->type() == Item::FUNC_ITEM) 06747 { 06748 /* 06749 If an equality predicate forms the whole and level, 06750 we call it standalone equality and it's processed here. 06751 E.g. in the following where condition 06752 WHERE a=5 AND (b=5 or a=c) 06753 (b=5) and (a=c) are standalone equalities. 06754 In general we can't leave alone standalone eqalities: 06755 for WHERE a=b AND c=d AND (b=c OR d=5) 06756 b=c is replaced by =(a,b,c,d). 06757 */ 06758 if (check_equality(cond, &cond_equal) && 06759 (item_equal= cond_equal.current_level.pop())) 06760 { 06761 item_equal->fix_length_and_dec(); 06762 item_equal->update_used_tables(); 06763 return item_equal; 06764 } 06765 /* 06766 For each field reference in cond, not from equal item predicates, 06767 set a pointer to the multiple equality it belongs to (if there is any) 06768 */ 06769 cond= cond->transform(&Item::equal_fields_propagator, 06770 (byte *) inherited); 06771 cond->update_used_tables(); 06772 } 06773 return cond; 06774 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4644 of file sql_select.cc.
References JOIN::best_ref, calc_used_field_length(), JOIN::const_tables, pos(), JOIN::thd, and st_join_table::used_fieldlength.
Referenced by best_access_path().
04645 { 04646 uint length=0; 04647 JOIN_TAB **pos,**end; 04648 THD *thd=join->thd; 04649 04650 for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ; 04651 pos != end ; 04652 pos++) 04653 { 04654 JOIN_TAB *join_tab= *pos; 04655 if (!join_tab->used_fieldlength) /* Not calced yet */ 04656 calc_used_field_length(thd, join_tab); 04657 length+=join_tab->used_fieldlength; 04658 } 04659 return length; 04660 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 13072 of file sql_select.cc.
References DBUG_ASSERT, DECIMAL_RESULT, Field::field_length, FIELD_TYPE_BIT, FIELD_TYPE_BLOB, JOIN::group, HA_KEY_BLOB_LENGTH, INT_RESULT, st_order::item, key_length, MAX_BLOB_WIDTH, my_decimal_get_binary_size(), MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VARCHAR, st_order::next, Field::pack_length(), REAL_RESULT, STRING_RESULT, JOIN::thd, JOIN::tmp_table_param, and Field::type().
Referenced by JOIN::exec().
13073 { 13074 uint key_length=0, parts=0, null_parts=0; 13075 13076 if (group) 13077 join->group= 1; 13078 for (; group ; group=group->next) 13079 { 13080 Item *group_item= *group->item; 13081 Field *field= group_item->get_tmp_table_field(); 13082 if (field) 13083 { 13084 enum_field_types type; 13085 if ((type= field->type()) == FIELD_TYPE_BLOB) 13086 key_length+=MAX_BLOB_WIDTH; // Can't be used as a key 13087 else if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_VAR_STRING) 13088 key_length+= field->field_length + HA_KEY_BLOB_LENGTH; 13089 else if (type == FIELD_TYPE_BIT) 13090 { 13091 /* Bit is usually stored as a longlong key for group fields */ 13092 key_length+= 8; // Big enough 13093 } 13094 else 13095 key_length+= field->pack_length(); 13096 } 13097 else 13098 { 13099 switch (group_item->result_type()) { 13100 case REAL_RESULT: 13101 key_length+= sizeof(double); 13102 break; 13103 case INT_RESULT: 13104 key_length+= sizeof(longlong); 13105 break; 13106 case DECIMAL_RESULT: 13107 key_length+= my_decimal_get_binary_size(group_item->max_length - 13108 (group_item->decimals ? 1 : 0), 13109 group_item->decimals); 13110 break; 13111 case STRING_RESULT: 13112 /* 13113 Group strings are taken as varstrings and require an length field. 13114 A field is not yet created by create_tmp_field() 13115 and the sizes should match up. 13116 */ 13117 key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH; 13118 break; 13119 default: 13120 /* This case should never be choosen */ 13121 DBUG_ASSERT(0); 13122 join->thd->fatal_error(); 13123 } 13124 } 13125 parts++; 13126 if (group_item->maybe_null) 13127 null_parts++; 13128 } 13129 join->tmp_table_param.group_length=key_length+null_parts; 13130 join->tmp_table_param.group_parts=parts; 13131 join->tmp_table_param.group_null_parts=null_parts; 13132 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void calc_used_field_length | ( | THD * | thd, | |
| JOIN_TAB * | join_tab | |||
| ) | [static] |
Definition at line 4607 of file sql_select.cc.
References bitmap_is_set(), BLOB_FLAG, st_table::field, Field::field_index, st_table::file, Field::flags, flags, max, st_table::maybe_null, ha_statistics::mean_rec_length, NOT_NULL_FLAG, st_table_share::null_fields, null_fields, Field::pack_length(), st_table::read_set, st_table_share::reclength, st_table::s, handler::stats, st_join_table::table, st_join_table::used_blobs, st_join_table::used_fieldlength, and st_join_table::used_fields.
Referenced by cache_record_length(), and join_init_cache().
04608 { 04609 uint null_fields,blobs,fields,rec_length; 04610 Field **f_ptr,*field; 04611 MY_BITMAP *read_set= join_tab->table->read_set;; 04612 04613 null_fields= blobs= fields= rec_length=0; 04614 for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++) 04615 { 04616 if (bitmap_is_set(read_set, field->field_index)) 04617 { 04618 uint flags=field->flags; 04619 fields++; 04620 rec_length+=field->pack_length(); 04621 if (flags & BLOB_FLAG) 04622 blobs++; 04623 if (!(flags & NOT_NULL_FLAG)) 04624 null_fields++; 04625 } 04626 } 04627 if (null_fields) 04628 rec_length+=(join_tab->table->s->null_fields+7)/8; 04629 if (join_tab->table->maybe_null) 04630 rec_length+=sizeof(my_bool); 04631 if (blobs) 04632 { 04633 uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length- 04634 (join_tab->table->s->reclength- rec_length)); 04635 rec_length+=(uint) max(4,blob_length); 04636 } 04637 join_tab->used_fields=fields; 04638 join_tab->used_fieldlength=rec_length; 04639 join_tab->used_blobs=blobs; 04640 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void change_cond_ref_to_const | ( | THD * | thd, | |
| I_List< COND_CMP > * | save_list, | |||
| Item * | and_father, | |||
| Item * | cond, | |||
| Item * | field, | |||
| Item * | value | |||
| ) | [static] |
Definition at line 7191 of file sql_select.cc.
References args, DTCollation::collation, Item::collation, cond, Item_func::COND_AND_FUNC, Item::COND_ITEM, Item::COND_OK, Item::const_item(), Item::eq(), Item_func::EQ_FUNC, Item_func::EQUAL_FUNC, func, I_List< T >::push_back(), Item::result_type(), STRING_RESULT, and value.
Referenced by propagate_cond_constants().
07194 { 07195 if (cond->type() == Item::COND_ITEM) 07196 { 07197 bool and_level= ((Item_cond*) cond)->functype() == 07198 Item_func::COND_AND_FUNC; 07199 List_iterator<Item> li(*((Item_cond*) cond)->argument_list()); 07200 Item *item; 07201 while ((item=li++)) 07202 change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item, 07203 field, value); 07204 return; 07205 } 07206 if (cond->eq_cmp_result() == Item::COND_OK) 07207 return; // Not a boolean function 07208 07209 Item_bool_func2 *func= (Item_bool_func2*) cond; 07210 Item **args= func->arguments(); 07211 Item *left_item= args[0]; 07212 Item *right_item= args[1]; 07213 Item_func::Functype functype= func->functype(); 07214 07215 if (right_item->eq(field,0) && left_item != value && 07216 (left_item->result_type() != STRING_RESULT || 07217 value->result_type() != STRING_RESULT || 07218 left_item->collation.collation == value->collation.collation)) 07219 { 07220 Item *tmp=value->new_item(); 07221 if (tmp) 07222 { 07223 thd->change_item_tree(args + 1, tmp); 07224 func->update_used_tables(); 07225 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) 07226 && and_father != cond && !left_item->const_item()) 07227 { 07228 cond->marker=1; 07229 COND_CMP *tmp2; 07230 if ((tmp2=new COND_CMP(and_father,func))) 07231 save_list->push_back(tmp2); 07232 } 07233 func->set_cmp_func(); 07234 } 07235 } 07236 else if (left_item->eq(field,0) && right_item != value && 07237 (right_item->result_type() != STRING_RESULT || 07238 value->result_type() != STRING_RESULT || 07239 right_item->collation.collation == value->collation.collation)) 07240 { 07241 Item *tmp=value->new_item(); 07242 if (tmp) 07243 { 07244 thd->change_item_tree(args, tmp); 07245 value= tmp; 07246 func->update_used_tables(); 07247 if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC) 07248 && and_father != cond && !right_item->const_item()) 07249 { 07250 args[0]= args[1]; // For easy check 07251 thd->change_item_tree(args + 1, value); 07252 cond->marker=1; 07253 COND_CMP *tmp2; 07254 if ((tmp2=new COND_CMP(and_father,func))) 07255 save_list->push_back(tmp2); 07256 } 07257 func->set_cmp_func(); 07258 } 07259 } 07260 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool change_group_ref | ( | THD * | thd, | |
| Item_func * | expr, | |||
| ORDER * | group_list, | |||
| bool * | changed | |||
| ) | [static] |
Definition at line 13784 of file sql_select.cc.
References Item_func::arg_count, Item_func::arguments(), Item::eq(), FALSE, Item::FIELD_ITEM, Item::FUNC_ITEM, Item::maybe_null, Item::name, st_order::next, Item::REF_ITEM, TRUE, and Item::type().
Referenced by JOIN::rollup_init().
13786 { 13787 if (expr->arg_count) 13788 { 13789 Name_resolution_context *context= &thd->lex->current_select->context; 13790 Item **arg,**arg_end; 13791 bool arg_changed= FALSE; 13792 for (arg= expr->arguments(), 13793 arg_end= expr->arguments()+expr->arg_count; 13794 arg != arg_end; arg++) 13795 { 13796 Item *item= *arg; 13797 if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM) 13798 { 13799 ORDER *group_tmp; 13800 for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next) 13801 { 13802 if (item->eq(*group_tmp->item,0)) 13803 { 13804 Item *new_item; 13805 if (!(new_item= new Item_ref(context, group_tmp->item, 0, 13806 item->name))) 13807 return 1; // fatal_error is set 13808 thd->change_item_tree(arg, new_item); 13809 arg_changed= TRUE; 13810 } 13811 } 13812 } 13813 else if (item->type() == Item::FUNC_ITEM) 13814 { 13815 if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed)) 13816 return 1; 13817 } 13818 } 13819 if (arg_changed) 13820 { 13821 expr->maybe_null= 1; 13822 *changed= TRUE; 13823 } 13824 } 13825 return 0; 13826 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool change_refs_to_tmp_fields | ( | THD * | thd, | |
| Item ** | ref_pointer_array, | |||
| List< Item > & | new_list1, | |||
| List< Item > & | new_list2, | |||
| uint | elements, | |||
| List< Item > & | items | |||
| ) | [static] |
Definition at line 13554 of file sql_select.cc.
References base_list::elements, base_list::empty(), Item::get_tmp_table_item(), List< T >::push_back(), and List_iterator_fast< T >::sublist().
Referenced by JOIN::exec().
13558 { 13559 List_iterator_fast<Item> it(all_fields); 13560 Item *item, *new_item; 13561 res_selected_fields.empty(); 13562 res_all_fields.empty(); 13563 13564 uint i, border= all_fields.elements - elements; 13565 for (i= 0; (item= it++); i++) 13566 { 13567 res_all_fields.push_back(new_item= item->get_tmp_table_item(thd)); 13568 ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= 13569 new_item; 13570 } 13571 13572 List_iterator_fast<Item> itr(res_all_fields); 13573 for (i= 0; i < border; i++) 13574 itr++; 13575 itr.sublist(res_selected_fields, elements); 13576 13577 return thd->is_fatal_error; 13578 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool change_to_use_tmp_fields | ( | THD * | thd, | |
| Item ** | ref_pointer_array, | |||
| List< Item > & | new_list1, | |||
| List< Item > & | new_list2, | |||
| uint | elements, | |||
| List< Item > & | items | |||
| ) | [static] |
Definition at line 13475 of file sql_select.cc.
References DBUG_ENTER, DBUG_RETURN, base_list::elements, base_list::empty(), FALSE, Item::FIELD_ITEM, Item::get_tmp_table_field(), Item::get_tmp_table_item(), st_table::group, String::length(), my_charset_bin, Item::name, Item_sum::print(), String::ptr(), List< T >::push_back(), sql_strmake(), List_iterator_fast< T >::sublist(), Item::SUM_FUNC_ITEM, Field::table, TRUE, Item::type(), and Item::with_sum_func.
Referenced by JOIN::exec().
13479 { 13480 List_iterator_fast<Item> it(all_fields); 13481 Item *item_field,*item; 13482 DBUG_ENTER("change_to_use_tmp_fields"); 13483 13484 res_selected_fields.empty(); 13485 res_all_fields.empty(); 13486 13487 uint i, border= all_fields.elements - elements; 13488 for (i= 0; (item= it++); i++) 13489 { 13490 Field *field; 13491 13492 if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) 13493 item_field= item; 13494 else 13495 { 13496 if (item->type() == Item::FIELD_ITEM) 13497 { 13498 item_field= item->get_tmp_table_item(thd); 13499 } 13500 else if ((field= item->get_tmp_table_field())) 13501 { 13502 if (item->type() == Item::SUM_FUNC_ITEM && field->table->group) 13503 item_field= ((Item_sum*) item)->result_item(field); 13504 else 13505 item_field= (Item*) new Item_field(field); 13506 if (!item_field) 13507 DBUG_RETURN(TRUE); // Fatal error 13508 item_field->name= item->name; 13509 #ifndef DBUG_OFF 13510 if (!item_field->name) 13511 { 13512 char buff[256]; 13513 String str(buff,sizeof(buff),&my_charset_bin); 13514 str.length(0); 13515 item->print(&str); 13516 item_field->name= sql_strmake(str.ptr(),str.length()); 13517 } 13518 #endif 13519 } 13520 else 13521 item_field= item; 13522 } 13523 res_all_fields.push_back(item_field); 13524 ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= 13525 item_field; 13526 } 13527 13528 List_iterator_fast<Item> itr(res_all_fields); 13529 for (i= 0; i < border; i++) 13530 itr++; 13531 itr.sublist(res_selected_fields, elements); 13532 DBUG_RETURN(FALSE); 13533 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool check_equality | ( | Item * | item, | |
| COND_EQUAL * | cond_equal | |||
| ) | [static] |
Definition at line 6441 of file sql_select.cc.
References Item_equal::add(), COND_EQUAL::current_level, Item_func::EQ_FUNC, FALSE, Item_field::field, Item::FIELD_ITEM, find_item_equal(), Item::FUNC_ITEM, Item_equal::merge(), List< T >::push_back(), Item::REF_ITEM, List_iterator< T >::remove(), Item::result_type(), Item_field::result_type(), STRING_RESULT, TRUE, Item::type(), and Item_ref::VIEW_REF.
Referenced by build_equal_items_for_cond().
06442 { 06443 if (item->type() == Item::FUNC_ITEM && 06444 ((Item_func*) item)->functype() == Item_func::EQ_FUNC) 06445 { 06446 Item *left_item= ((Item_func*) item)->arguments()[0]; 06447 Item *right_item= ((Item_func*) item)->arguments()[1]; 06448 06449 if (left_item->type() == Item::REF_ITEM && 06450 ((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF) 06451 { 06452 if (((Item_ref*)left_item)->depended_from) 06453 return FALSE; 06454 left_item= left_item->real_item(); 06455 } 06456 if (right_item->type() == Item::REF_ITEM && 06457 ((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF) 06458 { 06459 if (((Item_ref*)right_item)->depended_from) 06460 return FALSE; 06461 right_item= right_item->real_item(); 06462 } 06463 if (left_item->type() == Item::FIELD_ITEM && 06464 right_item->type() == Item::FIELD_ITEM && 06465 !((Item_field*)left_item)->depended_from && 06466 !((Item_field*)right_item)->depended_from) 06467 { 06468 /* The predicate the form field1=field2 is processed */ 06469 06470 Field *left_field= ((Item_field*) left_item)->field; 06471 Field *right_field= ((Item_field*) right_item)->field; 06472 06473 if (!left_field->eq_def(right_field)) 06474 return FALSE; 06475 06476 if (left_field->eq(right_field)) /* f = f */ 06477 return TRUE; 06478 06479 /* Search for multiple equalities containing field1 and/or field2 */ 06480 bool left_copyfl, right_copyfl; 06481 Item_equal *left_item_equal= 06482 find_item_equal(cond_equal, left_field, &left_copyfl); 06483 Item_equal *right_item_equal= 06484 find_item_equal(cond_equal, right_field, &right_copyfl); 06485 06486 if (left_item_equal && left_item_equal == right_item_equal) 06487 { 06488 /* 06489 The equality predicate is inference of one of the existing 06490 multiple equalities, i.e the condition is already covered 06491 by upper level equalities 06492 */ 06493 return TRUE; 06494 } 06495 06496 /* Copy the found multiple equalities at the current level if needed */ 06497 if (left_copyfl) 06498 { 06499 /* left_item_equal of an upper level contains left_item */ 06500 left_item_equal= new Item_equal(left_item_equal); 06501 cond_equal->current_level.push_back(left_item_equal); 06502 } 06503 if (right_copyfl) 06504 { 06505 /* right_item_equal of an upper level contains right_item */ 06506 right_item_equal= new Item_equal(right_item_equal); 06507 cond_equal->current_level.push_back(right_item_equal); 06508 } 06509 06510 if (left_item_equal) 06511 { 06512 /* left item was found in the current or one of the upper levels */ 06513 if (! right_item_equal) 06514 left_item_equal->add((Item_field *) right_item); 06515 else 06516 { 06517 /* Merge two multiple equalities forming a new one */ 06518 left_item_equal->merge(right_item_equal); 06519 /* Remove the merged multiple equality from the list */ 06520 List_iterator<Item_equal> li(cond_equal->current_level); 06521 while ((li++) != right_item_equal); 06522 li.remove(); 06523 } 06524 } 06525 else 06526 { 06527 /* left item was not found neither the current nor in upper levels */ 06528 if (right_item_equal) 06529 right_item_equal->add((Item_field *) left_item); 06530 else 06531 { 06532 /* None of the fields was found in multiple equalities */ 06533 Item_equal *item= new Item_equal((Item_field *) left_item, 06534 (Item_field *) right_item); 06535 cond_equal->current_level.push_back(item); 06536 } 06537 } 06538 return TRUE; 06539 } 06540 06541 { 06542 /* The predicate of the form field=const/const=field is processed */ 06543 Item *const_item= 0; 06544 Item_field *field_item= 0; 06545 if (left_item->type() == Item::FIELD_ITEM && 06546 !((Item_field*)left_item)->depended_from && 06547 right_item->const_item()) 06548 { 06549 field_item= (Item_field*) left_item; 06550 const_item= right_item; 06551 } 06552 else if (right_item->type() == Item::FIELD_ITEM && 06553 !((Item_field*)right_item)->depended_from && 06554 left_item->const_item()) 06555 { 06556 field_item= (Item_field*) right_item; 06557 const_item= left_item; 06558 } 06559 if (const_item && 06560 field_item->result_type() == const_item->result_type()) 06561 { 06562 bool copyfl; 06563 06564 if (field_item->result_type() == STRING_RESULT) 06565 { 06566 CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset(); 06567 if ((cs != ((Item_cond *) item)->compare_collation()) || 06568 !cs->coll->propagate(cs, 0, 0)) 06569 return FALSE; 06570 } 06571 06572 Item_equal *item_equal = find_item_equal(cond_equal, 06573 field_item->field, ©fl); 06574 if (copyfl) 06575 { 06576 item_equal= new Item_equal(item_equal); 06577 cond_equal->current_level.push_back(item_equal); 06578 } 06579 if (item_equal) 06580 { 06581 /* 06582 The flag cond_false will be set to 1 after this, if item_equal 06583 already contains a constant and its value is not equal to 06584 the value of const_item. 06585 */ 06586 item_equal->add(const_item); 06587 } 06588 else 06589 { 06590 item_equal= new Item_equal(const_item, field_item); 06591 cond_equal->current_level.push_back(item_equal); 06592 } 06593 return TRUE; 06594 } 06595 } 06596 } 06597 return FALSE; 06598 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 7783 of file sql_select.cc.
References st_nested_join::counter, JOIN::cur_embedding_map, st_table_list::embedding, st_join_table::embedding_map, st_join_table::join, st_nested_join::join_list, st_table_list::nested_join, st_nested_join::nj_map, st_table::pos_in_table_list, st_join_table::table, and TRUE.
Referenced by best_extension_by_limited_search(), and find_best().
07784 { 07785 TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding; 07786 JOIN *join= last_tab->join; 07787 07788 if (join->cur_embedding_map & ~next_tab->embedding_map) 07789 { 07790 /* 07791 next_tab is outside of the "pair of brackets" we're currently in. 07792 Cannot add it. 07793 */ 07794 return TRUE; 07795 } 07796 07797 /* 07798 Do update counters for "pairs of brackets" that we've left (marked as 07799 X,Y,Z in the above picture) 07800 */ 07801 for (;next_emb; next_emb= next_emb->embedding) 07802 { 07803 next_emb->nested_join->counter++; 07804 if (next_emb->nested_join->counter == 1) 07805 { 07806 /* 07807 next_emb is the first table inside a nested join we've "entered". In 07808 the picture above, we're looking at the 'X' bracket. Don't exit yet as 07809 X bracket might have Y pair bracket. 07810 */ 07811 join->cur_embedding_map |= next_emb->nested_join->nj_map; 07812 } 07813 07814 if (next_emb->nested_join->join_list.elements != 07815 next_emb->nested_join->counter) 07816 break; 07817 07818 /* 07819 We're currently at Y or Z-bracket as depicted in the above picture. 07820 Mark that we've left it and continue walking up the brackets hierarchy. 07821 */ 07822 join->cur_embedding_map &= ~next_emb->nested_join->nj_map; 07823 } 07824 return FALSE; 07825 }
Here is the caller graph for this function:

Definition at line 3928 of file sql_select.cc.
References JOIN::best_read, JOIN::best_ref, JOIN::const_tables, JOIN::cur_embedding_map, DBL_MAX, DBUG_ENTER, DBUG_VOID_RETURN, determine_search_depth(), find_best(), greedy_search(), JOIN::join_list, join_tab_cmp(), join_tab_cmp_straight(), MAX_TABLES, optimize_straight_join(), qsort(), reset_nj_counters(), JOIN::select_options, SELECT_STRAIGHT_JOIN, JOIN::tables, and JOIN::thd.
03929 { 03930 uint search_depth= join->thd->variables.optimizer_search_depth; 03931 uint prune_level= join->thd->variables.optimizer_prune_level; 03932 bool straight_join= join->select_options & SELECT_STRAIGHT_JOIN; 03933 DBUG_ENTER("choose_plan"); 03934 03935 join->cur_embedding_map= 0; 03936 reset_nj_counters(join->join_list); 03937 /* 03938 if (SELECT_STRAIGHT_JOIN option is set) 03939 reorder tables so dependent tables come after tables they depend 03940 on, otherwise keep tables in the order they were specified in the query 03941 else 03942 Apply heuristic: pre-sort all access plans with respect to the number of 03943 records accessed. 03944 */ 03945 qsort(join->best_ref + join->const_tables, join->tables - join->const_tables, 03946 sizeof(JOIN_TAB*), straight_join?join_tab_cmp_straight:join_tab_cmp); 03947 03948 if (straight_join) 03949 { 03950 optimize_straight_join(join, join_tables); 03951 } 03952 else 03953 { 03954 if (search_depth == MAX_TABLES+2) 03955 { /* 03956 TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before 03957 the greedy version. Will be removed when greedy_search is approved. 03958 */ 03959 join->best_read= DBL_MAX; 03960 find_best(join, join_tables, join->const_tables, 1.0, 0.0); 03961 } 03962 else 03963 { 03964 if (search_depth == 0) 03965 /* Automatically determine a reasonable value for 'search_depth' */ 03966 search_depth= determine_search_depth(join); 03967 greedy_search(join, join_tables, search_depth, prune_level); 03968 } 03969 } 03970 03971 /* 03972 Store the cost of this query into a user variable 03973 */ 03974 join->thd->status_var.last_query_cost= join->best_read; 03975 DBUG_VOID_RETURN; 03976 }
Here is the call graph for this function:

| static void clear_tables | ( | JOIN * | join | ) | [static] |
Definition at line 6277 of file sql_select.cc.
References JOIN::const_tables, and JOIN::table.
Referenced by JOIN::clear().
06278 { 06279 /* 06280 must clear only the non-const tables, as const tables 06281 are not re-calculated. 06282 */ 06283 for (uint i=join->const_tables ; i < join->tables ; i++) 06284 mark_as_null_row(join->table[i]); // All fields are NULL 06285 }
Here is the caller graph for this function:

Definition at line 12558 of file sql_select.cc.
References cp_buffer_from_ref(), st_join_table::join, st_table_ref::key_buff, st_table_ref::key_buff2, st_table_ref::key_err, st_table_ref::key_length, memcmp(), memcpy, st_join_table::ref, st_join_table::table, and JOIN::thd.
Referenced by join_read_key().
12559 { 12560 bool diff; 12561 if (!(diff=tab->ref.key_err)) 12562 { 12563 memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length); 12564 } 12565 if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, tab->table, 12566 &tab->ref)) || 12567 diff) 12568 return 1; 12569 return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length) 12570 != 0; 12571 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int compare_fields_by_table_order | ( | Item_field * | field1, | |
| Item_field * | field2, | |||
| void * | table_join_idx | |||
| ) | [static] |
Definition at line 6909 of file sql_select.cc.
References cmp, Item_field::field, OUTER_REF_TABLE_BIT, Field::table, st_table::tablenr, and Item_field::used_tables().
Referenced by substitute_for_best_equal_field().
06912 { 06913 int cmp= 0; 06914 bool outer_ref= 0; 06915 if (field2->used_tables() & OUTER_REF_TABLE_BIT) 06916 { 06917 outer_ref= 1; 06918 cmp= -1; 06919 } 06920 if (field2->used_tables() & OUTER_REF_TABLE_BIT) 06921 { 06922 outer_ref= 1; 06923 cmp++; 06924 } 06925 if (outer_ref) 06926 return cmp; 06927 JOIN_TAB **idx= (JOIN_TAB **) table_join_idx; 06928 cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr]; 06929 return cmp < 0 ? -1 : (cmp ? 1 : 0); 06930 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 12002 of file sql_select.cc.
References st_table_share::rec_buff_length, and st_table::s.
Referenced by remove_dup_with_compare().
12003 { 12004 for (; *ptr ; ptr++) 12005 { 12006 if ((*ptr)->cmp_offset(table->s->rec_buff_length)) 12007 return 1; 12008 } 12009 return 0; 12010 }
Here is the caller graph for this function:

Definition at line 8059 of file sql_select.cc.
References cond, Item_func::COND_AND_FUNC, Item::COND_ITEM, Item::COND_OK, Item::const_item(), Item::eq(), Item_func::EQ_FUNC, Item_func::EQUAL_FUNC, and func.
Referenced by remove_const().
08060 { 08061 if (cond->type() == Item::COND_ITEM) 08062 { 08063 bool and_level= (((Item_cond*) cond)->functype() 08064 == Item_func::COND_AND_FUNC); 08065 List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list()); 08066 Item *item; 08067 while ((item=li++)) 08068 { 08069 bool res=const_expression_in_where(item, comp_item, const_item); 08070 if (res) // Is a const value 08071 { 08072 if (and_level) 08073 return 1; 08074 } 08075 else if (!and_level) 08076 return 0; 08077 } 08078 return and_level ? 0 : 1; 08079 } 08080 else if (cond->eq_cmp_result() != Item::COND_OK) 08081 { // boolan compare function 08082 Item_func* func= (Item_func*) cond; 08083 if (func->functype() != Item_func::EQUAL_FUNC && 08084 func->functype() != Item_func::EQ_FUNC) 08085 return 0; 08086 Item *left_item= ((Item_func*) cond)->arguments()[0]; 08087 Item *right_item= ((Item_func*) cond)->arguments()[1]; 08088 if (left_item->eq(comp_item,1)) 08089 { 08090 if (right_item->const_item()) 08091 { 08092 if (*const_item) 08093 return right_item->eq(*const_item, 1); 08094 *const_item=right_item; 08095 return 1; 08096 } 08097 } 08098 else if (right_item->eq(comp_item,1)) 08099 { 08100 if (left_item->const_item()) 08101 { 08102 if (*const_item) 08103 return left_item->eq(*const_item, 1); 08104 *const_item=left_item; 08105 return 1; 08106 } 08107 } 08108 } 08109 return 0; 08110 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 12012 of file sql_select.cc.
References BLOB_FLAG, and mySTL::copy().
Referenced by remove_dup_with_compare().
12013 { 12014 for (; *ptr ; ptr++) 12015 { 12016 if ((*ptr)->flags & BLOB_FLAG) 12017 if (((Field_blob *) (*ptr))->copy()) 12018 return 1; // Error 12019 } 12020 return 0; 12021 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void copy_fields | ( | TMP_TABLE_PARAM * | param | ) |
Definition at line 13352 of file sql_select.cc.
References Copy_field::do_copy.
Referenced by Item_func_group_concat::add(), Item_sum_count_distinct::add(), JOIN::clear(), end_send_group(), end_unique_update(), end_update(), end_write(), end_write_group(), and QUICK_GROUP_MIN_MAX_SELECT::get_next().
13353 { 13354 Copy_field *ptr=param->copy_field; 13355 Copy_field *end=param->copy_field_end; 13356 13357 for (; ptr != end; ptr++) 13358 (*ptr->do_copy)(ptr); 13359 13360 List_iterator_fast<Item> it(param->copy_funcs); 13361 Item_copy_string *item; 13362 while ((item = (Item_copy_string*) it++)) 13363 item->copy(); 13364 }
Here is the caller graph for this function:

| void copy_funcs | ( | Item ** | func_ptr | ) |
Definition at line 13676 of file sql_select.cc.
References func.
Referenced by Item_func_group_concat::add(), Item_sum_count_distinct::add(), end_unique_update(), end_update(), end_write(), and end_write_group().
13677 { 13678 Item *func; 13679 for (; (func = *func_ptr) ; func_ptr++) 13680 func->save_in_result_field(1); 13681 }
Here is the caller graph for this function:

Definition at line 13637 of file sql_select.cc.
Referenced by end_write_group(), and JOIN::rollup_write_data().
13638 { 13639 for (; func_ptr != end_ptr ; func_ptr++) 13640 (void) (*func_ptr)->save_in_result_field(1); 13641 return; 13642 }
Here is the caller graph for this function:

Definition at line 12974 of file sql_select.cc.
References Item::const_item(), Item::FIELD_ITEM, Item::real_item(), Item::SUM_FUNC_ITEM, Item::type(), and Item::with_sum_func.
Referenced by JOIN::exec(), JOIN::prepare(), Item_func_group_concat::setup(), Item_sum_count_distinct::setup(), and Item_in_subselect::single_value_transformer().
12976 { 12977 List_iterator<Item> li(fields); 12978 Item *field; 12979 12980 param->field_count=param->sum_func_count=param->func_count= 12981 param->hidden_field_count=0; 12982 param->quick_group=1; 12983 while ((field=li++)) 12984 { 12985 Item::Type type=field->real_item()->type(); 12986 if (type == Item::FIELD_ITEM) 12987 param->field_count++; 12988 else if (type == Item::SUM_FUNC_ITEM) 12989 { 12990 if (! field->const_item()) 12991 { 12992 Item_sum *sum_item=(Item_sum*) field->real_item(); 12993 if (!sum_item->quick_group) 12994 param->quick_group=0; // UDF SUM function 12995 param->sum_func_count++; 12996 12997 for (uint i=0 ; i < sum_item->arg_count ; i++) 12998 { 12999 if (sum_item->args[0]->real_item()->type() == Item::FIELD_ITEM) 13000 param->field_count++; 13001 else 13002 param->func_count++; 13003 } 13004 } 13005 } 13006 else 13007 { 13008 param->func_count++; 13009 if (reset_with_sum_func) 13010 field->with_sum_func=0; 13011 } 13012 } 13013 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 12575 of file sql_select.cc.
References CHECK_FIELD_IGNORE, mySTL::copy(), dbug_tmp_restore_column_map(), dbug_tmp_use_all_columns(), st_table_ref::key_copy, and st_table::write_set.
Referenced by cmp_buffer_with_ref(), get_quick_select_for_ref(), join_ft_read_first(), join_read_always_key(), join_read_const(), and join_read_last_key().
12576 { 12577 enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; 12578 thd->count_cuted_fields= CHECK_FIELD_IGNORE; 12579 my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set); 12580 bool result= 0; 12581 12582 for (store_key **copy=ref->key_copy ; *copy ; copy++) 12583 { 12584 if ((*copy)->copy() & 1) 12585 { 12586 result= 1; 12587 break; 12588 } 12589 } 12590 thd->count_cuted_fields= save_count_cuted_fields; 12591 dbug_tmp_restore_column_map(table->write_set, old_map); 12592 return result; 12593 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static ORDER * create_distinct_group | ( | THD * | thd, | |
| Item ** | ref_pointer_array, | |||
| ORDER * | order, | |||
| List< Item > & | fields, | |||
| bool * | all_order_by_fields_used | |||
| ) | [static] |
Definition at line 12905 of file sql_select.cc.
References Item::marker, st_order::next, and order.
12908 { 12909 List_iterator<Item> li(fields); 12910 Item *item; 12911 ORDER *order,*group,**prev; 12912 12913 *all_order_by_fields_used= 1; 12914 while ((item=li++)) 12915 item->marker=0; /* Marker that field is not used */ 12916 12917 prev= &group; group=0; 12918 for (order=order_list ; order; order=order->next) 12919 { 12920 if (order->in_field_list) 12921 { 12922 ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER)); 12923 if (!ord) 12924 return 0; 12925 *prev=ord; 12926 prev= &ord->next; 12927 (*ord->item)->marker=1; 12928 } 12929 else 12930 *all_order_by_fields_used= 0; 12931 } 12932 12933 li.rewind(); 12934 while ((item=li++)) 12935 { 12936 if (!item->const_item() && !item->with_sum_func && !item->marker) 12937 { 12938 /* 12939 Don't put duplicate columns from the SELECT list into the 12940 GROUP BY list. 12941 */ 12942 ORDER *ord_iter; 12943 for (ord_iter= group; ord_iter; ord_iter= ord_iter->next) 12944 if ((*ord_iter->item)->eq(item, 1)) 12945 break; 12946 if (ord_iter) 12947 continue; 12948 12949 ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER)); 12950 if (!ord) 12951 return 0; 12952 /* 12953 We have here only field_list (not all_field_list), so we can use 12954 simple indexing of ref_pointer_array (order in the array and in the 12955 list are same) 12956 */ 12957 ord->item= ref_pointer_array; 12958 ord->asc=1; 12959 *prev=ord; 12960 prev= &ord->next; 12961 } 12962 ref_pointer_array++; 12963 } 12964 *prev=0; 12965 return group; 12966 }
| bool create_myisam_from_heap | ( | THD * | thd, | |
| TABLE * | table, | |||
| TMP_TABLE_PARAM * | param, | |||
| int | error, | |||
| bool | ignore_last_dupp_key_error | |||
| ) |
Definition at line 9437 of file sql_select.cc.
References handler::change_table_ptr(), handler::close(), create_myisam_tmp_table(), st_table_share::db_type, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, handler::delete_table(), handler::disable_indexes(), err, handler::extra(), st_table::file, get_new_handler(), HA_CHECK_DUP, HA_ERR_RECORD_FILE_FULL, HA_EXTRA_NO_ROWS, HA_EXTRA_WRITE_CACHE, handler::ha_index_or_rnd_end(), HA_KEY_SWITCH_ALL, handler::ha_rnd_end(), handler::ha_rnd_init(), handler::ha_start_bulk_insert(), HA_STATUS_VARIABLE, heap_hton, handler::indexes_are_disabled(), handler::info(), handler::is_fatal_error(), st_table::mem_root, MYF, myisam_hton, st_table::no_rows, open_tmp_table(), handler::print_error(), st_table::record, ha_statistics::records, handler::rnd_next(), st_table::s, handler::stats, LEX_STRING::str, strcmp(), st_table_share::table_name, st_table::use_all_columns(), and handler::write_row().
Referenced by end_update(), end_write(), end_write_group(), JOIN::rollup_write_data(), and schema_table_store_record().
09439 { 09440 TABLE new_table; 09441 TABLE_SHARE share; 09442 const char *save_proc_info; 09443 int write_err; 09444 DBUG_ENTER("create_myisam_from_heap"); 09445 09446 if (table->s->db_type != &heap_hton || 09447 error != HA_ERR_RECORD_FILE_FULL) 09448 { 09449 table->file->print_error(error,MYF(0)); 09450 DBUG_RETURN(1); 09451 } 09452 new_table= *table; 09453 share= *table->s; 09454 new_table.s= &share; 09455 new_table.s->db_type= &myisam_hton; 09456 if (!(new_table.file= get_new_handler(&share, &new_table.mem_root, 09457 &myisam_hton))) 09458 DBUG_RETURN(1); // End of memory 09459 09460 save_proc_info=thd->proc_info; 09461 thd->proc_info="converting HEAP to MyISAM"; 09462 09463 if (create_myisam_tmp_table(&new_table, param, 09464 thd->lex->select_lex.options | thd->options)) 09465 goto err2; 09466 if (open_tmp_table(&new_table)) 09467 goto err1; 09468 if (table->file->indexes_are_disabled()) 09469 new_table.file->disable_indexes(HA_KEY_SWITCH_ALL); 09470 table->file->ha_index_or_rnd_end(); 09471 table->file->ha_rnd_init(1); 09472 if (table->no_rows) 09473 { 09474 new_table.file->extra(HA_EXTRA_NO_ROWS); 09475 new_table.no_rows=1; 09476 } 09477 09478 #ifdef TO_BE_DONE_LATER_IN_4_1 09479 /* 09480 To use start_bulk_insert() (which is new in 4.1) we need to find 09481 all places where a corresponding end_bulk_insert() should be put. 09482 */ 09483 table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */ 09484 new_table.file->ha_start_bulk_insert(table->file->stats.records); 09485 #else 09486 /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */ 09487 new_table.file->extra(HA_EXTRA_WRITE_CACHE); 09488 #endif 09489 09490 /* 09491 copy all old rows from heap table to MyISAM table 09492 This is the only code that uses record[1] to read/write but this 09493 is safe as this is a temporary MyISAM table without timestamp/autoincrement 09494 or partitioning. 09495 */ 09496 while (!table->file->rnd_next(new_table.record[1])) 09497 { 09498 if ((write_err= new_table.file->write_row(new_table.record[1]))) 09499 goto err; 09500 } 09501 /* copy row that filled HEAP table */ 09502 if ((write_err=new_table.file->write_row(table->record[0]))) 09503 { 09504 if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) || 09505 !ignore_last_dupp_key_error) 09506 goto err; 09507 } 09508 09509 /* remove heap table and change to use myisam table */ 09510 (void) table->file->ha_rnd_end(); 09511 (void) table->file->close(); 09512 (void) table->file->delete_table(table->s->table_name.str); 09513 delete table->file; 09514 table->file=0; 09515 new_table.s= table->s; // Keep old share 09516 *table= new_table; 09517 *table->s= share; 09518 table->file->change_table_ptr(table, table->s); 09519 table->use_all_columns(); 09520 if (save_proc_info) 09521 thd->proc_info= (!strcmp(save_proc_info,"Copying to tmp table") ? 09522 "Copying to tmp table on disk" : save_proc_info); 09523 DBUG_RETURN(0); 09524 09525 err: 09526 DBUG_PRINT("error",("Got error: %d",write_err)); 09527 table->file->print_error(error,MYF(0)); // Give table is full error 09528 (void) table->file->ha_rnd_end(); 09529 (void) new_table.file->close(); 09530 err1: 09531 new_table.file->delete_table(new_table.s->table_name.str); 09532 err2: 09533 delete new_table.file; 09534 thd->proc_info=save_proc_info; 09535 DBUG_RETURN(1); 09536 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool create_myisam_tmp_table | ( | TABLE * | table, | |
| TMP_TABLE_PARAM * | param, | |||
| ulong | options | |||
| ) | [static] |
Definition at line 9287 of file sql_select.cc.
References alloc_root(), BLOB_FLAG, st_table_share::blob_ptr_size, bzero, st_table_share::db_record_offset, st_table::db_stat, DBUG_ENTER, DBUG_RETURN, err, error, FIELD_CHECK, FIELDFLAG_BINARY, st_table::file, st_mi_keydef::flag, HA_BINARY_PACK_KEY, HA_BLOB_PART, HA_CREATE_TMP_TABLE, HA_KEYTYPE_VARBINARY2, HA_KEYTYPE_VARTEXT2, HA_NOSAME, HA_NULL_ARE_EQUAL, HA_PACK_KEY, HA_SPACE_PACK, st_table::in_use, keyinfo, st_table_share::keys, LOCK_status, handler::max_key_length(), handler::max_key_parts(), st_table::mem_root, mi_create(), MI_UNIQUE_HASH_LENGTH, MYF, MYSQL_TYPE_STRING, NOT_NULL_FLAG, OPTION_BIG_TABLES, handler::print_error(), st_table_share::reclength, st_table::record, st_table::s, st_mi_keydef::seg, SELECT_SMALL_RESULT, statistic_increment, LEX_STRING::str, st_table_share::table_name, and st_table_share::uniques.
Referenced by create_myisam_from_heap(), and create_tmp_table().
09289 { 09290 int error; 09291 MI_KEYDEF keydef; 09292 MI_UNIQUEDEF uniquedef; 09293 KEY *keyinfo=param->keyinfo; 09294 TABLE_SHARE *share= table->s; 09295 DBUG_ENTER("create_myisam_tmp_table"); 09296 09297 if (share->keys) 09298 { // Get keys for ni_create 09299 bool using_unique_constraint=0; 09300 HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root, 09301 sizeof(*seg) * keyinfo->key_parts); 09302 if (!seg) 09303 goto err; 09304 09305 bzero(seg, sizeof(*seg) * keyinfo->key_parts); 09306 if (keyinfo->key_length >= table->file->max_key_length() || 09307 keyinfo->key_parts > table->file->max_key_parts() || 09308 share->uniques) 09309 { 09310 /* Can't create a key; Make a unique constraint instead of a key */ 09311 share->keys= 0; 09312 share->uniques= 1; 09313 using_unique_constraint=1; 09314 bzero((char*) &uniquedef,sizeof(uniquedef)); 09315 uniquedef.keysegs=keyinfo->key_parts; 09316 uniquedef.seg=seg; 09317 uniquedef.null_are_equal=1; 09318 09319 /* Create extra column for hash value */ 09320 bzero((byte*) param->recinfo,sizeof(*param->recinfo)); 09321 param->recinfo->type= FIELD_CHECK; 09322 param->recinfo->length=MI_UNIQUE_HASH_LENGTH; 09323 param->recinfo++; 09324 share->reclength+=MI_UNIQUE_HASH_LENGTH; 09325 } 09326 else 09327 { 09328 /* Create an unique key */ 09329 bzero((char*) &keydef,sizeof(keydef)); 09330 keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY; 09331 keydef.keysegs= keyinfo->key_parts; 09332 keydef.seg= seg; 09333 } 09334 for (uint i=0; i < keyinfo->key_parts ; i++,seg++) 09335 { 09336 Field *field=keyinfo->key_part[i].field; 09337 seg->flag= 0; 09338 seg->language= field->charset()->number; 09339 seg->length= keyinfo->key_part[i].length; 09340 seg->start= keyinfo->key_part[i].offset; 09341 if (field->flags & BLOB_FLAG) 09342 { 09343 seg->type= 09344 ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ? 09345 HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2); 09346 seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size); 09347 seg->flag= HA_BLOB_PART; 09348 seg->length=0; // Whole blob in unique constraint 09349 } 09350 else 09351 { 09352 seg->type= keyinfo->key_part[i].type; 09353 /* Tell handler if it can do suffic space compression */ 09354 if (field->real_type() == MYSQL_TYPE_STRING && 09355 keyinfo->key_part[i].length > 4) 09356 seg->flag|= HA_SPACE_PACK; 09357 } 09358 if (!(field->flags & NOT_NULL_FLAG)) 09359 { 09360 seg->null_bit= field->null_bit; 09361 seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]); 09362 /* 09363 We are using a GROUP BY on something that contains NULL 09364 In this case we have to tell MyISAM that two NULL should 09365 on INSERT be regarded at the same value 09366 */ 09367 if (!using_unique_constraint) 09368 keydef.flag|= HA_NULL_ARE_EQUAL; 09369 } 09370 } 09371 } 09372 MI_CREATE_INFO create_info; 09373 bzero((char*) &create_info,sizeof(create_info)); 09374 09375 if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == 09376 OPTION_BIG_TABLES) 09377 create_info.data_file_length= ~(ulonglong) 0; 09378 09379 if ((error=mi_create(share->table_name.str, share->keys, &keydef, 09380 (uint) (param->recinfo-param->start_recinfo), 09381 param->start_recinfo, 09382 share->uniques, &uniquedef, 09383 &create_info, 09384 HA_CREATE_TMP_TABLE))) 09385 { 09386 table->file->print_error(error,MYF(0)); /* purecov: inspected */ 09387 table->db_stat=0; 09388 goto err; 09389 } 09390 statistic_increment(table->in_use->status_var.created_tmp_disk_tables, 09391 &LOCK_status); 09392 share->db_record_offset= 1; 09393 DBUG_RETURN(0); 09394 err: 09395 DBUG_RETURN(1); 09396 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool create_ref_for_key | ( | JOIN * | join, | |
| JOIN_TAB * | j, | |||
| KEYUSE * | org_keyuse, | |||
| table_map | used_tables | |||
| ) | [static] |
Definition at line 4738 of file sql_select.cc.
References ALIGN_SIZE, JOIN::const_table_map, DBUG_ENTER, DBUG_RETURN, FT_KEYPART, get_store_key(), int(), st_table_ref::items, Item_func_match::join_key, JT_FT, st_table_ref::key, keyuse_t::key, key, st_table_ref::key_buff, st_table_ref::key_buff2, st_table_ref::key_copy, st_table_ref::key_err, st_table::key_info, st_table_ref::key_length, KEY_OPTIMIZE_REF_OR_NULL, st_table_ref::key_parts, keyinfo, keyuse_t::keypart, keyuse_t::null_rejecting, st_table_ref::null_rejecting, keyuse_t::optimize, st_join_table::ref, JOIN::select_options, keyuse_t::table, st_join_table::table, test, JOIN::thd, TRUE, st_join_table::type, keyuse_t::used_tables, and keyuse_t::val.
Referenced by get_best_combination(), and test_if_skip_sort_order().
04740 { 04741 KEYUSE *keyuse=org_keyuse; 04742 bool ftkey=(keyuse->keypart == FT_KEYPART); 04743 THD *thd= join->thd; 04744 uint keyparts,length,key; 04745 TABLE *table; 04746 KEY *keyinfo; 04747 DBUG_ENTER("create_ref_for_key"); 04748 04749 /* Use best key from find_best */ 04750 table=j->table; 04751 key=keyuse->key; 04752 keyinfo=table->key_info+key; 04753 04754 if (ftkey) 04755 { 04756 Item_func_match *ifm=(Item_func_match *)keyuse->val; 04757 04758 length=0; 04759 keyparts=1; 04760 ifm->join_key=1; 04761 } 04762 else 04763 { 04764 keyparts=length=0; 04765 uint found_part_ref_or_null= 0; 04766 /* 04767 Calculate length for the used key 04768 Stop if there is a missing key part or when we find second key_part 04769 with KEY_OPTIMIZE_REF_OR_NULL 04770 */ 04771 do 04772 { 04773 if (!(~used_tables & keyuse->used_tables)) 04774 { 04775 if (keyparts == keyuse->keypart && 04776 !(found_part_ref_or_null & keyuse->optimize)) 04777 { 04778 keyparts++; 04779 length+= keyinfo->key_part[keyuse->keypart].store_length; 04780 found_part_ref_or_null|= keyuse->optimize; 04781 } 04782 } 04783 keyuse++; 04784 } while (keyuse->table == table && keyuse->key == key); 04785 } /* not ftkey */ 04786 04787 /* set up fieldref */ 04788 keyinfo=table->key_info+key; 04789 j->ref.key_parts=keyparts; 04790 j->ref.key_length=length; 04791 j->ref.key=(int) key; 04792 if (!(j->ref.key_buff= (byte*) thd->calloc(ALIGN_SIZE(length)*2)) || 04793 !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) * 04794 (keyparts+1)))) || 04795 !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts))) 04796 { 04797 DBUG_RETURN(TRUE); 04798 } 04799 j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length); 04800 j->ref.key_err=1; 04801 j->ref.null_rejecting= 0; 04802 keyuse=org_keyuse; 04803 04804 store_key **ref_key= j->ref.key_copy; 04805 byte *key_buff=j->ref.key_buff, *null_ref_key= 0; 04806 bool keyuse_uses_no_tables= TRUE; 04807 if (ftkey) 04808 { 04809 j->ref.items[0]=((Item_func*)(keyuse->val))->key_item(); 04810 if (keyuse->used_tables) 04811 DBUG_RETURN(TRUE); // not supported yet. SerG 04812 04813 j->type=JT_FT; 04814 } 04815 else 04816 { 04817 uint i; 04818 for (i=0 ; i < keyparts ; keyuse++,i++) 04819 { 04820 while (keyuse->keypart != i || 04821 ((~used_tables) & keyuse->used_tables)) 04822 keyuse++; /* Skip other parts */ 04823 04824 uint maybe_null= test(keyinfo->key_part[i].null_bit); 04825 j->ref.items[i]=keyuse->val; // Save for cond removal 04826 if (keyuse->null_rejecting) 04827 j->ref.null_rejecting |= 1 << i; 04828 keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; 04829 if (!keyuse->used_tables && 04830 !(join->select_options & SELECT_DESCRIBE)) 04831 { // Compare against constant 04832 store_key_item tmp(thd, keyinfo->key_part[i].field, 04833 (char*)key_buff + maybe_null, 04834 maybe_null ? (char*) key_buff : 0, 04835 keyinfo->key_part[i].length, keyuse->val); 04836 if (thd->is_fatal_error) 04837 DBUG_RETURN(TRUE); 04838 tmp.copy(); 04839 } 04840 else 04841 *ref_key++= get_store_key(thd, 04842 keyuse,join->const_table_map, 04843 &keyinfo->key_part[i], 04844 (char*) key_buff,maybe_null); 04845 /* 04846 Remember if we are going to use REF_OR_NULL 04847 But only if field _really_ can be null i.e. we force JT_REF 04848 instead of JT_REF_OR_NULL in case if field can't be null 04849 */ 04850 if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null) 04851 null_ref_key= key_buff; 04852 key_buff+=keyinfo->key_part[i].store_length; 04853 } 04854 } /* not ftkey */ 04855 *ref_key=0; // end_marker 04856 if (j->type == JT_FT) 04857 DBUG_RETURN(0); 04858 if (j->type == JT_CONST) 04859 j->table->const_table= 1; 04860 else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY | 04861 HA_END_SPACE_KEY)) != HA_NOSAME) || 04862 keyparts != keyinfo->key_parts || null_ref_key) 04863 { 04864 /* Must read with repeat */ 04865 j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; 04866 j->ref.null_ref_key= null_ref_key; 04867 } 04868 else if (keyuse_uses_no_tables) 04869 { 04870 /* 04871 This happen if we are using a constant expression in the ON part 04872 of an LEFT JOIN. 04873 SELECT * FROM a LEFT JOIN b ON b.key=30 04874 Here we should not mark the table as a 'const' as a field may 04875 have a 'normal' value or a NULL value. 04876 */ 04877 j->type=JT_CONST; 04878 } 04879 else 04880 j->type=JT_EQ_REF; 04881 DBUG_RETURN(0); 04882 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int create_sort_index | ( | THD * | thd, | |
| JOIN * | join, | |||
| ORDER * | order, | |||
| ha_rows | filesort_limit, | |||
| ha_rows | select_limit | |||
| ) | [static] |
Definition at line 11866 of file sql_select.cc.
References SQL_SELECT::cleanup(), JOIN::const_tables, DBUG_ENTER, DBUG_RETURN, err, JOIN::examined_rows, handler::extra(), st_table::file, filesort(), st_join_table::first_unmatched, st_filesort_info::found_records, st_join_table::found_records, get_quick_select_for_ref(), get_schema_tables_result(), HA_EXTRA_NO_KEYREAD, HA_STATUS_VARIABLE, QUICK_SELECT_I::index, handler::info(), st_filesort_info::io_cache, st_join_table::join, join_init_read_record(), JOIN::join_tab, JT_ALL, JT_FT, st_table_ref::key, st_table::key_read, st_join_table::last_inner, make_unireg_sortorder(), my_malloc(), MY_WME, MY_ZEROFILL, MYF, OPTION_SCHEMA_TABLE, order, st_join_table::quick, SQL_SELECT::quick, st_join_table::read_first_record, st_join_table::records, st_join_table::ref, st_table::s, st_join_table::select, st_join_table::select_cond, JOIN::select_lex, st_table::sort, st_table::status, st_join_table::table, JOIN::tables, test_if_skip_sort_order(), st_table_share::tmp_table, and st_join_table::type.
Referenced by JOIN::exec().
11868 { 11869 SORT_FIELD *sortorder; 11870 uint length; 11871 ha_rows examined_rows; 11872 TABLE *table; 11873 SQL_SELECT *select; 11874 JOIN_TAB *tab; 11875 DBUG_ENTER("create_sort_index"); 11876 11877 if (join->tables == join->const_tables) 11878 DBUG_RETURN(0); // One row, no need to sort 11879 tab= join->join_tab + join->const_tables; 11880 table= tab->table; 11881 select= tab->select; 11882 11883 if (test_if_skip_sort_order(tab,order,select_limit,0)) 11884 DBUG_RETURN(0); 11885 if (!(sortorder=make_unireg_sortorder(order,&length))) 11886 goto err; /* purecov: inspected */ 11887 /* It's not fatal if the following alloc fails */ 11888 table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE), 11889 MYF(MY_WME | MY_ZEROFILL)); 11890 table->status=0; // May be wrong if quick_select 11891 11892 // If table has a range, move it to select 11893 if (select && !select->quick && tab->ref.key >= 0) 11894 { 11895 if (tab->quick) 11896 { 11897 select->quick=tab->quick; 11898 tab->quick=0; 11899 /* 11900 We can only use 'Only index' if quick key is same as ref_key 11901 and in index_merge 'Only index' cannot be used 11902 */ 11903 if (table->key_read && ((uint) tab->ref.key != select->quick->index)) 11904 { 11905 table->key_read=0; 11906 table->file->extra(HA_EXTRA_NO_KEYREAD); 11907 } 11908 } 11909 else 11910 { 11911 /* 11912 We have a ref on a const; Change this to a range that filesort 11913 can use. 11914 For impossible ranges (like when doing a lookup on NULL on a NOT NULL 11915 field, quick will contain an empty record set. 11916 */ 11917 if (!(select->quick= (tab->type == JT_FT ? 11918 new FT_SELECT(thd, table, tab->ref.key) : 11919 get_quick_select_for_ref(thd, table, &tab->ref, 11920 tab->found_records)))) 11921 goto err; 11922 } 11923 } 11924 11925 /* Fill schema tables with data before filesort if it's necessary */ 11926 if ((join->select_lex->options & OPTION_SCHEMA_TABLE) && 11927 get_schema_tables_result(join)) 11928 goto err; 11929 11930 if (table->s->tmp_table) 11931 table->file->info(HA_STATUS_VARIABLE); // Get record count 11932 table->sort.found_records=filesort(thd, table,sortorder, length, 11933 select, filesort_limit, 0, 11934 &examined_rows); 11935 tab->records= table->sort.found_records; // For SQL_CALC_ROWS 11936 if (select) 11937 { 11938 select->cleanup(); // filesort did select 11939 tab->select= 0; 11940 } 11941 tab->select_cond=0; 11942 tab->last_inner= 0; 11943 tab->first_unmatched= 0; 11944 tab->type=JT_ALL; // Read with normal read_record 11945 tab->read_first_record= join_init_read_record; 11946 tab->join->examined_rows+=examined_rows; 11947 if (table->key_read) // Restore if we used indexes 11948 { 11949 table->key_read=0; 11950 table->file->extra(HA_EXTRA_NO_KEYREAD); 11951 } 11952 DBUG_RETURN(table->sort.found_records == HA_POS_ERROR); 11953 err: 11954 DBUG_RETURN(-1); 11955 }
Here is the call graph for this function:

Here is the caller graph for this function:

| Field* create_tmp_field | ( | THD * | thd, | |
| TABLE * | table, | |||
| Item * | item, | |||
| Item::Type | type, | |||
| Item *** | copy_func, | |||
| Field ** | from_field, | |||
| Field ** | default_field, | |||
| bool | group, | |||
| bool | modify_item, | |||
| bool | table_cant_handle_bit_fields, | |||
| bool | make_copy_field, | |||
| uint | convert_blob_length | |||
| ) |
Definition at line 8334 of file sql_select.cc.
References Item::COND_ITEM, Item_sum::create_tmp_field(), create_tmp_field_from_field(), create_tmp_field_from_item(), DBUG_ASSERT, Item::DECIMAL_ITEM, Item::DEFAULT_VALUE_ITEM, Field::eq_def(), Item_field::field, Item::FIELD_AVG_ITEM, Item::FIELD_ITEM, Item::FIELD_STD_ITEM, FIELD_TYPE_BIT, Item::FUNC_ITEM, Item::INT_ITEM, Field::maybe_null(), Item::maybe_null, Item::name, NULL, Item::NULL_ITEM, Item::PROC_ITEM, Item::REAL_ITEM, Item::real_item(), Item::REF_ITEM, Item_field::result_field, Item::STRING_ITEM, Item::SUBSELECT_ITEM, Item::SUM_FUNC_ITEM, Field::type(), Item::type(), Item::TYPE_HOLDER, and Item::VARBIN_ITEM.
Referenced by create_table_from_items(), and create_tmp_table().
08341 { 08342 Field *result; 08343 Item::Type orig_type= type; 08344 Item *orig_item= 0; 08345 08346 if (type != Item::FIELD_ITEM && 08347 item->real_item()->type() == Item::FIELD_ITEM && 08348 (item->type() != Item::REF_ITEM || 08349 !((Item_ref *) item)->depended_from)) 08350 { 08351 orig_item= item; 08352 item= item->real_item(); 08353 type= Item::FIELD_ITEM; 08354 } 08355 08356 switch (type) { 08357 case Item::SUM_FUNC_ITEM: 08358 { 08359 Item_sum *item_sum=(Item_sum*) item; 08360 result= item_sum->create_tmp_field(group, table, convert_blob_length); 08361 if (!result) 08362 thd->fatal_error(); 08363 return result; 08364 } 08365 case Item::FIELD_ITEM: 08366 case Item::DEFAULT_VALUE_ITEM: 08367 { 08368 Item_field *field= (Item_field*) item; 08369 bool orig_modify= modify_item; 08370 if (orig_type == Item::REF_ITEM) 08371 modify_item= 0; 08372 /* 08373 If item have to be able to store NULLs but underlaid field can't do it, 08374 create_tmp_field_from_field() can't be used for tmp field creation. 08375 */ 08376 if (field->maybe_null && !field->field->maybe_null()) 08377 { 08378 result= create_tmp_field_from_item(thd, item, table, NULL, 08379 modify_item, convert_blob_length); 08380 *from_field= field->field; 08381 if (result && modify_item) 08382 field->result_field= result; 08383 } 08384 else if (table_cant_handle_bit_fields && field->field->type() == 08385 FIELD_TYPE_BIT) 08386 { 08387 *from_field= field->field; 08388 result= create_tmp_field_from_item(thd, item, table, copy_func, 08389 modify_item, convert_blob_length); 08390 if (result && modify_item) 08391 field->result_field= result; 08392 } 08393 else 08394 result= create_tmp_field_from_field(thd, (*from_field= field->field), 08395 orig_item ? orig_item->name : 08396 item->name, 08397 table, 08398 modify_item ? field : 08399 NULL, 08400 convert_blob_length); 08401 if (orig_type == Item::REF_ITEM && orig_modify) 08402 ((Item_ref*)orig_item)->set_result_field(result); 08403 if (field->field->eq_def(result)) 08404 *default_field= field->field; 08405 return result; 08406 } 08407 /* Fall through */ 08408 case Item::FUNC_ITEM: 08409 case Item::COND_ITEM: 08410 case Item::FIELD_AVG_ITEM: 08411 case Item::FIELD_STD_ITEM: 08412 case Item::SUBSELECT_ITEM: 08413 /* The following can only happen with 'CREATE TABLE ... SELECT' */ 08414 case Item::PROC_ITEM: 08415 case Item::INT_ITEM: 08416 case Item::REAL_ITEM: 08417 case Item::DECIMAL_ITEM: 08418 case Item::STRING_ITEM: 08419 case Item::REF_ITEM: 08420 case Item::NULL_ITEM: 08421 case Item::VARBIN_ITEM: 08422 if (make_copy_field) 08423 { 08424 DBUG_ASSERT(((Item_result_field*)item)->result_field); 08425 *from_field= ((Item_result_field*)item)->result_field; 08426 } 08427 return create_tmp_field_from_item(thd, item, table, 08428 (make_copy_field ? 0 : copy_func), 08429 modify_item, convert_blob_length); 08430 case Item::TYPE_HOLDER: 08431 return ((Item_type_holder *)item)->make_field_by_type(table); 08432 default: // Dosen't have to be stored 08433 return 0; 08434 } 08435 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 8283 of file sql_select.cc.
References DTCollation::collation, Item::collation, Item::field_type(), MAX_FIELD_VARCHARLENGTH, Item::max_length, Item::maybe_null, charset_info_st::mbmaxlen, MYSQL_TYPE_VARCHAR, Item::name, st_table::s, and Item::tmp_table_field_from_field_type().
Referenced by create_tmp_table().
08284 { 08285 if (item->field_type() == MYSQL_TYPE_VARCHAR) 08286 { 08287 Field *field; 08288 if (item->max_length > MAX_FIELD_VARCHARLENGTH / 08289 item->collation.collation->mbmaxlen) 08290 field= new Field_blob(item->max_length, item->maybe_null, 08291 item->name, item->collation.collation); 08292 else 08293 field= new Field_varstring(item->max_length, item->maybe_null, 08294 item->name, 08295 table->s, item->collation.collation); 08296 if (field) 08297 field->init(table); 08298 return field; 08299 } 08300 return item->tmp_table_field_from_field_type(table, 0); 08301 }
Here is the call graph for this function:

Here is the caller graph for this function:

| Field* create_tmp_field_from_field | ( | THD * | thd, | |
| Field * | org_field, | |||
| const char * | name, | |||
| TABLE * | table, | |||
| Item_field * | item, | |||
| uint | convert_blob_length | |||
| ) |
Definition at line 8139 of file sql_select.cc.
References BLOB_FLAG, Field::charset(), Field::field_name, Field::flags, HA_OPTION_PACK_RECORD, Field::init(), Field::maybe_null(), Item::maybe_null, MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_VARCHAR, Field::new_field(), NO_DEFAULT_VALUE_FLAG, NOT_NULL_FLAG, Field::orig_table, Item_field::result_field, st_table::s, Field::table, Field::type(), and UINT_MAX16.
Referenced by create_tmp_field(), and Item_sum_hybrid::create_tmp_field().
08142 { 08143 Field *new_field; 08144 08145 /* 08146 Make sure that the blob fits into a Field_varstring which has 08147 2-byte lenght. 08148 */ 08149 if (convert_blob_length && convert_blob_length < UINT_MAX16 && 08150 (org_field->flags & BLOB_FLAG)) 08151 new_field= new Field_varstring(convert_blob_length, 08152 org_field->maybe_null(), 08153 org_field->field_name, table->s, 08154 org_field->charset()); 08155 else 08156 new_field= org_field->new_field(thd->mem_root, table, 08157 table == org_field->table); 08158 if (new_field) 08159 { 08160 new_field->init(table); 08161 new_field->orig_table= org_field->orig_table; 08162 if (item) 08163 item->result_field= new_field; 08164 else 08165 new_field->field_name= name; 08166 new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG); 08167 if (org_field->maybe_null() || (item && item->maybe_null)) 08168 new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join 08169 if (org_field->type() == MYSQL_TYPE_VAR_STRING || 08170 org_field->type() == MYSQL_TYPE_VARCHAR) 08171 table->s->db_create_options|= HA_OPTION_PACK_RECORD; 08172 } 08173 return new_field; 08174 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static Field* create_tmp_field_from_item | ( | THD * | thd, | |
| Item * | item, | |||
| TABLE * | table, | |||
| Item *** | copy_func, | |||
| bool | modify_item, | |||
| uint | convert_blob_length | |||
| ) | [static] |
Definition at line 8201 of file sql_select.cc.
References DTCollation::collation, Item::collation, DBUG_ASSERT, DECIMAL_RESULT, Item::decimals, Item::field_type(), Field::init(), INT_RESULT, Item::is_result_field(), LINT_INIT, Item::make_string_field(), Item::max_length, Item::maybe_null, charset_info_st::mbmaxlen, MYSQL_TYPE_DATE, MYSQL_TYPE_DATETIME, MYSQL_TYPE_TIME, Item::name, REAL_RESULT, Item::result_type(), ROW_RESULT, st_table::s, Item::set_result_field(), STRING_RESULT, Item::tmp_table_field_from_field_type(), UINT_MAX16, and Item::unsigned_flag.
Referenced by create_tmp_field().
08204 { 08205 bool maybe_null= item->maybe_null; 08206 Field *new_field; 08207 LINT_INIT(new_field); 08208 08209 switch (item->result_type()) { 08210 case REAL_RESULT: 08211 new_field= new Field_double(item->max_length, maybe_null, 08212 item->name, item->decimals); 08213 break; 08214 case INT_RESULT: 08215 /* Select an integer type with the minimal fit precision */ 08216 if (item->max_length > 11) 08217 new_field=new Field_longlong(item->max_length, maybe_null, 08218 item->name, item->unsigned_flag); 08219 else 08220 new_field=new Field_long(item->max_length, maybe_null, 08221 item->name, item->unsigned_flag); 08222 break; 08223 case STRING_RESULT: 08224 DBUG_ASSERT(item->collation.collation); 08225 08226 enum enum_field_types type; 08227 /* 08228 DATE/TIME fields have STRING_RESULT result type. To preserve 08229 type they needed to be handled separately. 08230 */ 08231 if ((type= item->field_type()) == MYSQL_TYPE_DATETIME || 08232 type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE) 08233 new_field= item->tmp_table_field_from_field_type(table, 1); 08234 /* 08235 Make sure that the blob fits into a Field_varstring which has 08236 2-byte lenght. 08237 */ 08238 else if (item->max_length/item->collation.collation->mbmaxlen > 255 && 08239 item->max_length/item->collation.collation->mbmaxlen < UINT_MAX16 08240 && convert_blob_length) 08241 new_field= new Field_varstring(convert_blob_length, maybe_null, 08242 item->name, table->s, 08243 item->collation.collation); 08244 else 08245 new_field= item->make_string_field(table); 08246 break; 08247 case DECIMAL_RESULT: 08248 new_field= new Field_new_decimal(item->max_length, maybe_null, item->name, 08249 item->decimals, item->unsigned_flag); 08250 break; 08251 case ROW_RESULT: 08252 default: 08253 // This case should never be choosen 08254 DBUG_ASSERT(0); 08255 new_field= 0; 08256 break; 08257 } 08258 if (new_field) 08259 new_field->init(table); 08260 08261 if (copy_func && item->is_result_field()) 08262 *((*copy_func)++) = item; // Save for copy_funcs 08263 if (modify_item) 08264 item->set_result_field(new_field); 08265 return new_field; 08266 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* create_tmp_table | ( | THD * | thd, | |
| TMP_TABLE_PARAM * | param, | |||
| List< Item > & | fields, | |||
| ORDER * | group, | |||
| bool | distinct, | |||
| bool | save_sum_fields, | |||
| ulonglong | select_options, | |||
| ha_rows | rows_limit, | |||
| char * | table_alias | |||
| ) |
Definition at line 8496 of file sql_select.cc.
References ALIGN_SIZE, alloc_root(), args, AVG_STRING_LENGTH_TO_PACK_ROWS, bfill, bitmap_buffer_size, bitmap_lock_clear_bit(), bitmap_lock_set_next(), BLOB_FLAG, st_order::buff, bzero, Item::const_item(), CONVERT_IF_BIGGER_TO_BLOB, mySTL::copy(), create_myisam_tmp_table(), create_tmp_field(), create_tmp_field_for_schema(), current_pid, DBUG_ASSERT, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, st_table_share::default_values, err, st_order::field, FIELD_BLOB, Field::field_index, Field::field_length, FIELD_NORMAL, FIELD_SKIP_ENDSPACE, FIELD_TYPE_BIT, FIELDFLAG_BINARY, Field::flags, fn_format(), FN_REFLEN, free_root(), free_tmp_table(), get_new_handler(), GROUP_FLAG, HA_END_SPACE_ARE_EQUAL, HA_KEY_ALG_UNDEF, HA_KEYTYPE_BINARY, HA_KEYTYPE_TEXT, HA_KEYTYPE_VARTEXT1, HA_KEYTYPE_VARTEXT2, HA_NOSAME, HA_NULL_ARE_EQUAL, HA_OPEN_KEYFILE, HA_OPEN_RNDFILE, heap_hton, init_sql_alloc(), init_tmp_table_share(), int(), Field::is_real_null(), st_order::item, keyinfo, LOCK_status, Item::marker, MAX_BLOB_WIDTH, MAX_KEY, memcpy, mi_portable_sizeof_char_ptr, MI_UNIQUE_HASH_LENGTH, min, MIN_STRING_LENGTH_TO_PACK_ROWS, Field::move_field(), Field::move_field_offset(), multi_alloc_root(), MY_BIT_NONE, my_charset_bin, MY_REPLACE_EXT, MY_UNPACK_FILENAME, MYF, myisam_hton, MYSQL_TYPE_STRING, MYSQL_TYPE_VARCHAR, new(), Field::new_key_field(), Item::next, st_order::next, Field::NONE, NOT_NULL_FLAG, NULL, NullS, open_tmp_table(), OPTION_BIG_TABLES, Field::pack_length(), path, pos(), Field::ptr, RATIO_TO_PACK_ROWS, Field::real_type(), recinfo, reclength, st_table::record, Field::reset(), st_table::s, SELECT_SMALL_RESULT, set_if_bigger, set_if_smaller, Field::set_notnull(), Field::set_null(), setup_tmp_table_column_bitmaps(), statistic_increment, store_record, STRING_TOTAL_LENGTH_TO_PACK_ROWS, strlen(), strmov(), Item::SUM_FUNC_ITEM, Field::table, TABLE_ALLOC_BLOCK_SIZE, Field::table_name, temp_pool, test, test_flags, TEST_KEEP_TMP_TABLES, TL_WRITE, tmp_file_prefix, TMP_TABLE_ALL_COLUMNS, TMP_TABLE_FORCE_MYISAM, Item::type(), Field::type(), use_temp_pool, and Item::with_sum_func.
Referenced by JOIN::exec(), Item_func_group_concat::setup(), and Item_sum_count_distinct::setup().
08500 { 08501 MEM_ROOT *mem_root_save, own_root; 08502 TABLE *table; 08503 TABLE_SHARE *share; 08504 uint i,field_count,null_count,null_pack_length; 08505 uint copy_func_count= param->func_count; 08506 uint hidden_null_count, hidden_null_pack_length, hidden_field_count; 08507 uint blob_count,group_null_items, string_count; 08508 uint temp_pool_slot=MY_BIT_NONE; 08509 ulong reclength, string_total_length, fieldnr= 0; 08510 bool using_unique_constraint= 0; 08511 bool use_packed_rows= 0; 08512 bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS); 08513 char *tmpname,path[FN_REFLEN]; 08514 byte *pos, *group_buff, *bitmaps; 08515 uchar *null_flags; 08516 Field **reg_field, **from_field, **default_field; 08517 uint *blob_field; 08518 Copy_field *copy=0; 08519 KEY *keyinfo; 08520 KEY_PART_INFO *key_part_info; 08521 Item **copy_func; 08522 MI_COLUMNDEF *recinfo; 08523 uint total_uneven_bit_length= 0; 08524 bool force_copy_fields= param->force_copy_fields; 08525 DBUG_ENTER("create_tmp_table"); 08526 DBUG_PRINT("enter", 08527 ("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d", 08528 (int) distinct, (int) save_sum_fields, 08529 (ulong) rows_limit,test(group))); 08530 08531 statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status); 08532 08533 if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES)) 08534 temp_pool_slot = bitmap_lock_set_next(&temp_pool); 08535 08536 if (temp_pool_slot != MY_BIT_NONE) // we got a slot 08537 sprintf(path, "%s_%lx_%i", tmp_file_prefix, 08538 current_pid, temp_pool_slot); 08539 else 08540 { 08541 /* if we run out of slots or we are not using tempool */ 08542 sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid, 08543 thd->thread_id, thd->tmp_table++); 08544 } 08545 08546 /* 08547 No need to change table name to lower case as we are only creating 08548 MyISAM or HEAP tables here 08549 */ 08550 fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME); 08551 08552 if (group) 08553 { 08554 if (!param->quick_group) 08555 group=0; // Can't use group key 08556 else for (ORDER *tmp=group ; tmp ; tmp=tmp->next) 08557 { 08558 (*tmp->item)->marker=4; // Store null in key 08559 if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB) 08560 using_unique_constraint=1; 08561 } 08562 if (param->group_length >= MAX_BLOB_WIDTH) 08563 using_unique_constraint=1; 08564 if (group) 08565 distinct=0; // Can't use distinct 08566 } 08567 08568 field_count=param->field_count+param->func_count+param->sum_func_count; 08569 hidden_field_count=param->hidden_field_count; 08570 08571 /* 08572 When loose index scan is employed as access method, it already 08573 computes all groups and the result of all aggregate functions. We 08574 make space for the items of the aggregate function in the list of 08575 functions TMP_TABLE_PARAM::items_to_copy, so that the values of 08576 these items are stored in the temporary table. 08577 */ 08578 if (param->precomputed_group_by) 08579 copy_func_count+= param->sum_func_count; 08580 08581 init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0); 08582 08583 if (!multi_alloc_root(&own_root, 08584 &table, sizeof(*table), 08585 &share, sizeof(*share), 08586 ®_field, sizeof(Field*) * (field_count+1), 08587 &default_field, sizeof(Field*) * (field_count), 08588 &blob_field, sizeof(uint)*(field_count+1), 08589 &from_field, sizeof(Field*)*field_count, 08590 ©_func, sizeof(*copy_func)*(copy_func_count+1), 08591 ¶m->keyinfo, sizeof(*param->keyinfo), 08592 &key_part_info, 08593 sizeof(*key_part_info)*(param->group_parts+1), 08594 ¶m->start_recinfo, 08595 sizeof(*param->recinfo)*(field_count*2+4), 08596 &tmpname, (uint) strlen(path)+1, 08597 &group_buff, (group && ! using_unique_constraint ? 08598 param->group_length : 0), 08599 &bitmaps, bitmap_buffer_size(field_count)*2, 08600 NullS)) 08601 { 08602 if (temp_pool_slot != MY_BIT_NONE) 08603 bitmap_lock_clear_bit(&temp_pool, temp_pool_slot); 08604 DBUG_RETURN(NULL); /* purecov: inspected */ 08605 } 08606 /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */ 08607 if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count])) 08608 { 08609 if (temp_pool_slot != MY_BIT_NONE) 08610 bitmap_lock_clear_bit(&temp_pool, temp_pool_slot); 08611 free_root(&own_root, MYF(0)); /* purecov: inspected */ 08612 DBUG_RETURN(NULL); /* purecov: inspected */ 08613 } 08614 param->items_to_copy= copy_func; 08615 strmov(tmpname,path); 08616 /* make table according to fields */ 08617 08618 bzero((char*) table,sizeof(*table)); 08619 bzero((char*) reg_field,sizeof(Field*)*(field_count+1)); 08620 bzero((char*) default_field, sizeof(Field*) * (field_count)); 08621 bzero((char*) from_field,sizeof(Field*)*field_count); 08622 08623 table->mem_root= own_root; 08624 mem_root_save= thd->mem_root; 08625 thd->mem_root= &table->mem_root; 08626 08627 table->field=reg_field; 08628 table->alias= table_alias; 08629 table->reginfo.lock_type=TL_WRITE; /* Will be updated */ 08630 table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE; 08631 table->map=1; 08632 table->temp_pool_slot = temp_pool_slot; 08633 table->copy_blobs= 1; 08634 table->in_use= thd; 08635 table->quick_keys.init(); 08636 table->used_keys.init(); 08637 table->keys_in_use_for_query.init(); 08638 08639 table->s= share; 08640 init_tmp_table_share(share, "", 0, tmpname, tmpname); 08641 share->blob_field= blob_field; 08642 share->blob_ptr_size= mi_portable_sizeof_char_ptr; 08643 share->db_low_byte_first=1; // True for HEAP and MyISAM 08644 share->table_charset= param->table_charset; 08645 share->primary_key= MAX_KEY; // Indicate no primary key 08646 share->keys_for_keyread.init(); 08647 share->keys_in_use.init(); 08648 08649 /* Calculate which type of fields we will store in the temporary table */ 08650 08651 reclength= string_total_length= 0; 08652 blob_count= string_count= null_count= hidden_null_count= group_null_items= 0; 08653 param->using_indirect_summary_function=0; 08654 08655 List_iterator_fast<Item> li(fields); 08656 Item *item; 08657 Field **tmp_from_field=from_field; 08658 while ((item=li++)) 08659 { 08660 Item::Type type=item->type(); 08661 if (not_all_columns) 08662 { 08663 if (item->with_sum_func && type != Item::SUM_FUNC_ITEM) 08664 { 08665 /* 08666 Mark that the we have ignored an item that refers to a summary 08667 function. We need to know this if someone is going to use 08668 DISTINCT on the result. 08669 */ 08670 param->using_indirect_summary_function=1; 08671 continue; 08672 } 08673 if (item->const_item() && (int) hidden_field_count <= 0) 08674 continue; // We don't have to store this 08675 } 08676 if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields) 08677 { /* Can't calc group yet */ 08678 ((Item_sum*) item)->result_field=0; 08679 for (i=0 ; i < ((Item_sum*) item)->arg_count ; i++) 08680 { 08681 Item **argp= ((Item_sum*) item)->args + i; 08682 Item *arg= *argp; 08683 if (!arg->const_item()) 08684 { 08685 Field *new_field= 08686 create_tmp_field(thd, table, arg, arg->type(), ©_func, 08687 tmp_from_field, &default_field[fieldnr], 08688 group != 0,not_all_columns, 08689 distinct, 0, 08690 param->convert_blob_length); 08691 if (!new_field) 08692 goto err; // Should be OOM 08693 tmp_from_field++; 08694 reclength+=new_field->pack_length(); 08695 if (new_field->flags & BLOB_FLAG) 08696 { 08697 *blob_field++= fieldnr; 08698 blob_count++; 08699 } 08700 if (new_field->type() == FIELD_TYPE_BIT) 08701 total_uneven_bit_length+= new_field->field_length & 7; 08702 *(reg_field++)= new_field; 08703 if (new_field->real_type() == MYSQL_TYPE_STRING || 08704 new_field->real_type() == MYSQL_TYPE_VARCHAR) 08705 { 08706 string_count++; 08707 string_total_length+= new_field->pack_length(); 08708 } 08709 thd->mem_root= mem_root_save; 08710 thd->change_item_tree(argp, new Item_field(new_field)); 08711 thd->mem_root= &table->mem_root; 08712 if (!(new_field->flags & NOT_NULL_FLAG)) 08713 { 08714 null_count++; 08715 /* 08716 new_field->maybe_null() is still false, it will be 08717 changed below. But we have to setup Item_field correctly 08718 */ 08719 (*argp)->maybe_null=1; 08720 } 08721 new_field->field_index= fieldnr++; 08722 } 08723 } 08724 } 08725 else 08726 { 08727 /* 08728 The last parameter to create_tmp_field() is a bit tricky: 08729 08730 We need to set it to 0 in union, to get fill_record() to modify the 08731 temporary table. 08732 We need to set it to 1 on multi-table-update and in select to 08733 write rows to the temporary table. 08734 We here distinguish between UNION and multi-table-updates by the fact 08735 that in the later case group is set to the row pointer. 08736 08737 The test for item->marker == 4 is ensure we don't create a group-by 08738 key over a bit field as heap tables can't handle that. 08739 */ 08740 Field *new_field= (param->schema_table) ? 08741 create_tmp_field_for_schema(thd, item, table) : 08742 create_tmp_field(thd, table, item, type, ©_func, 08743 tmp_from_field, &default_field[fieldnr], 08744 group != 0, 08745 !force_copy_fields && 08746 (not_all_columns || group !=0), 08747 item->marker == 4, force_copy_fields, 08748 param->convert_blob_length); 08749 08750 if (!new_field) 08751 { 08752 if (thd->is_fatal_error) 08753 goto err; // Got OOM 08754 continue; // Some kindf of const item 08755 } 08756 if (type == Item::SUM_FUNC_ITEM) 08757 ((Item_sum *) item)->result_field= new_field; 08758 tmp_from_field++; 08759 reclength+=new_field->pack_length(); 08760 if (!(new_field->flags & NOT_NULL_FLAG)) 08761 null_count++; 08762 if (new_field->type() == FIELD_TYPE_BIT) 08763 total_uneven_bit_length+= new_field->field_length & 7; 08764 if (new_field->flags & BLOB_FLAG) 08765 { 08766 *blob_field++= fieldnr; 08767 blob_count++; 08768 } 08769 if (item->marker == 4 && item->maybe_null) 08770 { 08771 group_null_items++; 08772 new_field->flags|= GROUP_FLAG; 08773 } 08774 new_field->field_index= fieldnr++; 08775 *(reg_field++)= new_field; 08776 } 08777 if (!--hidden_field_count) 08778 { 08779 /* 08780 This was the last hidden field; Remember how many hidden fields could 08781 have null 08782 */ 08783 hidden_null_count=null_count; 08784 /* 08785 We need to update hidden_field_count as we may have stored group 08786 functions with constant arguments 08787 */ 08788 param->hidden_field_count= fieldnr; 08789 null_count= 0; 08790 } 08791 } 08792 DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field)); 08793 DBUG_ASSERT(field_count >= (uint) (reg_field - table->field)); 08794 field_count= fieldnr; 08795 *reg_field= 0; 08796 *blob_field= 0; // End marker 08797 share->fields= field_count; 08798 08799 /* If result table is small; use a heap */ 08800 if (blob_count || using_unique_constraint || 08801 (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) == 08802 OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM)) 08803 { 08804 table->file= get_new_handler(share, &table->mem_root, 08805 share->db_type= &myisam_hton); 08806 if (group && 08807 (param->group_parts > table->file->max_key_parts() || 08808 param->group_length > table->file->max_key_length())) 08809 using_unique_constraint=1; 08810 } 08811 else 08812 { 08813 table->file= get_new_handler(share, &table->mem_root, 08814 share->db_type= &heap_hton); 08815 } 08816 if (!table->file) 08817 goto err; 08818 08819 08820 if (!using_unique_constraint) 08821 reclength+= group_null_items; // null flag is stored separately 08822 08823 share->blob_fields= blob_count; 08824 if (blob_count == 0) 08825 { 08826 /* We need to ensure that first byte is not 0 for the delete link */ 08827 if (param->hidden_field_count) 08828 hidden_null_count++; 08829 else 08830 null_count++; 08831 } 08832 hidden_null_pack_length=(hidden_null_count+7)/8; 08833 null_pack_length= (hidden_null_pack_length + 08834 (null_count + total_uneven_bit_length + 7) / 8); 08835 reclength+=null_pack_length; 08836 if (!reclength) 08837 reclength=1; // Dummy select 08838 /* Use packed rows if there is blobs or a lot of space to gain */ 08839 if (blob_count || 08840 string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS && 08841 (reclength / string_total_length <= RATIO_TO_PACK_ROWS || 08842 string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)) 08843 use_packed_rows= 1; 08844 08845 share->reclength= reclength; 08846 { 08847 uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1); 08848 share->rec_buff_length= alloc_length; 08849 if (!(table->record[0]= (byte*) 08850 alloc_root(&table->mem_root, alloc_length*3))) 08851 goto err; 08852 table->record[1]= table->record[0]+alloc_length; 08853 share->default_values= table->record[1]+alloc_length; 08854 } 08855 copy_func[0]=0; // End marker 08856 08857 setup_tmp_table_column_bitmaps(table, bitmaps); 08858 08859 recinfo=param->start_recinfo; 08860 null_flags=(uchar*) table->record[0]; 08861 pos=table->record[0]+ null_pack_length; 08862 if (null_pack_length) 08863 { 08864 bzero((byte*) recinfo,sizeof(*recinfo)); 08865 recinfo->type=FIELD_NORMAL; 08866 recinfo->length=null_pack_length; 08867 recinfo++; 08868 bfill(null_flags,null_pack_length,255); // Set null fields 08869 08870 table->null_flags= (uchar*) table->record[0]; 08871 share->null_fields= null_count+ hidden_null_count; 08872 share->null_bytes= null_pack_length; 08873 } 08874 null_count= (blob_count == 0) ? 1 : 0; 08875 hidden_field_count=param->hidden_field_count; 08876 for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++) 08877 { 08878 Field *field= *reg_field; 08879 uint length; 08880 bzero((byte*) recinfo,sizeof(*recinfo)); 08881 08882 if (!(field->flags & NOT_NULL_FLAG)) 08883 { 08884 if (field->flags & GROUP_FLAG && !using_unique_constraint) 08885 { 08886 /* 08887 We have to reserve one byte here for NULL bits, 08888 as this is updated by 'end_update()' 08889 */ 08890 *pos++=0; // Null is stored here 08891 recinfo->length=1; 08892 recinfo->type=FIELD_NORMAL; 08893 recinfo++; 08894 bzero((byte*) recinfo,sizeof(*recinfo)); 08895 } 08896 else 08897 { 08898 recinfo->null_bit= 1 << (null_count & 7); 08899 recinfo->null_pos= null_count/8; 08900 } 08901 field->move_field((char*) pos,null_flags+null_count/8, 08902 1 << (null_count & 7)); 08903 null_count++; 08904 } 08905 else 08906 field->move_field((char*) pos,(uchar*) 0,0); 08907 if (field->type() == FIELD_TYPE_BIT) 08908 { 08909 /* We have to reserve place for extra bits among null bits */ 08910 ((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8, 08911 null_count & 7); 08912 null_count+= (field->field_length & 7); 08913 } 08914 field->reset(); 08915 08916 /* 08917 Test if there is a default field value. The test for ->ptr is to skip 08918 'offset' fields generated by initalize_tables 08919 */ 08920 if (default_field[i] && default_field[i]->ptr) 08921 { 08922 /* 08923 default_field[i] is set only in the cases when 'field' can 08924 inherit the default value that is defined for the field referred 08925 by the Item_field object from which 'field' has been created. 08926 */ 08927 my_ptrdiff_t diff; 08928 Field *orig_field= default_field[i]; 08929 /* Get the value from default_values */ 08930 diff= (my_ptrdiff_t) (orig_field->table->s->default_values- 08931 orig_field->table->record[0]); 08932 orig_field->move_field_offset(diff); // Points now at default_values 08933 if (orig_field->is_real_null()) 08934 field->set_null(); 08935 else 08936 { 08937 field->set_notnull(); 08938 memcpy(field->ptr, orig_field->ptr, field->pack_length()); 08939 } 08940 orig_field->move_field_offset(-diff); // Back to record[0] 08941 } 08942 08943 if (from_field[i]) 08944 { /* Not a table Item */ 08945 copy->set(field,from_field[i],save_sum_fields); 08946 copy++; 08947 } 08948 length=field->pack_length(); 08949 pos+= length; 08950 08951 /* Make entry for create table */ 08952 recinfo->length=length; 08953 if (field->flags & BLOB_FLAG) 08954 recinfo->type= (int) FIELD_BLOB; 08955 else if (use_packed_rows && 08956 field->real_type() == MYSQL_TYPE_STRING && 08957 length >= MIN_STRING_LENGTH_TO_PACK_ROWS) 08958 recinfo->type=FIELD_SKIP_ENDSPACE; 08959 else 08960 recinfo->type=FIELD_NORMAL; 08961 if (!--hidden_field_count) 08962 null_count=(null_count+7) & ~7; // move to next byte 08963 08964 // fix table name in field entry 08965 field->table_name= &table->alias; 08966 } 08967 08968 param->copy_field_end=copy; 08969 param->recinfo=recinfo; 08970 store_record(table,s->default_values); // Make empty default record 08971 08972 if (thd->variables.tmp_table_size == ~(ulong) 0) // No limit 08973 share->max_rows= ~(ha_rows) 0; 08974 else 08975 share->max_rows= (((share->db_type == &heap_hton) ? 08976 min(thd->variables.tmp_table_size, 08977 thd->variables.max_heap_table_size) : 08978 thd->variables.tmp_table_size)/ share->reclength); 08979 set_if_bigger(share->max_rows,1); // For dummy start options 08980 keyinfo= param->keyinfo; 08981 08982 if (group) 08983 { 08984 DBUG_PRINT("info",("Creating group key in temporary table")); 08985 table->group=group; /* Table is grouped by key */ 08986 param->group_buff=group_buff; 08987 share->keys=1; 08988 share->uniques= test(using_unique_constraint); 08989 table->key_info=keyinfo; 08990 keyinfo->key_part=key_part_info; 08991 keyinfo->flags=HA_NOSAME; 08992 keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts; 08993 keyinfo->key_length=0; 08994 keyinfo->rec_per_key=0; 08995 keyinfo->algorithm= HA_KEY_ALG_UNDEF; 08996 keyinfo->name= (char*) "group_key"; 08997 for (; group ; group=group->next,key_part_info++) 08998 { 08999 Field *field=(*group->item)->get_tmp_table_field(); 09000 bool maybe_null=(*group->item)->maybe_null; 09001 key_part_info->null_bit=0; 09002 key_part_info->field= field; 09003 key_part_info->offset= field->offset(); 09004 key_part_info->length= (uint16) field->key_length(); 09005 key_part_info->type= (uint8) field->key_type(); 09006 key_part_info->key_type = 09007 ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT || 09008 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 || 09009 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ? 09010 0 : FIELDFLAG_BINARY; 09011 if (!using_unique_constraint) 09012 { 09013 group->buff=(char*) group_buff; 09014 if (!(group->field= field->new_key_field(thd->mem_root,table, 09015 (char*) group_buff + 09016 test(maybe_null), 09017 field->null_ptr, 09018 field->null_bit))) 09019 goto err; /* purecov: inspected */ 09020 if (maybe_null) 09021 { 09022 /* 09023 To be able to group on NULL, we reserved place in group_buff 09024 for the NULL flag just before the column. (see above). 09025 The field data is after this flag. 09026 The NULL flag is updated in 'end_update()' and 'end_write()' 09027 */ 09028 keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL 09029 key_part_info->null_bit=field->null_bit; 09030 key_part_info->null_offset= (uint) (field->null_ptr - 09031 (uchar*) table->record[0]); 09032 group->buff++; // Pointer to field data 09033 group_buff++; // Skipp null flag 09034 } 09035 /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */ 09036 key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL; 09037 group_buff+= group->field->pack_length(); 09038 } 09039 keyinfo->key_length+= key_part_info->length; 09040 } 09041 } 09042 else 09043 { 09044 set_if_smaller(table->s->max_rows, rows_limit); 09045 param->end_write_records= rows_limit; 09046 } 09047 09048 if (distinct && field_count != param->hidden_field_count) 09049 { 09050 /* 09051 Create an unique key or an unique constraint over all columns 09052 that should be in the result. In the temporary table, there are 09053 'param->hidden_field_count' extra columns, whose null bits are stored 09054 in the first 'hidden_null_pack_length' bytes of the row. 09055 */ 09056 DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count)); 09057 09058 null_pack_length-=hidden_null_pack_length; 09059 keyinfo->key_parts= ((field_count-param->hidden_field_count)+ 09060 test(null_pack_length)); 09061 set_if_smaller(share->max_rows, rows_limit); 09062 param->end_write_records= rows_limit; 09063 table->distinct= 1; 09064 share->keys= 1; 09065 if (blob_count) 09066 { 09067 using_unique_constraint=1; 09068 share->uniques= 1; 09069 } 09070 if (!(key_part_info= (KEY_PART_INFO*) 09071 alloc_root(&table->mem_root, 09072 keyinfo->key_parts * sizeof(KEY_PART_INFO)))) 09073 goto err; 09074 bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO)); 09075 table->key_info=keyinfo; 09076 keyinfo->key_part=key_part_info; 09077 keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL; 09078 keyinfo->key_length=(uint16) reclength; 09079 keyinfo->name= (char*) "distinct_key"; 09080 keyinfo->algorithm= HA_KEY_ALG_UNDEF; 09081 keyinfo->rec_per_key=0; 09082 if (null_pack_length) 09083 { 09084 key_part_info->null_bit=0; 09085 key_part_info->offset=hidden_null_pack_length; 09086 key_part_info->length=null_pack_length; 09087 key_part_info->field= new Field_string((char*) table->record[0], 09088 (uint32) key_part_info->length, 09089 (uchar*) 0, 09090 (uint) 0, 09091 Field::NONE, 09092 NullS, &my_charset_bin); 09093 if (!key_part_info->field) 09094 goto err; 09095 key_part_info->field->init(table); 09096 key_part_info->key_type=FIELDFLAG_BINARY; 09097 key_part_info->type= HA_KEYTYPE_BINARY; 09098 key_part_info++; 09099 } 09100 /* Create a distinct key over the columns we are going to return */ 09101 for (i=param->hidden_field_count, reg_field=table->field + i ; 09102 i < field_count; 09103 i++, reg_field++, key_part_info++) 09104 { 09105 key_part_info->null_bit=0; 09106 key_part_info->field= *reg_field; 09107 key_part_info->offset= (*reg_field)->offset(); 09108 key_part_info->length= (uint16) (*reg_field)->pack_length(); 09109 key_part_info->type= (uint8) (*reg_field)->key_type(); 09110 key_part_info->key_type = 09111 ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT || 09112 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 || 09113 (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ? 09114 0 : FIELDFLAG_BINARY; 09115 } 09116 } 09117 if (thd->is_fatal_error) // If end of memory 09118 goto err; /* purecov: inspected */ 09119 share->db_record_offset= 1; 09120 if (share->db_type == &myisam_hton) 09121 { 09122 if (create_myisam_tmp_table(table,param,select_options)) 09123 goto err; 09124 } 09125 if (open_tmp_table(table)) 09126 goto err; 09127 09128 thd->mem_root= mem_root_save; 09129 09130 DBUG_RETURN(table); 09131 09132 err: 09133 thd->mem_root= mem_root_save; 09134 free_tmp_table(thd,table); /* purecov: inspected */ 09135 if (temp_pool_slot != MY_BIT_NONE) 09136 bitmap_lock_clear_bit(&temp_pool, temp_pool_slot); 09137 DBUG_RETURN(NULL); /* purecov: inspected */ 09138 }
Here is the call graph for this function:

Here is the caller graph for this function:

| TABLE* create_virtual_tmp_table | ( | THD * | thd, | |
| List< create_field > & | field_list | |||
| ) |
Definition at line 9165 of file sql_select.cc.
References ALIGN_SIZE, bitmap_buffer_size, BLOB_FLAG, bzero, create_field::charset, base_list::elements, error, f_maybe_null, create_field::field_name, Field::flags, create_field::geom_type, create_field::interval, create_field::length, make_field(), mi_portable_sizeof_char_ptr, Field::move_field(), multi_alloc_root(), NOT_NULL_FLAG, NULL, NullS, create_field::pack_flag, Field::pack_length(), Field::reset(), setup_tmp_table_column_bitmaps(), create_field::sql_type, and create_field::unireg_check.
Referenced by sp_rcontext::init_var_table(), and Item_sum_distinct::setup().
09166 { 09167 uint field_count= field_list.elements; 09168 uint blob_count= 0; 09169 Field **field; 09170 create_field *cdef; /* column definition */ 09171 uint record_length= 0; 09172 uint null_count= 0; /* number of columns which may be null */ 09173 uint null_pack_length; /* NULL representation array length */ 09174 uint *blob_field; 09175 byte *bitmaps; 09176 TABLE *table; 09177 TABLE_SHARE *share; 09178 09179 if (!multi_alloc_root(thd->mem_root, 09180 &table, sizeof(*table), 09181 &share, sizeof(*share), 09182 &field, (field_count + 1) * sizeof(Field*), 09183 &blob_field, (field_count+1) *sizeof(uint), 09184 &bitmaps, bitmap_buffer_size(field_count)*2, 09185 NullS)) 09186 return 0; 09187 09188 bzero(table, sizeof(*table)); 09189 bzero(share, sizeof(*share)); 09190 table->field= field; 09191 table->s= share; 09192 share->blob_field= blob_field; 09193 share->fields= field_count; 09194 share->blob_ptr_size= mi_portable_sizeof_char_ptr; 09195 setup_tmp_table_column_bitmaps(table, bitmaps); 09196 09197 /* Create all fields and calculate the total length of record */ 09198 List_iterator_fast<create_field> it(field_list); 09199 while ((cdef= it++)) 09200 { 09201 *field= make_field(share, 0, cdef->length, 09202 (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0), 09203 f_maybe_null(cdef->pack_flag) ? 1 : 0, 09204 cdef->pack_flag, cdef->sql_type, cdef->charset, 09205 cdef->geom_type, cdef->unireg_check, 09206 cdef->interval, cdef->field_name); 09207 if (!*field) 09208 goto error; 09209 (*field)->init(table); 09210 record_length+= (*field)->pack_length(); 09211 if (! ((*field)->flags & NOT_NULL_FLAG)) 09212 null_count++; 09213 09214 if ((*field)->flags & BLOB_FLAG) 09215 share->blob_field[blob_count++]= (uint) (field - table->field); 09216 09217 field++; 09218 } 09219 *field= NULL; /* mark the end of the list */ 09220 share->blob_field[blob_count]= 0; /* mark the end of the list */ 09221 share->blob_fields= blob_count; 09222 09223 null_pack_length= (null_count + 7)/8; 09224 share->reclength= record_length + null_pack_length; 09225 share->rec_buff_length= ALIGN_SIZE(share->reclength + 1); 09226 table->record[0]= (byte*) thd->alloc(share->rec_buff_length); 09227 if (!table->record[0]) 09228 goto error; 09229 09230 if (null_pack_length) 09231 { 09232 table->null_flags= (uchar*) table->record[0]; 09233 share->null_fields= null_count; 09234 share->null_bytes= null_pack_length; 09235 } 09236 09237 table->in_use= thd; /* field->reset() may access table->in_use */ 09238 { 09239 /* Set up field pointers */ 09240 byte *null_pos= table->record[0]; 09241 byte *field_pos= null_pos + share->null_bytes; 09242 uint null_bit= 1; 09243 09244 for (field= table->field; *field; ++field) 09245 { 09246 Field *cur_field= *field; 09247 if ((cur_field->flags & NOT_NULL_FLAG)) 09248 cur_field->move_field((char*) field_pos); 09249 else 09250 { 09251 cur_field->move_field((char*) field_pos, (uchar*) null_pos, null_bit); 09252 null_bit<<= 1; 09253 if (null_bit == (1 << 8)) 09254 { 09255 ++null_pos; 09256 null_bit= 1; 09257 } 09258 } 09259 cur_field->reset(); 09260 09261 field_pos+= cur_field->pack_length(); 09262 } 09263 } 09264 return table; 09265 error: 09266 for (field= table->field; *field; ++field) 09267 delete *field; /* just invokes field destructor */ 09268 return 0; 09269 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 4055 of file sql_select.cc.
References JOIN::const_tables, and JOIN::tables.
Referenced by choose_plan().
04056 { 04057 uint table_count= join->tables - join->const_tables; 04058 uint search_depth; 04059 /* TODO: this value should be determined dynamically, based on statistics: */ 04060 uint max_tables_for_exhaustive_opt= 7; 04061 04062 if (table_count <= max_tables_for_exhaustive_opt) 04063 search_depth= table_count+1; // use exhaustive for small number of tables 04064 else 04065 /* 04066 TODO: this value could be determined by some mapping of the form: 04067 depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE] 04068 */ 04069 search_depth= max_tables_for_exhaustive_opt; // use greedy search 04070 04071 return search_depth; 04072 }
Here is the caller graph for this function:

| static int do_select | ( | JOIN * | join, | |
| List< Item > * | fields, | |||
| TABLE * | tmp_table, | |||
| Procedure * | proc | |||
| ) | [static] |
Definition at line 9621 of file sql_select.cc.
References JOIN::conds, JOIN::const_tables, DBUG_ENTER, DBUG_PRINT, DBUG_RETURN, empty_record, error, handler::extra(), JOIN::fields, st_table::file, HA_EXTRA_NO_CACHE, HA_EXTRA_WRITE_CACHE, handler::ha_index_or_rnd_end(), JOIN::join_free(), JOIN::join_tab, MYF, NESTED_LOOP_NO_MORE_ROWS, NESTED_LOOP_OK, NESTED_LOOP_QUERY_LIMIT, st_join_table::next_select, handler::print_error(), JOIN::procedure, JOIN::procedure_fields_list, JOIN::result, JOIN::send_records, JOIN::send_row_on_empty_set(), setup_end_select_func(), sub_select(), JOIN::tables, JOIN::thd, JOIN::tmp_table, JOIN::tmp_table_param, Item::val_int(), and VOID.
Referenced by JOIN::exec().
09622 { 09623 int rc= 0; 09624 enum_nested_loop_state error= NESTED_LOOP_OK; 09625 JOIN_TAB *join_tab; 09626 DBUG_ENTER("do_select"); 09627 09628 join->procedure=procedure; 09629 join->tmp_table= table; /* Save for easy recursion */ 09630 join->fields= fields; 09631 09632 if (table) 09633 { 09634 VOID(table->file->extra(HA_EXTRA_WRITE_CACHE)); 09635 empty_record(table); 09636 if (table->group && join->tmp_table_param.sum_func_count && 09637 table->s->keys && !table->file->inited) 09638 table->file->ha_index_init(0, 0); 09639 } 09640 /* Set up select_end */ 09641 join->join_tab[join->tables-1].next_select= setup_end_select_func(join); 09642 09643 join_tab=join->join_tab+join->const_tables; 09644 join->send_records=0; 09645 if (join->tables == join->const_tables) 09646 { 09647 /* 09648 HAVING will be checked after processing aggregate functions, 09649 But WHERE should checkd here (we alredy have read tables) 09650 */ 09651 if (!join->conds || join->conds->val_int()) 09652 { 09653 Next_select_func end_select= join->join_tab[join->tables-1].next_select; 09654 error= (*end_select)(join,join_tab,0); 09655 if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT) 09656 error= (*end_select)(join,join_tab,1); 09657 } 09658 else if (join->send_row_on_empty_set()) 09659 { 09660 List<Item> *columns_list= (procedure ? &join->procedure_fields_list : 09661 fields); 09662 rc= join->result->send_data(*columns_list); 09663 } 09664 } 09665 else 09666 { 09667 error= sub_select(join,join_tab,0); 09668 if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS) 09669 error= sub_select(join,join_tab,1); 09670 if (error == NESTED_LOOP_QUERY_LIMIT) 09671 error= NESTED_LOOP_OK; /* select_limit used */ 09672 } 09673 if (error == NESTED_LOOP_NO_MORE_ROWS) 09674 error= NESTED_LOOP_OK; 09675 09676 if (error == NESTED_LOOP_OK) 09677 { 09678 /* 09679 Sic: this branch works even if rc != 0, e.g. when 09680 send_data above returns an error. 09681 */ 09682 if (!table) // If sending data to client 09683 { 09684 /* 09685 The following will unlock all cursors if the command wasn't an 09686 update command 09687 */ 09688 join->join_free(); // Unlock all cursors 09689 if (join->result->send_eof()) 09690 rc= 1; // Don't send error 09691 } 09692 DBUG_PRINT("info",("%ld records output",join->send_records)); 09693 } 09694 else 09695 rc= -1; 09696 if (table) 09697 { 09698 int tmp, new_errno= 0; 09699 if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE))) 09700 { 09701 DBUG_PRINT("error",("extra(HA_EXTRA_NO_CACHE) failed")); 09702 new_errno= tmp; 09703 } 09704 if ((tmp=table->file->ha_index_or_rnd_end())) 09705 { 09706 DBUG_PRINT("error",("ha_index_or_rnd_end() failed")); 09707 new_errno= tmp; 09708 } 09709 if (new_errno) 09710 table->file->print_error(new_errno,MYF(0)); 09711 } 09712 #ifndef DBUG_OFF 09713 if (rc) 09714 { 09715 DBUG_PRINT("error",("Error: do_select() failed")); 09716 } 09717 #endif 09718 DBUG_RETURN(join->thd->net.report_error ? -1 : rc); 09719 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static Item* eliminate_item_equal | ( | COND * | cond, | |
| COND_EQUAL * | upper_levels, | |||
| Item_equal * | item_equal | |||
| ) | [static] |
Definition at line 6976 of file sql_select.cc.
References cond, Item::COND_ITEM, DBUG_ASSERT, Item_field::find_item_equal(), Item_equal::get_const(), List< T >::head(), List< T >::push_back(), and Item::val_int().
Referenced by substitute_for_best_equal_field().
06978 { 06979 List<Item> eq_list; 06980 Item_func_eq *eq_item= 0; 06981 if (((Item *) item_equal)->const_item() && !item_equal->val_int()) 06982 return new Item_int((longlong) 0,1); 06983 Item *item_const= item_equal->get_const(); 06984 Item_equal_iterator it(*item_equal); 06985 Item *head; 06986 if (item_const) 06987 head= item_const; 06988 else 06989 { 06990 head= item_equal->get_first(); 06991 it++; 06992 } 06993 Item_field *item_field; 06994 while ((item_field= it++)) 06995 { 06996 Item_equal *upper= item_field->find_item_equal(upper_levels); 06997 Item_field *item= item_field; 06998 if (upper) 06999 { 07000 if (item_const && upper->get_const()) 07001 item= 0; 07002 else 07003 { 07004 Item_equal_iterator li(*item_equal); 07005 while ((item= li++) != item_field) 07006 { 07007 if (item->find_item_equal(upper_levels) == upper) 07008 break; 07009 } 07010 } 07011 } 07012 if (item == item_field) 07013 { 07014 if (eq_item) 07015 eq_list.push_back(eq_item); 07016 eq_item= new Item_func_eq(item_field, head); 07017 if (!eq_item) 07018 return 0; 07019 eq_item->set_cmp_func(); 07020 eq_item->quick_fix_field(); 07021 } 07022 } 07023 07024 if (!cond && !eq_list.head()) 07025 { 07026 if (!eq_item) 07027 return new Item_int((longlong) 1,1); 07028 return eq_item; 07029 } 07030 07031 if (eq_item) 07032 eq_list.push_back(eq_item); 07033 if (!cond) 07034 cond= new Item_cond_and(eq_list); 07035 else 07036 { 07037 DBUG_ASSERT(cond->type() == Item::COND_ITEM); 07038 ((Item_cond *) cond)->add_at_head(&eq_list); 07039 } 07040 07041 cond->quick_fix_field(); 07042 cond->update_used_tables(); 07043 07044 return cond; 07045 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static enum_nested_loop_state end_send | ( | JOIN * | join, | |
| JOIN_TAB *join_tab | __attribute__((unused)), | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 10708 of file sql_select.cc.
References DBUG_ENTER, DBUG_RETURN, JOIN::do_send_rows, Procedure::end_of_records(), error, JOIN::fetch_limit, JOIN::fields, st_table::file, HA_STATS_RECORDS_IS_EXACT, HA_STATUS_VARIABLE, handler::ha_table_flags(), JOIN::having, JOIN::join_tab, st_table_ref::key, my_b_inited, NESTED_LOOP_CURSOR_LIMIT, NESTED_LOOP_ERROR, NESTED_LOOP_OK, NESTED_LOOP_QUERY_LIMIT, OPTION_FOUND_ROWS, JOIN::procedure, JOIN::procedure_fields_list, SQL_SELECT::quick, st_join_table::ref, JOIN::result, st_join_table::select, st_join_table::select_cond, JOIN::select_options, JOIN::send_group_parts, JOIN::send_records, Procedure::send_row(), JOIN::sort_and_group, st_join_table::table, JOIN::tables, JOIN::tmp_table, JOIN::unit, and Item::val_int().
10710 { 10711 DBUG_ENTER("end_send"); 10712 if (!end_of_records) 10713 { 10714 int error; 10715 if (join->having && join->having->val_int() == 0) 10716 DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having 10717 error=0; 10718 if (join->procedure) 10719 error=join->procedure->send_row(join->procedure_fields_list); 10720 else if (join->do_send_rows) 10721 error=join->result->send_data(*join->fields); 10722 if (error) 10723 DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ 10724 if (++join->send_records >= join->unit->select_limit_cnt && 10725 join->do_send_rows) 10726 { 10727 if (join->select_options & OPTION_FOUND_ROWS) 10728 { 10729 JOIN_TAB *jt=join->join_tab; 10730 if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group 10731 && !join->send_group_parts && !join->having && !jt->select_cond && 10732 !(jt->select && jt->select->quick) && 10733 (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) && 10734 (jt->ref.key < 0)) 10735 { 10736 /* Join over all rows in table; Return number of found rows */ 10737 TABLE *table=jt->table; 10738 10739 join->select_options ^= OPTION_FOUND_ROWS; 10740 if (table->sort.record_pointers || 10741 (table->sort.io_cache && my_b_inited(table->sort.io_cache))) 10742 { 10743 /* Using filesort */ 10744 join->send_records= table->sort.found_records; 10745 } 10746 else 10747 { 10748 table->file->info(HA_STATUS_VARIABLE); 10749 join->send_records= table->file->stats.records; 10750 } 10751 } 10752 else 10753 { 10754 join->do_send_rows= 0; 10755 if (join->unit->fake_select_lex) 10756 join->unit->fake_select_lex->select_limit= 0; 10757 DBUG_RETURN(NESTED_LOOP_OK); 10758 } 10759 } 10760 DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely 10761 } 10762 else if (join->send_records >= join->fetch_limit) 10763 { 10764 /* 10765 There is a server side cursor and all rows for 10766 this fetch request are sent. 10767 */ 10768 DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT); 10769 } 10770 } 10771 else 10772 { 10773 if (join->procedure && join->procedure->end_of_records()) 10774 DBUG_RETURN(NESTED_LOOP_ERROR); 10775 } 10776 DBUG_RETURN(NESTED_LOOP_OK); 10777 }
Here is the call graph for this function:

| static enum_nested_loop_state end_send | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| bool | end_of_records | |||
| ) | [static] |
| static enum_nested_loop_state end_send_group | ( | JOIN * | join, | |
| JOIN_TAB *join_tab | __attribute__((unused)), | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 10782 of file sql_select.cc.
References Procedure::add(), JOIN::clear(), copy_fields(), DBUG_ENTER, DBUG_RETURN, JOIN::do_send_rows, Procedure::end_group(), Procedure::end_of_records(), error, JOIN::fetch_limit, JOIN::fields, JOIN::first_record, JOIN::group, JOIN::group_fields, JOIN::having, init_sum_functions(), NESTED_LOOP_CURSOR_LIMIT, NESTED_LOOP_ERROR, NESTED_LOOP_OK, NESTED_LOOP_QUERY_LIMIT, Item::no_rows_in_result(), OPTION_FOUND_ROWS, JOIN::procedure, JOIN::result, JOIN::rollup, JOIN::rollup_send_data(), JOIN::select_options, JOIN::send_group_parts, JOIN::send_records, Procedure::send_row(), st_rollup::state, st_rollup::STATE_NONE, JOIN::sum_funcs, JOIN::sum_funcs_end, test_if_group_changed(), JOIN::tmp_table_param, JOIN::unit, update_sum_func(), Item::val_int(), and VOID.
10784 { 10785 int idx= -1; 10786 enum_nested_loop_state ok_code= NESTED_LOOP_OK; 10787 DBUG_ENTER("end_send_group"); 10788 10789 if (!join->first_record || end_of_records || 10790 (idx=test_if_group_changed(join->group_fields)) >= 0) 10791 { 10792 if (join->first_record || (end_of_records && !join->group)) 10793 { 10794 if (join->procedure) 10795 join->procedure->end_group(); 10796 if (idx < (int) join->send_group_parts) 10797 { 10798 int error=0; 10799 if (join->procedure) 10800 { 10801 if (join->having && join->having->val_int() == 0) 10802 error= -1; // Didn't satisfy having 10803 else 10804 { 10805 if (join->do_send_rows) 10806 error=join->procedure->send_row(*join->fields) ? 1 : 0; 10807 join->send_records++; 10808 } 10809 if (end_of_records && join->procedure->end_of_records()) 10810 error= 1; // Fatal error 10811 } 10812 else 10813 { 10814 if (!join->first_record) 10815 { 10816 List_iterator_fast<Item> it(*join->fields); 10817 Item *item; 10818 /* No matching rows for group function */ 10819 join->clear(); 10820 10821 while ((item= it++)) 10822 item->no_rows_in_result(); 10823 } 10824 if (join->having && join->having->val_int() == 0) 10825 error= -1; // Didn't satisfy having 10826 else 10827 { 10828 if (join->do_send_rows) 10829 error=join->result->send_data(*join->fields) ? 1 : 0; 10830 join->send_records++; 10831 } 10832 if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0) 10833 { 10834 if (join->rollup_send_data((uint) (idx+1))) 10835 error= 1; 10836 } 10837 } 10838 if (error > 0) 10839 DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ 10840 if (end_of_records) 10841 DBUG_RETURN(NESTED_LOOP_OK); 10842 if (join->send_records >= join->unit->select_limit_cnt && 10843 join->do_send_rows) 10844 { 10845 if (!(join->select_options & OPTION_FOUND_ROWS)) 10846 DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely 10847 join->do_send_rows=0; 10848 join->unit->select_limit_cnt = HA_POS_ERROR; 10849 } 10850 else if (join->send_records >= join->fetch_limit) 10851 { 10852 /* 10853 There is a server side cursor and all rows 10854 for this fetch request are sent. 10855 */ 10856 /* 10857 Preventing code duplication. When finished with the group reset 10858 the group functions and copy_fields. We fall through. bug #11904 10859 */ 10860 ok_code= NESTED_LOOP_CURSOR_LIMIT; 10861 } 10862 } 10863 } 10864 else 10865 { 10866 if (end_of_records) 10867 DBUG_RETURN(NESTED_LOOP_OK); 10868 join->first_record=1; 10869 VOID(test_if_group_changed(join->group_fields)); 10870 } 10871 if (idx < (int) join->send_group_parts) 10872 { 10873 /* 10874 This branch is executed also for cursors which have finished their 10875 fetch limit - the reason for ok_code. 10876 */ 10877 copy_fields(&join->tmp_table_param); 10878 if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) 10879 DBUG_RETURN(NESTED_LOOP_ERROR); 10880 if (join->procedure) 10881 join->procedure->add(); 10882 DBUG_RETURN(ok_code); 10883 } 10884 } 10885 if (update_sum_func(join->sum_funcs)) 10886 DBUG_RETURN(NESTED_LOOP_ERROR); 10887 if (join->procedure) 10888 join->procedure->add(); 10889 DBUG_RETURN(NESTED_LOOP_OK); 10890 }
Here is the call graph for this function:

| static enum_nested_loop_state end_send_group | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| bool | end_of_records | |||
| ) | [static] |
| static enum_nested_loop_state end_unique_update | ( | JOIN * | join, | |
| JOIN_TAB *join_tab | __attribute__((unused)), | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 11032 of file sql_select.cc.
References copy_fields(), copy_funcs(), DBUG_ENTER, DBUG_RETURN, handler::dup_ref, error, st_table::file, handler::get_dup_key(), init_tmptable_sum_functions(), MYF, NESTED_LOOP_ERROR, NESTED_LOOP_KILLED, NESTED_LOOP_OK, handler::print_error(), st_table::record, restore_record, handler::rnd_pos(), JOIN::send_records, JOIN::sum_funcs, JOIN::thd, JOIN::tmp_table, JOIN::tmp_table_param, handler::update_row(), update_tmptable_sum_func(), and handler::write_row().
11034 { 11035 TABLE *table=join->tmp_table; 11036 int error; 11037 DBUG_ENTER("end_unique_update"); 11038 11039 if (end_of_records) 11040 DBUG_RETURN(NESTED_LOOP_OK); 11041 if (join->thd->killed) // Aborted by user 11042 { 11043 join->thd->send_kill_message(); 11044 DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ 11045 } 11046 11047 init_tmptable_sum_functions(join->sum_funcs); 11048 copy_fields(&join->tmp_table_param); // Groups are copied twice. 11049 copy_funcs(join->tmp_table_param.items_to_copy); 11050 11051 if (!(error=table->file->write_row(table->record[0]))) 11052 join->send_records++; // New group 11053 else 11054 { 11055 if ((int) table->file->get_dup_key(error) < 0) 11056 { 11057 table->file->print_error(error,MYF(0)); /* purecov: inspected */ 11058 DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ 11059 } 11060 if (table->file->rnd_pos(table->record[1],table->file->dup_ref)) 11061 { 11062 table->file->print_error(error,MYF(0)); /* purecov: inspected */ 11063 DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ 11064 } 11065 restore_record(table,record[1]); 11066 update_tmptable_sum_func(join->sum_funcs,table); 11067 if ((error=table->file->update_row(table->record[1], 11068 table->record[0]))) 11069 { 11070 table->file->print_error(error,MYF(0)); /* purecov: inspected */ 11071 DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ 11072 } 11073 } 11074 DBUG_RETURN(NESTED_LOOP_OK); 11075 }
Here is the call graph for this function:

| static enum_nested_loop_state end_unique_update | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| bool | end_of_records | |||
| ) | [static] |
Referenced by end_update(), and setup_end_select_func().
Here is the caller graph for this function:

| static enum_nested_loop_state end_update | ( | JOIN * | join, | |
| JOIN_TAB *join_tab | __attribute__((unused)), | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 10958 of file sql_select.cc.
References st_order::buff, copy_fields(), copy_funcs(), create_myisam_from_heap(), DBUG_ENTER, DBUG_RETURN, end_unique_update(), error, st_order::field, st_table::file, JOIN::found_records, st_table::group, handler::ha_index_init(), HA_READ_KEY_EXACT, handler::index_read(), init_tmptable_sum_functions(), Field::is_null(), st_order::item, JOIN::join_tab, st_table::key_info, st_key::key_part, Item::maybe_null, memcpy, MYF, NESTED_LOOP_ERROR, NESTED_LOOP_KILLED, NESTED_LOOP_OK, st_order::next, st_join_table::next_select, st_key_part_info::null_bit, st_key_part_info::offset, st_table::record, restore_record, Item::save_org_in_field(), JOIN::send_records, JOIN::sum_funcs, JOIN::tables, JOIN::thd, JOIN::tmp_table, JOIN::tmp_table_param, update_tmptable_sum_func(), and handler::write_row().
10960 { 10961 TABLE *table=join->tmp_table; 10962 ORDER *group; 10963 int error; 10964 DBUG_ENTER("end_update"); 10965 10966 if (end_of_records) 10967 DBUG_RETURN(NESTED_LOOP_OK); 10968 if (join->thd->killed) // Aborted by user 10969 { 10970 join->thd->send_kill_message(); 10971 DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ 10972 } 10973 10974 join->found_records++; 10975 copy_fields(&join->tmp_table_param); // Groups are copied twice. 10976 /* Make a key of group index */ 10977 for (group=table->group ; group ; group=group->next) 10978 { 10979 Item *item= *group->item; 10980 item->save_org_in_field(group->field); 10981 /* Store in the used key if the field was 0 */ 10982 if (item->maybe_null) 10983 group->buff[-1]= (char) group->field->is_null(); 10984 } 10985 if (!table->file->index_read(table->record[1], 10986 join->tmp_table_param.group_buff,0, 10987 HA_READ_KEY_EXACT)) 10988 { /* Update old record */ 10989 restore_record(table,record[1]); 10990 update_tmptable_sum_func(join->sum_funcs,table); 10991 if ((error=table->file->update_row(table->record[1], 10992 table->record[0]))) 10993 { 10994 table->file->print_error(error,MYF(0)); /* purecov: inspected */ 10995 DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */ 10996 } 10997 DBUG_RETURN(NESTED_LOOP_OK); 10998 } 10999 11000 /* 11001 Copy null bits from group key to table 11002 We can't copy all data as the key may have different format 11003 as the row data (for example as with VARCHAR keys) 11004 */ 11005 KEY_PART_INFO *key_part; 11006 for (group=table->group,key_part=table->key_info[0].key_part; 11007 group ; 11008 group=group->next,key_part++) 11009 { 11010 if (key_part->null_bit) 11011 memcpy(table->record[0]+key_part->offset, group->buff, 1); 11012 } 11013 init_tmptable_sum_functions(join->sum_funcs); 11014 copy_funcs(join->tmp_table_param.items_to_copy); 11015 if ((error=table->file->write_row(table->record[0]))) 11016 { 11017 if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, 11018 error, 0)) 11019 DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error 11020 /* Change method to update rows */ 11021 table->file->ha_index_init(0, 0); 11022 join->join_tab[join->tables-1].next_select=end_unique_update; 11023 } 11024 join->send_records++; 11025 DBUG_RETURN(NESTED_LOOP_OK); 11026 }
Here is the call graph for this function:

| static enum_nested_loop_state end_update | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| bool | end_of_records | |||
| ) | [static] |
| static enum_nested_loop_state end_write | ( | JOIN * | join, | |
| JOIN_TAB *join_tab | __attribute__((unused)), | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 10895 of file sql_select.cc.
References copy_fields(), copy_funcs(), create_myisam_from_heap(), DBUG_ENTER, DBUG_RETURN, JOIN::do_send_rows, error, st_table::file, JOIN::found_records, Item::get_tmp_table_field(), st_table::group, HA_CHECK_DUP, JOIN::having, handler::is_fatal_error(), Field::is_null(), st_order::item, Item::maybe_null, NESTED_LOOP_ERROR, NESTED_LOOP_KILLED, NESTED_LOOP_OK, NESTED_LOOP_QUERY_LIMIT, st_order::next, OPTION_FOUND_ROWS, Field::ptr, st_table::record, st_table::s, JOIN::select_options, JOIN::send_records, JOIN::thd, JOIN::tmp_table, JOIN::tmp_table_param, st_table_share::uniques, JOIN::unit, Item::val_int(), and handler::write_row().
10897 { 10898 TABLE *table=join->tmp_table; 10899 DBUG_ENTER("end_write"); 10900 10901 if (join->thd->killed) // Aborted by user 10902 { 10903 join->thd->send_kill_message(); 10904 DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ 10905 } 10906 if (!end_of_records) 10907 { 10908 copy_fields(&join->tmp_table_param); 10909 copy_funcs(join->tmp_table_param.items_to_copy); 10910 #ifdef TO_BE_DELETED 10911 if (!table->uniques) // If not unique handling 10912 { 10913 /* Copy null values from group to row */ 10914 ORDER *group; 10915 for (group=table->group ; group ; group=group->next) 10916 { 10917 Item *item= *group->item; 10918 if (item->maybe_null) 10919 { 10920 Field *field=item->get_tmp_table_field(); 10921 field->ptr[-1]= (byte) (field->is_null() ? 1 : 0); 10922 } 10923 } 10924 } 10925 #endif 10926 if (!join->having || join->having->val_int()) 10927 { 10928 int error; 10929 join->found_records++; 10930 if ((error=table->file->write_row(table->record[0]))) 10931 { 10932 if (!table->file->is_fatal_error(error, HA_CHECK_DUP)) 10933 goto end; 10934 if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param, 10935 error,1)) 10936 DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error 10937 table->s->uniques=0; // To ensure rows are the same 10938 } 10939 if (++join->send_records >= join->tmp_table_param.end_write_records && 10940 join->do_send_rows) 10941 { 10942 if (!(join->select_options & OPTION_FOUND_ROWS)) 10943 DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); 10944 join->do_send_rows=0; 10945 join->unit->select_limit_cnt = HA_POS_ERROR; 10946 DBUG_RETURN(NESTED_LOOP_OK); 10947 } 10948 } 10949 } 10950 end: 10951 DBUG_RETURN(NESTED_LOOP_OK); 10952 }
Here is the call graph for this function:

| static enum_nested_loop_state end_write | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| bool | end_of_records | |||
| ) | [static] |
| static enum_nested_loop_state end_write_group | ( | JOIN * | join, | |
| JOIN_TAB *join_tab | __attribute__((unused)), | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 11080 of file sql_select.cc.
References Procedure::add(), JOIN::clear(), copy_fields(), copy_funcs(), copy_sum_funcs(), create_myisam_from_heap(), DBUG_ENTER, DBUG_RETURN, Procedure::end_group(), error, st_table::file, JOIN::first_record, JOIN::group, JOIN::group_fields, JOIN::having, init_sum_functions(), NESTED_LOOP_ERROR, NESTED_LOOP_KILLED, NESTED_LOOP_OK, JOIN::procedure, st_table::record, JOIN::rollup, JOIN::rollup_write_data(), JOIN::send_group_parts, st_rollup::state, st_rollup::STATE_NONE, JOIN::sum_funcs, JOIN::sum_funcs_end, test_if_group_changed(), JOIN::thd, JOIN::tmp_table, JOIN::tmp_table_param, update_sum_func(), Item::val_int(), VOID, and handler::write_row().
11082 { 11083 TABLE *table=join->tmp_table; 11084 int idx= -1; 11085 DBUG_ENTER("end_write_group"); 11086 11087 if (join->thd->killed) 11088 { // Aborted by user 11089 join->thd->send_kill_message(); 11090 DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */ 11091 } 11092 if (!join->first_record || end_of_records || 11093 (idx=test_if_group_changed(join->group_fields)) >= 0) 11094 { 11095 if (join->first_record || (end_of_records && !join->group)) 11096 { 11097 if (join->procedure) 11098 join->procedure->end_group(); 11099 int send_group_parts= join->send_group_parts; 11100 if (idx < send_group_parts) 11101 { 11102 if (!join->first_record) 11103 { 11104 /* No matching rows for group function */ 11105 join->clear(); 11106 } 11107 copy_sum_funcs(join->sum_funcs, 11108 join->sum_funcs_end[send_group_parts]); 11109 if (!join->having || join->having->val_int()) 11110 { 11111 int error= table->file->write_row(table->record[0]); 11112 if (error && create_myisam_from_heap(join->thd, table, 11113 &join->tmp_table_param, 11114 error, 0)) 11115 DBUG_RETURN(NESTED_LOOP_ERROR); 11116 } 11117 if (join->rollup.state != ROLLUP::STATE_NONE) 11118 { 11119 if (join->rollup_write_data((uint) (idx+1), table)) 11120 DBUG_RETURN(NESTED_LOOP_ERROR); 11121 } 11122 if (end_of_records) 11123 DBUG_RETURN(NESTED_LOOP_OK); 11124 } 11125 } 11126 else 11127 { 11128 if (end_of_records) 11129 DBUG_RETURN(NESTED_LOOP_OK); 11130 join->first_record=1; 11131 VOID(test_if_group_changed(join->group_fields)); 11132 } 11133 if (idx < (int) join->send_group_parts) 11134 { 11135 copy_fields(&join->tmp_table_param); 11136 copy_funcs(join->tmp_table_param.items_to_copy); 11137 if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1])) 11138 DBUG_RETURN(NESTED_LOOP_ERROR); 11139 if (join->procedure) 11140 join->procedure->add(); 11141 DBUG_RETURN(NESTED_LOOP_OK); 11142 } 11143 } 11144 if (update_sum_func(join->sum_funcs)) 11145 DBUG_RETURN(NESTED_LOOP_ERROR); 11146 if (join->procedure) 11147 join->procedure->add(); 11148 DBUG_RETURN(NESTED_LOOP_OK); 11149 }
Here is the call graph for this function:

| static enum_nested_loop_state end_write_group | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| bool | end_of_records | |||
| ) | [static] |
Definition at line 6032 of file sql_select.cc.
References st_join_table::cached_eq_ref_table, DBUG_ASSERT, st_join_table::eq_ref_table, st_table_ref::items, JT_CONST, JT_EQ_REF, st_table_ref::key_parts, st_table::map, map, st_table::maybe_null, st_order::next, only_eq_ref_tables(), order, st_join_table::ref, st_join_table::table, and st_join_table::type.
Referenced by only_eq_ref_tables().
06033 { 06034 if (tab->cached_eq_ref_table) // If cached 06035 return tab->eq_ref_table; 06036 tab->cached_eq_ref_table=1; 06037 if (tab->type == JT_CONST) // We can skip const tables 06038 return (tab->eq_ref_table=1); /* purecov: inspected */ 06039 if (tab->type != JT_EQ_REF || tab->table->maybe_null) 06040 return (tab->eq_ref_table=0); // We must use this 06041 Item **ref_item=tab->ref.items; 06042 Item **end=ref_item+tab->ref.key_parts; 06043 uint found=0; 06044 table_map map=tab->table->map; 06045 06046 for (; ref_item != end ; ref_item++) 06047 { 06048 if (! (*ref_item)->const_item()) 06049 { // Not a const ref 06050 ORDER *order; 06051 for (order=start_order ; order ; order=order->next) 06052 { 06053 if ((*ref_item)->eq(order->item[0],0)) 06054 break; 06055 } 06056 if (order) 06057 { 06058 found++; 06059 DBUG_ASSERT(!(order->used & map)); 06060 order->used|=map; 06061 continue; // Used in ORDER BY 06062 } 06063 if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables())) 06064 return (tab->eq_ref_table=0); 06065 } 06066 } 06067 /* Check that there was no reference to table before sort order */ 06068 for (; found && start_order ; start_order=start_order->next) 06069 { 06070 if (start_order->used & map) 06071 { 06072 found--; 06073 continue; 06074 } 06075 if (start_order->depend_map & map) 06076 return (tab->eq_ref_table=0); 06077 } 06078 return tab->eq_ref_table=1; 06079 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5788 of file sql_select.cc.
References ER, ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, JOIN::join_tab, JT_ALL, my_message(), MYF, SQL_SELECT::quick, st_join_table::select, JOIN::tables, and st_join_table::type.
05789 { 05790 for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables; 05791 tab < end; 05792 tab++) 05793 { 05794 if (tab->type == JT_ALL && (!tab->select || !tab->select->quick)) 05795 { 05796 my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE, 05797 ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0)); 05798 return(1); 05799 } 05800 } 05801 return(0); 05802 }
Here is the call graph for this function:

| static enum_nested_loop_state evaluate_join_record | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab, | |||
| int | error, | |||
| my_bool * | report_error | |||
| ) | [static] |
Definition at line 9933 of file sql_select.cc.
References DBUG_PRINT, JOIN::examined_rows, st_read_record::file, st_join_table::first_unmatched, st_join_table::first_upper, st_join_table::found, JOIN::found_records, st_join_table::last_inner, NESTED_LOOP_ERROR, NESTED_LOOP_KILLED, NESTED_LOOP_NO_MORE_ROWS, NESTED_LOOP_OK, st_join_table::next_select, st_reginfo::not_exists_optimize, st_join_table::not_used_in_distinct, st_join_table::read_record, st_table::reginfo, JOIN::return_tab, st_join_table::select_cond, st_join_table::table, JOIN::thd, handler::unlock_row(), and Item::val_int().
Referenced by sub_select().
09935 { 09936 bool not_exists_optimize= join_tab->table->reginfo.not_exists_optimize; 09937 bool not_used_in_distinct=join_tab->not_used_in_distinct; 09938 ha_rows found_records=join->found_records; 09939 COND *select_cond= join_tab->select_cond; 09940 09941 if (error > 0 || (*report_error)) // Fatal error 09942 return NESTED_LOOP_ERROR; 09943 if (error < 0) 09944 return NESTED_LOOP_NO_MORE_ROWS; 09945 if (join->thd->killed) // Aborted by user 09946 { 09947 join->thd->send_kill_message(); 09948 return NESTED_LOOP_KILLED; /* purecov: inspected */ 09949 } 09950 DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond)); 09951 if (!select_cond || select_cond->val_int()) 09952 { 09953 /* 09954 There is no select condition or the attached pushed down 09955 condition is true => a match is found. 09956 */ 09957 bool found= 1; 09958 while (join_tab->first_unmatched && found) 09959 { 09960 /* 09961 The while condition is always false if join_tab is not 09962 the last inner join table of an outer join operation. 09963 */ 09964 JOIN_TAB *first_unmatched= join_tab->first_unmatched; 09965 /* 09966 Mark that a match for current outer table is found. 09967 This activates push down conditional predicates attached 09968 to the all inner tables of the outer join. 09969 */ 09970 first_unmatched->found= 1; 09971 for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) 09972 { 09973 /* Check all predicates that has just been activated. */ 09974 /* 09975 Actually all predicates non-guarded by first_unmatched->found 09976 will be re-evaluated again. It could be fixed, but, probably, 09977 it's not worth doing now. 09978 */ 09979 if (tab->select_cond && !tab->select_cond->val_int()) 09980 { 09981 /* The condition attached to table tab is false */ 09982 if (tab == join_tab) 09983 found= 0; 09984 else 09985 { 09986 /* 09987 Set a return point if rejected predicate is attached 09988 not to the last table of the current nest level. 09989 */ 09990 join->return_tab= tab; 09991 return NESTED_LOOP_OK; 09992 } 09993 } 09994 } 09995 /* 09996 Check whether join_tab is not the last inner table 09997 for another embedding outer join. 09998 */ 09999 if ((first_unmatched= first_unmatched->first_upper) && 10000 first_unmatched->last_inner != join_tab) 10001 first_unmatched= 0; 10002 join_tab->first_unmatched= first_unmatched; 10003 } 10004 10005 /* 10006 It was not just a return to lower loop level when one 10007 of the newly activated predicates is evaluated as false 10008 (See above join->return_tab= tab). 10009 */ 10010 join->examined_rows++; 10011 join->thd->row_count++; 10012 10013 if (found) 10014 { 10015 enum enum_nested_loop_state rc; 10016 if (not_exists_optimize) 10017 return NESTED_LOOP_NO_MORE_ROWS; 10018 /* A match from join_tab is found for the current partial join. */ 10019 rc= (*join_tab->next_select)(join, join_tab+1, 0); 10020 if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS) 10021 return rc; 10022 if (join->return_tab < join_tab) 10023 return NESTED_LOOP_OK; 10024 /* 10025 Test if this was a SELECT DISTINCT query on a table that 10026 was not in the field list; In this case we can abort if 10027 we found a row, as no new rows can be added to the result. 10028 */ 10029 if (not_used_in_distinct && found_records != join->found_records) 10030 return NESTED_LOOP_OK; 10031 } 10032 else 10033 join_tab->read_record.file->unlock_row(); 10034 } 10035 else 10036 { 10037 /* 10038 The condition pushed down to the table join_tab rejects all rows 10039 with the beginning coinciding with the current partial join. 10040 */ 10041 join->examined_rows++; 10042 join->thd->row_count++; 10043 } 10044 return NESTED_LOOP_OK; 10045 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static enum_nested_loop_state evaluate_null_complemented_join_record | ( | JOIN * | join, | |
| JOIN_TAB * | join_tab | |||
| ) | [static] |
Definition at line 10056 of file sql_select.cc.
References st_join_table::first_unmatched, st_join_table::found, st_join_table::last_inner, NESTED_LOOP_OK, st_join_table::next_select, st_join_table::not_null_compl, restore_record, JOIN::return_tab, st_join_table::select_cond, st_join_table::table, and Item::val_int().
Referenced by sub_select().
10057 { 10058 /* 10059 The table join_tab is the first inner table of a outer join operation 10060 and no matches has been found for the current outer row. 10061 */ 10062 JOIN_TAB *last_inner_tab= join_tab->last_inner; 10063 /* Cache variables for faster loop */ 10064 COND *select_cond; 10065 for ( ; join_tab <= last_inner_tab ; join_tab++) 10066 { 10067 /* Change the the values of guard predicate variables. */ 10068 join_tab->found= 1; 10069 join_tab->not_null_compl= 0; 10070 /* The outer row is complemented by nulls for each inner tables */ 10071 restore_record(join_tab->table,s->default_values); // Make empty record 10072 mark_as_null_row(join_tab->table); // For group by without error 10073 select_cond= join_tab->select_cond; 10074 /* Check all attached conditions for inner table rows. */ 10075 if (select_cond && !select_cond->val_int()) 10076 return NESTED_LOOP_OK; 10077 } 10078 join_tab--; 10079 /* 10080 The row complemented by nulls might be the first row 10081 of embedding outer joins. 10082 If so, perform the same actions as in the code 10083 for the first regular outer join row above. 10084 */ 10085 for ( ; ; ) 10086 { 10087 JOIN_TAB *first_unmatched= join_tab->first_unmatched; 10088 if ((first_unmatched= first_unmatched->first_upper) && 10089 first_unmatched->last_inner != join_tab) 10090 first_unmatched= 0; 10091 join_tab->first_unmatched= first_unmatched; 10092 if (!first_unmatched) 10093 break; 10094 first_unmatched->found= 1; 10095 for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++) 10096 { 10097 if (tab->select_cond && !tab->select_cond->val_int()) 10098 { 10099 join->return_tab= tab; 10100 return NESTED_LOOP_OK; 10101 } 10102 } 10103 } 10104 /* 10105 The row complemented by nulls satisfies all conditions 10106 attached to inner tables. 10107 Send the row complemented by nulls to be joined with the 10108 remaining tables. 10109 */ 10110 return (*join_tab->next_select)(join, join_tab+1, 0); 10111 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void find_best | ( | JOIN * | join, | |
| table_map | rest_tables, | |||
| uint | index, | |||
| double | record_count, | |||
| double | read_time | |||
| ) | [static] |
Definition at line 4531 of file sql_select.cc.
References best_access_path(), JOIN::best_positions, JOIN::best_read, JOIN::best_ref, check_interleaving_with_nj(), JOIN::const_tables, DBL_MAX, DBUG_PRINT, st_join_table::dependent, st_join_table::key_dependent, st_table::map, memcpy, pos(), JOIN::positions, st_position::read_time, records, st_position::records_read, restore_prev_nj_state(), JOIN::select_options, SELECT_STRAIGHT_JOIN, JOIN::sort_by_table, swap_variables, st_position::table, st_join_table::table, JOIN::thd, and TIME_FOR_COMPARE.
Referenced by choose_plan().
04533 { 04534 ha_rows rec; 04535 double tmp; 04536 THD *thd= join->thd; 04537 if (!rest_tables) 04538 { 04539 DBUG_PRINT("best",("read_time: %g record_count: %g",read_time, 04540 record_count)); 04541 04542 read_time+=record_count/(double) TIME_FOR_COMPARE; 04543 if (join->sort_by_table && 04544 join->sort_by_table != 04545 join->positions[join->const_tables].table->table) 04546 read_time+=record_count; // We have to make a temp table 04547 if (read_time < join->best_read) 04548 { 04549 memcpy((gptr) join->best_positions,(gptr) join->positions, 04550 sizeof(POSITION)*idx); 04551 join->best_read= read_time - 0.001; 04552 } 04553 return; 04554 } 04555 if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read) 04556 return; /* Found better before */ 04557 04558 JOIN_TAB *s; 04559 double best_record_count=DBL_MAX,best_read_time=DBL_MAX; 04560 for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++) 04561 { 04562 table_map real_table_bit=s->table->map; 04563 if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) && 04564 (!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s))) 04565 { 04566 double records, best; 04567 best_access_path(join, s, thd, rest_tables, idx, record_count, 04568 read_time); 04569 records= join->positions[idx].records_read; 04570 best= join->positions[idx].read_time; 04571 /* 04572 Go to the next level only if there hasn't been a better key on 04573 this level! This will cut down the search for a lot simple cases! 04574 */ 04575 double current_record_count=record_count*records; 04576 double current_read_time=read_time+best; 04577 if (best_record_count > current_record_count || 04578 best_read_time > current_read_time || 04579 idx == join->const_tables && s->table == join->sort_by_table) 04580 { 04581 if (best_record_count >= current_record_count && 04582 best_read_time >= current_read_time && 04583 (!(s->key_dependent & rest_tables) || records < 2.0)) 04584 { 04585 best_record_count=current_record_count; 04586 best_read_time=current_read_time; 04587 } 04588 swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); 04589 find_best(join,rest_tables & ~real_table_bit,idx+1, 04590 current_record_count,current_read_time); 04591 if (thd->killed) 04592 return; 04593 swap_variables(JOIN_TAB*, join->best_ref[idx], *pos); 04594 } 04595 restore_prev_nj_state(s); 04596 if (join->select_options & SELECT_STRAIGHT_JOIN) 04597 break; // Don't test all combinations 04598 } 04599 } 04600 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 11574 of file sql_select.cc.
References Item::FIELD_ITEM, and Item::type().
11575 { 11576 List<Item> *fields= (List<Item> *) data; 11577 bool part_found= 0; 11578 List_iterator<Item> li(*fields); 11579 Item *item; 11580 11581 while ((item= li++)) 11582 { 11583 if (item->type() == Item::FIELD_ITEM && 11584 ((Item_field*) item)->field->eq(field)) 11585 { 11586 part_found= 1; 11587 break; 11588 } 11589 } 11590 return part_found; 11591 }
Here is the call graph for this function:

Definition at line 11538 of file sql_select.cc.
References Item::FIELD_ITEM, and st_order::next.
11539 { 11540 ORDER *group= (ORDER *) data; 11541 bool part_found= 0; 11542 for (ORDER *tmp_group= group; tmp_group; tmp_group=tmp_group->next) 11543 { 11544 Item *item= (*tmp_group->item)->real_item(); 11545 if (item->type() == Item::FIELD_ITEM && 11546 ((Item_field*) item)->field->eq(field)) 11547 { 11548 part_found= 1; 11549 break; 11550 } 11551 } 11552 return part_found; 11553 }
| Item_equal* find_item_equal | ( | COND_EQUAL * | cond_equal, | |
| Field * | field, | |||
| bool * | inherited_fl | |||
| ) |
Definition at line 6340 of file sql_select.cc.
References Item_equal::contains(), COND_EQUAL::current_level, FALSE, TRUE, and COND_EQUAL::upper_levels.
Referenced by check_equality().
06342 { 06343 Item_equal *item= 0; 06344 bool in_upper_level= FALSE; 06345 while (cond_equal) 06346 { 06347 List_iterator_fast<Item_equal> li(cond_equal->current_level); 06348 while ((item= li++)) 06349 { 06350 if (item->contains(field)) 06351 goto finish; 06352 } 06353 in_upper_level= TRUE; 06354 cond_equal= cond_equal->upper_levels; 06355 } 06356 in_upper_level= FALSE; 06357 finish: 06358 *inherited_fl= in_upper_level; 06359 return item; 06360 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static bool find_order_in_list | ( | THD * | thd, | |
| Item ** | ref_pointer_array, | |||
| TABLE_LIST * | tables, | |||
| ORDER * | order, | |||
| List< Item > & | fields, | |||
| List< Item > & | all_fields, | |||
| bool | is_group_field | |||
| ) | [static] |
Definition at line 12634 of file sql_select.cc.
References Item::basic_const_item(), count, counter, current_thd, el, base_list::elements, Field::eq(), ER, ER_BAD_FIELD_ERROR, ER_NON_UNIQ_ERROR, FALSE, Item::FIELD_ITEM, find_field_in_tables(), find_item_in_list(), Item::fix_fields(), Item::fixed, Item::full_name(), Item::INT_ITEM, my_error(), MYF, not_found_field, not_found_item, NULL, order, List< T >::push_front(), push_warning_printf(), Item::REF_ITEM, TRUE, Item::type(), Item::val_int(), view_ref_found, and MYSQL_ERROR::WARN_LEVEL_WARN.
Referenced by setup_group(), and setup_order().
12637 { 12638 Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */ 12639 Item::Type order_item_type; 12640 Item **select_item; /* The corresponding item from the SELECT clause. */ 12641 Field *from_field; /* The corresponding field from the FROM clause. */ 12642 uint counter; 12643 bool unaliased; 12644 12645 /* 12646 Local SP variables may be int but are expressions, not positions. 12647 (And they can't be used before fix_fields is called for them). 12648 */ 12649 if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item()) 12650 { /* Order by position */ 12651 uint count= (uint) order_item->val_int(); 12652 if (!count || count > fields.elements) 12653 { 12654 my_error(ER_BAD_FIELD_ERROR, MYF(0), 12655 order_item->full_name(), thd->where); 12656 return

