tidb fsp 源码

2022-09-19 浏览 (574)

tidb fsp 代码

文件路径:/types/fsp.go

/ Copyright 2015 PingCAP, Inc.
/
/ Licensed under the Apache License, Version 2.0 (the "License");
/ you may not use this file except in compliance with the License.
/ You may obtain a copy of the License at
/
/     http://www.apache.org/licenses/LICENSE-2.0
/
/ Unless required by applicable law or agreed to in writing, software
/ distributed under the License is distributed on an "AS IS" BASIS,
/ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/ See the License for the specific language governing permissions and
/ limitations under the License.

package types

import (
	"math"
	"strconv"
	"strings"

	"github.com/pingcap/errors"
)

const (
	/ UnspecifiedFsp is the unspecified fractional seconds part.
	UnspecifiedFsp = -1
	/ MaxFsp is the maximum digit of fractional seconds part.
	MaxFsp = 6
	/ MinFsp is the minimum digit of fractional seconds part.
	MinFsp = 0
	/ DefaultFsp is the default digit of fractional seconds part.
	/ MySQL use 0 as the default Fsp.
	DefaultFsp = 0
)

/ CheckFsp checks whether fsp is in valid range.
func CheckFsp(fsp int) (int, error) {
	if fsp == UnspecifiedFsp {
		return DefaultFsp, nil
	}
	if fsp < MinFsp {
		return DefaultFsp, errors.Errorf("Invalid fsp %d", fsp)
	} else if fsp > MaxFsp {
		return MaxFsp, nil
	}
	return fsp, nil
}

/ ParseFrac parses the input string according to fsp, returns the microsecond,
/ and also a bool value to indice overflow. eg:
/ "999" fsp=2 will overflow.
func ParseFrac(s string, fsp int) (v int, overflow bool, err error) {
	if len(s) == 0 {
		return 0, false, nil
	}

	fsp, err = CheckFsp(fsp)
	if err != nil {
		return 0, false, errors.Trace(err)
	}

	if fsp >= len(s) {
		tmp, e := strconv.ParseInt(s, 10, 64)
		if e != nil {
			return 0, false, errors.Trace(e)
		}
		v = int(float64(tmp) * math.Pow10(MaxFsp-len(s)))
		return
	}

	/ Round when fsp < string length.
	tmp, e := strconv.ParseInt(s[:fsp+1], 10, 64)
	if e != nil {
		return 0, false, errors.Trace(e)
	}
	tmp = (tmp + 5) / 10

	if float64(tmp) >= math.Pow10(fsp) {
		/ overflow
		return 0, true, nil
	}

	/ Get the final frac, with 6 digit number
	/  1236 round 3 -> 124 -> 124000
	/  0312 round 2 -> 3 -> 30000
	/  999 round 2 -> 100 -> overflow
	v = int(float64(tmp) * math.Pow10(MaxFsp-fsp))
	return
}

/ alignFrac is used to generate alignment frac, like `100` -> `100000` ,`-100` -> `-100000`
func alignFrac(s string, fsp int) string {
	sl := len(s)
	if sl > 0 && s[0] == '-' {
		sl = sl - 1
	}
	if sl < fsp {
		return s + strings.Repeat("0", fsp-sl)
	}

	return s
}

相关信息

tidb 源码目录

相关文章

tidb binary_literal 源码

tidb compare 源码

tidb convert 源码

tidb core_time 源码

tidb datum 源码

tidb datum_eval 源码

tidb enum 源码

tidb errors 源码

tidb etc 源码

tidb eval_type 源码

^