summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc84
1 files changed, 34 insertions, 50 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index f14f331008d..08eae68c855 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -729,7 +729,7 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr,
int QUICK_RANGE_SELECT::init()
{
DBUG_ENTER("QUICK_RANGE_SELECT::init");
- DBUG_RETURN(error= file->index_init(index));
+ DBUG_RETURN(error= file->ha_index_init(index));
}
QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
@@ -737,7 +737,8 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT()
DBUG_ENTER("QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT");
if (!dont_free)
{
- file->index_end();
+ if (file->inited)
+ file->ha_index_end();
file->extra(HA_EXTRA_NO_KEYREAD);
delete_dynamic(&ranges); /* ranges are allocated in alloc */
if (free_file)
@@ -1514,7 +1515,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_map prev_tables,
ha_rows limit, bool force_quick_range)
{
- uint basflag;
uint idx;
double scan_time;
DBUG_ENTER("test_quick_select");
@@ -1529,14 +1529,13 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
if (!cond || (specialflag & SPECIAL_SAFE_MODE) && ! force_quick_range ||
!limit)
DBUG_RETURN(0); /* purecov: inspected */
- if (!((basflag= head->file->table_flags()) & HA_KEYPOS_TO_RNDPOS) &&
- keys_to_use.is_set_all() || keys_to_use.is_clear_all())
- DBUG_RETURN(0); /* Not smart database */
+ if (keys_to_use.is_clear_all())
+ DBUG_RETURN(0);
records=head->file->records;
if (!records)
records++; /* purecov: inspected */
scan_time=(double) records / TIME_FOR_COMPARE+1;
- read_time=(double) head->file->scan_time()+ scan_time + 1.0;
+ read_time=(double) head->file->scan_time()+ scan_time + 1.1;
if (head->force_index)
scan_time= read_time= DBL_MAX;
if (limit < records)
@@ -1557,7 +1556,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
/* set up parameter that is passed to all functions */
param.thd= thd;
- param.baseflag=basflag;
+ param.baseflag=head->file->table_flags();
param.prev_tables=prev_tables | const_tables;
param.read_tables=read_tables;
param.current_table= head->map;
@@ -2971,7 +2970,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
}
if (found_records != HA_POS_ERROR && found_records > 2 &&
read_index_only &&
- (param->table->file->index_flags(keynr) & HA_KEY_READ_ONLY) &&
+ (param->table->file->index_flags(keynr) & HA_KEYREAD_ONLY) &&
!(pk_is_clustered && keynr == param->table->primary_key))
{
/* We can resolve this by only reading through this key. */
@@ -2988,6 +2987,8 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree,
found_records)+
(double) found_records / TIME_FOR_COMPARE);
}
+ DBUG_PRINT("info",("read_time: %g found_read_time: %g",
+ read_time, found_read_time));
if (read_time > found_read_time && found_records != HA_POS_ERROR
/*|| read_time == DBL_MAX*/ )
{
@@ -3991,7 +3992,7 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
{
swap_variables(SEL_ARG *,key1,key2);
}
- else if (!(key1=key1->clone_tree()))
+ if (key1->use_count > 0 || !(key1=key1->clone_tree()))
return 0; // OOM
}
@@ -4060,10 +4061,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *next=key2->next; // Keys are not overlapping
if (key2_shared)
{
- SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy
- if (!tmp)
+ SEL_ARG *cpy= new SEL_ARG(*key2); // Must make copy
+ if (!cpy)
return 0; // OOM
- key1=key1->insert(tmp);
+ key1=key1->insert(cpy);
key2->increment_use_count(key1->use_count+1);
}
else
@@ -4299,8 +4300,17 @@ SEL_ARG::find_range(SEL_ARG *key)
/*
-** Remove a element from the tree
-** This also frees all sub trees that is used by the element
+ Remove a element from the tree
+
+ SYNOPSIS
+ tree_delete()
+ key Key that is to be deleted from tree (this)
+
+ NOTE
+ This also frees all sub trees that is used by the element
+
+ RETURN
+ root of new tree (with key deleted)
*/
SEL_ARG *
@@ -4308,7 +4318,10 @@ SEL_ARG::tree_delete(SEL_ARG *key)
{
enum leaf_color remove_color;
SEL_ARG *root,*nod,**par,*fix_par;
- root=this; this->parent= 0;
+ DBUG_ENTER("tree_delete");
+
+ root=this;
+ this->parent= 0;
/* Unlink from list */
if (key->prev)
@@ -4355,7 +4368,7 @@ SEL_ARG::tree_delete(SEL_ARG *key)
}
if (root == &null_element)
- return 0; // Maybe root later
+ DBUG_RETURN(0); // Maybe root later
if (remove_color == BLACK)
root=rb_delete_fixup(root,nod,fix_par);
test_rb_tree(root,root->parent);
@@ -4363,7 +4376,7 @@ SEL_ARG::tree_delete(SEL_ARG *key)
root->use_count=this->use_count; // Fix root counters
root->elements=this->elements-1;
root->maybe_flag=this->maybe_flag;
- return root;
+ DBUG_RETURN(root);
}
@@ -5223,7 +5236,6 @@ bool QUICK_ROR_UNION_SELECT::check_if_keys_used(List<Item> *fields)
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
TABLE_REF *ref)
{
- table->file->index_end(); // Remove old cursor
QUICK_RANGE_SELECT *quick=new QUICK_RANGE_SELECT(thd, table, ref->key, 1);
KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part;
@@ -5719,22 +5731,13 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
uint used_key_parts)
: QUICK_RANGE_SELECT(*q), rev_it(rev_ranges)
{
- bool not_read_after_key = file->table_flags() & HA_NOT_READ_AFTER_KEY;
QUICK_RANGE *r;
QUICK_RANGE **pr= (QUICK_RANGE**)ranges.buffer;
QUICK_RANGE **last_range= pr + ranges.elements;
- for (; pr!=last_range; ++pr)
- {
- r= *pr;
- rev_ranges.push_front(r);
- if (not_read_after_key && range_reads_after_key(r))
- {
- error = HA_ERR_UNSUPPORTED;
- dont_free=1; // Don't free memory from 'q'
- return;
- }
- }
+ for (; pr!=last_range; pr++)
+ rev_ranges.push_front(*pr);
+
/* Remove EQ_RANGE flag for keys that are not using the full key */
for (r = rev_it++; r; r = rev_it++)
{
@@ -5803,29 +5806,10 @@ int QUICK_SELECT_DESC::get_next()
else
{
DBUG_ASSERT(range->flag & NEAR_MAX || range_reads_after_key(range));
-#ifndef NOT_IMPLEMENTED_YET
result=file->index_read(record, (byte*) range->max_key,
range->max_length,
((range->flag & NEAR_MAX) ?
HA_READ_BEFORE_KEY : HA_READ_PREFIX_LAST_OR_PREV));
-#else
- /*
- Heikki changed Sept 11, 2002: since InnoDB does not store the cursor
- position if READ_KEY_EXACT is used to a primary key with all
- key columns specified, we must use below HA_READ_KEY_OR_NEXT,
- so that InnoDB stores the cursor position and is able to move
- the cursor one step backward after the search.
- */
- /*
- Note: even if max_key is only a prefix, HA_READ_AFTER_KEY will
- do the right thing - go past all keys which match the prefix
- */
- result=file->index_read(record, (byte*) range->max_key,
- range->max_length,
- ((range->flag & NEAR_MAX) ?
- HA_READ_KEY_OR_NEXT : HA_READ_AFTER_KEY));
- result = file->index_prev(record);
-#endif
}
if (result)
{