diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2010-02-12 00:58:23 +0300 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2010-02-12 00:58:23 +0300 |
commit | 5c836140a5e0d4f98eb2ca2981a3d7574b6fbe8c (patch) | |
tree | 3cab87ca5e2cfe5e2c3e0bf75933c060cacc9775 /sql/item_cmpfunc.h | |
parent | 64e63fb85d62420656cdb87c281d2b5da9db7666 (diff) | |
download | mariadb-git-5c836140a5e0d4f98eb2ca2981a3d7574b6fbe8c.tar.gz |
Apply Jorgen Loland's fix: Bug#45221: Query "SELECT pk FROM C WHERE pk IN (SELECT int_key)" failing
XOR conditions are not optimized, and Item_cond_xor therefore
acts like type Func_item even though it inherits from Item_cond.
A subtle difference between Item_func and Item_cond is that
you can get the children Items from the former by calling
arguments(), and from the latter by calling argument_list().
However, since Item_cond_xor inherits from Item_cond,
arguments() did not return any Items.
The fact that Item_cond_xor::arguments() did not return it's
children items lead to a problem for make_cond_for_index();
the method accepted that XOR items on unindexed columns were
pushed using ICP. ICP evaluation of non-indexed columns
does not (and should not) work.
The fix for this bug is to make Item_cond_xor return it's
children items when the arguments() method is used. This makes
Item_cond_xor behave more like Item_func and in turn allows
make_cond_for_index() to discover any conflicting children
Items.
This is a temporary fix and should be removed when Item_cond_xor
is optimized.
Diffstat (limited to 'sql/item_cmpfunc.h')
-rw-r--r-- | sql/item_cmpfunc.h | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index d093cf613f8..f01b4d6cab1 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -1715,14 +1715,34 @@ inline bool is_cond_or(Item *item) class Item_cond_xor :public Item_cond { public: - Item_cond_xor() :Item_cond() {} - Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {} + Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) + { + /* + Items must be stored in args[] as well because this Item_cond is + treated as a FUNC_ITEM (see type()). I.e., users of it will get + it's children by calling arguments(), not argument_list(). This + is a temporary solution until XOR is optimized and treated like + a full Item_cond citizen. + */ + arg_count= 2; + args= tmp_arg; + args[0]= i1; + args[1]= i2; + } enum Functype functype() const { return COND_XOR_FUNC; } /* TODO: remove the next line when implementing XOR optimization */ enum Type type() const { return FUNC_ITEM; } longlong val_int(); const char *func_name() const { return "xor"; } void top_level_item() {} + /* Since child Items are stored in args[], Items cannot be added. + However, since Item_cond_xor is treated as a FUNC_ITEM (see + type()), the methods below should never be called. + */ + bool add(Item *item) { DBUG_ASSERT(FALSE); return FALSE; } + bool add_at_head(Item *item) { DBUG_ASSERT(FALSE); return FALSE; } + bool add_at_head(List<Item> *nlist) { DBUG_ASSERT(FALSE); return FALSE; } + void copy_andor_arguments(THD *thd, Item_cond *item) { DBUG_ASSERT(FALSE); } }; |