List:Commits« Previous MessageNext Message »
From:gluh Date:March 7 2006 11:25am
Subject:bk commit into 5.1 tree (gluh:1.2161) BUG#15447
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of gluh. When gluh 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.2161 06/03/07 15:25:08 gluh@stripped +11 -0
  Fix for bug#15447 Partitions: NULL is treated as zero
    NULL value handling

  sql/sql_yacc.yy
    1.473 06/03/07 15:23:15 gluh@stripped +36 -10
    Fix for bug#15447 Partitions: NULL is treated as zero
      NULL value handling

  sql/sql_show.cc
    1.317 06/03/07 15:23:15 gluh@stripped +6 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      NULL value handling

  sql/sql_partition.cc
    1.46 06/03/07 15:23:15 gluh@stripped +41 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      NULL value handling

  sql/partition_info.h
    1.4 06/03/07 15:23:15 gluh@stripped +6 -1
    Fix for bug#15447 Partitions: NULL is treated as zero
      added null value flag to partition_info object
      added has_null partition id variable

  sql/partition_element.h
    1.4 06/03/07 15:23:15 gluh@stripped +2 -1
    Fix for bug#15447 Partitions: NULL is treated as zero
      added null value flag to partition_element object

  sql/ha_partition.cc
    1.34 06/03/07 15:23:15 gluh@stripped +1 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      NULL value handling

  sql/ha_ndbcluster.cc
    1.280 06/03/07 15:23:15 gluh@stripped +1 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      NULL value handling

  mysql-test/t/partition.test
    1.19 06/03/07 15:23:15 gluh@stripped +57 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      test case

  mysql-test/t/ndb_partition_error.test
    1.5 06/03/07 15:23:15 gluh@stripped +13 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      test case

  mysql-test/r/partition.result
    1.15 06/03/07 15:23:15 gluh@stripped +49 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      test case

  mysql-test/r/ndb_partition_error.result
    1.9 06/03/07 15:23:15 gluh@stripped +9 -0
    Fix for bug#15447 Partitions: NULL is treated as zero
      test case

# 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:	gluh
# Host:	eagle.intranet.mysql.r18.ru
# Root:	/home/gluh/MySQL/Merge/5.1-new

