1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Many files:

After review fixes for Item_equal.
This commit is contained in:
igor@rurik.mysql.com
2004-02-18 22:21:37 -08:00
parent 76e94787a2
commit 09fa16424a
14 changed files with 687 additions and 295 deletions

View File

@ -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)
{
switch (cond_func->functype()) {
case Item_func::BETWEEN:
if (cond_func->arguments()[0]->type() != Item::FIELD_ITEM)
DBUG_RETURN(0);
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)
DBUG_RETURN(0);
field_item= (Item_field*) (func->key_item());
value= NULL;
break;
}
case Item_func::MULT_EQUAL_FUNC:
{
Item_equal *item_equal= (Item_equal *) cond;
if (!(value= item_equal->get_const()))
DBUG_RETURN(0);
Item_equal_iterator it(*item_equal);
ref_tables= value->used_tables();
while ((field_item= it++))
{
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(ftree);
}
default:
if (cond_func->arguments()[0]->type() == Item::FIELD_ITEM)
{
field_item= (Item_field*) (cond_func->arguments()[0]);
value= NULL;
value= cond_func->arg_count > 1 ? cond_func->arguments()[1] : 0;
}
else
DBUG_RETURN(0);
}
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_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++))
{
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);
}
}
}
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() &&
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];