List:Commits« Previous MessageNext Message »
From:Alexey Botchkov Date:October 6 2008 3:19pm
Subject:bzr push into mysql-6.0 branch (holyfoot:2846 to 2848)
View as plain text  
 2848 Alexey Botchkov	2008-10-06 [merge]
      merging
modified:
  mysql-test/r/partition.result
  mysql-test/t/partition.test
  sql/ha_partition.cc

 2847 Alexey Botchkov	2008-10-06 [merge]
      merging
modified:
  sql/opt_range.cc
  sql/partition_info.h
  sql/sql_partition.cc

 2846 Mattias Jonsson	2008-10-03 [merge]
      merge

=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2008-09-01 11:42:44 +0000
+++ b/mysql-test/r/partition.result	2008-10-06 13:16:20 +0000
@@ -1688,4 +1688,74 @@ select count(*) from t1, t2 where t1.cre
 count(*)
 1
 drop table t1, t2;
+create table t1 (s1 int) partition by hash(s1) partitions 2;
+create index i on t1 (s1);
+insert into t1 values (1);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+select * from t1;
+s1
+1
+1
+1
+1
+1
+1
+1
+1
+drop table t1;
+create table t1 (s1 int) partition by range(s1) 
+(partition pa1 values less than (10),
+partition pa2 values less than MAXVALUE);
+create index i on t1 (s1);
+insert into t1 values (1);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+select * from t1;
+s1
+1
+1
+1
+1
+1
+1
+1
+1
+drop table t1;
+create table t1 (s1 int) partition by range(s1) 
+(partition pa1 values less than (10),
+partition pa2 values less than MAXVALUE);
+create index i on t1 (s1);
+insert into t1 values (20);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+select * from t1;
+s1
+20
+20
+20
+20
+20
+20
+20
+20
+drop table t1;
+create table t1 (s1 int) partition by range(s1) 
+(partition pa1 values less than (10),
+partition pa2 values less than MAXVALUE);
+create index i on t1 (s1);
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+insert into t1 select s1 from t1 where s1=3;
+select count(*) from t1;
+count(*)
+288
+drop table t1;
 End of 5.1 tests

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2008-09-01 11:42:44 +0000
+++ b/mysql-test/t/partition.test	2008-10-06 13:16:20 +0000
@@ -1839,4 +1839,53 @@ select count(*) from t1, t2 where t1.cre
 
 drop table t1, t2;
 
+#
+# Bug #38005 Partitions: error with insert select
+#
+
+create table t1 (s1 int) partition by hash(s1) partitions 2;
+create index i on t1 (s1);
+insert into t1 values (1);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+select * from t1;
+drop table t1;
+
+create table t1 (s1 int) partition by range(s1) 
+        (partition pa1 values less than (10),
+         partition pa2 values less than MAXVALUE);
+create index i on t1 (s1);
+insert into t1 values (1);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+select * from t1;
+drop table t1;
+
+create table t1 (s1 int) partition by range(s1) 
+        (partition pa1 values less than (10),
+         partition pa2 values less than MAXVALUE);
+create index i on t1 (s1);
+insert into t1 values (20);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+select * from t1;
+drop table t1;
+
+create table t1 (s1 int) partition by range(s1) 
+        (partition pa1 values less than (10),
+         partition pa2 values less than MAXVALUE);
+create index i on t1 (s1);
+insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8);
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1;
+insert into t1 select s1 from t1 order by s1 desc;
+insert into t1 select s1 from t1 where s1=3;
+select count(*) from t1;
+drop table t1;
+
 --echo End of 5.1 tests

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2008-10-03 12:35:01 +0000
+++ b/sql/ha_partition.cc	2008-10-06 13:16:20 +0000
@@ -4305,6 +4305,17 @@ int ha_partition::handle_unordered_scan_
       break;
     case partition_index_first:
       DBUG_PRINT("info", ("index_first on partition %d", i));
+      /* MyISAM engine can fail if we call index_first() when indexes disabled */
+      /* that happens if the table is empty. */
+      /* Here we use file->stats.records instead of file->records() because */
+      /* file->records() is supposed to return an EXACT count, and it can be   */
+      /* possibly slow. We don't need an exact number, an approximate one- from*/
+      /* the last ::info() call - is sufficient. */
+      if (file->stats.records == 0)
+      {
+        error= HA_ERR_END_OF_FILE;
+        break;
+      }
       error= file->index_first(buf);
       break;
     case partition_index_first_unordered:
