← Back to team overview

maria-developers team mailing list archive

Rev 2752: Apply Jorgen Loland's fix: Bug#45221: Query "SELECT pk FROM C WHERE pk IN (SELECT int_key)" failing in file:///home/psergey/dev/maria-5.3-subqueries-r6/

 

At file:///home/psergey/dev/maria-5.3-subqueries-r6/

------------------------------------------------------------
revno: 2752
revision-id: psergey@xxxxxxxxxxxx-20100211215823-63ikirl70ztmlk05
parent: psergey@xxxxxxxxxxxx-20100211215602-irdyu314ddwew1xd
committer: Sergey Petrunya <psergey@xxxxxxxxxxxx>
branch nick: maria-5.3-subqueries-r6
timestamp: Fri 2010-02-12 00:58:23 +0300
message:
  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.
=== modified file 'mysql-test/r/group_by.result'
--- a/mysql-test/r/group_by.result	2009-02-26 17:17:06 +0000
+++ b/mysql-test/r/group_by.result	2010-02-11 21:58:23 +0000
@@ -1542,8 +1542,8 @@
 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 @@
 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

=== modified file 'sql/item_cmpfunc.h'
--- a/sql/item_cmpfunc.h	2010-01-17 14:55:08 +0000
+++ b/sql/item_cmpfunc.h	2010-02-11 21:58:23 +0000
@@ -1715,14 +1715,34 @@
 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); }
 };