1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug #30788: Inconsistent retrieval of char/varchar

Index lookup does not always guarantee that we can
simply remove the relevant conditions from the WHERE
clause. Reasons can be e.g. conversion errors, 
partial indexes etc. 
The optimizer was removing these parts of the WHERE 
condition without any further checking.
This leads to "false positives" when using indexes.
Fixed by checking the index reference conditions
(using WHERE) when using indexes with sub-queries.
This commit is contained in:
gkodinov/kgeorge@magare.gmz
2007-11-21 11:40:05 +02:00
parent 7ca65155ad
commit 2e2ac428ae
5 changed files with 101 additions and 21 deletions

View File

@ -217,6 +217,7 @@ static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
bool distinct, const char *message=NullS);
static Item *remove_additional_cond(Item* conds);
static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
static bool test_if_ref(Item_field *left_item,Item *right_item);
/*
@ -673,9 +674,6 @@ err:
without "checking NULL", remove the predicates that were pushed down
into the subquery.
We can remove the equalities that will be guaranteed to be true by the
fact that subquery engine will be using index lookup.
If the subquery compares scalar values, we can remove the condition that
was wrapped into trig_cond (it will be checked when needed by the subquery
engine)
@ -685,6 +683,12 @@ err:
and non-NULL values, we'll do a full table scan and will rely on the
equalities corresponding to non-NULL parts of left tuple to filter out
non-matching records.
TODO: We can remove the equalities that will be guaranteed to be true by the
fact that subquery engine will be using index lookup. This must be done only
for cases where there are no conversion errors of significance, e.g. 257
that is searched in a byte. But this requires homogenization of the return
codes of all Field*::store() methods.
*/
void JOIN::remove_subq_pushed_predicates(Item **where)
@ -692,17 +696,13 @@ void JOIN::remove_subq_pushed_predicates(Item **where)
if (conds->type() == Item::FUNC_ITEM &&
((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM)
((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
((Item_func *)conds)->arguments()[0]))
{
*where= 0;
return;
}
if (conds->type() == Item::COND_ITEM &&
((class Item_func *)this->conds)->functype() ==
Item_func::COND_AND_FUNC)
{
*where= remove_additional_cond(conds);
}
}
@ -1219,7 +1219,7 @@ JOIN::optimize()
{
if (!having)
{
Item *where= 0;
Item *where= conds;
if (join_tab[0].type == JT_EQ_REF &&
join_tab[0].ref.items[0]->name == in_left_expr_name)
{
@ -11862,8 +11862,12 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
Item *ref_item=part_of_refkey(field->table,field);
if (ref_item && ref_item->eq(right_item,1))
{
right_item= right_item->real_item();
if (right_item->type() == Item::FIELD_ITEM)
return (field->eq_def(((Item_field *) right_item)->field));
/* remove equalities injected by IN->EXISTS transformation */
else if (right_item->type() == Item::CACHE_ITEM)
return ((Item_cache *)right_item)->eq_def (field);
if (right_item->const_item() && !(right_item->is_null()))
{
/*