summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2003-11-26 17:54:20 -0800
committerunknown <igor@rurik.mysql.com>2003-11-26 17:54:20 -0800
commitc00a80999200ac936f0cfbef8f222b8a3ff75cf9 (patch)
treea91cac5023ee2fa7af51d53c7bbdfedba0e95e45 /sql/opt_range.cc
parent35eca8e13d56ab4e4dc54b52d0b8b0d4270aceb1 (diff)
parentda566c16c0c03f56caa8bd6bfd9452b73ad1a456 (diff)
downloadmariadb-git-c00a80999200ac936f0cfbef8f222b8a3ff75cf9.tar.gz
Post-merge after itroducing Item_equal
sql/item.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_select.h: Auto merged sql/opt_range.cc: Post_merge
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc225
1 files changed, 150 insertions, 75 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index a2c29a1ff6f..789c9cb9f3e 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1252,11 +1252,75 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM& param,
return result;
}
+
+static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
+ Field *field, Item *value,
+ Item_result cmp_type)
+{
+ SEL_TREE *tree= 0;
+ DBUG_ENTER("get_func_mm_tree");
+
+ if (cond_func->functype() == Item_func::NE_FUNC)
+ {
+
+ tree= get_mm_parts(param, field, Item_func::LT_FUNC,
+ value, cmp_type);
+ if (tree)
+ {
+ tree= tree_or(param, tree, get_mm_parts(param, field,
+ Item_func::GT_FUNC,
+ value, cmp_type));
+ }
+ }
+ else if (cond_func->functype() == Item_func::BETWEEN)
+ {
+
+ tree= get_mm_parts(param, field, Item_func::GE_FUNC,
+ cond_func->arguments()[1],cmp_type);
+ if (tree)
+ {
+ tree= tree_and(param, tree, get_mm_parts(param, field,
+ Item_func::LE_FUNC,
+ cond_func->arguments()[2],
+ cmp_type));
+ }
+ }
+ else if (cond_func->functype() == Item_func::IN_FUNC)
+ {
+ Item_func_in *func=(Item_func_in*) cond_func;
+ tree= get_mm_parts(param, field, Item_func::EQ_FUNC,
+ func->arguments()[1], cmp_type);
+ if (tree)
+ {
+ for (uint i =2 ; i < func->argument_count() ; i++)
+ {
+ tree= tree_or(param, tree, get_mm_parts(param, field,
+ Item_func::EQ_FUNC,
+ func->arguments()[i],
+ cmp_type));
+ }
+ }
+ }
+ else
+ {
+ Item_func::Functype func_type=
+ (value != cond_func->arguments()[0]) ? cond_func->functype() :
+ ((Item_bool_func2*) cond_func)->rev_functype();
+ tree= get_mm_parts(param, field, func_type, value, cmp_type);
+ }
+ DBUG_RETURN(tree);
+
+}
+
+
/* make a select tree of all keys in condition */
static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
{
SEL_TREE *tree=0;
+ SEL_TREE *ftree= 0;
+ Item_field *field_item= 0;
+ Item *value;
DBUG_ENTER("get_mm_tree");
if (cond->type() == Item::COND_ITEM)
@@ -1304,9 +1368,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(new SEL_TREE(SEL_TREE::IMPOSSIBLE));
}
- table_map ref_tables=cond->used_tables();
+ table_map ref_tables= 0;
+ table_map param_comp= ~(param->prev_tables | param->read_tables |
+ param->current_table);
if (cond->type() != Item::FUNC_ITEM)
{ // Should be a field
+ ref_tables= cond->used_tables();
if ((ref_tables & param->current_table) ||
(ref_tables & ~(param->prev_tables | param->read_tables)))
DBUG_RETURN(0);
@@ -1318,76 +1385,98 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
DBUG_RETURN(0); // Can't be calculated
if (cond_func->functype() == Item_func::BETWEEN)
- {
+ {
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{
- Field *field=((Item_field*) (cond_func->arguments()[0]))->field;
- Item_result cmp_type=field->cmp_type();
- 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)));
+ field_item= (Item_field*) (cond_func->arguments()[0]);
+ value= NULL;
}
- DBUG_RETURN(0);
+ else
+ DBUG_RETURN(0);
}
- if (cond_func->functype() == Item_func::IN_FUNC)
- { // COND OR
+ else if (cond_func->functype() == Item_func::IN_FUNC)
+ {
Item_func_in *func=(Item_func_in*) cond_func;
if (func->key_item()->type() == Item::FIELD_ITEM)
{
- Field *field=((Item_field*) (func->key_item()))->field;
- Item_result cmp_type=field->cmp_type();
- tree= get_mm_parts(param,field,Item_func::EQ_FUNC,
- func->arguments()[1],cmp_type);
- if (!tree)
- DBUG_RETURN(tree); // Not key field
- for (uint i=2 ; i < func->argument_count(); i++)
+ field_item= (Item_field*) (func->key_item());
+ value= NULL;
+ }
+ else
+ DBUG_RETURN(0);
+ }
+ else if (cond_func->functype() == Item_func::MULT_EQUAL_FUNC)
+ {
+ Item_equal *item_equal= (Item_equal *) cond;
+ Item_equal_iterator it(*item_equal);
+ if (!(value= item_equal->get_const()))
+ value= it++;
+ while (value)
+ {
+ ref_tables= value->used_tables();
+ Item_equal_iterator li(*item_equal);
+ while ((field_item= li++))
{
- SEL_TREE *new_tree=get_mm_parts(param,field,Item_func::EQ_FUNC,
- func->arguments()[i],cmp_type);
- tree=tree_or(param,tree,new_tree);
+ if (field_item != value)
+ {
+ Field *field= field_item->field;
+ Item_result cmp_type= field->cmp_type();
+ if (!((ref_tables | field->table->map) & param_comp))
+ {
+ tree= get_mm_parts(param, field, Item_func::EQ_FUNC,
+ value,cmp_type);
+ ftree= !ftree ? tree : tree_and(param, ftree, tree);
+ }
+ }
}
- DBUG_RETURN(tree);
- }
- 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)
- {
- tree= get_mm_parts(param,
- ((Item_field*) (cond_func->arguments()[0]))->field,
- cond_func->functype(),
- cond_func->arg_count > 1 ? cond_func->arguments()[1] :
- 0,
- ((Item_field*) (cond_func->arguments()[0]))->field->
- cmp_type());
- }
- /* check const op field */
- if (!tree &&
- cond_func->have_rev_func() &&
- cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
- {
- DBUG_RETURN(get_mm_parts(param,
- ((Item_field*)
- (cond_func->arguments()[1]))->field,
- ((Item_bool_func2*) cond_func)->rev_functype(),
- cond_func->arguments()[0],
- ((Item_field*)
- (cond_func->arguments()[1]))->field->cmp_type()
- ));
+ if (item_equal->get_const())
+ break;
+ value= it++;
+ }
+ DBUG_RETURN(ftree);
}
- DBUG_RETURN(tree);
+ else if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
+ {
+ field_item= (Item_field*) (cond_func->arguments()[0]);
+ value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
+ }
+ else if (cond_func->have_rev_func() &&
+ cond_func->arguments()[1]->type() == Item::FIELD_ITEM)
+ {
+ field_item= (Item_field*) (cond_func->arguments()[1]);
+ value= cond_func->arguments()[0];
+ }
+ else
+ DBUG_RETURN(0);
+
+ for (uint i= 0; i < cond_func->arg_count; i++)
+ {
+ Item *arg= cond_func->arguments()[i];
+ if (arg != field_item)
+ ref_tables|= arg->used_tables();
+ }
+ Field *field= field_item->field;
+ Item_result cmp_type= field->cmp_type();
+ if (!((ref_tables | field->table->map) & param_comp))
+ ftree= get_func_mm_tree(param, cond_func, field, value, cmp_type);
+ Item_equal *item_equal= field_item->item_equal;
+ if (item_equal)
+ {
+ Item_equal_iterator it(*item_equal);
+ Item_field *item;
+ while ((item= it++))
+ {
+ Field *f= item->field;
+ if (field->eq(f))
+ continue;
+ if (!((ref_tables | f->table->map) & param_comp))
+ {
+ tree= get_func_mm_tree(param, cond_func, f, value, cmp_type);
+ ftree= !ftree ? tree : tree_and(param, ftree, tree);
+ }
+ }
+ }
+ DBUG_RETURN(ftree);
}
@@ -1395,17 +1484,10 @@ static SEL_TREE *
get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
Item *value, Item_result cmp_type)
{
- bool ne_func= FALSE;
DBUG_ENTER("get_mm_parts");
if (field->table != param->table)
DBUG_RETURN(0);
- if (type == Item_func::NE_FUNC)
- {
- ne_func= TRUE;
- type= Item_func::LT_FUNC;
- }
-
KEY_PART *key_part = param->key_parts;
KEY_PART *end = param->key_parts_end;
SEL_TREE *tree=0;
@@ -1442,13 +1524,6 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
}
}
- if (ne_func)
- {
- SEL_TREE *tree2= get_mm_parts(param, field, Item_func::GT_FUNC,
- value, cmp_type);
- if (tree2)
- tree= tree_or(param,tree,tree2);
- }
DBUG_RETURN(tree);
}