code: func (d *ddl) AddTablePartitions(ctx sessionctx.Context, ident ast.Ident, spec *ast.AlterTableSpec) error {
  	is := d.infoHandle.Get()
  	schema, ok := is.SchemaByName(ident.Schema)
  	if !ok {
  		return errors.Trace(infoschema.ErrDatabaseNotExists.GenWithStackByArgs(schema))
  	}
  	t, err := is.TableByName(ident.Schema, ident.Name)
  	if err != nil {
  		return errors.Trace(infoschema.ErrTableNotExists.GenWithStackByArgs(ident.Schema, ident.Name))
  	}
  
  	meta := t.Meta()
  	if meta.GetPartitionInfo() == nil {
  		return errors.Trace(ErrPartitionMgmtOnNonpartitioned)
  	}
  	// We don't support add hash type partition now.
  	if meta.Partition.Type == model.PartitionTypeHash {
  		return errors.Trace(ErrUnsupportedAddPartition)
  	}
  
  	partInfo, err := buildPartitionInfo(meta, d, spec)
  	if err != nil {
  		return errors.Trace(err)
  	}
  
  	err = checkAddPartitionTooManyPartitions(uint64(len(meta.Partition.Definitions) + len(partInfo.Definitions)))
  	if err != nil {
  		return errors.Trace(err)
  	}
  
  	err = checkPartitionNameUnique(meta, partInfo)
  	if err != nil {
  		return errors.Trace(err)
  	}
  
  	err = checkAddPartitionValue(meta, partInfo)
  	if err != nil {
  		return errors.Trace(err)
  	}
  
  	job := &model.Job{
  		SchemaID:   schema.ID,
  		TableID:    meta.ID,
  		Type:       model.ActionAddTablePartition,
  		BinlogInfo: &model.HistoryInfo{},
  		Args:       []interface{}{partInfo},
  	}
  
  	err = d.doDDLJob(ctx, job)
  	err = d.callHookOnChanged(err)
  	return errors.Trace(err)
  }
docs: // AddTablePartitions will add a new partition to the table.