List:Commits« Previous MessageNext Message »
From:reggie Date:March 31 2006 5:39pm
Subject:bk commit into 5.1 tree (reggie:1.2261)
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.2261 06/03/31 11:39:44 reggie@stripped +4 -0
  cleaned up a few method comments
  moved several functions from sql_partition to be member functions

  sql/sql_table.cc
    1.321 06/03/31 11:39:35 reggie@stripped +1 -1
    calling the member func now instead

  sql/sql_partition.cc
    1.59 06/03/31 11:39:35 reggie@stripped +5 -382
    move these funcs from sql_partition to this class

  sql/partition_info.h
    1.6 06/03/31 11:39:35 reggie@stripped +6 -0
    move these funcs from sql_partition to this class

  sql/partition_info.cc
    1.8 06/03/31 11:39:35 reggie@stripped +358 -3
    cleaned up a few method comments
    moved several functions from sql_partition to be member functions

# 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-bug17631

--- 1.320/sql/sql_table.cc	2006-03-24 13:56:48 -06:00
+++ 1.321/sql/sql_table.cc	2006-03-31 11:39:35 -06:00
@@ -2115,7 +2115,7 @@
     }
     DBUG_PRINT("info", ("db_type = %d",
                          ha_legacy_type(part_info->default_engine_type)));