--- 1.316/sql/sql_show.cc	Mon Mar  6 14:35:33 2006
+++ 1.317/sql/sql_show.cc	Tue Mar  7 15:23:15 2006
@@ -3832,6 +3832,12 @@ static int get_schema_partitions_record(
         uint no_items= part_elem->list_val_list.elements;
         tmp_str.length(0);
         tmp_res.length(0);
+        if (part_elem->has_null_value)
+        {
+          tmp_str.append("NULL");
+          if (no_items > 0)
+            tmp_str.append(",");
+        }
         while ((list_value= list_val_it++))
         {
           tmp_res.set(*list_value, cs);

--- 1.472/sql/sql_yacc.yy	Mon Mar  6 22:33:15 2006
+++ 1.473/sql/sql_yacc.yy	Tue Mar  7 15:23:15 2006
@@ -42,6 +42,12 @@
 #include <myisam.h>
 #include <myisammrg.h>
 
+typedef struct p_elem_val
+{ 
+  longlong value;
+  bool null_value;
+} part_elem_value;
+
 int yylex(void *yylval, void *yythd);
 
 const LEX_STRING null_lex_str={0,0};
@@ -105,6 +111,7 @@ inline Item *is_truth_value(Item *A, boo
   sp_name *spname;
   struct st_lex *lex;
   sp_head *sphead;
+  struct p_elem_val *p_elem_value;
 }
 
 %{
@@ -752,7 +759,7 @@ bool my_yyoverflow(short **a, YYSTYPE **
 %type <ulonglong_number>
 	ulonglong_num size_number
 
-%type <longlong_number>
+%type <p_elem_value>
         part_bit_expr
 
 %type <lock_type>
@@ -3781,7 +3788,7 @@ part_func_max:
 part_range_func:
         '(' part_bit_expr ')' 
         {
-          Lex->part_info->curr_part_elem->range_value= $2;
+          Lex->part_info->curr_part_elem->range_value= $2->value;
         }
         ;
 
@@ -3793,12 +3800,12 @@ part_list_func:
 part_list_item:
         part_bit_expr
         {
-          longlong *value_ptr;
-          if (!(value_ptr= (longlong*)sql_alloc(sizeof(longlong))) ||
-              ((*value_ptr= $1, FALSE) ||
-     Lex->part_info->curr_part_elem->list_val_list.push_back(value_ptr)))
+          part_elem_value *value_ptr= $1;
+          if (!value_ptr->null_value &&
+             Lex->part_info->curr_part_elem->
+              list_val_list.push_back((longlong*) &value_ptr->value))
           {
-            mem_alloc_error(sizeof(longlong));
+            mem_alloc_error(sizeof(part_elem_value));
             YYABORT;
           }
         }
@@ -3818,6 +3825,15 @@ part_bit_expr:
 
           context->table_list= 0;
           thd->where= "partition function";
+
+          part_elem_value *value_ptr= 
+            (part_elem_value*)sql_alloc(sizeof(part_elem_value));
+          if (!value_ptr)
+          {
+            mem_alloc_error(sizeof(part_elem_value));
+            YYABORT;
+          }
+
           if (part_expr->fix_fields(YYTHD, (Item**)0) ||
               ((context->table_list= save_list), FALSE) ||
               (!part_expr->const_item()) ||
@@ -3827,13 +3843,23 @@ part_bit_expr:
             YYABORT;
           }
           thd->where= save_where;
-          if (part_expr->result_type() != INT_RESULT)
+          value_ptr->value= part_expr->val_int();
+          if ((value_ptr->null_value= part_expr->null_value))
+          {
+            if (Lex->part_info->curr_part_elem->has_null_value)
+            {
+              my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+              YYABORT;
+            }
+            Lex->part_info->curr_part_elem->has_null_value= TRUE;
+          }
+          else if (part_expr->result_type() != INT_RESULT &&
+                   !part_expr->null_value)
           {
             yyerror(ER(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR));
             YYABORT;
           }
-          item_value= part_expr->val_int();
-          $$= item_value; 
+          $$= value_ptr; 
         }
         ;
 

--- 1.279/sql/ha_ndbcluster.cc	Wed Mar  1 21:23:59 2006
+++ 1.280/sql/ha_ndbcluster.cc	Tue Mar  7 15:23:15 2006
@@ -6012,6 +6012,7 @@ void ha_ndbcluster::print_error(int erro
   {
     char buf[100];
     my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
+             m_part_info->part_expr->null_value ? "NULL" :
              llstr(m_part_info->part_expr->val_int(), buf));
   }
   else

--- 1.14/mysql-test/r/partition.result	Mon Mar  6 14:35:33 2006
+++ 1.15/mysql-test/r/partition.result	Tue Mar  7 15:23:15 2006
@@ -373,4 +373,53 @@ end//
 call p()//
 drop procedure p//
 drop table t1//
+create table t1 (a int,b int,c int,key(a,b))
+partition by range (a)
+partitions 3
+(partition x1 values less than (0) tablespace ts1,
+partition x2 values less than (10) tablespace ts2,
+partition x3 values less than maxvalue tablespace ts3);
+insert into t1 values (NULL, 1, 1);
+insert into t1 values (0, 1, 1);
+insert into t1 values (12, 1, 1);
+select partition_name, partition_description, table_rows
+from information_schema.partitions where table_schema ='test';
+partition_name	partition_description	table_rows
+x1	0	1
+x2	10	1
+x3	MAXVALUE	1
+drop table t1;
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11,12),
+partition x234 values in (1 ,NULL, NULL));
+ERROR HY000: Multiple definition of same constant in list partitioning
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11, NULL),
+partition x234 values in (1 ,NULL));
+ERROR HY000: Multiple definition of same constant in list partitioning
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11, 12),
+partition x234 values in (5, 1));
+insert into t1 values (NULL,1,1);
+ERROR HY000: Table has no partition for value NULL
+drop table t1;
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11, 12),
+partition x234 values in (NULL, 1));
+insert into t1 values (11,1,6);
+insert into t1 values (NULL,1,1);
+select partition_name, partition_description, table_rows
+from information_schema.partitions where table_schema ='test';
+partition_name	partition_description	table_rows
+x123	11,12	1
+x234	NULL,1	1
+drop table t1;
 End of 5.1 tests

