diff options
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r-- | sql/opt_range.cc | 94 |
1 files changed, 51 insertions, 43 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 683bf1bdc13..10b9fc9fbfd 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -712,7 +712,7 @@ QUICK_SELECT_I::QUICK_SELECT_I() QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc, MEM_ROOT *parent_alloc) - :dont_free(0),error(0),free_file(0),cur_range(NULL),range(0) + :dont_free(0),sorted(0),error(0),free_file(0),cur_range(NULL),range(0) { index= key_nr; head= table; @@ -1725,9 +1725,10 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, } if (tree) - {/* - It is possible to use a range-based quick select (but it might be slower - than 'all' table scan). + { + /* + It is possible to use a range-based quick select (but it might be + slower than 'all' table scan). */ if (tree->merges.is_empty()) { @@ -4839,7 +4840,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root) uint e_count=0; if (this == root && use_count != 1) { - sql_print_error("Note: Use_count: Wrong count %lu for root",use_count); + sql_print_information("Use_count: Wrong count %lu for root",use_count); return; } if (this->type != SEL_ARG::KEY_RANGE) @@ -4852,7 +4853,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root) ulong count=count_key_part_usage(root,pos->next_key_part); if (count > pos->next_key_part->use_count) { - sql_print_error("Note: Use_count: Wrong count for key at 0x%lx, %lu should be %lu", + sql_print_information("Use_count: Wrong count for key at 0x%lx, %lu should be %lu", pos,pos->next_key_part->use_count,count); return; } @@ -4860,7 +4861,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root) } } if (e_count != elements) - sql_print_error("Warning: Wrong use count: %u (should be %u) for tree at 0x%lx", + sql_print_warning("Wrong use count: %u (should be %u) for tree at 0x%lx", e_count, elements, (gptr) this); } @@ -5233,8 +5234,6 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree, QUICK_RANGE_SELECT *quick; DBUG_ENTER("get_quick_select"); - - if (param->table->key_info[param->real_keynr[idx]].flags & HA_SPATIAL) quick=new QUICK_RANGE_SELECT_GEOM(param->thd, param->table, param->real_keynr[idx], @@ -5243,7 +5242,7 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree, else quick=new QUICK_RANGE_SELECT(param->thd, param->table, param->real_keynr[idx], - test(parent_alloc), parent_alloc); + test(parent_alloc)); if (quick) { @@ -5370,7 +5369,6 @@ get_quick_keys(PARAM *param,QUICK_RANGE_SELECT *quick,KEY_PART *key, if (insert_dynamic(&quick->ranges, (gptr)&range)) return 1; - end: if (key_tree->right != &null_element) return get_quick_keys(param,quick,key,key_tree->right, @@ -5455,14 +5453,18 @@ bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List<Item> *fields) return 0; } + /**************************************************************************** Create a QUICK RANGE based on a key + This allocates things in a new memory root, as this may be called many times + during a query. ****************************************************************************/ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) { - QUICK_RANGE_SELECT *quick=new QUICK_RANGE_SELECT(thd, table, ref->key, 1); + MEM_ROOT *old_root= my_pthread_getspecific_ptr(MEM_ROOT*, THR_MALLOC); + QUICK_RANGE_SELECT *quick= new QUICK_RANGE_SELECT(thd, table, ref->key, 0); KEY *key_info = &table->key_info[ref->key]; KEY_PART *key_part; QUICK_RANGE *range; @@ -5473,17 +5475,12 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, if (quick->init()) { delete quick; - return 0; - } - - if (cp_buffer_from_ref(ref)) - { - if (thd->is_fatal_error) - goto err; // out of memory + goto err; } - if (!(range= new QUICK_RANGE())) - goto err; // out of memory + if (cp_buffer_from_ref(ref) && thd->is_fatal_error || + !(range= new QUICK_RANGE())) + goto err; // out of memory range->min_key=range->max_key=(char*) ref->key_buff; range->min_length=range->max_length=ref->key_length; @@ -5526,9 +5523,12 @@ QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, goto err; } +ok: + my_pthread_setspecific_ptr(THR_MALLOC, old_root); return quick; err: + my_pthread_setspecific_ptr(THR_MALLOC, old_root); delete quick; return 0; } @@ -6481,8 +6481,8 @@ cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts, - GA = <G_1, ..., G_k> - from the GROUP BY clause (if any) = SA - if Q is a DISTINCT query (based on the equivalence of DISTINCT and GROUP queries. - - NGA = QA - (GA union C) = {NG_1, ..., NG_m} - the ones not in GROUP BY - and not referenced by MIN/MAX functions. + - NGA = QA - (GA union C) = {NG_1, ..., NG_m} - the ones not in + GROUP BY and not referenced by MIN/MAX functions. with the following properties specified below. SA1. There is at most one attribute in SA referenced by any number of @@ -6860,7 +6860,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) if (!index_info) /* No usable index found. */ DBUG_RETURN(NULL); - /* Check (SA3,WA1) for the where clause. */ if (!check_group_min_max_predicates(join->conds, min_max_arg_item, (index_info->flags & HA_SPATIAL) ? @@ -7194,16 +7193,16 @@ SEL_ARG * get_index_range_tree(uint index, SEL_TREE* range_tree, PARAM *param, group_key_parts [in] Number of index key parts in the group prefix range_tree [in] Tree of ranges for all indexes index_tree [in] The range tree for the current index - quick_prefix_records [in] Number of records retrieved by the internally used - quick range select if any + quick_prefix_records [in] Number of records retrieved by the internally + used quick range select if any have_min [in] True if there is a MIN function have_max [in] True if there is a MAX function read_cost [out] The cost to retrieve rows via this quick select records [out] The number of rows retrieved DESCRIPTION - This method computes the access cost of a TRP_GROUP_MIN_MAX instance and the - number of rows returned. It updates this->read_cost and this->records. + This method computes the access cost of a TRP_GROUP_MIN_MAX instance and + the number of rows returned. It updates this->read_cost and this->records. NOTES The cost computation distinguishes several cases: @@ -7260,8 +7259,8 @@ void cost_group_min_max(TABLE* table, KEY *index_info, uint used_key_parts, double quick_prefix_selectivity; double io_cost; double cpu_cost= 0; /* TODO: CPU cost of index_read calls? */ - DBUG_ENTER("TRP_GROUP_MIN_MAX::cost"); + table_records= table->file->records; keys_per_block= (table->file->block_size / 2 / (index_info->key_length + table->file->ref_length) @@ -7349,7 +7348,6 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows, MEM_ROOT *parent_alloc) { QUICK_GROUP_MIN_MAX_SELECT *quick; - DBUG_ENTER("TRP_GROUP_MIN_MAX::make_quick"); quick= new QUICK_GROUP_MIN_MAX_SELECT(param->table, @@ -7357,7 +7355,8 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows, have_min, have_max, min_max_arg_part, group_prefix_len, used_key_parts, index_info, index, read_cost, records, - key_infix_len, key_infix, parent_alloc); + key_infix_len, key_infix, + parent_alloc); if (!quick) DBUG_RETURN(NULL); @@ -7440,17 +7439,20 @@ TRP_GROUP_MIN_MAX::make_quick(PARAM *param, bool retrieve_full_rows, None */ -QUICK_GROUP_MIN_MAX_SELECT::QUICK_GROUP_MIN_MAX_SELECT( - TABLE *table, JOIN *join_arg, bool have_min_arg, bool have_max_arg, - KEY_PART_INFO *min_max_arg_part_arg, uint group_prefix_len_arg, - uint used_key_parts_arg, KEY *index_info_arg, uint use_index, - double read_cost_arg, ha_rows records_arg, uint key_infix_len_arg, - byte *key_infix_arg, MEM_ROOT *parent_alloc) -: join(join_arg), index_info(index_info_arg), - group_prefix_len(group_prefix_len_arg), have_min(have_min_arg), - have_max(have_max_arg), seen_first_key(FALSE), - min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg), - key_infix_len(key_infix_len_arg) +QUICK_GROUP_MIN_MAX_SELECT:: +QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg, + bool have_max_arg, + KEY_PART_INFO *min_max_arg_part_arg, + uint group_prefix_len_arg, + uint used_key_parts_arg, KEY *index_info_arg, + uint use_index, double read_cost_arg, + ha_rows records_arg, uint key_infix_len_arg, + byte *key_infix_arg, MEM_ROOT *parent_alloc) + :join(join_arg), index_info(index_info_arg), + group_prefix_len(group_prefix_len_arg), have_min(have_min_arg), + have_max(have_max_arg), seen_first_key(FALSE), + min_max_arg_part(min_max_arg_part_arg), key_infix(key_infix_arg), + key_infix_len(key_infix_len_arg) { head= table; file= head->file; @@ -7463,6 +7465,12 @@ QUICK_GROUP_MIN_MAX_SELECT::QUICK_GROUP_MIN_MAX_SELECT( real_prefix_len= group_prefix_len + key_infix_len; group_prefix= NULL; min_max_arg_len= min_max_arg_part ? min_max_arg_part->store_length : 0; + + /* + We can't have parent_alloc set as the init function can't handle this case + yet. + */ + DBUG_ASSERT(!parent_alloc); if (!parent_alloc) { init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0); @@ -8571,7 +8579,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose) } -#endif +#endif /* NOT_USED */ /***************************************************************************** ** Instantiate templates |