code: func resolveAlterTableSpec(ctx sessionctx.Context, specs []*ast.AlterTableSpec) ([]*ast.AlterTableSpec, error) {
  	validSpecs := make([]*ast.AlterTableSpec, 0, len(specs))
  	algorithm := ast.AlterAlgorithmDefault
  	for _, spec := range specs {
  		if spec.Tp == ast.AlterTableAlgorithm {
  			// Find the last AlterTableAlgorithm.
  			algorithm = spec.Algorithm
  		}
  		if isIgnorableSpec(spec.Tp) {
  			continue
  		}
  		validSpecs = append(validSpecs, spec)
  	}
  
  	if len(validSpecs) != 1 {
  		// TODO: Hanlde len(validSpecs) == 0.
  		// Now we only allow one schema changing at the same time.
  		return nil, errRunMultiSchemaChanges
  	}
  
  	// Verify whether the algorithm is supported.
  	for _, spec := range validSpecs {
  		resolvedAlgorithm, err := ResolveAlterAlgorithm(spec, algorithm)
  		if err != nil {
  			if algorithm != ast.AlterAlgorithmCopy {
  				return nil, errors.Trace(err)
  			}
  			// For the compatibility, we return warning instead of error when the algorithm is COPY,
  			// because the COPY ALGORITHM is not supported in TiDB.
  			ctx.GetSessionVars().StmtCtx.AppendError(err)
  		}
  
  		spec.Algorithm = resolvedAlgorithm
  	}
  
  	// Only handle valid specs.
  	return validSpecs, nil
  }
docs: // resolveAlterTableSpec resolves alter table algorithm and removes ignore table spec in specs.
  // returns valied specs, and the occurred error.