List:Commits« Previous MessageNext Message »
From:reggie Date:February 24 2006 12:50pm
Subject:bk commit into 5.1 tree (reggie:1.2163) BUG#17432
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of reggie. When reggie 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.2163 06/02/24 06:50:25 reggie@stripped +3 -0
  BUG#  17430 Partitoins: crash on SELECT * FROM t1 WHERE f_int1 IS NULL
  BUG# 17432: Partitions: wrong result, SELECT ... WHERE <column> is null

  sql/sql_partition.cc
    1.38 06/02/24 06:50:17 reggie@stripped +29 -6
    improve null handling by returning LONGLONG_MIN for values that are NULL

  mysql-test/t/partition.test
    1.17 06/02/24 06:50:17 reggie@stripped +40 -0
    test cases for bug #17432 and 17430

  mysql-test/r/partition.result
    1.13 06/02/24 06:50:16 reggie@stripped +33 -0
    result block for tests

# 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:	reggie
# Host:	linux.site
# Root:	/home/reggie/work/mysql-5.1-release

--- 1.12/mysql-test/r/partition.result	2006-02-17 13:06:00 -06:00
+++ 1.13/mysql-test/r/partition.result	2006-02-24 06:50:16 -06:00
@@ -315,4 +315,37 @@
 create table t1 (s1 int, unique (s1)) partition by list (s1) (partition x1 VALUES in (10), partition x2 values in (20));
 alter table t1 add partition (partition x3 values in (30));
 drop table t1;
+CREATE TABLE t1 (
+f_int1 INTEGER, f_int2 INTEGER,
+f_char1 CHAR(10), f_char2 CHAR(10), f_charbig VARCHAR(1000)
+)
+PARTITION BY RANGE(f_int1 DIV 2)
+SUBPARTITION BY HASH(f_int1)
+SUBPARTITIONS 2
+(PARTITION parta VALUES LESS THAN (0),
+PARTITION partb VALUES LESS THAN (5),
+PARTITION parte VALUES LESS THAN (10),
+PARTITION partf VALUES LESS THAN (2147483647));
+INSERT INTO t1 SET f_int1 = NULL , f_int2 = -20, f_char1 = CAST(-20 AS CHAR),
+f_char2 = CAST(-20 AS CHAR), f_charbig = '#NULL#';
+SELECT * FROM t1 WHERE f_int1 IS NULL;
+f_int1	f_int2	f_char1	f_char2	f_charbig
+NULL	-20	-20	-20	#NULL#
+SELECT * FROM t1;
+f_int1	f_int2	f_char1	f_char2	f_charbig
+NULL	-20	-20	-20	#NULL#
+drop table t1;
+CREATE TABLE t1 (
+f_int1 INTEGER, f_int2 INTEGER,
+f_char1 CHAR(10), f_char2 CHAR(10), f_charbig VARCHAR(1000)  )
+PARTITION BY LIST(MOD(f_int1,2))
+SUBPARTITION BY KEY(f_int1)
+(PARTITION part1 VALUES IN (-1) (SUBPARTITION sp1, SUBPARTITION sp2),
+PARTITION part2 VALUES IN (0) (SUBPARTITION sp3, SUBPARTITION sp5),
+PARTITION part3 VALUES IN (1) (SUBPARTITION sp4, SUBPARTITION sp6));
+INSERT INTO t1 SET f_int1 = 2, f_int2 = 2, f_char1 = '2', f_char2 = '2', f_charbig = '===2===';
+INSERT INTO t1 SET f_int1 = 2, f_int2 = 2, f_char1 = '2', f_char2 = '2', f_charbig = '===2===';
+SELECT * FROM t1 WHERE f_int1  IS NULL;
+f_int1	f_int2	f_char1	f_char2	f_charbig
+drop table t1;
 End of 5.1 tests

--- 1.16/mysql-test/t/partition.test	2006-02-16 10:15:32 -06:00
+++ 1.17/mysql-test/t/partition.test	2006-02-24 06:50:17 -06:00
@@ -408,4 +408,44 @@
 alter table t1 add partition (partition x3 values in (30));
 drop table t1;
 
