summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorunknown <igor@rurik.mysql.com>2004-02-18 22:21:37 -0800
committerunknown <igor@rurik.mysql.com>2004-02-18 22:21:37 -0800
commitc88e5213d4f8acbbba33d293a9573042818f0aec (patch)
tree930d3af069574ba2f718af7997089edaeb3b22fc /sql/opt_range.cc
parent4b058cba0d059ecb9dd2d69e911f0523e411b19d (diff)
downloadmariadb-git-c88e5213d4f8acbbba33d293a9573042818f0aec.tar.gz
Many files:
After review fixes for Item_equal. sql/item.cc: After review fixes for Item_equal. sql/item.h: After review fixes for Item_equal. sql/item_cmpfunc.cc: After review fixes for Item_equal. sql/item_cmpfunc.h: After review fixes for Item_equal. sql/item_func.h: After review fixes for Item_equal. sql/item_func.cc: After review fixes for Item_equal. sql/item_row.cc: After review fixes for Item_equal. sql/item_row.h: After review fixes for Item_equal. sql/item_strfunc.h: After review fixes for Item_equal. sql/opt_range.cc: After review fixes for Item_equal. sql/sql_list.h: After review fixes for Item_equal. sql/sql_select.cc: After review fixes for Item_equal. mysql-test/r/select.result: After review fixes for Item_equal. mysql-test/r/subselect.result: After review fixes for Item_equal.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc148
1 files changed, 86 insertions, 62 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 80d9bf92b45..67603eeeccd 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1494,6 +1494,21 @@ static int get_quick_select_params(SEL_TREE *tree, PARAM *param,
}
+/*
+ Build a SEL_TREE for a simple predicate
+
+ SYNOPSIS
+ get_func_mm_tree()
+ param PARAM from SQL_SELECT::test_quick_select
+ cond_func item for the predicate
+ field field in the predicate
+ value constant in the predicate
+ cmp_type compare type for the field
+
+ RETURN
+ Pointer to thre built tree
+*/
+
static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
Field *field, Item *value,
Item_result cmp_type)
@@ -1501,21 +1516,18 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
SEL_TREE *tree= 0;
DBUG_ENTER("get_func_mm_tree");
- if (cond_func->functype() == Item_func::NE_FUNC)
- {
-
+ switch (cond_func->functype()) {
+ case 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));
+ Item_func::GT_FUNC,
+ value, cmp_type));
}
- }
- else if (cond_func->functype() == Item_func::BETWEEN)
- {
-
+ break;
+ case Item_func::BETWEEN:
tree= get_mm_parts(param, field, Item_func::GE_FUNC,
cond_func->arguments()[1],cmp_type);
if (tree)
@@ -1525,30 +1537,42 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
cond_func->arguments()[2],
cmp_type));
}
- }
- else if (cond_func->functype() == Item_func::IN_FUNC)
+ break;
+ case 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++)
+ Item **arg, **end;
+ for (arg= func->arguments()+2, end= arg+func->argument_count()-2;
+ arg < end ; arg++)
{
tree= tree_or(param, tree, get_mm_parts(param, field,
Item_func::EQ_FUNC,
- func->arguments()[i],
+ *arg,
cmp_type));
}
}
+ break;
}
- else
+ default:
{
+ /*
+ Here the function for the following predicates are processed:
+ <, <=, =, >=, >, LIKE, IS NULL, IS NOT NULL.
+ If the predicate is of the form (value op field) it is handled
+ as the equivalent predicate (field rev_op value), e.g.
+ 2 <= a is handled as a >= 2.
+ */
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);
}
@@ -1625,71 +1649,71 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
DBUG_RETURN(0); // Can't be calculated
- if (cond_func->functype() == Item_func::BETWEEN)
- {
- if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
- {
- field_item= (Item_field*) (cond_func->arguments()[0]);
- value= NULL;
- }
- else
+ switch (cond_func->functype()) {
+ case Item_func::BETWEEN:
+ if (cond_func->arguments()[0]->type() != Item::FIELD_ITEM)
DBUG_RETURN(0);
- }
- else if (cond_func->functype() == Item_func::IN_FUNC)
+ field_item= (Item_field*) (cond_func->arguments()[0]);
+ value= NULL;
+ break;
+ case Item_func::IN_FUNC:
{
Item_func_in *func=(Item_func_in*) cond_func;
- if (func->key_item()->type() == Item::FIELD_ITEM)
- {
- field_item= (Item_field*) (func->key_item());
- value= NULL;
- }
- else
+ if (func->key_item()->type() != Item::FIELD_ITEM)
DBUG_RETURN(0);
+ field_item= (Item_field*) (func->key_item());
+ value= NULL;
+ break;
}
- else if (cond_func->functype() == Item_func::MULT_EQUAL_FUNC)
+ case 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)
+ DBUG_RETURN(0);
+ Item_equal_iterator it(*item_equal);
+ ref_tables= value->used_tables();
+ while ((field_item= it++))
{
- ref_tables= value->used_tables();
- Item_equal_iterator li(*item_equal);
- while ((field_item= li++))
+ Field *field= field_item->field;
+ Item_result cmp_type= field->cmp_type();
+ if (!((ref_tables | field->table->map) & param_comp))
{
- 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);
- }
- }
+ tree= get_mm_parts(param, field, Item_func::EQ_FUNC,
+ value,cmp_type);
+ ftree= !ftree ? tree : tree_and(param, ftree, tree);
}
- if (item_equal->get_const())
- break;
- value= it++;
}
+
DBUG_RETURN(ftree);
}
- 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() &&
+ default:
+ 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];
+ {
+ field_item= (Item_field*) (cond_func->arguments()[1]);
+ value= cond_func->arguments()[0];
+ }
+ else
+ DBUG_RETURN(0);
}
- else
- DBUG_RETURN(0);
+ /*
+ If the where condition contains a predicate (ti.field op const),
+ then not only SELL_TREE for this predicate is built, but
+ the trees for the results of substitution of ti.field for
+ each tj.field belonging to the same multiple equality as ti.field
+ are built as well.
+ E.g. for WHERE t1.a=t2.a AND t2.a > 10
+ a SEL_TREE for t2.a > 10 will be built for quick select from t2
+ and
+ a SEL_TREE for t1.a > 10 will be built for quick select from t1.
+ */
+
for (uint i= 0; i < cond_func->arg_count; i++)
{
Item *arg= cond_func->arguments()[i];