--- 1.18/mysql-test/t/partition.test	Wed Mar  1 12:42:26 2006
+++ 1.19/mysql-test/t/partition.test	Tue Mar  7 15:23:15 2006
@@ -483,4 +483,61 @@ drop procedure p//
 drop table t1//
 delimiter ;//
 
+#
+# Bug #15447  Partitions: NULL is treated as zero
+#
+
+# NULL for RANGE partition
+create table t1 (a int,b int,c int,key(a,b))
+partition by range (a)
+partitions 3
+(partition x1 values less than (0) tablespace ts1,
+ partition x2 values less than (10) tablespace ts2,
+ partition x3 values less than maxvalue tablespace ts3);
+
+insert into t1 values (NULL, 1, 1);
+insert into t1 values (0, 1, 1);
+insert into t1 values (12, 1, 1);
+
+select partition_name, partition_description, table_rows
+from information_schema.partitions where table_schema ='test';
+drop table t1;
+
+# NULL for LIST partition
+--error 1473
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11,12),
+ partition x234 values in (1 ,NULL, NULL));
+
+--error 1473
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11, NULL),
+ partition x234 values in (1 ,NULL));
+
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11, 12),
+ partition x234 values in (5, 1));
+--error 1504
+insert into t1 values (NULL,1,1);
+drop table t1;
+
+create table t1 (a int,b int, c int)
+partition by list(a)
+partitions 2
+(partition x123 values in (11, 12),
+ partition x234 values in (NULL, 1));
+
+insert into t1 values (11,1,6);
+insert into t1 values (NULL,1,1);
+
+select partition_name, partition_description, table_rows
+from information_schema.partitions where table_schema ='test';
+drop table t1;
+
 --echo End of 5.1 tests

--- 1.33/sql/ha_partition.cc	Sun Feb 26 01:20:52 2006
+++ 1.34/sql/ha_partition.cc	Tue Mar  7 15:23:15 2006
@@ -5092,6 +5092,7 @@ void ha_partition::print_error(int error
   {
     char buf[100];
     my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
+             m_part_info->part_expr->null_value ? "NULL" :
              llstr(m_part_info->part_expr->val_int(), buf));
   }
   else