+#
+# Bug #17432: Partition functions containing NULL values should return
+#             LONGLONG_MIN
+#
+CREATE TABLE t1 (
+ f_int1 INTEGER, f_int2 INTEGER,
+ f_char1 CHAR(10), f_char2 CHAR(10), f_charbig VARCHAR(1000)
+ )
+ PARTITION BY RANGE(f_int1 DIV 2)
+ SUBPARTITION BY HASH(f_int1)
+ SUBPARTITIONS 2
+ (PARTITION parta VALUES LESS THAN (0),
+  PARTITION partb VALUES LESS THAN (5),
+  PARTITION parte VALUES LESS THAN (10),
+  PARTITION partf VALUES LESS THAN (2147483647));
+INSERT INTO t1 SET f_int1 = NULL , f_int2 = -20, f_char1 = CAST(-20 AS CHAR),
+                   f_char2 = CAST(-20 AS CHAR), f_charbig = '#NULL#';
+SELECT * FROM t1 WHERE f_int1 IS NULL;
+SELECT * FROM t1;
+drop table t1;
+
+#
+# Bug 17430: Crash when SELECT * from t1 where field IS NULL
+#
+
+CREATE TABLE t1 (
+ f_int1 INTEGER, f_int2 INTEGER,
+ f_char1 CHAR(10), f_char2 CHAR(10), f_charbig VARCHAR(1000)  )
+ PARTITION BY LIST(MOD(f_int1,2))
+ SUBPARTITION BY KEY(f_int1)
+ (PARTITION part1 VALUES IN (-1) (SUBPARTITION sp1, SUBPARTITION sp2),
+  PARTITION part2 VALUES IN (0) (SUBPARTITION sp3, SUBPARTITION sp5),
+  PARTITION part3 VALUES IN (1) (SUBPARTITION sp4, SUBPARTITION sp6));
+
+INSERT INTO t1 SET f_int1 = 2, f_int2 = 2, f_char1 = '2', f_char2 = '2', f_charbig = '===2===';
+INSERT INTO t1 SET f_int1 = 2, f_int2 = 2, f_char1 = '2', f_char2 = '2', f_charbig = '===2===';
+
+SELECT * FROM t1 WHERE f_int1  IS NULL;
+drop table t1;
+
 --echo End of 5.1 tests

--- 1.37/sql/sql_partition.cc	2006-02-15 05:52:22 -06:00
+++ 1.38/sql/sql_partition.cc	2006-02-24 06:50:17 -06:00
@@ -2630,6 +2630,29 @@
 
 
 /*
+  A function to handle correct handling of NULL values in partition
+  functions.
+  SYNOPSIS
+    part_val_int()
+    item_expr                 The item expression to evaluate
+  RETURN VALUES
+    The value of the partition function, LONGLONG_MIN if any null value
+    in function
+*/
+
+static
+inline
+longlong
+part_val_int(Item *item_expr)
+{
+  longlong value= item_expr->val_int();
+  if (item_expr->null_value)
+    value= LONGLONG_MIN;
+  return value;
+}
+
+
+/*
   The next set of functions are used to calculate the partition identity.
   A handler sets up a variable that corresponds to one of these functions
   to be able to quickly call it whenever the partition id needs to calculated
@@ -2725,7 +2748,7 @@
                                longlong *func_value)
 {
   DBUG_ENTER("get_part_id_hash");
-  *func_value= part_expr->val_int();
+  *func_value= part_val_int(part_expr);
   longlong int_hash_id= *func_value % no_parts;
   DBUG_RETURN(int_hash_id < 0 ? -int_hash_id : int_hash_id);
 }
@@ -2754,7 +2777,7 @@
 {
   DBUG_ENTER("get_part_id_linear_hash");
 
-  *func_value= part_expr->val_int();
+  *func_value= part_val_int(part_expr);
   DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
                                            part_info->linear_hash_mask,
                                            no_parts));
@@ -2892,7 +2915,7 @@
   longlong list_value;
   int min_list_index= 0;
   int max_list_index= part_info->no_list_values - 1;
-  longlong part_func_value= part_info->part_expr->val_int();
+  longlong part_func_value= part_val_int(part_info->part_expr);
   DBUG_ENTER("get_partition_id_list");
 
   *func_value= part_func_value;
@@ -2968,7 +2991,7 @@
   longlong list_value;
   uint min_list_index= 0, max_list_index= part_info->no_list_values - 1;
   /* Get the partitioning function value for the endpoint */
-  longlong part_func_value= part_info->part_expr->val_int();
+  longlong part_func_value= part_val_int(part_info->part_expr);
   while (max_list_index >= min_list_index)
   {
     list_index= (max_list_index + min_list_index) >> 1;
@@ -3002,7 +3025,7 @@
   uint min_part_id= 0;
   uint max_part_id= max_partition;
   uint loc_part_id;
-  longlong part_func_value= part_info->part_expr->val_int();
+  longlong part_func_value= part_val_int(part_info->part_expr);
   DBUG_ENTER("get_partition_id_int_range");
 
   while (max_part_id > min_part_id)
@@ -3077,7 +3100,7 @@
   uint max_partition= part_info->no_parts - 1;
   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_info->part_expr->val_int();
+  longlong part_func_value= part_val_int(part_info->part_expr);
   while (max_part_id > min_part_id)
   {
     loc_part_id= (max_part_id + min_part_id + 1) >> 1;
Thread
bk commit into 5.1 tree (reggie:1.2163) BUG#17432reggie24 Feb