char *generate_partition_syntax(THD *thd, partition_info *part_info,
                                uint *buf_length,
                                bool show_partition_options,
                                HA_CREATE_INFO *create_info,
                                Alter_info *alter_info)
{
  uint i,j, tot_num_parts, num_subparts;
  partition_element *part_elem;
  int err= 0;
  List_iterator<partition_element> part_it(part_info->partitions);
  StringBuffer<1024> str;
  DBUG_ENTER("generate_partition_syntax");

  err+= str.append(STRING_WITH_LEN(" PARTITION BY "));
  switch (part_info->part_type)
  {
    case RANGE_PARTITION:
      err+= str.append(STRING_WITH_LEN("RANGE "));
      break;
    case LIST_PARTITION:
      err+= str.append(STRING_WITH_LEN("LIST "));
      break;
    case HASH_PARTITION:
      if (part_info->linear_hash_ind)
        err+= str.append(STRING_WITH_LEN("LINEAR "));
      if (part_info->list_of_part_fields)
      {
        err+= add_key_with_algorithm(&str, part_info);
        err+= add_part_field_list(thd, &str, part_info->part_field_list);
      }
      else
        err+= str.append(STRING_WITH_LEN("HASH "));
      break;
    case VERSIONING_PARTITION:
      err+= str.append(STRING_WITH_LEN("SYSTEM_TIME "));
      break;
    default:
      DBUG_ASSERT(0);
      /* We really shouldn't get here, no use in continuing from here */
      my_error(ER_OUT_OF_RESOURCES, MYF(ME_FATALERROR));
      DBUG_RETURN(NULL);
  }
  if (part_info->part_type == VERSIONING_PARTITION)
  {
    Vers_part_info *vers_info= part_info->vers_info;
    DBUG_ASSERT(vers_info);
    if (vers_info->interval.is_set())
    {
      err+= str.append(STRING_WITH_LEN("INTERVAL "));
      err+= append_interval(&str, vers_info->interval.type,
                                  vers_info->interval.step);
      if (create_info) // not SHOW CREATE
      {
        err+= str.append(STRING_WITH_LEN(" STARTS "));
        err+= str.append_ulonglong(vers_info->interval.start);
      }
    }
    if (vers_info->limit)
    {
      err+= str.append(STRING_WITH_LEN("LIMIT "));
      err+= str.append_ulonglong(vers_info->limit);
    }
  }
  else if (part_info->part_expr)
  {
    err+= str.append('(');
    part_info->part_expr->print_for_table_def(&str);
    err+= str.append(')');
  }
  else if (part_info->column_list)
  {
    err+= str.append(STRING_WITH_LEN(" COLUMNS"));
    err+= add_part_field_list(thd, &str, part_info->part_field_list);
  }
  if ((!part_info->use_default_num_partitions) &&
       part_info->use_default_partitions)
  {
    err+= str.append(STRING_WITH_LEN("\nPARTITIONS "));
    err+= str.append_ulonglong(part_info->num_parts);
  }
  if (part_info->is_sub_partitioned())
  {
    err+= str.append(STRING_WITH_LEN("\nSUBPARTITION BY "));
    /* Must be hash partitioning for subpartitioning */
    if (part_info->linear_hash_ind)
      err+= str.append(STRING_WITH_LEN("LINEAR "));
    if (part_info->list_of_subpart_fields)
    {
      err+= add_key_with_algorithm(&str, part_info);
      err+= add_part_field_list(thd, &str, part_info->subpart_field_list);
    }
    else
      err+= str.append(STRING_WITH_LEN("HASH "));
    if (part_info->subpart_expr)
    {
      err+= str.append('(');
      part_info->subpart_expr->print_for_table_def(&str);
      err+= str.append(')');
    }
    if ((!part_info->use_default_num_subpartitions) && 
          part_info->use_default_subpartitions)
    {
      err+= str.append(STRING_WITH_LEN("\nSUBPARTITIONS "));
      err+= str.append_ulonglong(part_info->num_subparts);
    }
  }
  tot_num_parts= part_info->partitions.elements;
  num_subparts= part_info->num_subparts;

  if (!part_info->use_default_partitions)
  {
    bool first= TRUE;
    err+= str.append(STRING_WITH_LEN("\n("));
    i= 0;
    do
    {
      part_elem= part_it++;
      if (part_elem->part_state != PART_TO_BE_DROPPED &&
          part_elem->part_state != PART_REORGED_DROPPED)
      {
        if (!first)
          err+= str.append(STRING_WITH_LEN(",\n "));
        first= FALSE;
        err+= str.append(STRING_WITH_LEN("PARTITION "));
        err+= append_identifier(thd, &str, part_elem->partition_name,
                                           strlen(part_elem->partition_name));
        err+= add_partition_values(&str, part_info, part_elem,
                                   create_info, alter_info);
        if (!part_info->is_sub_partitioned() ||
            part_info->use_default_subpartitions)
        {
          if (show_partition_options)
            err+= add_partition_options(&str, part_elem);
        }
        else
        {
          err+= str.append(STRING_WITH_LEN("\n ("));
          List_iterator<partition_element> sub_it(part_elem->subpartitions);
          j= 0;
          do
          {
            part_elem= sub_it++;
            err+= str.append(STRING_WITH_LEN("SUBPARTITION "));
            err+= append_identifier(thd, &str, part_elem->partition_name,
                                               strlen(part_elem->partition_name));
            if (show_partition_options)
              err+= add_partition_options(&str, part_elem);
            if (j != (num_subparts-1))
              err+= str.append(STRING_WITH_LEN(",\n  "));
            else
              err+= str.append(')');
          } while (++j < num_subparts);
        }
      }
      if (i == (tot_num_parts-1))
        err+= str.append(')');
    } while (++i < tot_num_parts);
  }
  if (err)
    DBUG_RETURN(NULL);
  *buf_length= str.length();
  DBUG_RETURN(thd->strmake(str.ptr(), str.length()));
}