static bool set_up_field_array(THD *thd, TABLE *table,
                              bool is_sub_part)
{
  Field **ptr, *field, **field_array;
  uint num_fields= 0;
  uint size_field_array;
  uint i= 0;
  uint inx;
  partition_info *part_info= table->part_info;
  int result= FALSE;
  DBUG_ENTER("set_up_field_array");

  ptr= table->field;
  while ((field= *(ptr++))) 
  {
    if (field->flags & GET_FIXED_FIELDS_FLAG)
    {
      if (table->versioned(VERS_TRX_ID)
          && unlikely(field->flags & VERS_SYSTEM_FIELD))
      {
        my_error(ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED, MYF(0));
        DBUG_RETURN(TRUE);
      }
      num_fields++;
    }
  }
  if (unlikely(num_fields > MAX_REF_PARTS))
  {
    char *err_str;
    if (is_sub_part)
      err_str= (char*)"subpartition function";
    else
      err_str= (char*)"partition function";
    my_error(ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR, MYF(0), err_str);
    DBUG_RETURN(TRUE);
  }
  if (num_fields == 0)
  {
    /*
      We are using hidden key as partitioning field
    */
    DBUG_ASSERT(!is_sub_part);
    DBUG_RETURN(FALSE);
  }
  size_field_array= (num_fields+1)*sizeof(Field*);
  field_array= (Field**) thd->calloc(size_field_array);
  if (unlikely(!field_array))
    DBUG_RETURN(TRUE);

  ptr= table->field;
  while ((field= *(ptr++))) 
  {
    if (field->flags & GET_FIXED_FIELDS_FLAG)
    {
      field->flags&= ~GET_FIXED_FIELDS_FLAG;
      field->flags|= FIELD_IN_PART_FUNC_FLAG;
      if (likely(!result))
      {
        if (!is_sub_part && part_info->column_list)
        {
          List_iterator<const char> it(part_info->part_field_list);
          const char *field_name;

          DBUG_ASSERT(num_fields == part_info->part_field_list.elements);
          inx= 0;
          do
          {
            field_name= it++;
            if (!my_strcasecmp(system_charset_info,
                               field_name,
                               field->field_name.str))
              break;
          } while (++inx < num_fields);
          if (inx == num_fields)
          {
            /*
              Should not occur since it should already been checked in either
              add_column_list_values, handle_list_of_fields,
              check_partition_info etc.
            */
            DBUG_ASSERT(0);
            my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
            result= TRUE;
            continue;
          }
        }
        else
          inx= i;
        field_array[inx]= field;
        i++;

        /*
          We check that the fields are proper. It is required for each
          field in a partition function to:
          1) Not be a BLOB of any type
            A BLOB takes too long time to evaluate so we don't want it for
            performance reasons.
        */

        if (unlikely(field->flags & BLOB_FLAG))
        {
          my_error(ER_BLOB_FIELD_IN_PART_FUNC_ERROR, MYF(0));
          result= TRUE;
        }
      }
    }
  }
  field_array[num_fields]= 0;
  if (!is_sub_part)
  {
    part_info->part_field_array= field_array;
    part_info->num_part_fields= num_fields;
  }
  else
  {
    part_info->subpart_field_array= field_array;
    part_info->num_subpart_fields= num_fields;
  }
  DBUG_RETURN(result);
}