@@ -4392,10 +4403,32 @@ int ha_partition::handle_ordered_index_s
                                   m_start_key.flag);
       break;
     case partition_index_first:
+      /* MyISAM engine can fail if we call index_first() when indexes disabled */
+      /* that happens if the table is empty. */
+      /* Here we use file->stats.records instead of file->records() because */
+      /* file->records() is supposed to return an EXACT count, and it can be   */
+      /* possibly slow. We don't need an exact number, an approximate one- from*/
+      /* the last ::info() call - is sufficient. */
+      if (file->stats.records == 0)
+      {
+        error= HA_ERR_END_OF_FILE;
+        break;
+      }
       error= file->index_first(rec_buf_ptr);
       reverse_order= FALSE;
       break;
     case partition_index_last:
+      /* MyISAM engine can fail if we call index_last() when indexes disabled */
+      /* that happens if the table is empty. */
+      /* Here we use file->stats.records instead of file->records() because */
+      /* file->records() is supposed to return an EXACT count, and it can be   */
+      /* possibly slow. We don't need an exact number, an approximate one- from*/
+      /* the last ::info() call - is sufficient. */
+      if (file->stats.records == 0)
+      {
+        error= HA_ERR_END_OF_FILE;
+        break;
+      }
       error= file->index_last(rec_buf_ptr);
       reverse_order= TRUE;
       break;

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2008-08-25 18:23:27 +0000
+++ b/sql/opt_range.cc	2008-10-06 13:00:13 +0000
@@ -3197,10 +3197,12 @@ int find_used_partitions(PART_PRUNE_PARA
                                                        ppar->subpart_fields););
         /* Find the subpartition (it's HASH/KEY so we always have one) */
         partition_info *part_info= ppar->part_info;
-        uint32 subpart_id= part_info->get_subpartition_id(part_info);
-        
+        uint32 part_id, subpart_id;
+                 
+        if (part_info->get_subpartition_id(part_info, &subpart_id))
+          return 0;
+
         /* Mark this partition as used in each subpartition. */
-        uint32 part_id;
         while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
                 NOT_A_PARTITION_ID)
         {

=== modified file 'sql/partition_info.h'
--- a/sql/partition_info.h	2008-03-27 19:02:15 +0000
+++ b/sql/partition_info.h	2008-10-06 13:00:13 +0000
@@ -25,8 +25,9 @@ class partition_info;
 typedef int (*get_part_id_func)(partition_info *part_info,
                                  uint32 *part_id,
                                  longlong *func_value);
-typedef uint32 (*get_subpart_id_func)(partition_info *part_info);
-
+typedef int (*get_subpart_id_func)(partition_info *part_info,
+                                   uint32 *part_id);
+ 
 struct st_ddl_log_memory_entry;
 
 class partition_info : public Sql_alloc

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2008-09-04 18:30:34 +0000
+++ b/sql/sql_partition.cc	2008-10-06 13:00:13 +0000
@@ -74,10 +74,8 @@ static int get_part_id_charset_func_subp
 static int get_part_part_id_charset_func(partition_info *part_info,
                                          uint32 *part_id,
                                          longlong *func_value);
-static uint32 get_subpart_id_charset_func(partition_info *part_info);
-int get_partition_id_list(partition_info *part_info,
-                          uint32 *part_id,
-                          longlong *func_value);
+static int get_subpart_id_charset_func(partition_info *part_info,
+                                       uint32 *part_id);
 int get_partition_id_list(partition_info *part_info,
                           uint32 *part_id,
                           longlong *func_value);
@@ -120,10 +118,14 @@ int get_partition_id_list_sub_linear_has
 int get_partition_id_list_sub_linear_key(partition_info *part_info,
                                          uint32 *part_id,
                                          longlong *func_value);
-uint32 get_partition_id_hash_sub(partition_info *part_info); 
-uint32 get_partition_id_key_sub(partition_info *part_info); 
-uint32 get_partition_id_linear_hash_sub(partition_info *part_info); 
-uint32 get_partition_id_linear_key_sub(partition_info *part_info); 
+int get_partition_id_hash_sub(partition_info *part_info,
+                              uint32 *part_id); 
+int get_partition_id_key_sub(partition_info *part_info,
+                             uint32 *part_id); 
+int get_partition_id_linear_hash_sub(partition_info *part_info,
+                                     uint32 *part_id); 
+int get_partition_id_linear_key_sub(partition_info *part_info,
+                                    uint32 *part_id); 
 static uint32 get_next_partition_via_walking(PARTITION_ITERATOR*);
 static void set_up_range_analysis_info(partition_info *part_info);
 static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*);
