summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2003-12-23 02:24:12 -0800
committerunknown <igor@rurik.mysql.com>2003-12-23 02:24:12 -0800
commitb02b6c708eb56c890cbc9a08c73e9f88c4645fcb (patch)
tree5e777a4d18231796e5654856dfb16db8d8a4cd75 /sql/opt_range.cc
parentd4898d174c7e728a66831a299b8dddfd5ca6e802 (diff)
parent9c264e4ad27731b17bddf6369792c78ecc91d626 (diff)
downloadmariadb-git-b02b6c708eb56c890cbc9a08c73e9f88c4645fcb.tar.gz
Auto Merge
BitKeeper/etc/ignore: auto-union mysql-test/r/bdb.result: Auto merged mysql-test/r/func_group.result: Auto merged mysql-test/r/func_test.result: Auto merged mysql-test/r/heap_btree.result: Auto merged mysql-test/r/index_merge.result: Auto merged mysql-test/r/innodb.result: Auto merged mysql-test/r/join_outer.result: Auto merged mysql-test/r/range.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/t/range.test: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/item_func.h: Auto merged sql/item_strfunc.h: Auto merged sql/sql_list.h: Auto merged sql/sql_select.cc: Auto merged sql/sql_select.h: Auto merged sql/opt_range.cc: Merge
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc226
1 files changed, 150 insertions, 76 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index fa1b80f007e..80d9bf92b45 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1493,11 +1493,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)
@@ -1545,9 +1609,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);
@@ -1559,76 +1626,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);
}
@@ -1636,17 +1725,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;
@@ -1683,14 +1765,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);
}