[Commits] Rev 3862: Fix for MDEV-4836: Merge with current 5.5 in file:///data0/psergey/dev2/5.5-pull2/

Sergey Petrunya psergey at askmonty.org
Mon Aug 26 15:32:00 EEST 2013


At file:///data0/psergey/dev2/5.5-pull2/

------------------------------------------------------------
revno: 3862 [merge]
revision-id: psergey at askmonty.org-20130826123158-016kvy1cdp3cozr9
parent: psergey at askmonty.org-20130826122314-hmnll6t7dsppg844
parent: psergey at askmonty.org-20130823123256-c4zh1ovpmuz1bgin
committer: Sergey Petrunya <psergey at askmonty.org>
branch nick: 5.5-pull2
timestamp: Mon 2013-08-26 16:31:58 +0400
message:
  Fix for MDEV-4836: Merge with current 5.5
modified:
  mysql-test/r/join_outer.result sp1f-join_outer.result-20001228015633-vk2jshiracfus3ze2d2bim2csnnrc5us
  mysql-test/r/join_outer_jcl6.result join_outer_jcl6.resu-20091221012858-uiftww98yhc31z02-1
  mysql-test/t/join_outer.test   sp1f-join_outer.test-20001228015636-himrcptylaquy6l5d7pl7pawom3ytmtw
  sql/item_cmpfunc.cc            sp1f-item_cmpfunc.cc-19700101030959-hrk7pi2n6qpwxauufnkizirsoucdcx2e
  sql/sql_select.cc              sp1f-sql_select.cc-19700101030959-egb7whpkh76zzvikycs5nsnuviu4fdlb
  sql/sql_select.h               sp1f-sql_select.h-19700101030959-oqegfxr76xlgmrzd6qlevonoibfnwzoz
=== modified file 'mysql-test/r/join_outer.result'
--- a/mysql-test/r/join_outer.result	2013-08-26 12:23:14 +0000
+++ b/mysql-test/r/join_outer.result	2013-08-26 12:31:58 +0000
@@ -2139,6 +2139,18 @@ id	select_type	table	type	possible_keys
 1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t0.a	1	Using index
 drop table t0, t1;
 #
+# MDEV-4836: Wrong result on <not null date column> IS NULL (old documented hack stopped working)
+#  (this is a regression after fix for MDEV-4817)
+#
+CREATE TABLE t1 (id INT, d DATE NOT NULL);
+INSERT INTO t1 VALUES (1,'0000-00-00'),(2,'0000-00-00');
+CREATE TABLE t2 (i INT);
+SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL;
+id	d	i
+1	0000-00-00	NULL
+2	0000-00-00	NULL
+DROP TABLE t1,t2;
+#
 # Bug mdev-4942: LEFT JOIN with conjunctive 
 #                <non-nullable datetime field> IS NULL in WHERE 
 #                causes an assert failure  

=== modified file 'mysql-test/r/join_outer_jcl6.result'
--- a/mysql-test/r/join_outer_jcl6.result	2013-08-26 12:23:14 +0000
+++ b/mysql-test/r/join_outer_jcl6.result	2013-08-26 12:31:58 +0000
@@ -2150,6 +2150,18 @@ id	select_type	table	type	possible_keys
 1	SIMPLE	t1	eq_ref	PRIMARY	PRIMARY	4	test.t0.a	1	Using index
 drop table t0, t1;
 #
+# MDEV-4836: Wrong result on <not null date column> IS NULL (old documented hack stopped working)
+#  (this is a regression after fix for MDEV-4817)
+#
+CREATE TABLE t1 (id INT, d DATE NOT NULL);
+INSERT INTO t1 VALUES (1,'0000-00-00'),(2,'0000-00-00');
+CREATE TABLE t2 (i INT);
+SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL;
+id	d	i
+1	0000-00-00	NULL
+2	0000-00-00	NULL
+DROP TABLE t1,t2;
+#
 # Bug mdev-4942: LEFT JOIN with conjunctive 
 #                <non-nullable datetime field> IS NULL in WHERE 
 #                causes an assert failure  