@@ -2234,17 +2236,24 @@ bool partition_key_modified(TABLE *table
   SYNOPSIS
     part_val_int()
     item_expr                 The item expression to evaluate
+    out:result                The value of the partition function,
+                                LONGLONG_MIN if any null value in function
   RETURN VALUES
-    The value of the partition function, LONGLONG_MIN if any null value
-    in function
+    TRUE      Error in val_int()
+    FALSE     ok
 */
 
-static inline longlong part_val_int(Item *item_expr)
+static inline int part_val_int(Item *item_expr, longlong *result)
 {
-  longlong value= item_expr->val_int();
+  *result= item_expr->val_int();
   if (item_expr->null_value)
-    value= LONGLONG_MIN;
-  return value;
+  {
+    if (current_thd->is_error())
+      return TRUE;
+    else
+      *result= LONGLONG_MIN;
+  }
+  return FALSE;
 }
 
 /*
@@ -2294,24 +2303,29 @@ static uint32 get_part_id_for_sub(uint32
     get_part_id_hash()
     no_parts                 Number of hash partitions
     part_expr                Item tree of hash function
-    out:func_value      Value of hash function
+    out:part_id              The returned partition id
+    out:func_value           Value of hash function
 
   RETURN VALUE
-    Calculated partition id
+    != 0                          Error code
+    FALSE                         Success
 */
 
-inline
-static uint32 get_part_id_hash(uint no_parts,
-                               Item *part_expr,
-                               longlong *func_value)
+static int get_part_id_hash(uint no_parts,
+                            Item *part_expr,
+                            uint32 *part_id,
+                            longlong *func_value)
 {
   longlong int_hash_id;
   DBUG_ENTER("get_part_id_hash");
 
-  *func_value= part_val_int(part_expr);
+  if (part_val_int(part_expr, func_value))
+    DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+
   int_hash_id= *func_value % no_parts;
 
-  DBUG_RETURN(int_hash_id < 0 ? (uint32) -int_hash_id : (uint32) int_hash_id);
+  *part_id= int_hash_id < 0 ? (uint32) -int_hash_id : (uint32) int_hash_id;
+  DBUG_RETURN(FALSE);
 }
 
 
@@ -2324,24 +2338,29 @@ static uint32 get_part_id_hash(uint no_p
                         desired information is given
     no_parts            Number of hash partitions
     part_expr           Item tree of hash function
+    out:part_id         The returned partition id
     out:func_value      Value of hash function
 
   RETURN VALUE
-    Calculated partition id
+    != 0     Error code
+    0        OK
 */
 
-inline
-static uint32 get_part_id_linear_hash(partition_info *part_info,
-                                      uint no_parts,
-                                      Item *part_expr,
-                                      longlong *func_value)
+static int get_part_id_linear_hash(partition_info *part_info,
+                                   uint no_parts,
+                                   Item *part_expr,
+                                   uint32 *part_id,
+                                   longlong *func_value)
 {
   DBUG_ENTER("get_part_id_linear_hash");
 
-  *func_value= part_val_int(part_expr);
-  DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
-                                           part_info->linear_hash_mask,
-                                           no_parts));
+  if (part_val_int(part_expr, func_value))
+    DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+
+  *part_id= get_part_id_from_linear_hash(*func_value,
+                                         part_info->linear_hash_mask,
+                                         no_parts);
+  DBUG_RETURN(FALSE);
 }
 
 
@@ -2481,49 +2500,7 @@ static void restore_part_field_pointers(
   }
   return;
 }
