code: func (c *trimFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
  	if err := c.verifyArgs(args); err != nil {
  		return nil, err
  	}
  
  	switch len(args) {
  	case 1:
  		bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString)
  		argType := args[0].GetType()
  		bf.tp.Flen = argType.Flen
  		SetBinFlagOrBinStr(argType, bf.tp)
  		sig := &builtinTrim1ArgSig{bf}
  		return sig, nil
  
  	case 2:
  		bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString, types.ETString)
  		argType := args[0].GetType()
  		SetBinFlagOrBinStr(argType, bf.tp)
  		sig := &builtinTrim2ArgsSig{bf}
  		return sig, nil
  
  	case 3:
  		bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString, types.ETString, types.ETInt)
  		argType := args[0].GetType()
  		bf.tp.Flen = argType.Flen
  		SetBinFlagOrBinStr(argType, bf.tp)
  		sig := &builtinTrim3ArgsSig{bf}
  		return sig, nil
  
  	default:
  		return nil, c.verifyArgs(args)
  	}
  }
docs: // getFunction sets trim built-in function signature.
  // The syntax of trim in mysql is 'TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str), TRIM([remstr FROM] str)',
  // but we wil convert it into trim(str), trim(str, remstr) and trim(str, remstr, direction) in AST.