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.cc89
1 files changed, 51 insertions, 38 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 23fb36c0c91..947c930b2f4 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -341,8 +341,8 @@ SQL_SELECT *make_select(TABLE *head, table_map const_tables,
DBUG_RETURN(0);
if (!(select= new SQL_SELECT))
{
- *error= 1;
- DBUG_RETURN(0); /* purecov: inspected */
+ *error= 1; // out of memory
+ DBUG_RETURN(0); /* purecov: inspected */
}
select->read_tables=read_tables;
select->const_tables=const_tables;
@@ -456,15 +456,17 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
SEL_ARG *tmp;
if (type != KEY_RANGE)
{
- tmp=new SEL_ARG(type);
+ if(!(tmp=new SEL_ARG(type)))
+ return 0; // out of memory
tmp->prev= *next_arg; // Link into next/prev chain
(*next_arg)->next=tmp;
(*next_arg)= tmp;
}
else
{
- tmp=new SEL_ARG(field,part, min_value,max_value,
- min_flag, max_flag, maybe_flag);
+ if(!(tmp=new SEL_ARG(field,part, min_value,max_value,
+ min_flag, max_flag, maybe_flag)))
+ return 0; // out of memory
tmp->parent=new_parent;
tmp->next_key_part=next_key_part;
if (left != &null_element)
@@ -762,6 +764,8 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
while ((item=li++))
{
SEL_TREE *new_tree=get_mm_tree(param,item);
+ if(current_thd->fatal_error)
+ DBUG_RETURN(0); // out of memory
tree=tree_and(param,tree,new_tree);
if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
break;
@@ -777,7 +781,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
{
SEL_TREE *new_tree=get_mm_tree(param,item);
if (!new_tree)
- DBUG_RETURN(0);
+ DBUG_RETURN(0); // out of memory
tree=tree_or(param,tree,new_tree);
if (!tree || tree->type == SEL_TREE::ALWAYS)
break;
@@ -793,18 +797,16 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(new SEL_TREE(SEL_TREE::ALWAYS));
DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE));
}
+
table_map ref_tables=cond->used_tables();
- if (ref_tables & ~(param->prev_tables | param->read_tables |
- param->current_table))
- DBUG_RETURN(0); // Can't be calculated yet
if (cond->type() != Item::FUNC_ITEM)
{ // Should be a field
- if (ref_tables & param->current_table)
+ if ((ref_tables & param->current_table) ||
+ (ref_tables & ~(param->prev_tables | param->read_tables)))
DBUG_RETURN(0);
DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE));
}
- if (!(ref_tables & param->current_table))
- DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true
+
Item_func *cond_func= (Item_func*) cond;
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
DBUG_RETURN(0); // Can't be calculated
@@ -815,12 +817,13 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
{
Field *field=((Item_field*) (cond_func->arguments()[0]))->field;
Item_result cmp_type=field->cmp_type();
- tree= get_mm_parts(param,field,Item_func::GE_FUNC,
- cond_func->arguments()[1],cmp_type);
- DBUG_RETURN(tree_and(param,tree,
+ DBUG_RETURN(tree_and(param,
+ get_mm_parts(param, field,
+ Item_func::GE_FUNC,
+ cond_func->arguments()[1], cmp_type),
get_mm_parts(param, field,
Item_func::LE_FUNC,
- cond_func->arguments()[2],cmp_type)));
+ cond_func->arguments()[2], cmp_type)));
}
DBUG_RETURN(0);
}
@@ -846,6 +849,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(0); // Can't optimize this IN
}
+ if (ref_tables & ~(param->prev_tables | param->read_tables |
+ param->current_table))
+ DBUG_RETURN(0); // Can't be calculated yet
+ if (!(ref_tables & param->current_table))
+ DBUG_RETURN(new SEL_TREE(SEL_TREE::MAYBE)); // This may be false or true
+
/* check field op const */
/* btw, ft_func's arguments()[0] isn't FIELD_ITEM. SerG*/
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
@@ -877,14 +886,15 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
static SEL_TREE *
-get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
- Item_result cmp_type)
+get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
+ Item *value, Item_result cmp_type)
{
DBUG_ENTER("get_mm_parts");
if (field->table != param->table)
DBUG_RETURN(0);
- KEY_PART *key_part = param->key_parts,*end=param->key_parts_end;
+ KEY_PART *key_part = param->key_parts;
+ KEY_PART *end = param->key_parts_end;
SEL_TREE *tree=0;
if (value &&
value->used_tables() & ~(param->prev_tables | param->read_tables))
@@ -894,8 +904,8 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
if (field->eq(key_part->field))
{
SEL_ARG *sel_arg=0;
- if (!tree)
- tree=new SEL_TREE();
+ if (!tree && !(tree=new SEL_TREE()))
+ DBUG_RETURN(0); // out of memory
if (!value || !(value->used_tables() & ~param->read_tables))
{
sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value);
@@ -907,8 +917,11 @@ get_mm_parts(PARAM *param,Field *field, Item_func::Functype type,Item *value,
DBUG_RETURN(tree);
}
}
- else
- sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY);// This key may be used later
+ else {
+ // This key may be used later
+ if(!(sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY)))
+ DBUG_RETURN(0); // out of memory
+ }
sel_arg->part=(uchar) key_part->part;
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
}
@@ -995,9 +1008,8 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
DBUG_RETURN(0);
if (!maybe_null) // Not null field
DBUG_RETURN(type == Item_func::ISNULL_FUNC ? &null_element : 0);
- tree=new SEL_ARG(field,is_null_string,is_null_string);
- if (!tree)
- DBUG_RETURN(0);
+ if (!(tree=new SEL_ARG(field,is_null_string,is_null_string)))
+ DBUG_RETURN(0); // out of memory
if (type == Item_func::ISNOTNULL_FUNC)
{
tree->min_flag=NEAR_MIN; /* IS NOT NULL -> X > NULL */
@@ -1035,7 +1047,7 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
field->get_key_image(str+maybe_null,key_part->part_length,
field->charset(),key_part->image_type);
if (!(tree=new SEL_ARG(field,str,str)))
- DBUG_RETURN(0);
+ DBUG_RETURN(0); // out of memory
switch (type) {
case Item_func::LT_FUNC:
@@ -1475,7 +1487,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *key2_next=key2->next;
if (key2_shared)
{
- key2=new SEL_ARG(*key2);
+ if(!(key2=new SEL_ARG(*key2)))
+ return 0; // out of memory
key2->increment_use_count(key1->use_count+1);
key2->next=key2_next; // New copy of key2
}
@@ -2319,16 +2332,16 @@ get_quick_keys(PARAM *param,QUICK_SELECT *quick,KEY_PART *key,
}
/* Get range for retrieving rows in QUICK_SELECT::get_next */
- range= new QUICK_RANGE(param->min_key,
- (uint) (tmp_min_key - param->min_key),
- param->max_key,
- (uint) (tmp_max_key - param->max_key),
- flag);
+ if(!(range= new QUICK_RANGE(param->min_key,
+ (uint) (tmp_min_key - param->min_key),
+ param->max_key,
+ (uint) (tmp_max_key - param->max_key),
+ flag)))
+ return 1; // out of memory
+
set_if_bigger(quick->max_used_key_length,range->min_length);
set_if_bigger(quick->max_used_key_length,range->max_length);
set_if_bigger(quick->used_key_parts, (uint) key_tree->part+1);
- if (!range) // Not enough memory
- return 1;
quick->ranges.push_back(range);
end:
@@ -2389,17 +2402,17 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
uint part;
if (!quick)
- return 0;
+ return 0; /* no ranges found */
if (cp_buffer_from_ref(ref))
{
if (current_thd->is_fatal_error)
- return 0; // End of memory
+ return 0; // out of memory
return quick; // empty range
}
QUICK_RANGE *range= new QUICK_RANGE();
if (!range)
- goto err;
+ goto err; // out of memory
range->min_key=range->max_key=(char*) ref->key_buff;
range->min_length=range->max_length=ref->key_length;