mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 20:12:31 +01:00
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.
This commit is contained in:
parent
64e63fb85d
commit
5c836140a5
2 changed files with 26 additions and 6 deletions
|
@ -1542,8 +1542,8 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN SELECT 1 FROM t1 WHERE a IN
|
||||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL PRIMARY 4 NULL 144 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 144 Using where
|
||||
1 PRIMARY t1 index PRIMARY,i2 PRIMARY 4 NULL 144 Using index
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t1)
|
||||
CREATE TABLE t2 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
|
||||
|
@ -1555,8 +1555,8 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN SELECT 1 FROM t2 WHERE a IN
|
||||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 144 Using where
|
||||
1 PRIMARY t2 index a a 5 NULL 4 Using index
|
||||
1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t2)
|
||||
SHOW VARIABLES LIKE 'old';
|
||||
Variable_name Value
|
||||
old OFF
|
||||
|
|
|
@ -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); }
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue