github.com/pingcap/tidb/parser@v0.0.0-20231013125129-93a834a6bf8d/mysql/locale_format.go (about)

     1  package mysql
     2  
     3  import (
     4  	"bytes"
     5  	"strconv"
     6  	"strings"
     7  	"unicode"
     8  
     9  	"github.com/pingcap/errors"
    10  )
    11  
    12  func formatENUS(number string, precision string) (string, error) {
    13  	var buffer bytes.Buffer
    14  	if unicode.IsDigit(rune(precision[0])) {
    15  		for i, v := range precision {
    16  			if unicode.IsDigit(v) {
    17  				continue
    18  			}
    19  			precision = precision[:i]
    20  			break
    21  		}
    22  	} else {
    23  		precision = "0"
    24  	}
    25  	if number[0] == '-' && number[1] == '.' {
    26  		number = strings.Replace(number, "-", "-0", 1)
    27  	} else if number[0] == '.' {
    28  		number = strings.Replace(number, ".", "0.", 1)
    29  	}
    30  
    31  	if (number[:1] == "-" && !unicode.IsDigit(rune(number[1]))) ||
    32  		(!unicode.IsDigit(rune(number[0])) && number[:1] != "-") {
    33  		buffer.Write([]byte{'0'})
    34  		position, err := strconv.ParseUint(precision, 10, 64)
    35  		if err == nil && position > 0 {
    36  			buffer.Write([]byte{'.'})
    37  			buffer.WriteString(strings.Repeat("0", int(position)))
    38  		}
    39  		return buffer.String(), nil
    40  	} else if number[:1] == "-" {
    41  		buffer.Write([]byte{'-'})
    42  		number = number[1:]
    43  	}
    44  
    45  	for i, v := range number {
    46  		if unicode.IsDigit(v) {
    47  			continue
    48  		} else if i == 1 && number[1] == '.' {
    49  			continue
    50  		} else if v == '.' && number[1] != '.' {
    51  			continue
    52  		} else {
    53  			number = number[:i]
    54  			break
    55  		}
    56  	}
    57  
    58  	comma := []byte{','}
    59  	parts := strings.Split(number, ".")
    60  	pos := 0
    61  	if len(parts[0])%3 != 0 {
    62  		pos += len(parts[0]) % 3
    63  		buffer.WriteString(parts[0][:pos])
    64  		buffer.Write(comma)
    65  	}
    66  	for ; pos < len(parts[0]); pos += 3 {
    67  		buffer.WriteString(parts[0][pos : pos+3])
    68  		buffer.Write(comma)
    69  	}
    70  	buffer.Truncate(buffer.Len() - 1)
    71  
    72  	position, err := strconv.ParseUint(precision, 10, 64)
    73  	if err == nil {
    74  		if position > 0 {
    75  			buffer.Write([]byte{'.'})
    76  			if len(parts) == 2 {
    77  				if uint64(len(parts[1])) >= position {
    78  					buffer.WriteString(parts[1][:position])
    79  				} else {
    80  					buffer.WriteString(parts[1])
    81  					buffer.WriteString(strings.Repeat("0", int(position)-len(parts[1])))
    82  				}
    83  			} else {
    84  				buffer.WriteString(strings.Repeat("0", int(position)))
    85  			}
    86  		}
    87  	}
    88  
    89  	return buffer.String(), nil
    90  }
    91  
    92  func formatZHCN(_ string, _ string) (string, error) {
    93  	return "", errors.New("not implemented")
    94  }
    95  
    96  func formatNotSupport(_ string, _ string) (string, error) {
    97  	return "", errors.New("not support for the specific locale")
    98  }