func (v Value) IsSigned() bool {
	return IsSigned(v.typ)
}
IsSigned returns true if Value is a signed integral.
package sqltypes
import (
	"encoding/base64"
	"errors"
	"fmt"
	"math"
	"strconv"
	"strings"
	"time"
	"github.com/xelabs/go-mysqlstack/sqlparser/depends/common"
	querypb "github.com/xelabs/go-mysqlstack/sqlparser/depends/query"
)
var (
	NULL = Value{}
	DontEscape = byte(255)
	nullstr    = []byte("null")
)
type BinWriter interface {
	Write([]byte) (int, error)
	WriteByte(byte) error
}
type Value struct {
	typ querypb.Type
	val []byte
}
func NewValue(typ querypb.Type, val []byte) (v Value, err error) {
	switch {
	case IsSigned(typ):
		if _, err := strconv.ParseInt(string(val), 0, 64); err != nil {
			return NULL, err
		}
		return MakeTrusted(typ, val), nil
	case IsUnsigned(typ):
		if _, err := strconv.ParseUint(string(val), 0, 64); err != nil {
			return NULL, err
		}
		return MakeTrusted(typ, val), nil
	case IsFloat(typ) || typ == Decimal:
		if _, err := strconv.ParseFloat(string(val), 64); err != nil {
			return NULL, err
		}
		return MakeTrusted(typ, val), nil
	case IsQuoted(typ) || typ == Bit || typ == Null:
		return MakeTrusted(typ, val), nil
	}
	return NULL, fmt.Errorf("invalid type specified for MakeValue: %v", typ)
}
func MakeTrusted(typ querypb.Type, val []byte) Value {
	if typ == Null {
		return NULL
	}
	return Value{typ: typ, val: val}
}
func NewInt64(v int64) Value {
	return MakeTrusted(Int64, strconv.AppendInt(nil, v, 10))
}
func NewInt32(v int32) Value {
	return MakeTrusted(Int32, strconv.AppendInt(nil, int64(v), 10))
}
func NewUint64(v uint64) Value {
	return MakeTrusted(Uint64, strconv.AppendUint(nil, v, 10))
}
func NewFloat32(v float32) Value {
	return MakeTrusted(Float32, strconv.AppendFloat(nil, float64(v), 'f', -1, 64))
}
func NewFloat64(v float64) Value {
	return MakeTrusted(Float64, strconv.AppendFloat(nil, v, 'g', -1, 64))
}
func NewVarChar(v string) Value {
	return MakeTrusted(VarChar, []byte(v))
}
func NewVarBinary(v string) Value {
	return MakeTrusted(VarBinary, []byte(v))
}
func NewIntegral(val string) (n Value, err error) {
	signed, err := strconv.ParseInt(val, 0, 64)
	if err == nil {
		return MakeTrusted(Int64, strconv.AppendInt(nil, signed, 10)), nil
	}
	unsigned, err := strconv.ParseUint(val, 0, 64)
	if err != nil {
		return Value{}, err
	}
	return MakeTrusted(Uint64, strconv.AppendUint(nil, unsigned, 10)), nil
}
func MakeString(val []byte) Value {
	return MakeTrusted(VarBinary, val)
}
func BuildValue(goval interface{}) (v Value, err error) {
	switch goval := goval.(type) {
	case nil:
	case []byte:
		v = MakeTrusted(VarBinary, goval)
	case int64:
		v = MakeTrusted(Int64, strconv.AppendInt(nil, int64(goval), 10))
	case uint64:
		v = MakeTrusted(Uint64, strconv.AppendUint(nil, uint64(goval), 10))
	case float64:
		v = MakeTrusted(Float64, strconv.AppendFloat(nil, goval, 'f', -1, 64))
	case int:
		v = MakeTrusted(Int64, strconv.AppendInt(nil, int64(goval), 10))
	case int8:
		v = MakeTrusted(Int8, strconv.AppendInt(nil, int64(goval), 10))
	case int16:
		v = MakeTrusted(Int16, strconv.AppendInt(nil, int64(goval), 10))
	case int32:
		v = MakeTrusted(Int32, strconv.AppendInt(nil, int64(goval), 10))
	case uint:
		v = MakeTrusted(Uint64, strconv.AppendUint(nil, uint64(goval), 10))
	case uint8:
		v = MakeTrusted(Uint8, strconv.AppendUint(nil, uint64(goval), 10))
	case uint16:
		v = MakeTrusted(Uint16, strconv.AppendUint(nil, uint64(goval), 10))
	case uint32:
		v = MakeTrusted(Uint32, strconv.AppendUint(nil, uint64(goval), 10))
	case float32:
		v = MakeTrusted(Float32, strconv.AppendFloat(nil, float64(goval), 'f', -1, 64))
	case string:
		v = MakeTrusted(VarBinary, []byte(goval))
	case time.Time:
		v = MakeTrusted(Datetime, []byte(goval.Format("2006-01-02 15:04:05")))
	case Value:
		v = goval
	case *querypb.BindVariable:
		return ValueFromBytes(goval.Type, goval.Value)
	default:
		return v, fmt.Errorf("unexpected type %T: %v", goval, goval)
	}
	return v, nil
}
func BuildConverted(typ querypb.Type, goval interface{}) (v Value, err error) {
	if IsIntegral(typ) {
		switch goval := goval.(type) {
		case []byte:
			return ValueFromBytes(typ, goval)
		case string:
			return ValueFromBytes(typ, []byte(goval))
		case Value:
			if goval.IsQuoted() {
				return ValueFromBytes(typ, goval.Raw())
			}
		}
	}
	return BuildValue(goval)
}
func ValueFromBytes(typ querypb.Type, val []byte) (v Value, err error) {
	switch {
	case IsSigned(typ):
		signed, err := strconv.ParseInt(string(val), 0, 64)
		if err != nil {
			return NULL, err
		}
		v = MakeTrusted(typ, strconv.AppendInt(nil, signed, 10))
	case IsUnsigned(typ):
		unsigned, err := strconv.ParseUint(string(val), 0, 64)
		if err != nil {
			return NULL, err
		}
		v = MakeTrusted(typ, strconv.AppendUint(nil, unsigned, 10))
	case typ == Tuple:
		return NULL, errors.New("tuple not allowed for ValueFromBytes")
	case IsFloat(typ) || typ == Decimal:
		_, err := strconv.ParseFloat(string(val), 64)
		if err != nil {
			return NULL, err
		}
		fallthrough
	default:
		v = MakeTrusted(typ, val)
	}
	return v, nil
}
func BuildIntegral(val string) (n Value, err error) {
	signed, err := strconv.ParseInt(val, 0, 64)
	if err == nil {
		return MakeTrusted(Int64, strconv.AppendInt(nil, signed, 10)), nil
	}
	unsigned, err := strconv.ParseUint(val, 0, 64)
	if err != nil {
		return Value{}, err
	}
	return MakeTrusted(Uint64, strconv.AppendUint(nil, unsigned, 10)), nil
}
func (v Value) Type() querypb.Type {
	return v.typ
}
func (v Value) Raw() []byte {
	return v.val
}
func (v Value) Len() int {
	return len(v.val)
}
type Values []Value
func (vs Values) Len() int {
	len := 0
	for _, v := range vs {
		len += v.Len()
	}
	return len
}
func (v Value) String() string {
	return common.BytesToString(v.val)
}
func (v Value) ToNative() interface{} {
	var out interface{}
	var err error
	switch {
	case v.typ == Null:
	case IsSigned(v.typ):
		out, err = v.ParseInt64()
	case IsUnsigned(v.typ):
		out, err = v.ParseUint64()
	case IsFloat(v.typ):
		out, err = v.ParseFloat64()
	case v.typ == Tuple:
		err = errors.New("unexpected tuple")
	default:
		out = v.val
	}
	if err != nil {
		panic(err)
	}
	return out
}
func (v Value) ParseInt64() (val int64, err error) {
	return strconv.ParseInt(v.String(), 10, 64)
}
func (v Value) ParseUint64() (val uint64, err error) {
	return strconv.ParseUint(v.String(), 10, 64)
}
func (v Value) ParseFloat64() (val float64, err error) {
	return strconv.ParseFloat(v.String(), 64)
}
func (v Value) EncodeSQL(b BinWriter) {
	_ = v.ToNative()
	switch {
	case v.typ == Null:
		writebytes(nullstr, b)
	case IsQuoted(v.typ):
		encodeBytesSQL(v.val, b)
	default:
		writebytes(v.val, b)
	}
}
func (v Value) EncodeASCII(b BinWriter) {
	_ = v.ToNative()
	switch {
	case v.typ == Null:
		writebytes(nullstr, b)
	case IsQuoted(v.typ):
		encodeBytesASCII(v.val, b)
	default:
		writebytes(v.val, b)
	}
}
func (v Value) IsNull() bool {
	return v.typ == Null
}
func (v Value) IsIntegral() bool {
	return IsIntegral(v.typ)
}