code: func builtinTrim(args []types.Datum, _ context.Context) (d types.Datum, err error) {
  	// args[0] -> Str
  	// args[1] -> RemStr
  	// args[2] -> Direction
  	// eval str
  	if args[0].IsNull() {
  		return d, nil
  	}
  	str, err := args[0].ToString()
  	if err != nil {
  		return d, errors.Trace(err)
  	}
  	remstr := ""
  	// eval remstr
  	if len(args) > 1 {
  		if args[1].Kind() != types.KindNull {
  			remstr, err = args[1].ToString()
  			if err != nil {
  				return d, errors.Trace(err)
  			}
  		}
  	}
  	// do trim
  	var result string
  	var direction ast.TrimDirectionType
  	if len(args) > 2 {
  		direction = args[2].GetValue().(ast.TrimDirectionType)
  	} else {
  		direction = ast.TrimBothDefault
  	}
  	if direction == ast.TrimLeading {
  		if len(remstr) > 0 {
  			result = trimLeft(str, remstr)
  		} else {
  			result = strings.TrimLeft(str, spaceChars)
  		}
  	} else if direction == ast.TrimTrailing {
  		if len(remstr) > 0 {
  			result = trimRight(str, remstr)
  		} else {
  			result = strings.TrimRight(str, spaceChars)
  		}
  	} else if len(remstr) > 0 {
  		x := trimLeft(str, remstr)
  		result = trimRight(x, remstr)
  	} else {
  		result = strings.Trim(str, spaceChars)
  	}
  	d.SetString(result)
  	return d, nil
  }
docs: // See https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_trim