--- 1.45/sql/sql_partition.cc	Thu Mar  2 12:23:20 2006
+++ 1.46/sql/sql_partition.cc	Tue Mar  7 15:23:15 2006
@@ -531,6 +531,7 @@ static bool check_list_constants(partiti
   bool result= TRUE;
   longlong curr_value, prev_value;
   partition_element* part_def;
+  bool found_null= FALSE;
   List_iterator<partition_element> list_func_it(part_info->partitions);
   DBUG_ENTER("check_list_constants");
 
@@ -556,6 +557,17 @@ static bool check_list_constants(partiti
   do
   {
     part_def= list_func_it++;
+    if (part_def->has_null_value)
+    {
+      if (found_null)
+      {
+        my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+        goto end;
+      }
+      part_info->has_null_value= TRUE;
+      part_info->has_null_part_id= i;
+      found_null= TRUE;
+    }
     List_iterator<longlong> list_val_it1(part_def->list_val_list);
     while (list_val_it1++)
       no_list_values++;
@@ -2041,6 +2053,16 @@ static int add_partition_values(File fpt
     err+= add_string(fptr, "VALUES IN ");
     uint no_items= p_elem->list_val_list.elements;
     err+= add_begin_parenthesis(fptr);
+    if (p_elem->has_null_value)
+    {
+      err+= add_string(fptr, "NULL");
+      if (no_items == 0)
+      {
+        err+= add_end_parenthesis(fptr);
+        goto end;
+      }
+      err+= add_comma(fptr);
+    }
     i= 0;
     do
     {
@@ -2051,6 +2073,7 @@ static int add_partition_values(File fpt
     } while (++i < no_items);
     err+= add_end_parenthesis(fptr);
   }
+end:
   return err + add_space(fptr);
 }
 
@@ -2631,6 +2654,15 @@ int get_partition_id_list(partition_info
   longlong part_func_value= part_val_int(part_info->part_expr);
   DBUG_ENTER("get_partition_id_list");
 
+  if (part_info->part_expr->null_value)
+  {
+    if (part_info->has_null_value)
+    {
+      *part_id= part_info->has_null_part_id;
+      DBUG_RETURN(0);
+    }
+    goto notfound;
+  }
   *func_value= part_func_value;
   while (max_list_index >= min_list_index)
   {
@@ -2741,6 +2773,11 @@ int get_partition_id_range(partition_inf
   longlong part_func_value= part_val_int(part_info->part_expr);
   DBUG_ENTER("get_partition_id_int_range");
 
+  if (part_info->part_expr->null_value)
+  {
+    *part_id= 0;
+    DBUG_RETURN(0);
+  }
   while (max_part_id > min_part_id)
   {
     loc_part_id= (max_part_id + min_part_id + 1) >> 1;
@@ -2814,6 +2851,10 @@ uint32 get_partition_id_range_for_endpoi
   uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
   /* Get the partitioning function value for the endpoint */
   longlong part_func_value= part_val_int(part_info->part_expr);
+
+  if (part_info->part_expr->null_value)
+    DBUG_RETURN(0);
+
   while (max_part_id > min_part_id)
   {
     loc_part_id= (max_part_id + min_part_id + 1) >> 1;

--- 1.8/mysql-test/r/ndb_partition_error.result	Tue Feb 28 15:27:45 2006
+++ 1.9/mysql-test/r/ndb_partition_error.result	Tue Mar  7 15:23:15 2006
@@ -36,3 +36,12 @@ INSERT INTO t1 VALUES (2);
 UPDATE t1 SET id=5 WHERE id=2;
 ERROR HY000: Table has no partition for value 5
 DROP TABLE t1;
+create table t1 (a int,b int, c int)
+engine = ndb
+partition by list(a)
+partitions 2
+(partition x123 values in (11, 12),
+partition x234 values in (5, 1));
+insert into t1 values (NULL,1,1);
+ERROR HY000: Table has no partition for value NULL
+drop table t1;

--- 1.4/mysql-test/t/ndb_partition_error.test	Tue Feb 28 15:27:45 2006
+++ 1.5/mysql-test/t/ndb_partition_error.test	Tue Mar  7 15:23:15 2006
@@ -56,3 +56,16 @@ INSERT INTO t1 VALUES (2);
 --error ER_NO_PARTITION_FOR_GIVEN_VALUE
 UPDATE t1 SET id=5 WHERE id=2;
 DROP TABLE t1;
+
+#
+# NULL for LIST partition
+#
+create table t1 (a int,b int, c int)
+engine = ndb
+partition by list(a)
+partitions 2
+(partition x123 values in (11, 12),
+ partition x234 values in (5, 1));
+--error 1504
+insert into t1 values (NULL,1,1);
+drop table t1;

--- 1.3/sql/partition_element.h	Wed Mar  1 01:07:00 2006
+++ 1.4/sql/partition_element.h	Tue Mar  7 15:23:15 2006
@@ -51,13 +51,14 @@ public:
   handlerton *engine_type;
   enum partition_state part_state;
   uint16 nodegroup_id;
+  bool has_null_value;
 
   partition_element()
   : part_max_rows(0), part_min_rows(0), partition_name(NULL),
     tablespace_name(NULL), range_value(0), part_comment(NULL),
     data_file_name(NULL), index_file_name(NULL),
     engine_type(NULL),part_state(PART_NORMAL),
-    nodegroup_id(UNDEF_NODEGROUP)
+    nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE)
   {
     subpartitions.empty();
     list_val_list.empty();

--- 1.3/sql/partition_info.h	Wed Mar  1 01:07:01 2006
+++ 1.4/sql/partition_info.h	Tue Mar  7 15:23:15 2006
@@ -181,6 +181,9 @@ public:
   bool linear_hash_ind;
   bool fixed;
   bool from_openfrm;
+  bool has_null_value;
+  uint has_null_part_id;
+
 
   partition_info()
   : get_partition_id(NULL), get_part_partition_id(NULL),
@@ -211,7 +214,9 @@ public:
     list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
     linear_hash_ind(FALSE),
     fixed(FALSE),
-    from_openfrm(FALSE)
+    from_openfrm(FALSE),
+    has_null_value(FALSE),
+    has_null_part_id(0)
   {
     all_fields_in_PF.clear_all();
     all_fields_in_PPF.clear_all();
Thread
bk commit into 5.1 tree (gluh:1.2161) BUG#15447gluh7 Mar