List:Commits« Previous MessageNext Message »
From:igor Date:April 1 2006 5:26am
Subject:bk commit into 5.0 tree (igor:1.2125) BUG#16504
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of igor. When igor does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2125 06/03/31 21:26:17 igor@stripped +9 -0
  Fixed bug #16504.
  Multiple equalities were not adjusted after reading constant tables.
  It resulted in neglecting good index based methods that could be
  used to access of other tables.

  sql/sql_select.cc
    1.403 06/03/31 21:26:11 igor@stripped +69 -9
    Fixed bug #16504.
    Adjusted multiple equalities after reading constant tables.
    Fixed a few typo in comments.

  sql/item_cmpfunc.h
    1.121 06/03/31 21:26:11 igor@stripped +1 -0
    Fixed bug #16504.
    Added method Item_equal::check_const that check appearance of new 
    constant items in a multiple equality.

  sql/item_cmpfunc.cc
    1.196 06/03/31 21:26:11 igor@stripped +35 -2
    Fixed bug #16504.
    Added method Item_equal::check_const that check appearance of new 
    constant items in a multiple equality.

  sql/item.cc
    1.211 06/03/31 21:26:11 igor@stripped +1 -1
    Fixed bug #16504.
    An Item_equal object may contain only a constant member.
    It may happen after reading constant tables.

  mysql-test/t/select.test
    1.98 06/03/31 21:26:11 igor@stripped +23 -0
    Added a test case for bug #16504.

  mysql-test/r/varbinary.result
    1.16 06/03/31 21:26:11 igor@stripped +1 -1
    Adjusted a test case results after fix for bug #16504.

  mysql-test/r/subselect.result
    1.138 06/03/31 21:26:11 igor@stripped +1 -1
    Adjusted a test case results after fix for bug #16504.

  mysql-test/r/select.result
    1.119 06/03/31 21:26:10 igor@stripped +19 -0
    Added a test case for bug #16504.

  mysql-test/r/having.result
    1.21 06/03/31 21:26:10 igor@stripped +1 -1
    Adjusted a test case results after fix for bug #16504.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	igor
# Host:	rurik.mysql.com
# Root:	/home/igor/dev/mysql-5.0-0

--- 1.210/sql/item.cc	2006-03-27 18:28:49 -08:00
+++ 1.211/sql/item.cc	2006-03-31 21:26:11 -08:00
@@ -3744,7 +3744,7 @@
   if (item_equal)
   {
     Item_field *subst= item_equal->get_first();
-    if (!field->eq(subst->field))
+    if (subst && !field->eq(subst->field))
       return subst;
   }
   return this;

--- 1.195/sql/item_cmpfunc.cc	2006-03-24 12:44:49 -08:00
+++ 1.196/sql/item_cmpfunc.cc	2006-03-31 21:26:11 -08:00
@@ -3602,7 +3602,8 @@
   Item_func_eq *func= new Item_func_eq(c, const_item);
   func->set_cmp_func();
   func->quick_fix_field();
-  cond_false =  !(func->val_int());
+  if ((cond_false= !func->val_int()))
+    const_item_cache= 1;
 }
 
 void Item_equal::add(Item_field *f)
@@ -3734,13 +3735,45 @@
   } while (swap);
 }
 