=== modified file 'mysql-test/t/join_outer.test'
--- a/mysql-test/t/join_outer.test	2013-08-26 12:23:14 +0000
+++ b/mysql-test/t/join_outer.test	2013-08-26 12:31:58 +0000
@@ -1686,6 +1686,15 @@ explain select * from t1 left join t0 on
 
 drop table t0, t1;
 
+--echo #
+--echo # MDEV-4836: Wrong result on <not null date column> IS NULL (old documented hack stopped working)
+--echo #  (this is a regression after fix for MDEV-4817)
+--echo #
+CREATE TABLE t1 (id INT, d DATE NOT NULL);
+INSERT INTO t1 VALUES (1,'0000-00-00'),(2,'0000-00-00');
+CREATE TABLE t2 (i INT);
+SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL;
+DROP TABLE t1,t2;
 
 --echo #
 --echo # Bug mdev-4942: LEFT JOIN with conjunctive 

=== modified file 'sql/item_cmpfunc.cc'
--- a/sql/item_cmpfunc.cc	2013-08-22 12:23:54 +0000
+++ b/sql/item_cmpfunc.cc	2013-08-26 12:31:58 +0000
@@ -4302,7 +4302,8 @@ Item_cond::fix_fields(THD *thd, Item **r
     used_tables_cache|=     item->used_tables();
     if (item->const_item())
     {
-      if (!item->is_expensive() && item->val_int() == 0)
+      if (!item->is_expensive() && !cond_is_datetime_is_null(item) && 
+          item->val_int() == 0)
       {
         /* 
           This is "... OR false_cond OR ..." 
@@ -4314,27 +4315,18 @@ Item_cond::fix_fields(THD *thd, Item **r
         /* 
           This is  "... OR const_cond OR ..."
           In this case, cond_or->not_null_tables()=0, because the condition
-          some_cond_or might be true regardless of what tables are 
-          NULL-complemented.
+          const_cond might evaluate to true (regardless of whether some tables
+          were NULL-complemented).
         */
         and_tables_cache= (table_map) 0;
       }
     }
     else
     {
-      /*
-        If an item is a 
-         - constant
-         - inexpensive 
-         - its value is 0
-        then we don't need to account it in not_null_tables_cache
-      */
-      //if (!(item->const_item() && !item->is_expensive() ))
-      {
-        table_map tmp_table_map= item->not_null_tables();
-        not_null_tables_cache|= tmp_table_map;
-        and_tables_cache&= tmp_table_map;
-      }
+      table_map tmp_table_map= item->not_null_tables();
+      not_null_tables_cache|= tmp_table_map;
+      and_tables_cache&= tmp_table_map;
+
       const_item_cache= FALSE;
     } 
   
@@ -4363,7 +4355,8 @@ Item_cond::eval_not_null_tables(uchar *o
     table_map tmp_table_map;
     if (item->const_item())
     {
-      if (!item->is_expensive() && item->val_int() == 0)
+      if (!item->is_expensive() && !cond_is_datetime_is_null(item) && 
+          item->val_int() == 0)
       {
         /* 
           This is "... OR false_cond OR ..." 

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2013-08-26 12:23:14 +0000
+++ b/sql/sql_select.cc	2013-08-26 12:31:58 +0000
@@ -13527,6 +13527,35 @@ void propagate_new_equalities(THD *thd,
 } 
 
 
+/*
+  Check if passed condtition has for of
+
+    not_null_date_col IS NULL
+
+  where not_null_date_col has a datte or datetime type
+*/
+
+bool cond_is_datetime_is_null(Item *cond)
+{
+  if (cond->type() == Item::FUNC_ITEM &&
+      ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
+  {
+    Item **args= ((Item_func_isnull*) cond)->arguments();
+    if (args[0]->type() == Item::FIELD_ITEM)
+    {
+      Field *field=((Item_field*) args[0])->field;
+
+      if (((field->type() == MYSQL_TYPE_DATE) ||
+           (field->type() == MYSQL_TYPE_DATETIME)) &&
+          (field->flags & NOT_NULL_FLAG))
+      {
+        return TRUE;
+      }
+    }
+  }
+  return FALSE;
+}
+
 
 /**
   @brief
@@ -13781,53 +13810,45 @@ internal_remove_eq_conds(THD *thd, COND
       return item;
     }
   }
-  else if (cond->type() == Item::FUNC_ITEM &&
-	   ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
+  else if (cond_is_datetime_is_null(cond))
   {
-    Item_func_isnull *func=(Item_func_isnull*) cond;
-    Item **args= func->arguments();
-    if (args[0]->type() == Item::FIELD_ITEM)
-    {
-      Field *field=((Item_field*) args[0])->field;
-      /* fix to replace 'NULL' dates with '0' (shreeve at uci.edu) */
-      /*
-        See BUG#12594011
-        Documentation says that
-        SELECT datetime_notnull d FROM t1 WHERE d IS NULL
-        shall return rows where d=='0000-00-00'
-
-        Thus, for DATE and DATETIME columns defined as NOT NULL,
-        "date_notnull IS NULL" has to be modified to
-        "date_notnull IS NULL OR date_notnull == 0" (if outer join)
-        "date_notnull == 0"                         (otherwise)
+    /* fix to replace 'NULL' dates with '0' (shreeve at uci.edu) */
+    /*
+      See BUG#12594011
+      Documentation says that
+      SELECT datetime_notnull d FROM t1 WHERE d IS NULL
+      shall return rows where d=='0000-00-00'
+
+      Thus, for DATE and DATETIME columns defined as NOT NULL,
+      "date_notnull IS NULL" has to be modified to
+      "date_notnull IS NULL OR date_notnull == 0" (if outer join)
+      "date_notnull == 0"                         (otherwise)
+
+    */
+    Item **args= ((Item_func_isnull*) cond)->arguments();
+    Field *field=((Item_field*) args[0])->field;
+
+    Item *item0= new(thd->mem_root) Item_int((longlong)0, 1);
+    Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0);
+    if (!eq_cond)
+      return cond;
 
-      */
-      if (((field->type() == MYSQL_TYPE_DATE) ||
-           (field->type() == MYSQL_TYPE_DATETIME)) &&
-          (field->flags & NOT_NULL_FLAG))
-      {
-        Item *item0= new(thd->mem_root) Item_int((longlong)0, 1);
-        Item *eq_cond= new(thd->mem_root) Item_func_eq(args[0], item0);
-        if (!eq_cond)
-          return cond;
+    if (field->table->pos_in_table_list->outer_join)
+    {
+      // outer join: transform "col IS NULL" to "col IS NULL or col=0"
+      Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond);
+      if (!or_cond)
+        return cond;
+      cond= or_cond;
+    }
+    else
+    {
+      // not outer join: transform "col IS NULL" to "col=0"
+      cond= eq_cond;
+    }
 
-        if (field->table->pos_in_table_list->outer_join)
-        {
-          // outer join: transform "col IS NULL" to "col IS NULL or col=0"
-          Item *or_cond= new(thd->mem_root) Item_cond_or(eq_cond, cond);
-          if (!or_cond)
-            return cond;
-          cond= or_cond;
-        }
-        else
-        {
-          // not outer join: transform "col IS NULL" to "col=0"
-          cond= eq_cond;
-        }
+    cond->fix_fields(thd, &cond);
 
-        cond->fix_fields(thd, &cond);
-      }
-    }
     if (cond->const_item() && !cond->is_expensive())
     {
       *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;

=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h	2013-07-16 17:09:54 +0000
+++ b/sql/sql_select.h	2013-08-23 12:32:56 +0000
@@ -1795,6 +1795,7 @@ ORDER *simple_remove_const(ORDER *order,
 bool const_expression_in_where(COND *cond, Item *comp_item,
                                Field *comp_field= NULL,
                                Item **const_item= NULL);
+bool cond_is_datetime_is_null(Item *cond);
 
 /* Table elimination entry point function */
 void eliminate_tables(JOIN *join);



More information about the commits mailing list