summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-11-03 13:01:38 +0200
committerunknown <monty@mysql.com>2004-11-03 13:01:38 +0200
commit614cda698a2c07ae158cbaf9a0a102a04866e28c (patch)
tree39f6697332c041cfd44f3c685d341ba5024ca0f5 /sql/opt_range.cc
parent09e0503538cbf882cdb1c215a45becfd3826d67a (diff)
parentf5a47f156b6778a0f6751556e56a0afe25d6be13 (diff)
downloadmariadb-git-614cda698a2c07ae158cbaf9a0a102a04866e28c.tar.gz
Merge on pull
BitKeeper/etc/ignore: auto-union mysql-test/r/grant2.result: Auto merged mysql-test/r/sql_mode.result: Auto merged mysql-test/t/grant2.test: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/mysql_priv.h: Auto merged sql/mysqld.cc: Auto merged sql/opt_range.cc: Auto merged sql/set_var.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_parse.cc: Auto merged sql/sql_yacc.yy: Auto merged
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc93
1 files changed, 51 insertions, 42 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 48f48797a60..286d0d01842 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -714,6 +714,7 @@ 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)
{
+ sorted= 0;
index= key_nr;
head= table;
key_part_info= head->key_info[index].key_part;
@@ -1725,9 +1726,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 +4841,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 +4854,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 +4862,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 +5235,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 +5243,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 +5370,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 +5454,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 +5476,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 +5524,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 +6482,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 +6861,6 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree)
if (!index_info) /* No usable index found. */
DBUG_RETURN(NULL);
-
/* Check (SA3) for the where clause. */
if (join->conds && min_max_arg_item &&
!check_group_min_max_predicates(join->conds, min_max_arg_item,
@@ -7207,16 +7207,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:
@@ -7273,8 +7273,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)
@@ -7362,7 +7362,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,
@@ -7370,7 +7369,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);
@@ -7453,17 +7453,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;
@@ -7476,6 +7479,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);
@@ -8584,7 +8593,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
}
-#endif
+#endif /* NOT_USED */
/*****************************************************************************
** Instantiate templates