-/*
-  This function is used to calculate the partition id where all partition
-  fields have been prepared to point to a record where the partition field
-  values are bound.
 
-  SYNOPSIS
-    get_partition_id()
-    part_info           A reference to the partition_info struct where all the
-                        desired information is given
-    out:part_id         The partition id is returned through this pointer
-    out: func_value     Value of partition function (longlong)
-
-  RETURN VALUE
-    part_id                     Partition id of partition that would contain
-                                row with given values of PF-fields
-    HA_ERR_NO_PARTITION_FOUND   The fields of the partition function didn't
-                                fit into any partition and thus the values of 
-                                the PF-fields are not allowed.
-
-  DESCRIPTION
-    A routine used from write_row, update_row and delete_row from any
-    handler supporting partitioning. It is also a support routine for
-    get_partition_set used to find the set of partitions needed to scan
-    for a certain index scan or full table scan.
-    
-    It is actually 14 different variants of this function which are called
-    through a function pointer.
-
-    get_partition_id_list
-    get_partition_id_range
-    get_partition_id_hash_nosub
-    get_partition_id_key_nosub
-    get_partition_id_linear_hash_nosub
-    get_partition_id_linear_key_nosub
-    get_partition_id_range_sub_hash
-    get_partition_id_range_sub_key
-    get_partition_id_range_sub_linear_hash
-    get_partition_id_range_sub_linear_key
-    get_partition_id_list_sub_hash
-    get_partition_id_list_sub_key
-    get_partition_id_list_sub_linear_hash
-    get_partition_id_list_sub_linear_key
-*/
 
 /*
   This function is used to calculate the main partition to use in the case of
@@ -2535,14 +2512,13 @@ static void restore_part_field_pointers(
     part_info           A reference to the partition_info struct where all the
                         desired information is given
     out:part_id         The partition id is returned through this pointer
-    out: func_value     The value calculated by partition function
+    out:func_value      The value calculated by partition function
 
   RETURN VALUE
-    part_id                     Partition id of partition that would contain
-                                row with given values of PF-fields
     HA_ERR_NO_PARTITION_FOUND   The fields of the partition function didn't
                                 fit into any partition and thus the values of 
                                 the PF-fields are not allowed.
+    0                           OK
 
   DESCRIPTION
     
@@ -2622,14 +2598,15 @@ static int get_part_part_id_charset_func
 }
 
 
-static uint32 get_subpart_id_charset_func(partition_info *part_info)
+static int get_subpart_id_charset_func(partition_info *part_info,
+                                       uint32 *part_id)
 {
   int res;
   DBUG_ENTER("get_subpart_id_charset_func");
   copy_to_part_field_buffers(part_info->subpart_charset_field_array,
                              part_info->subpart_field_buffers,
                              part_info->restore_subpart_field_ptrs);
-  res= part_info->get_subpartition_id_charset(part_info);
+  res= part_info->get_subpartition_id_charset(part_info, part_id);
   restore_part_field_pointers(part_info->subpart_charset_field_array,
                               part_info->restore_subpart_field_ptrs);
   DBUG_RETURN(res);
@@ -2644,11 +2621,15 @@ int get_partition_id_list(partition_info
   int list_index;
   int min_list_index= 0;
   int max_list_index= part_info->no_list_values - 1;
-  longlong part_func_value= part_val_int(part_info->part_expr);
+  longlong part_func_value;
+  int error= part_val_int(part_info->part_expr, &part_func_value);
   longlong list_value;
   bool unsigned_flag= part_info->part_expr->unsigned_flag;
   DBUG_ENTER("get_partition_id_list");
 
+  if (error)
+    goto notfound;
+
   if (part_info->part_expr->null_value)
   {
     if (part_info->has_null_value)
@@ -2793,10 +2774,14 @@ int get_partition_id_range(partition_inf
   uint min_part_id= 0;
   uint max_part_id= max_partition;
   uint loc_part_id;
-  longlong part_func_value= part_val_int(part_info->part_expr);
+  longlong part_func_value;
+  int error= part_val_int(part_info->part_expr, &part_func_value);
   bool unsigned_flag= part_info->part_expr->unsigned_flag;
   DBUG_ENTER("get_partition_id_range");
 
+  if (error)
+    DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+
   if (part_info->part_expr->null_value)
   {
     *part_id= 0;
@@ -2955,9 +2940,8 @@ int get_partition_id_hash_nosub(partitio
                                 uint32 *part_id,
                                 longlong *func_value)
 {
-  *part_id= get_part_id_hash(part_info->no_parts, part_info->part_expr,
-                             func_value);
-  return 0;
+  return get_part_id_hash(part_info->no_parts, part_info->part_expr,
+                          part_id, func_value);
 }
 
 
@@ -2965,9 +2949,8 @@ int get_partition_id_linear_hash_nosub(p
                                        uint32 *part_id,
                                        longlong *func_value)
 {
-  *part_id= get_part_id_linear_hash(part_info, part_info->no_parts,
-                                    part_info->part_expr, func_value);
-  return 0;
+  return get_part_id_linear_hash(part_info, part_info->no_parts,
+                                 part_info->part_expr, part_id, func_value);
 }
 
 
@@ -3009,8 +2992,12 @@ int get_partition_id_range_sub_hash(part
     DBUG_RETURN(error);
   }
   no_subparts= part_info->no_subparts;
-  sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr,
-                                &local_func_value);
+  if (unlikely((error= get_part_id_hash(no_subparts, part_info->subpart_expr,
+                                        &sub_part_id, &local_func_value))))
+  {
+    DBUG_RETURN(error);
+  }
+
   *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
   DBUG_RETURN(0);
 }
@@ -3032,9 +3019,14 @@ int get_partition_id_range_sub_linear_ha
     DBUG_RETURN(error);
   }
   no_subparts= part_info->no_subparts;
-  sub_part_id= get_part_id_linear_hash(part_info, no_subparts,
-                                       part_info->subpart_expr,
-                                       &local_func_value);
+  if (unlikely((error= get_part_id_linear_hash(part_info, no_subparts,
+                                               part_info->subpart_expr,
+                                               &sub_part_id,
+                                               &local_func_value))))
+  {
+    DBUG_RETURN(error);
+  }
+
   *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
   DBUG_RETURN(0);
 }
@@ -3104,8 +3096,12 @@ int get_partition_id_list_sub_hash(parti
     DBUG_RETURN(error);
   }
   no_subparts= part_info->no_subparts;
-  sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr,
-                                &local_func_value);
+  if (unlikely((error= get_part_id_hash(no_subparts, part_info->subpart_expr,
+                                        &sub_part_id, &local_func_value))))
+  {
+    DBUG_RETURN(error);
+  }
+
   *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
   DBUG_RETURN(0);
 }
@@ -3127,9 +3123,14 @@ int get_partition_id_list_sub_linear_has
     DBUG_RETURN(error);
   }
   no_subparts= part_info->no_subparts;
-  sub_part_id= get_part_id_linear_hash(part_info, no_subparts,
-                                       part_info->subpart_expr,
-                                       &local_func_value);
+  if (unlikely((error= get_part_id_linear_hash(part_info, no_subparts,
+                                               part_info->subpart_expr,
+                                               &sub_part_id,
+                                               &local_func_value))))
+  {
+    DBUG_RETURN(error);
+  }
+   
   *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
   DBUG_RETURN(0);
 }
@@ -3207,37 +3208,44 @@ int get_partition_id_list_sub_linear_key
     get_partition_id_linear_key_sub
 */
 