+
+/*
+  Check appearance of new constant items in the multiple equality object
+
+  SYNOPSIS
+    check()
+  
+  DESCRIPTION
+    The function checks appearance of new constant items among
+    the members of multiple equalities. Each new constant item is
+    compared with the designated constant item if there is any in the
+    multiple equality. If there is none the first new constant item
+    becomes designated.
+      
+  RETURN VALUES
+    none    
+*/
+
+void Item_equal::check_const()
+{
+  List_iterator<Item_field> it(fields);
+  Item *item;
+  while ((item= it++))
+  {
+    if (item->const_item())
+    {
+      it.remove();
+      add(item);
+    }
+  }
+}
+
 bool Item_equal::fix_fields(THD *thd, Item **ref)
 {
   List_iterator_fast<Item_field> li(fields);
   Item *item;
   not_null_tables_cache= used_tables_cache= 0;
   const_item_cache= 0;
-  while ((item=li++))
+  while ((item= li++))
   {
     table_map tmp_table_map;
     used_tables_cache|= item->used_tables();

--- 1.120/sql/item_cmpfunc.h	2006-02-25 07:46:25 -08:00
+++ 1.121/sql/item_cmpfunc.h	2006-03-31 21:26:11 -08:00
@@ -1196,6 +1196,7 @@
   bool contains(Field *field);
   Item_field* get_first() { return fields.head(); }
   void merge(Item_equal *item);
+  void check_const();
   enum Functype functype() const { return MULT_EQUAL_FUNC; }
   longlong val_int(); 
   const char *func_name() const { return "multiple equal"; }

--- 1.402/sql/sql_select.cc	2006-03-30 11:34:07 -08:00
+++ 1.403/sql/sql_select.cc	2006-03-31 21:26:11 -08:00
@@ -136,7 +136,7 @@
 end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
 
 static int test_if_group_changed(List<Cached_item> &list);
-static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
+static int join_read_const_table(JOIN *join, JOIN_TAB *tab, POSITION *pos);
 static int join_read_system(JOIN_TAB *tab);
 static int join_read_const(JOIN_TAB *tab);
 static int join_read_key(JOIN_TAB *tab);
@@ -2111,7 +2111,7 @@
     s= p_pos->table;
     s->type=JT_SYSTEM;
     join->const_table_map|=s->table->map;
-    if ((tmp=join_read_const_table(s, p_pos)))
+    if ((tmp=join_read_const_table(join, s, p_pos)))
     {
       if (tmp > 0)
 	DBUG_RETURN(1);			// Fatal error
@@ -2148,7 +2148,8 @@
 	  s->type=JT_SYSTEM;
 	  join->const_table_map|=table->map;
 	  set_position(join,const_count++,s,(KEYUSE*) 0);
-	  if ((tmp= join_read_const_table(s,join->positions+const_count-1)))
+	  if ((tmp= join_read_const_table(join, s,
+                                          join->positions+const_count-1)))
 	  {
 	    if (tmp > 0)
 	      DBUG_RETURN(1);			// Fatal error
@@ -2200,7 +2201,7 @@
 	      if (create_ref_for_key(join, s, start_keyuse,
 				     found_const_table_map))
 		DBUG_RETURN(1);
-	      if ((tmp=join_read_const_table(s,
+	      if ((tmp=join_read_const_table(join, s,
 					     join->positions+const_count-1)))
 	      {
 		if (tmp > 0)
@@ -6796,8 +6797,8 @@
       return item_equal;
     }
     /* 
-      For each field reference in cond, not from equalitym predicates,
-      set a pointer to the multiple equality if belongs to (if there is any)
+      For each field reference in cond, not from equal item predicates,
+      set a pointer to the multiple equality it belongs to (if there is any)
     */ 
     cond= cond->transform(&Item::equal_fields_propagator,
                             (byte *) inherited);
@@ -6982,7 +6983,7 @@
 
   NOTES
     Before generating an equality function checks that it has not
-    been generated for multiple equalies of the upper levels.
+    been generated for multiple equalities of the upper levels.
     E.g. for the following where condition
     WHERE a=5 AND ((a=b AND b=c) OR  c>4)
     the upper level AND condition will contain =(5,a),
@@ -7155,7 +7156,7 @@
       {
         cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
         // This occurs when eliminate_item_equal() founds that cond is
-        // always false and substitues it with Item_int 0.
+        // always false and substitutes it with Item_int 0.
         // Due to this, value of item_equal will be 0, so just return it.
         if (cond->type() != Item::COND_ITEM)
           break;
@@ -7177,6 +7178,45 @@
 }
 
 
+/* 
+  Check appearance of new constant items in multiple equalities
+  of a condition after reading a constant table
+ 
+  SYNOPSIS
+    check_const_equal_item()
+    cond       condition whose multiple equalities are to be checked
+    table      constant table that has been read 
+
+  DESCRIPTION
+    The function retrieves the cond condition and for each encountered
+    multiple equality checks whether new constants have appeared after
+    reading the constant (single row) table tab. If so it adjusts
+    the multiple equality appropriately.
+*/
+
+static void check_const_equal_items(COND *cond,
+                                    JOIN_TAB *tab)
+{
+  if (!(cond->used_tables() & tab->table->map))
+    return;
+
+  if (cond->type() == Item::COND_ITEM)
+  {
+    List<Item> *cond_list= ((Item_cond*) cond)->argument_list(); 
+    List_iterator_fast<Item> li(*cond_list);
+    Item *item;
+    while ((item= li++))
+      check_const_equal_items(item, tab);
+  }
+  else if (cond->type() == Item::FUNC_ITEM && 
+           ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
+  {
+    Item_equal *item_equal= (Item_equal *) cond;
+    item_equal->check_const();
+  }
+}
+
+
 /*
   change field = field to field = const for each found field = const in the
   and_level
@@ -10099,7 +10139,7 @@
 
 
 static int
-join_read_const_table(JOIN_TAB *tab, POSITION *pos)
+join_read_const_table(JOIN *join, JOIN_TAB *tab, POSITION *pos)
 {
   int error;
   DBUG_ENTER("join_read_const_table");
@@ -10151,6 +10191,26 @@
   }
   if (!table->null_row)
     table->maybe_null=0;
+
+  /* Check appearance of new constant items in Item_equal objects */
+  if (join->conds)
+    check_const_equal_items(join->conds, tab);
+  TABLE_LIST *tbl;
+  for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
+  {
+    TABLE_LIST *embedded;
+    TABLE_LIST *embedding= tbl;
+    do
+    {
+      embedded= embedding;
+      if (embedded->on_expr)
+         check_const_equal_items(embedded->on_expr, tab);
+      embedding= embedded->embedding;
+    }
+    while (embedding &&
+           embedding->nested_join->join_list.head() == embedded);
+  }
+
   DBUG_RETURN(0);
 }
 

--- 1.137/mysql-test/r/subselect.result	2006-03-23 06:09:27 -08:00
+++ 1.138/mysql-test/r/subselect.result	2006-03-31 21:26:11 -08:00
@@ -547,7 +547,7 @@
 1	PRIMARY	t1	const	PRIMARY,numreponse	PRIMARY	7	const,const	1	Using index
 2	SUBQUERY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Select tables optimized away
 Warnings:
-Note	1003	select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numreponse` = (select max(`test`.`t1`.`numreponse`) AS `MAX(numreponse)` from `test`.`t1` where (`test`.`t1`.`numeropost` = _latin1'1'))) and (`test`.`t1`.`numeropost` = _latin1'1'))
+Note	1003	select `test`.`t1`.`numreponse` AS `numreponse` from `test`.`t1` where ((`test`.`t1`.`numeropost` = _latin1'1'))
 drop table t1;
 CREATE TABLE t1 (a int(1));
 INSERT INTO t1 VALUES (1);

--- 1.20/mysql-test/r/having.result	2006-02-02 23:56:02 -08:00
+++ 1.21/mysql-test/r/having.result	2006-03-31 21:26:10 -08:00
@@ -12,7 +12,7 @@
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
 Warnings:
-Note	1003	select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where (`test`.`t1`.`a` = 0) having (count(`test`.`t1`.`a`) >= 0)
+Note	1003	select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (count(`test`.`t1`.`a`) >= 0)
 drop table t1;
 CREATE TABLE t1 (
 raw_id int(10) NOT NULL default '0',

--- 1.118/mysql-test/r/select.result	2006-01-13 05:27:37 -08:00
+++ 1.119/mysql-test/r/select.result	2006-03-31 21:26:10 -08:00
@@ -3371,3 +3371,22 @@
 drop table t1,t2;
 select * from (select * left join t on f1=f2) tt;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'on f1=f2) tt' at line 1
+CREATE TABLE t1 (sku int PRIMARY KEY, pr int);
+CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255));
+INSERT INTO t1 VALUES
+(10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
+INSERT INTO t2 VALUES 
+(10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
+(50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
+SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
+FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
+sku	sppr	name	sku	pr
+20	10	bbb	10	10
+20	10	bbb	20	10
+EXPLAIN
+SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
+FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	const	PRIMARY	PRIMARY	4	const	1	
+1	SIMPLE	t1	ALL	PRIMARY	NULL	NULL	NULL	6	Using where
+DROP TABLE t1,t2;

--- 1.15/mysql-test/r/varbinary.result	2004-07-19 22:48:24 -07:00
+++ 1.16/mysql-test/r/varbinary.result	2006-03-31 21:26:11 -08:00
@@ -15,7 +15,7 @@
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	const	UNIQ	UNIQ	8	const	1	
 Warnings:
-Note	1003	select `test`.`t1`.`ID` AS `ID`,`test`.`t1`.`UNIQ` AS `UNIQ` from `test`.`t1` where (`test`.`t1`.`UNIQ` = 4084688022709641610)
+Note	1003	select `test`.`t1`.`ID` AS `ID`,`test`.`t1`.`UNIQ` AS `UNIQ` from `test`.`t1` where 1
 drop table t1;
 select x'hello';
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'x'hello'' at line 1

--- 1.97/mysql-test/t/select.test	2006-01-13 05:27:37 -08:00
+++ 1.98/mysql-test/t/select.test	2006-03-31 21:26:11 -08:00
@@ -2848,3 +2848,26 @@
 #
 --error 1064
 select * from (select * left join t on f1=f2) tt;
+
+#
+# Bug #16504: re-evaluation of Item_equal object after reading const table
+#
+
+CREATE TABLE t1 (sku int PRIMARY KEY, pr int);
+CREATE TABLE t2 (sku int PRIMARY KEY, sppr int, name varchar(255));
+
+INSERT INTO t1 VALUES
+  (10, 10), (20, 10), (30, 20), (40, 30), (50, 10), (60, 10);
+
+INSERT INTO t2 VALUES 
+  (10, 10, 'aaa'), (20, 10, 'bbb'), (30, 10, 'ccc'), (40, 20, 'ddd'),
+  (50, 10, 'eee'), (60, 20, 'fff'), (70, 20, 'ggg'), (80, 30, 'hhh');
+
+SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
+  FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
+EXPLAIN
+SELECT t2.sku, t2.sppr, t2.name, t1.sku, t1.pr
+  FROM t2, t1 WHERE t2.sku=20 AND (t2.sku=t1.sku OR t2.sppr=t1.sku);
+
+
+DROP TABLE t1,t2;
Thread
bk commit into 5.0 tree (igor:1.2125) BUG#16504igor1 Apr