-    if (check_partition_info(part_info, &engine_type, file,
+    if (part_info->check_partition_info( &engine_type, file,
                              create_info->max_rows))
       goto err;
     part_info->default_engine_type= engine_type;

--- 1.58/sql/sql_partition.cc	2006-03-28 06:25:13 -06:00
+++ 1.59/sql/sql_partition.cc	2006-03-31 11:39:35 -06:00
@@ -411,383 +411,6 @@
 
 
 /*
-  This routine allocates an array for all range constants to achieve a fast
-  check what partition a certain value belongs to. At the same time it does
-  also check that the range constants are defined in increasing order and
-  that the expressions are constant integer expressions.
-
-  SYNOPSIS
-    check_range_constants()
-    part_info             Partition info
-
-  RETURN VALUE
-    TRUE                An error occurred during creation of range constants
-    FALSE               Successful creation of range constant mapping
-
-  DESCRIPTION
-    This routine is called from check_partition_info to get a quick error
-    before we came too far into the CREATE TABLE process. It is also called
-    from fix_partition_func every time we open the .frm file. It is only
-    called for RANGE PARTITIONed tables.
-*/
-
-static bool check_range_constants(partition_info *part_info)
-{
-  partition_element* part_def;
-  longlong current_largest_int= LONGLONG_MIN;
-  longlong part_range_value_int;
-  uint no_parts= part_info->no_parts;
-  uint i;
-  List_iterator<partition_element> it(part_info->partitions);
-  bool result= TRUE;
-  DBUG_ENTER("check_range_constants");
-  DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
-
-  part_info->part_result_type= INT_RESULT;
-  part_info->range_int_array= 
-                      (longlong*)sql_alloc(no_parts * sizeof(longlong));
-  if (unlikely(part_info->range_int_array == NULL))
-  {
-    mem_alloc_error(no_parts * sizeof(longlong));
-    goto end;
-  }
-  i= 0;
-  do
-  {
-    part_def= it++;
-    if ((i != (no_parts - 1)) || !part_info->defined_max_value)
-      part_range_value_int= part_def->range_value; 
-    else
-      part_range_value_int= LONGLONG_MAX;
-    if (likely(current_largest_int < part_range_value_int))
-    {
-      current_largest_int= part_range_value_int;
-      part_info->range_int_array[i]= part_range_value_int;
-    }
-    else
-    {
-      my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
-      goto end;
-    }
-  } while (++i < no_parts);
-  result= FALSE;
-end:
-  DBUG_RETURN(result);
-}
-
-
-/*
-  A support routine for check_list_constants used by qsort to sort the
-  constant list expressions.
-
-  SYNOPSIS
-    list_part_cmp()
-      a                First list constant to compare with
-      b                Second list constant to compare with
-
-  RETURN VALUE
-    +1                 a > b
-    0                  a  == b
-    -1                 a < b
-*/
-
-static int list_part_cmp(const void* a, const void* b)
-{
-  longlong a1= ((LIST_PART_ENTRY*)a)->list_value;
-  longlong b1= ((LIST_PART_ENTRY*)b)->list_value;
-  if (a1 < b1)
-    return -1;
-  else if (a1 > b1)
-    return +1;
-  else
-    return 0;
-}
-
-
-/*
-  This routine allocates an array for all list constants to achieve a fast
-  check what partition a certain value belongs to. At the same time it does
-  also check that there are no duplicates among the list constants and that
-  that the list expressions are constant integer expressions.
-
-  SYNOPSIS
-    check_list_constants()
-    part_info             Partition info
-
-  RETURN VALUE
-    TRUE                  An error occurred during creation of list constants
-    FALSE                 Successful creation of list constant mapping
-
-  DESCRIPTION
-    This routine is called from check_partition_info to get a quick error
-    before we came too far into the CREATE TABLE process. It is also called
-    from fix_partition_func every time we open the .frm file. It is only
-    called for LIST PARTITIONed tables.
-*/
-
-static bool check_list_constants(partition_info *part_info)
-{
-  uint i, no_parts;
-  uint no_list_values= 0;
-  uint list_index= 0;
-  longlong *list_value;
-  bool not_first;
-  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");
-
-  part_info->part_result_type= INT_RESULT;
-
-  /*
-    We begin by calculating the number of list values that have been
-    defined in the first step.
-
-    We use this number to allocate a properly sized array of structs
-    to keep the partition id and the value to use in that partition.
-    In the second traversal we assign them values in the struct array.
-
-    Finally we sort the array of structs in order of values to enable
-    a quick binary search for the proper value to discover the
-    partition id.
-    After sorting the array we check that there are no duplicates in the
-    list.
-  */
-
-  no_parts= part_info->no_parts;
-  i= 0;
-  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++;
-  } while (++i < no_parts);
-  list_func_it.rewind();
-  part_info->no_list_values= no_list_values;
-  part_info->list_array=
-      (LIST_PART_ENTRY*)sql_alloc(no_list_values*sizeof(LIST_PART_ENTRY));
-  if (unlikely(part_info->list_array == NULL))
-  {
-    mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY));
-    goto end;
-  }
-
-  i= 0;
-  do
-  {
-    part_def= list_func_it++;
-    List_iterator<longlong> list_val_it2(part_def->list_val_list);
-    while ((list_value= list_val_it2++))
-    {
-      part_info->list_array[list_index].list_value= *list_value;
-      part_info->list_array[list_index++].partition_id= i;
-    }
-  } while (++i < no_parts);
-
-  qsort((void*)part_info->list_array, no_list_values,
-        sizeof(LIST_PART_ENTRY), &list_part_cmp);
-
-  not_first= FALSE;
-  i= prev_value= 0; //prev_value initialised to quiet compiler
-  do
-  {
-    curr_value= part_info->list_array[i].list_value;
-    if (likely(!not_first || prev_value != curr_value))
-    {
-      prev_value= curr_value;
-      not_first= TRUE;
-    }
-    else
-    {
-      my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
-      goto end;
-    }
-  } while (++i < no_list_values);
-  result= FALSE;
-end:
-  DBUG_RETURN(result);
-}
-
-
-
-
-
-
-
-/*
-  Check that all partitions use the same storage engine.
-  This is currently a limitation in this version.
-
-  SYNOPSIS
-    check_engine_mix()
-    engine_array           An array of engine identifiers
-    no_parts               Total number of partitions
-
-  RETURN VALUE
-    TRUE                   Error, mixed engines
-    FALSE                  Ok, no mixed engines
-  DESCRIPTION
-    Current check verifies only that all handlers are the same.
-    Later this check will be more sophisticated.
-*/
-
-static bool check_engine_mix(handlerton **engine_array, uint no_parts)
-{
-  uint i= 0;
-  bool result= FALSE;
-  DBUG_ENTER("check_engine_mix");
-
-  do
-  {
-    if (engine_array[i] != engine_array[0])
-    {
-      result= TRUE;
-      break;
-    }
-  } while (++i < no_parts);
-  DBUG_RETURN(result);
-}
-
-
-/*
-  This code is used early in the CREATE TABLE and ALTER TABLE process.
-
-  SYNOPSIS
-    check_partition_info()
-    part_info           The reference to all partition information
-    file                A reference to a handler of the table
-    max_rows            Maximum number of rows stored in the table
-    engine_type         Return value for used engine in partitions
-
-  RETURN VALUE
-    TRUE                 Error, something went wrong
-    FALSE                Ok, full partition data structures are now generated
-
-  DESCRIPTION
-    We will check that the partition info requested is possible to set-up in
-    this version. This routine is an extension of the parser one could say.
-    If defaults were used we will generate default data structures for all
-    partitions.
-
-*/
-
-bool check_partition_info(partition_info *part_info,handlerton **eng_type,
-                          handler *file, ulonglong max_rows)
-{
-  handlerton **engine_array= NULL;
-  uint part_count= 0;
-  uint i, no_parts, tot_partitions;
-  bool result= TRUE;
-  char *same_name;
-  DBUG_ENTER("check_partition_info");
-
-  if (unlikely(!part_info->is_sub_partitioned() &&
-               !(part_info->use_default_subpartitions &&
-                 part_info->use_default_no_subpartitions)))
-  {
-    my_error(ER_SUBPARTITION_ERROR, MYF(0));
-    goto end;
-  }
-  if (unlikely(part_info->is_sub_partitioned() &&
-              (!(part_info->part_type == RANGE_PARTITION ||
-                 part_info->part_type == LIST_PARTITION))))
-  {
-    /* Only RANGE and LIST partitioning can be subpartitioned */
-    my_error(ER_SUBPARTITION_ERROR, MYF(0));
-    goto end;
-  }
-  if (unlikely(part_info->set_up_defaults_for_partitioning(file,
-                                                           max_rows, 
-                                                           (uint)0)))
-    goto end;
-  tot_partitions= part_info->get_tot_partitions();
-  if (unlikely(tot_partitions > MAX_PARTITIONS))
-  {
-    my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
-    goto end;
-  }
-  if ((same_name= part_info->has_unique_names()))
-  {
-    my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
-    goto end;
-  }
-  engine_array= (handlerton**)my_malloc(tot_partitions * sizeof(handlerton *), 
-                                        MYF(MY_WME));
-  if (unlikely(!engine_array))
-    goto end;
-  i= 0;
-  no_parts= part_info->no_parts;
-  {
-    List_iterator<partition_element> part_it(part_info->partitions);
-    do
-    {
-      partition_element *part_elem= part_it++;
-      if (!part_info->is_sub_partitioned())
-      {
-        if (part_elem->engine_type == NULL)
-          part_elem->engine_type= part_info->default_engine_type;
-        DBUG_PRINT("info", ("engine = %d",
-                   ha_legacy_type(part_elem->engine_type)));
-        engine_array[part_count++]= part_elem->engine_type;
-      }
-      else
-      {
-        uint j= 0, no_subparts= part_info->no_subparts;;
-        List_iterator<partition_element> sub_it(part_elem->subpartitions);
-        do
-        {
-          part_elem= sub_it++;
-          if (part_elem->engine_type == NULL)
-            part_elem->engine_type= part_info->default_engine_type;
-          DBUG_PRINT("info", ("engine = %u",
-                     ha_legacy_type(part_elem->engine_type)));
-          engine_array[part_count++]= part_elem->engine_type;
-        } while (++j < no_subparts);
-      }
-    } while (++i < part_info->no_parts);
-  }
-  if (unlikely(check_engine_mix(engine_array, part_count)))
-  {
-    my_error(ER_MIX_HANDLER_ERROR, MYF(0));
-    goto end;
-  }
-
-  if (eng_type)
-    *eng_type= (handlerton*)engine_array[0];
-
-  /*
-    We need to check all constant expressions that they are of the correct
-    type and that they are increasing for ranges and not overlapping for
-    list constants.
-  */
-
-  if (unlikely((part_info->part_type == RANGE_PARTITION &&
-                check_range_constants(part_info)) ||
-               (part_info->part_type == LIST_PARTITION &&
-                check_list_constants(part_info))))
-    goto end;
-  result= FALSE;
-end:
-  my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
-  DBUG_RETURN(result);
-}
-
-
-/*
   This method is used to set-up both partition and subpartitioning
   field array and used for all types of partitioning.
   It is part of the logic around fix_partition_func.
@@ -1814,13 +1437,13 @@
     if (part_info->part_type == RANGE_PARTITION)
     {
       error_str= partition_keywords[PKW_RANGE].str; 
-      if (unlikely(check_range_constants(part_info)))
+      if (unlikely(part_info->check_range_constants()))
         goto end;
     }
     else if (part_info->part_type == LIST_PARTITION)
     {
       error_str= partition_keywords[PKW_LIST].str; 
-      if (unlikely(check_list_constants(part_info)))
+      if (unlikely(part_info->check_list_constants()))
         goto end;
     }
     else
@@ -3638,10 +3261,10 @@
    | Forminfo     288 bytes      |
    -------------------------------
    | Screen buffer, to make      |
+   |field names readable        |
    -------------------------------
    | Packed field info           |
+   |17 + 1 + strlen(field_name) |
    | + 1 end of file character   |
    -------------------------------
    | Partition info              |
@@ -4862,7 +4485,7 @@
         tab_part_info->use_default_subpartitions= FALSE;
         tab_part_info->use_default_no_subpartitions= FALSE;
       }
-      if (check_partition_info(tab_part_info, (handlerton**)NULL,
+      if (tab_part_info->check_partition_info((handlerton**)NULL,
                                table->file, ULL(0)))
       {
         DBUG_RETURN(TRUE);

--- 1.7/sql/partition_info.cc	2006-03-18 08:46:34 -06:00
+++ 1.8/sql/partition_info.cc	2006-03-31 11:39:35 -06:00
@@ -124,7 +124,6 @@
 
   SYNOPSIS
     set_up_default_partitions()
-    part_info           The reference to all partition information
     file                A reference to a handler of the table
     max_rows            Maximum number of rows stored in the table
     start_no            Starting partition number
@@ -201,7 +200,6 @@
 
   SYNOPSIS
     set_up_default_subpartitions()
-    part_info           The reference to all partition information
     file                A reference to a handler of the table
     max_rows            Maximum number of rows stored in the table
 
@@ -271,7 +269,6 @@
 
   SYNOPSIS
     set_up_defaults_for_partitioning()
-    part_info           The reference to all partition information
     file                A reference to a handler of the table
     max_rows            Maximum number of rows stored in the table
     start_no            Starting partition number
@@ -387,5 +384,363 @@
   } 
   DBUG_RETURN(NULL);
 }
+
+
+/*
+  Check that all partitions use the same storage engine.
+  This is currently a limitation in this version.
+
+  SYNOPSIS
+    check_engine_mix()
+    engine_array           An array of engine identifiers
+    no_parts               Total number of partitions
+
+  RETURN VALUE
+    TRUE                   Error, mixed engines
+    FALSE                  Ok, no mixed engines
+  DESCRIPTION
+    Current check verifies only that all handlers are the same.
+    Later this check will be more sophisticated.
+*/
+
+bool partition_info::check_engine_mix(handlerton **engine_array, uint no_parts)
+{
+  uint i= 0;
+  bool result= FALSE;
+  DBUG_ENTER("partition_info::check_engine_mix");
+
+  do
+  {
+    if (engine_array[i] != engine_array[0])
+    {
+      result= TRUE;
+      break;
+    }
+  } while (++i < no_parts);
+  DBUG_RETURN(result);
+}
+
+
+/*
+  This routine allocates an array for all range constants to achieve a fast
+  check what partition a certain value belongs to. At the same time it does
+  also check that the range constants are defined in increasing order and
+  that the expressions are constant integer expressions.
+
+  SYNOPSIS
+    check_range_constants()
+
+  RETURN VALUE
+    TRUE                An error occurred during creation of range constants
+    FALSE               Successful creation of range constant mapping
+
+  DESCRIPTION
+    This routine is called from check_partition_info to get a quick error
+    before we came too far into the CREATE TABLE process. It is also called
+    from fix_partition_func every time we open the .frm file. It is only
+    called for RANGE PARTITIONed tables.
+*/
+
+bool partition_info::check_range_constants()
+{
+  partition_element* part_def;
+  longlong current_largest_int= LONGLONG_MIN;
+  longlong part_range_value_int;
+  uint i;
+  List_iterator<partition_element> it(partitions);
+  bool result= TRUE;
+  DBUG_ENTER("partition_info::check_range_constants");
+  DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
+
+  part_result_type= INT_RESULT;
+  range_int_array= (longlong*)sql_alloc(no_parts * sizeof(longlong));
+  if (unlikely(range_int_array == NULL))
+  {
+    mem_alloc_error(no_parts * sizeof(longlong));
+    goto end;
+  }
+  i= 0;
+  do
+  {
+    part_def= it++;
+    if ((i != (no_parts - 1)) || !defined_max_value)
+      part_range_value_int= part_def->range_value; 
+    else
+      part_range_value_int= LONGLONG_MAX;
+    if (likely(current_largest_int < part_range_value_int))
+    {
+      current_largest_int= part_range_value_int;
+      range_int_array[i]= part_range_value_int;
+    }
+    else
+    {
+      my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
+      goto end;
+    }
+  } while (++i < no_parts);
+  result= FALSE;
+end:
+  DBUG_RETURN(result);
+}
+
+
+/*
+  A support routine for check_list_constants used by qsort to sort the
+  constant list expressions.
+
+  SYNOPSIS
+    list_part_cmp()
+      a                First list constant to compare with
+      b                Second list constant to compare with
+
+  RETURN VALUE
+    +1                 a > b
+    0                  a  == b
+    -1                 a < b
+*/
+
+int partition_info::list_part_cmp(const void* a, const void* b)
+{
+  longlong a1= ((LIST_PART_ENTRY*)a)->list_value;
+  longlong b1= ((LIST_PART_ENTRY*)b)->list_value;
+  if (a1 < b1)
+    return -1;
+  else if (a1 > b1)
+    return +1;
+  else
+    return 0;
+}
+
+
+/*
+  This routine allocates an array for all list constants to achieve a fast
+  check what partition a certain value belongs to. At the same time it does
+  also check that there are no duplicates among the list constants and that
+  that the list expressions are constant integer expressions.
+
+  SYNOPSIS
+    check_list_constants()
+
+  RETURN VALUE
+    TRUE                  An error occurred during creation of list constants
+    FALSE                 Successful creation of list constant mapping
+
+  DESCRIPTION
+    This routine is called from check_partition_info to get a quick error
+    before we came too far into the CREATE TABLE process. It is also called
+    from fix_partition_func every time we open the .frm file. It is only
+    called for LIST PARTITIONed tables.
+*/
+
+bool partition_info::check_list_constants()
+{
+  uint i;
+  uint list_index= 0;
+  longlong *list_value;
+  bool not_first;
+  bool result= TRUE;
+  longlong curr_value, prev_value;
+  partition_element* part_def;
+  bool found_null= FALSE;
+  List_iterator<partition_element> list_func_it(partitions);
+  DBUG_ENTER("partition_info::check_list_constants");
+
+  part_result_type= INT_RESULT;
+  no_list_values= 0;
+  /*
+    We begin by calculating the number of list values that have been
+    defined in the first step.
+
+    We use this number to allocate a properly sized array of structs
+    to keep the partition id and the value to use in that partition.
+    In the second traversal we assign them values in the struct array.
+
+    Finally we sort the array of structs in order of values to enable
+    a quick binary search for the proper value to discover the
+    partition id.
+    After sorting the array we check that there are no duplicates in the
+    list.
+  */
+
+  i= 0;
+  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;
+      }
+      has_null_value= TRUE;
+      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++;
+  } while (++i < no_parts);
+  list_func_it.rewind();
+  list_array= (LIST_PART_ENTRY*)sql_alloc(no_list_values*sizeof(LIST_PART_ENTRY));
+  if (unlikely(list_array == NULL))
+  {
+    mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY));
+    goto end;
+  }
+
+  i= 0;
+  do
+  {
+    part_def= list_func_it++;
+    List_iterator<longlong> list_val_it2(part_def->list_val_list);
+    while ((list_value= list_val_it2++))
+    {
+      list_array[list_index].list_value= *list_value;
+      list_array[list_index++].partition_id= i;
+    }
+  } while (++i < no_parts);
+
+  qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY), 
+        &list_part_cmp);
+
+  not_first= FALSE;
+  i= prev_value= 0; //prev_value initialised to quiet compiler
+  do
+  {
+    curr_value= list_array[i].list_value;
+    if (likely(!not_first || prev_value != curr_value))
+    {
+      prev_value= curr_value;
+      not_first= TRUE;
+    }
+    else
+    {
+      my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
+      goto end;
+    }
+  } while (++i < no_list_values);
+  result= FALSE;
+end:
+  DBUG_RETURN(result);
+}
+
+
+/*
+  This code is used early in the CREATE TABLE and ALTER TABLE process.
+
+  SYNOPSIS
+    check_partition_info()
+    file                A reference to a handler of the table
+    max_rows            Maximum number of rows stored in the table
+    engine_type         Return value for used engine in partitions
+
+  RETURN VALUE
+    TRUE                 Error, something went wrong
+    FALSE                Ok, full partition data structures are now generated
+
+  DESCRIPTION
+    We will check that the partition info requested is possible to set-up in
+    this version. This routine is an extension of the parser one could say.
+    If defaults were used we will generate default data structures for all
+    partitions.
+
+*/
+
+bool partition_info::check_partition_info(handlerton **eng_type,
+                                          handler *file, ulonglong max_rows)
+{
+  handlerton **engine_array= NULL;
+  uint part_count= 0;
+  uint i, tot_partitions;
+  bool result= TRUE;
+  char *same_name;
+  DBUG_ENTER("partition_info::check_partition_info");
+
+  if (unlikely(!is_sub_partitioned() && 
+               !(use_default_subpartitions && use_default_no_subpartitions)))
+  {
+    my_error(ER_SUBPARTITION_ERROR, MYF(0));
+    goto end;
+  }
+  if (unlikely(is_sub_partitioned() &&
+              (!(part_type == RANGE_PARTITION || 
+                 part_type == LIST_PARTITION))))
+  {
+    /* Only RANGE and LIST partitioning can be subpartitioned */
+    my_error(ER_SUBPARTITION_ERROR, MYF(0));
+    goto end;
+  }
+  if (unlikely(set_up_defaults_for_partitioning(file, max_rows, (uint)0)))
+    goto end;
+  tot_partitions= get_tot_partitions();
+  if (unlikely(tot_partitions > MAX_PARTITIONS))
+  {
+    my_error(ER_TOO_MANY_PARTITIONS_ERROR, MYF(0));
+    goto end;
+  }
+  if ((same_name= has_unique_names()))
+  {
+    my_error(ER_SAME_NAME_PARTITION, MYF(0), same_name);
+    goto end;
+  }
+  engine_array= (handlerton**)my_malloc(tot_partitions * sizeof(handlerton *), 
+                                        MYF(MY_WME));
+  if (unlikely(!engine_array))
+    goto end;
+  i= 0;
+  {
+    List_iterator<partition_element> part_it(partitions);
+    do
+    {
+      partition_element *part_elem= part_it++;
+      if (!is_sub_partitioned())
+      {
+        if (part_elem->engine_type == NULL)
+          part_elem->engine_type= default_engine_type;
+        DBUG_PRINT("info", ("engine = %d",
+                   ha_legacy_type(part_elem->engine_type)));
+        engine_array[part_count++]= part_elem->engine_type;
+      }
+      else
+      {
+        uint j= 0;
+        List_iterator<partition_element> sub_it(part_elem->subpartitions);
+        do
+        {
+          part_elem= sub_it++;
+          if (part_elem->engine_type == NULL)
+            part_elem->engine_type= default_engine_type;
+          DBUG_PRINT("info", ("engine = %u",
+                     ha_legacy_type(part_elem->engine_type)));
+          engine_array[part_count++]= part_elem->engine_type;
+        } while (++j < no_subparts);
+      }
+    } while (++i < no_parts);
+  }
+  if (unlikely(partition_info::check_engine_mix(engine_array, part_count)))
+  {
+    my_error(ER_MIX_HANDLER_ERROR, MYF(0));
+    goto end;
+  }
+
+  if (eng_type)
+    *eng_type= (handlerton*)engine_array[0];
+
+  /*
+    We need to check all constant expressions that they are of the correct
+    type and that they are increasing for ranges and not overlapping for
+    list constants.
+  */
+
+  if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
+                (part_type == LIST_PARTITION && check_list_constants())))
+    goto end;
+  result= FALSE;
+end:
+  my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
+  DBUG_RETURN(result);
+}
+
 
 #endif /* WITH_PARTITION_STORAGE_ENGINE */

--- 1.5/sql/partition_info.h	2006-03-18 08:46:34 -06:00
+++ 1.6/sql/partition_info.h	2006-03-31 11:39:35 -06:00
@@ -245,7 +245,13 @@
   bool set_up_defaults_for_partitioning(handler *file, ulonglong max_rows,
                                         uint start_no);
   char *has_unique_names();
+  static bool check_engine_mix(handlerton **engine_array, uint no_parts);
+  bool check_range_constants();
+  bool check_list_constants();
+  bool check_partition_info(handlerton **eng_type,
+                            handler *file, ulonglong max_rows);
 private:
+  static int list_part_cmp(const void* a, const void* b);
   bool set_up_default_partitions(handler *file, ulonglong max_rows,
                                  uint start_no);
   bool set_up_default_subpartitions(handler *file, ulonglong max_rows);
Thread
bk commit into 5.1 tree (reggie:1.2261)reggie31 Mar