90 Star 482 Fork 141

平凯星辰(北京)科技有限公司 / tidb

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
builtin_miscellaneous.go 23.19 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
// Copyright 2017 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,
// See the License for the specific language governing permissions and
// limitations under the License.
package expression
import (
"bytes"
"encoding/binary"
"fmt"
"math"
"net"
"strings"
"time"
"github.com/juju/errors"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/types"
"github.com/pingcap/tidb/types/json"
"github.com/pingcap/tidb/util/charset"
"github.com/twinj/uuid"
)
var (
_ functionClass = &sleepFunctionClass{}
_ functionClass = &lockFunctionClass{}
_ functionClass = &releaseLockFunctionClass{}
_ functionClass = &anyValueFunctionClass{}
_ functionClass = &defaultFunctionClass{}
_ functionClass = &inetAtonFunctionClass{}
_ functionClass = &inetNtoaFunctionClass{}
_ functionClass = &inet6AtonFunctionClass{}
_ functionClass = &inet6NtoaFunctionClass{}
_ functionClass = &isFreeLockFunctionClass{}
_ functionClass = &isIPv4FunctionClass{}
_ functionClass = &isIPv4CompatFunctionClass{}
_ functionClass = &isIPv4MappedFunctionClass{}
_ functionClass = &isIPv6FunctionClass{}
_ functionClass = &isUsedLockFunctionClass{}
_ functionClass = &masterPosWaitFunctionClass{}
_ functionClass = &nameConstFunctionClass{}
_ functionClass = &releaseAllLocksFunctionClass{}
_ functionClass = &uuidFunctionClass{}
_ functionClass = &uuidShortFunctionClass{}
)
var (
_ builtinFunc = &builtinSleepSig{}
_ builtinFunc = &builtinLockSig{}
_ builtinFunc = &builtinReleaseLockSig{}
_ builtinFunc = &builtinDecimalAnyValueSig{}
_ builtinFunc = &builtinDurationAnyValueSig{}
_ builtinFunc = &builtinIntAnyValueSig{}
_ builtinFunc = &builtinJSONAnyValueSig{}
_ builtinFunc = &builtinRealAnyValueSig{}
_ builtinFunc = &builtinStringAnyValueSig{}
_ builtinFunc = &builtinTimeAnyValueSig{}
_ builtinFunc = &builtinInetAtonSig{}
_ builtinFunc = &builtinInetNtoaSig{}
_ builtinFunc = &builtinInet6AtonSig{}
_ builtinFunc = &builtinInet6NtoaSig{}
_ builtinFunc = &builtinIsIPv4Sig{}
_ builtinFunc = &builtinIsIPv4CompatSig{}
_ builtinFunc = &builtinIsIPv4MappedSig{}
_ builtinFunc = &builtinIsIPv6Sig{}
_ builtinFunc = &builtinUUIDSig{}
)
type sleepFunctionClass struct {
baseFunctionClass
}
func (c *sleepFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETReal)
bf.tp.Flen = 21
sig := &builtinSleepSig{bf}
return sig, nil
}
type builtinSleepSig struct {
baseBuiltinFunc
}
func (b *builtinSleepSig) Clone() builtinFunc {
newSig := &builtinSleepSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinSleepSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_sleep
func (b *builtinSleepSig) evalInt(row types.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalReal(b.ctx, row)
if err != nil {
return 0, isNull, errors.Trace(err)
}
sessVars := b.ctx.GetSessionVars()
if isNull {
if sessVars.StrictSQLMode {
return 0, true, errIncorrectArgs.GenByArgs("sleep")
}
return 0, true, nil
}
// processing argument is negative
if val < 0 {
if sessVars.StrictSQLMode {
return 0, false, errIncorrectArgs.GenByArgs("sleep")
}
return 0, false, nil
}
if val > math.MaxFloat64/float64(time.Second.Nanoseconds()) {
return 0, false, errIncorrectArgs.GenByArgs("sleep")
}
dur := time.Duration(val * float64(time.Second.Nanoseconds()))
select {
case <-time.After(dur):
// TODO: Handle Ctrl-C is pressed in `mysql` client.
// return 1 when SLEEP() is KILLed
}
return 0, false, nil
}
type lockFunctionClass struct {
baseFunctionClass
}
func (c *lockFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString, types.ETInt)
sig := &builtinLockSig{bf}
bf.tp.Flen = 1
return sig, nil
}
type builtinLockSig struct {
baseBuiltinFunc
}
func (b *builtinLockSig) Clone() builtinFunc {
newSig := &builtinLockSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinLockSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_get-lock
// The lock function will do nothing.
// Warning: get_lock() function is parsed but ignored.
func (b *builtinLockSig) evalInt(_ types.Row) (int64, bool, error) {
return 1, false, nil
}
type releaseLockFunctionClass struct {
baseFunctionClass
}
func (c *releaseLockFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString)
sig := &builtinReleaseLockSig{bf}
bf.tp.Flen = 1
return sig, nil
}
type builtinReleaseLockSig struct {
baseBuiltinFunc
}
func (b *builtinReleaseLockSig) Clone() builtinFunc {
newSig := &builtinReleaseLockSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinReleaseLockSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_release-lock
// The release lock function will do nothing.
// Warning: release_lock() function is parsed but ignored.
func (b *builtinReleaseLockSig) evalInt(_ types.Row) (int64, bool, error) {
return 1, false, nil
}
type anyValueFunctionClass struct {
baseFunctionClass
}
func (c *anyValueFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
argTp := args[0].GetType().EvalType()
bf := newBaseBuiltinFuncWithTp(ctx, args, argTp, argTp)
args[0].GetType().Flag |= bf.tp.Flag
*bf.tp = *args[0].GetType()
var sig builtinFunc
switch argTp {
case types.ETDecimal:
sig = &builtinDecimalAnyValueSig{bf}
case types.ETDuration:
sig = &builtinDurationAnyValueSig{bf}
case types.ETInt:
bf.tp.Decimal = 0
sig = &builtinIntAnyValueSig{bf}
case types.ETJson:
sig = &builtinJSONAnyValueSig{bf}
case types.ETReal:
sig = &builtinRealAnyValueSig{bf}
case types.ETString:
bf.tp.Decimal = types.UnspecifiedLength
sig = &builtinStringAnyValueSig{bf}
case types.ETDatetime, types.ETTimestamp:
bf.tp.Charset, bf.tp.Collate, bf.tp.Flag = charset.CharsetUTF8, charset.CollationUTF8, 0
sig = &builtinTimeAnyValueSig{bf}
default:
panic("unexpected types.EvalType of builtin function ANY_VALUE")
}
return sig, nil
}
type builtinDecimalAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinDecimalAnyValueSig) Clone() builtinFunc {
newSig := &builtinDecimalAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalDecimal evals a builtinDecimalAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinDecimalAnyValueSig) evalDecimal(row types.Row) (*types.MyDecimal, bool, error) {
return b.args[0].EvalDecimal(b.ctx, row)
}
type builtinDurationAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinDurationAnyValueSig) Clone() builtinFunc {
newSig := &builtinDurationAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalDuration evals a builtinDurationAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinDurationAnyValueSig) evalDuration(row types.Row) (types.Duration, bool, error) {
return b.args[0].EvalDuration(b.ctx, row)
}
type builtinIntAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinIntAnyValueSig) Clone() builtinFunc {
newSig := &builtinIntAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinIntAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinIntAnyValueSig) evalInt(row types.Row) (int64, bool, error) {
return b.args[0].EvalInt(b.ctx, row)
}
type builtinJSONAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinJSONAnyValueSig) Clone() builtinFunc {
newSig := &builtinJSONAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalJSON evals a builtinJSONAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinJSONAnyValueSig) evalJSON(row types.Row) (json.BinaryJSON, bool, error) {
return b.args[0].EvalJSON(b.ctx, row)
}
type builtinRealAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinRealAnyValueSig) Clone() builtinFunc {
newSig := &builtinRealAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalReal evals a builtinRealAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinRealAnyValueSig) evalReal(row types.Row) (float64, bool, error) {
return b.args[0].EvalReal(b.ctx, row)
}
type builtinStringAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinStringAnyValueSig) Clone() builtinFunc {
newSig := &builtinStringAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalString evals a builtinStringAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinStringAnyValueSig) evalString(row types.Row) (string, bool, error) {
return b.args[0].EvalString(b.ctx, row)
}
type builtinTimeAnyValueSig struct {
baseBuiltinFunc
}
func (b *builtinTimeAnyValueSig) Clone() builtinFunc {
newSig := &builtinTimeAnyValueSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalTime evals a builtinTimeAnyValueSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
func (b *builtinTimeAnyValueSig) evalTime(row types.Row) (types.Time, bool, error) {
return b.args[0].EvalTime(b.ctx, row)
}
type defaultFunctionClass struct {
baseFunctionClass
}
func (c *defaultFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "DEFAULT")
}
type inetAtonFunctionClass struct {
baseFunctionClass
}
func (c *inetAtonFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString)
bf.tp.Flen = 21
bf.tp.Flag |= mysql.UnsignedFlag
sig := &builtinInetAtonSig{bf}
return sig, nil
}
type builtinInetAtonSig struct {
baseBuiltinFunc
}
func (b *builtinInetAtonSig) Clone() builtinFunc {
newSig := &builtinInetAtonSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinInetAtonSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet-aton
func (b *builtinInetAtonSig) evalInt(row types.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return 0, true, errors.Trace(err)
}
// ip address should not end with '.'.
if len(val) == 0 || val[len(val)-1] == '.' {
return 0, true, nil
}
var (
byteResult, result uint64
dotCount int
)
for _, c := range val {
if c >= '0' && c <= '9' {
digit := uint64(c - '0')
byteResult = byteResult*10 + digit
if byteResult > 255 {
return 0, true, nil
}
} else if c == '.' {
dotCount++
if dotCount > 3 {
return 0, true, nil
}
result = (result << 8) + byteResult
byteResult = 0
} else {
return 0, true, nil
}
}
// 127 -> 0.0.0.127
// 127.255 -> 127.0.0.255
// 127.256 -> NULL
// 127.2.1 -> 127.2.0.1
switch dotCount {
case 1:
result <<= 8
fallthrough
case 2:
result <<= 8
}
return int64((result << 8) + byteResult), false, nil
}
type inetNtoaFunctionClass struct {
baseFunctionClass
}
func (c *inetNtoaFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETInt)
bf.tp.Flen = 93
bf.tp.Decimal = 0
sig := &builtinInetNtoaSig{bf}
return sig, nil
}
type builtinInetNtoaSig struct {
baseBuiltinFunc
}
func (b *builtinInetNtoaSig) Clone() builtinFunc {
newSig := &builtinInetNtoaSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalString evals a builtinInetNtoaSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet-ntoa
func (b *builtinInetNtoaSig) evalString(row types.Row) (string, bool, error) {
val, isNull, err := b.args[0].EvalInt(b.ctx, row)
if err != nil || isNull {
return "", true, errors.Trace(err)
}
if val < 0 || uint64(val) > math.MaxUint32 {
//not an IPv4 address.
return "", true, nil
}
ip := make(net.IP, net.IPv4len)
binary.BigEndian.PutUint32(ip, uint32(val))
ipv4 := ip.To4()
if ipv4 == nil {
//Not a vaild ipv4 address.
return "", true, nil
}
return ipv4.String(), false, nil
}
type inet6AtonFunctionClass struct {
baseFunctionClass
}
func (c *inet6AtonFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString)
bf.tp.Flen = 16
types.SetBinChsClnFlag(bf.tp)
bf.tp.Decimal = 0
sig := &builtinInet6AtonSig{bf}
return sig, nil
}
type builtinInet6AtonSig struct {
baseBuiltinFunc
}
func (b *builtinInet6AtonSig) Clone() builtinFunc {
newSig := &builtinInet6AtonSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalString evals a builtinInet6AtonSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet6-aton
func (b *builtinInet6AtonSig) evalString(row types.Row) (string, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return "", true, errors.Trace(err)
}
if len(val) == 0 {
return "", true, nil
}
ip := net.ParseIP(val)
if ip == nil {
return "", true, nil
}
var isMappedIpv6 bool
if ip.To4() != nil && strings.Contains(val, ":") {
//mapped ipv6 address.
isMappedIpv6 = true
}
var result []byte
if isMappedIpv6 || ip.To4() == nil {
result = make([]byte, net.IPv6len)
} else {
result = make([]byte, net.IPv4len)
}
if isMappedIpv6 {
copy(result[12:], ip.To4())
result[11] = 0xff
result[10] = 0xff
} else if ip.To4() == nil {
copy(result, ip.To16())
} else {
copy(result, ip.To4())
}
return string(result[:]), false, nil
}
type inet6NtoaFunctionClass struct {
baseFunctionClass
}
func (c *inet6NtoaFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString)
bf.tp.Flen = 117
bf.tp.Decimal = 0
sig := &builtinInet6NtoaSig{bf}
return sig, nil
}
type builtinInet6NtoaSig struct {
baseBuiltinFunc
}
func (b *builtinInet6NtoaSig) Clone() builtinFunc {
newSig := &builtinInet6NtoaSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalString evals a builtinInet6NtoaSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet6-ntoa
func (b *builtinInet6NtoaSig) evalString(row types.Row) (string, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return "", true, errors.Trace(err)
}
ip := net.IP([]byte(val)).String()
if len(val) == net.IPv6len && !strings.Contains(ip, ":") {
ip = fmt.Sprintf("::ffff:%s", ip)
}
if net.ParseIP(ip) == nil {
return "", true, nil
}
return ip, false, nil
}
type isFreeLockFunctionClass struct {
baseFunctionClass
}
func (c *isFreeLockFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "IS_FREE_LOCK")
}
type isIPv4FunctionClass struct {
baseFunctionClass
}
func (c *isIPv4FunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString)
bf.tp.Flen = 1
sig := &builtinIsIPv4Sig{bf}
return sig, nil
}
type builtinIsIPv4Sig struct {
baseBuiltinFunc
}
func (b *builtinIsIPv4Sig) Clone() builtinFunc {
newSig := &builtinIsIPv4Sig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinIsIPv4Sig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4
func (b *builtinIsIPv4Sig) evalInt(row types.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return 0, err != nil, errors.Trace(err)
}
if isIPv4(val) {
return 1, false, nil
}
return 0, false, nil
}
// isIPv4 checks IPv4 address which satisfying the format A.B.C.D(0<=A/B/C/D<=255).
// Mapped IPv6 address like '::ffff:1.2.3.4' would return false.
func isIPv4(ip string) bool {
// acc: keep the decimal value of each segment under check, which should between 0 and 255 for valid IPv4 address.
// pd: sentinel for '.'
dots, acc, pd := 0, 0, true
for _, c := range ip {
switch {
case '0' <= c && c <= '9':
acc = acc*10 + int(c-'0')
pd = false
case c == '.':
dots++
if dots > 3 || acc > 255 || pd {
return false
}
acc, pd = 0, true
default:
return false
}
}
if dots != 3 || acc > 255 || pd {
return false
}
return true
}
type isIPv4CompatFunctionClass struct {
baseFunctionClass
}
func (c *isIPv4CompatFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString)
bf.tp.Flen = 1
sig := &builtinIsIPv4CompatSig{bf}
return sig, nil
}
type builtinIsIPv4CompatSig struct {
baseBuiltinFunc
}
func (b *builtinIsIPv4CompatSig) Clone() builtinFunc {
newSig := &builtinIsIPv4CompatSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals Is_IPv4_Compat
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4-compat
func (b *builtinIsIPv4CompatSig) evalInt(row types.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return 0, err != nil, errors.Trace(err)
}
ipAddress := []byte(val)
if len(ipAddress) != net.IPv6len {
//Not an IPv6 address, return false
return 0, false, nil
}
prefixCompat := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
if !bytes.HasPrefix(ipAddress, prefixCompat) {
return 0, false, nil
}
return 1, false, nil
}
type isIPv4MappedFunctionClass struct {
baseFunctionClass
}
func (c *isIPv4MappedFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString)
bf.tp.Flen = 1
sig := &builtinIsIPv4MappedSig{bf}
return sig, nil
}
type builtinIsIPv4MappedSig struct {
baseBuiltinFunc
}
func (b *builtinIsIPv4MappedSig) Clone() builtinFunc {
newSig := &builtinIsIPv4MappedSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals Is_IPv4_Mapped
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4-mapped
func (b *builtinIsIPv4MappedSig) evalInt(row types.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return 0, err != nil, errors.Trace(err)
}
ipAddress := []byte(val)
if len(ipAddress) != net.IPv6len {
//Not an IPv6 address, return false
return 0, false, nil
}
prefixMapped := []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}
if !bytes.HasPrefix(ipAddress, prefixMapped) {
return 0, false, nil
}
return 1, false, nil
}
type isIPv6FunctionClass struct {
baseFunctionClass
}
func (c *isIPv6FunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETInt, types.ETString)
bf.tp.Flen = 1
sig := &builtinIsIPv6Sig{bf}
return sig, nil
}
type builtinIsIPv6Sig struct {
baseBuiltinFunc
}
func (b *builtinIsIPv6Sig) Clone() builtinFunc {
newSig := &builtinIsIPv6Sig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalInt evals a builtinIsIPv6Sig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv6
func (b *builtinIsIPv6Sig) evalInt(row types.Row) (int64, bool, error) {
val, isNull, err := b.args[0].EvalString(b.ctx, row)
if err != nil || isNull {
return 0, err != nil, errors.Trace(err)
}
ip := net.ParseIP(val)
if ip != nil && !isIPv4(val) {
return 1, false, nil
}
return 0, false, nil
}
type isUsedLockFunctionClass struct {
baseFunctionClass
}
func (c *isUsedLockFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "IS_USED_LOCK")
}
type masterPosWaitFunctionClass struct {
baseFunctionClass
}
func (c *masterPosWaitFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "MASTER_POS_WAIT")
}
type nameConstFunctionClass struct {
baseFunctionClass
}
func (c *nameConstFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "NAME_CONST")
}
type releaseAllLocksFunctionClass struct {
baseFunctionClass
}
func (c *releaseAllLocksFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "RELEASE_ALL_LOCKS")
}
type uuidFunctionClass struct {
baseFunctionClass
}
func (c *uuidFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
if err := c.verifyArgs(args); err != nil {
return nil, errors.Trace(err)
}
bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString)
bf.tp.Flen = 36
sig := &builtinUUIDSig{bf}
return sig, nil
}
type builtinUUIDSig struct {
baseBuiltinFunc
}
func (b *builtinUUIDSig) Clone() builtinFunc {
newSig := &builtinUUIDSig{}
newSig.cloneFrom(&b.baseBuiltinFunc)
return newSig
}
// evalString evals a builtinUUIDSig.
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_uuid
func (b *builtinUUIDSig) evalString(_ types.Row) (d string, isNull bool, err error) {
return uuid.NewV1().String(), false, nil
}
type uuidShortFunctionClass struct {
baseFunctionClass
}
func (c *uuidShortFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenByArgs("FUNCTION", "UUID_SHORT")
}
Go
1
https://gitee.com/pingcap/tidb.git
git@gitee.com:pingcap/tidb.git
pingcap
tidb
tidb
v2.0.11

搜索帮助