-uint32 get_partition_id_hash_sub(partition_info *part_info)
+int get_partition_id_hash_sub(partition_info *part_info,
+                              uint32 *part_id)
 {
   longlong func_value;
   return get_part_id_hash(part_info->no_subparts, part_info->subpart_expr,
-                          &func_value);
+                          part_id, &func_value);
 }
 
 
-uint32 get_partition_id_linear_hash_sub(partition_info *part_info)
+int get_partition_id_linear_hash_sub(partition_info *part_info,
+                                     uint32 *part_id)
 {
   longlong func_value;
   return get_part_id_linear_hash(part_info, part_info->no_subparts,
-                                 part_info->subpart_expr, &func_value);
+                                 part_info->subpart_expr, part_id,
+                                 &func_value);
 }
 
 
-uint32 get_partition_id_key_sub(partition_info *part_info)
+int get_partition_id_key_sub(partition_info *part_info,
+                             uint32 *part_id)
 {
   longlong func_value;
-  return get_part_id_key(part_info->table->file,
-                         part_info->subpart_field_array,
-                         part_info->no_subparts, &func_value);
+  *part_id= get_part_id_key(part_info->table->file,
+                            part_info->subpart_field_array,
+                            part_info->no_subparts, &func_value);
+  return FALSE;
 }
 
 
-uint32 get_partition_id_linear_key_sub(partition_info *part_info)
+int get_partition_id_linear_key_sub(partition_info *part_info,
+                                       uint32 *part_id)
 {
   longlong func_value;
-  return get_part_id_linear_key(part_info,
-                                part_info->subpart_field_array,
-                                part_info->no_subparts, &func_value);
+  *part_id= get_part_id_linear_key(part_info,
+                                   part_info->subpart_field_array,
+                                   part_info->no_subparts, &func_value);
+  return FALSE;
 }
 
 
