From 4b245a280333cf25083ba118fa662f3ec13c9b44 Mon Sep 17 00:00:00 2001
From: "aivanov@mysql.com" <>
Date: Wed, 7 Sep 2005 17:42:47 +0400
Subject: [PATCH] join_outer.result, opt_range.cc, item_cmpfunc.cc:   Post
 merge changes sql_yacc.yy:   Post merge changes sql_select.cc:   Fixed bugs
 #12101, #12102: wrong calculation of not_null_tables()    for some
 expressions (post merge changes).    The function add_key_fields() is
 modified. There cannot be NOT before    BETWEEN/IN anymore. Rather
 Item_func_between/in objects can represent    now [NOT]BETWEEN/IN
 expressions.

---
 mysql-test/r/join_outer.result | 10 +++++-----
 sql/item_cmpfunc.cc            | 16 ++++++++--------
 sql/opt_range.cc               | 16 ++++------------
 sql/sql_select.cc              | 13 -------------
 sql/sql_yacc.yy                | 16 ++++++++--------
 5 files changed, 25 insertions(+), 46 deletions(-)

diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 6295356b80..92b352aa60 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1123,14 +1123,14 @@ a	b	a	b
 7	8	7	5
 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	
+1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	Using where
 1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	
 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	
-1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using where
+1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	Using where
+1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	
 EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b-2, t2.b, t2.b-1);
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
-1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	
-1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	Using where
+1	SIMPLE	t2	ALL	PRIMARY	NULL	NULL	NULL	4	Using where
+1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t2.a	1	
 DROP TABLE t1,t2;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 46284c422c..dfdc7319d4 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1018,9 +1018,9 @@ longlong Item_func_interval::val_int()
 */
 
 bool
-Item_func_between::fix_fields(THD *thd, struct st_table_list *tables, Item **ref)
+Item_func_between::fix_fields(THD *thd, Item **ref)
 {
-  if (Item_func_opt_neg::fix_fields(thd, tables, ref))
+  if (Item_func_opt_neg::fix_fields(thd, ref))
     return 1;
 
   /* not_null_tables_cache == union(T1(e),T1(e1),T1(e2)) */
@@ -1132,8 +1132,8 @@ longlong Item_func_between::val_int()
     a_dec= args[1]->val_decimal(&a_buf);
     b_dec= args[2]->val_decimal(&b_buf);
     if (!args[1]->null_value && !args[2]->null_value)
-      return (my_decimal_cmp(dec, a_dec)>=0) && (my_decimal_cmp(dec, b_dec)<=0);
-
+      return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
+                          my_decimal_cmp(dec, b_dec) <= 0) != negated);
     if (args[1]->null_value && args[2]->null_value)
       null_value=1;
     else if (args[1]->null_value)
@@ -1320,12 +1320,12 @@ Item_func_ifnull::str_op(String *str)
 */
 
 bool
-Item_func_if::fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
+Item_func_if::fix_fields(THD *thd, Item **ref)
 {
   DBUG_ASSERT(fixed == 0);
   args[0]->top_level_item();
 
-  if (Item_func::fix_fields(thd, tlist, ref))
+  if (Item_func::fix_fields(thd, ref))
     return 1;
 
   not_null_tables_cache= (args[1]->not_null_tables()
@@ -2305,11 +2305,11 @@ bool Item_func_in::nulls_in_row()
 */
 
 bool
-Item_func_in::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
+Item_func_in::fix_fields(THD *thd, Item **ref)
 {
   Item **arg, **arg_end;
 
-  if (Item_func_opt_neg::fix_fields(thd, tables, ref))
+  if (Item_func_opt_neg::fix_fields(thd, ref))
     return 1;
 
   /* not_null_tables_cache == union(T1(e),union(T1(ei))) */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index ecf4b5de1c..cb25025115 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3524,20 +3524,12 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
   }
 
   Item_func *cond_func= (Item_func*) cond;
-  if (cond_func->functype() == Item_func::NOT_FUNC)
-  {
-    /* Optimize NOT BETWEEN and NOT IN */
-    Item *arg= cond_func->arguments()[0];
-    if (arg->type() != Item::FUNC_ITEM)
-      DBUG_RETURN(0);
-    cond_func= (Item_func*) arg;
-    if (cond_func->functype() != Item_func::BETWEEN &&
-        cond_func->functype() != Item_func::IN_FUNC)
-      DBUG_RETURN(0);
-    inv= TRUE;
-  }
+  if (cond_func->functype() == Item_func::BETWEEN ||
+      cond_func->functype() == Item_func::IN_FUNC)
+    inv= ((Item_func_opt_neg *) cond_func)->negated;
   else if (cond_func->select_optimize() == Item_func::OPTIMIZE_NONE)
     DBUG_RETURN(0);			       
+
   param->cond= cond;
 
   switch (cond_func->functype()) {
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 0de06ea395..83a4cd4bbf 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2862,19 +2862,6 @@ add_key_fields(KEY_FIELD **key_fields,uint *and_level,
   if (cond->type() != Item::FUNC_ITEM)
     return;
   Item_func *cond_func= (Item_func*) cond;
-  if (cond_func->functype() == Item_func::NOT_FUNC)
-  {
-    Item *item= cond_func->arguments()[0];
-    /*
-      At this moment all NOT before simple comparison predicates
-      are eliminated. NOT IN and NOT BETWEEN are treated similar
-      IN and BETWEEN respectively.
-    */
-    if (item->type() == Item::FUNC_ITEM &&
-        ((Item_func *) item)->select_optimize() == Item_func::OPTIMIZE_KEY)
-      add_key_fields(key_fields,and_level,item,usable_tables);
-    return;
-  }
   switch (cond_func->select_optimize()) {
   case Item_func::OPTIMIZE_NONE:
     break;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 8723c558df..ad1fd68ddc 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4274,7 +4274,9 @@ predicate:
             else
             {
               $5->push_front($1);
-              $$= negate_expression(YYTHD, new Item_func_in(*$5));
+              Item_func_in *item = new Item_func_in(*$5);
+              item->negate();
+              $$= item;
             }            
           }
         | bit_expr IN_SYM in_subselect
@@ -4284,7 +4286,11 @@ predicate:
 	| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
 	  { $$= new Item_func_between($1,$3,$5); }
 	| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
-	  { $$= negate_expression(YYTHD, new Item_func_between($1,$4,$6)); }
+    {
+      Item_func_between *item= new Item_func_between($1,$4,$6);
+      item->negate();
+      $$= item;
+    }
 	| bit_expr SOUNDS_SYM LIKE bit_expr
 	  { $$= new Item_func_eq(new Item_func_soundex($1),
 				 new Item_func_soundex($4)); }
@@ -4350,12 +4356,6 @@ all_or_any: ALL     { $$ = 1; }
         |   ANY_SYM { $$ = 0; }
         ;
 
-
-
-
-
-
-
 interval_expr:
          INTERVAL_SYM expr { $$=$2; }
         ;
-- 
2.30.9