@@ -3326,37 +3334,40 @@ static bool check_part_func_bound(Field 
     buf           A buffer that can be used to evaluate the partition function
     key_info      The index object
     key_spec      A key_range containing key and key length
+    out:part_id   The returned partition id
 
   RETURN VALUES
-    part_id       Subpartition id to use
+    TRUE                    All fields in partition function are set
+    FALSE                   Not all fields in partition function are set
 
   DESCRIPTION
     Use key buffer to set-up record in buf, move field pointers and
     get the partition identity and restore field pointers afterwards.
 */
 
-static uint32 get_sub_part_id_from_key(const TABLE *table,uchar *buf,
-                                       KEY *key_info,
-                                       const key_range *key_spec)
+static int get_sub_part_id_from_key(const TABLE *table,uchar *buf,
+                                    KEY *key_info,
+                                    const key_range *key_spec,
+                                    uint32 *part_id)
 {
   uchar *rec0= table->record[0];
   partition_info *part_info= table->part_info;
-  uint32 part_id;
+  int res;
   DBUG_ENTER("get_sub_part_id_from_key");
 
   key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length);
   if (likely(rec0 == buf))
   {
-    part_id= part_info->get_subpartition_id(part_info);
+    res= part_info->get_subpartition_id(part_info, part_id);
   }
   else
   {
     Field **part_field_array= part_info->subpart_field_array;
     set_field_ptr(part_field_array, buf, rec0);
-    part_id= part_info->get_subpartition_id(part_info);
+    res= part_info->get_subpartition_id(part_info, part_id);
     set_field_ptr(part_field_array, rec0, buf);
   }
-  DBUG_RETURN(part_id);
+  DBUG_RETURN(res);
 }
 
 /*
@@ -3575,7 +3586,13 @@ void get_partition_set(const TABLE *tabl
       else if (part_info->is_sub_partitioned())
       {
         if (part_info->all_fields_in_SPF.is_set(index))
-          sub_part= get_sub_part_id_from_key(table, buf, key_info, key_spec);
+        {
+          if (get_sub_part_id_from_key(table, buf, key_info, key_spec, &sub_part))
+          {
+            part_spec->start_part= no_parts;
+            DBUG_VOID_RETURN;
+          }
+        }
         else if (part_info->all_fields_in_PPF.is_set(index))
         {
           if (get_part_id_from_key(table,buf,key_info,
@@ -3621,7 +3638,14 @@ void get_partition_set(const TABLE *tabl
         else if (part_info->is_sub_partitioned())
         {
           if (check_part_func_bound(part_info->subpart_field_array))
-            sub_part= get_sub_part_id_from_key(table, buf, key_info, key_spec);
+          {
+            if (get_sub_part_id_from_key(table, buf, key_info, key_spec, &sub_part))
+            {
+              part_spec->start_part= no_parts;
+              clear_indicator_in_key_fields(key_info);
+              DBUG_VOID_RETURN;
+            }
+          }
           else if (check_part_func_bound(part_info->part_field_array))
           {
             if (get_part_id_from_key(table,buf,key_info,key_spec,&part_part))
@@ -6824,9 +6848,11 @@ int get_part_iter_for_interval_via_walki
     field->set_null();
     if (is_subpart)
     {
-      part_id= part_info->get_subpartition_id(part_info);
-      init_single_partition_iterator(part_id, part_iter);
-      DBUG_RETURN(1); /* Ok, iterator initialized */
+      if (!part_info->get_subpartition_id(part_info, &part_id))
+      {
+        init_single_partition_iterator(part_id, part_iter);
+        DBUG_RETURN(1); /* Ok, iterator initialized */
+      }
     }
     else
     {
@@ -6997,13 +7023,18 @@ static uint32 get_next_partition_via_wal
 static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter)
 {
   Field *field= part_iter->part_info->subpart_field_array[0];
+  uint32 res;
   if (part_iter->field_vals.cur == part_iter->field_vals.end)
   {
     part_iter->field_vals.cur= part_iter->field_vals.start;
     return NOT_A_PARTITION_ID;
   }
   field->store(part_iter->field_vals.cur++, FALSE);
-  return part_iter->part_info->get_subpartition_id(part_iter->part_info);
+  if (part_iter->part_info->get_subpartition_id(part_iter->part_info,
+                                                &res))
+    return NOT_A_PARTITION_ID;
+  return res;
+
 }
 
 

Thread
bzr push into mysql-6.0 branch (holyfoot:2846 to 2848) Alexey Botchkov6 Oct