446 lines
14 KiB
Go
446 lines
14 KiB
Go
// 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 (
|
|
"github.com/juju/errors"
|
|
"github.com/pingcap/tidb/context"
|
|
"github.com/pingcap/tidb/util/types"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
_ functionClass = &sleepFunctionClass{}
|
|
_ functionClass = &lockFunctionClass{}
|
|
_ functionClass = &releaseLockFunctionClass{}
|
|
_ functionClass = &anyValueFunctionClass{}
|
|
_ functionClass = &defaultFunctionClass{}
|
|
_ functionClass = &inetAtonFunctionClass{}
|
|
_ functionClass = &inetNtoaFunctionClass{}
|
|
_ functionClass = &inet6AtonFunctionClass{}
|
|
_ functionClass = &inet6NtonFunctionClass{}
|
|
_ 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 = &builtinAnyValueSig{}
|
|
_ builtinFunc = &builtinDefaultSig{}
|
|
_ builtinFunc = &builtinInetAtonSig{}
|
|
_ builtinFunc = &builtinInetNtoaSig{}
|
|
_ builtinFunc = &builtinInet6AtonSig{}
|
|
_ builtinFunc = &builtinInet6NtonSig{}
|
|
_ builtinFunc = &builtinIsFreeLockSig{}
|
|
_ builtinFunc = &builtinIsIPv4Sig{}
|
|
_ builtinFunc = &builtinIsIPv4CompatSig{}
|
|
_ builtinFunc = &builtinIsIPv4MappedSig{}
|
|
_ builtinFunc = &builtinIsIPv6Sig{}
|
|
_ builtinFunc = &builtinIsUsedLockSig{}
|
|
_ builtinFunc = &builtinMasterPosWaitSig{}
|
|
_ builtinFunc = &builtinNameConstSig{}
|
|
_ builtinFunc = &builtinReleaseAllLocksSig{}
|
|
_ builtinFunc = &builtinUUIDSig{}
|
|
_ builtinFunc = &builtinUUIDShortSig{}
|
|
)
|
|
|
|
type sleepFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *sleepFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
err := errors.Trace(c.verifyArgs(args))
|
|
bt := &builtinSleepSig{newBaseBuiltinFunc(args, ctx)}
|
|
bt.deterministic = false
|
|
return bt, errors.Trace(err)
|
|
}
|
|
|
|
type builtinSleepSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See http://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_sleep
|
|
func (b *builtinSleepSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
args, err := b.evalArgs(row)
|
|
if err != nil {
|
|
return types.Datum{}, errors.Trace(err)
|
|
}
|
|
sessVars := b.ctx.GetSessionVars()
|
|
if args[0].IsNull() {
|
|
if sessVars.StrictSQLMode {
|
|
return d, errors.New("incorrect arguments to sleep")
|
|
}
|
|
d.SetInt64(0)
|
|
return
|
|
}
|
|
// processing argument is negative
|
|
zero := types.NewIntDatum(0)
|
|
sc := sessVars.StmtCtx
|
|
ret, err := args[0].CompareDatum(sc, zero)
|
|
if err != nil {
|
|
return d, errors.Trace(err)
|
|
}
|
|
if ret == -1 {
|
|
if sessVars.StrictSQLMode {
|
|
return d, errors.New("incorrect arguments to sleep")
|
|
}
|
|
d.SetInt64(0)
|
|
return
|
|
}
|
|
|
|
// TODO: consider it's interrupted using KILL QUERY from other session, or
|
|
// interrupted by time out.
|
|
duration := time.Duration(args[0].GetFloat64() * float64(time.Second.Nanoseconds()))
|
|
time.Sleep(duration)
|
|
d.SetInt64(0)
|
|
return
|
|
}
|
|
|
|
type lockFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *lockFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinLockSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinLockSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// The lock function will do nothing.
|
|
// Warning: get_lock() function is parsed but ignored.
|
|
func (b *builtinLockSig) eval(_ []types.Datum) (d types.Datum, err error) {
|
|
d.SetInt64(1)
|
|
return d, nil
|
|
}
|
|
|
|
type releaseLockFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *releaseLockFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinReleaseLockSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinReleaseLockSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// The release lock function will do nothing.
|
|
// Warning: release_lock() function is parsed but ignored.
|
|
func (b *builtinReleaseLockSig) eval(_ []types.Datum) (d types.Datum, err error) {
|
|
d.SetInt64(1)
|
|
return
|
|
}
|
|
|
|
type anyValueFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *anyValueFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinAnyValueSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinAnyValueSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_any-value
|
|
func (b *builtinAnyValueSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("ANY_VALUE")
|
|
}
|
|
|
|
type defaultFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *defaultFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinDefaultSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinDefaultSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_default
|
|
func (b *builtinDefaultSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("DEFAULT")
|
|
}
|
|
|
|
type inetAtonFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *inetAtonFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinInetAtonSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinInetAtonSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet-aton
|
|
func (b *builtinInetAtonSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("INET_ATON")
|
|
}
|
|
|
|
type inetNtoaFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *inetNtoaFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinInetNtoaSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinInetNtoaSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet-ntoa
|
|
func (b *builtinInetNtoaSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("INET_NTOA")
|
|
}
|
|
|
|
type inet6AtonFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *inet6AtonFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinInet6AtonSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinInet6AtonSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet6-aton
|
|
func (b *builtinInet6AtonSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("INET6_ATON")
|
|
}
|
|
|
|
type inet6NtonFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *inet6NtonFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinInet6NtonSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinInet6NtonSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_inet6-ntoa
|
|
func (b *builtinInet6NtonSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("INET6_NTON")
|
|
}
|
|
|
|
type isFreeLockFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *isFreeLockFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinIsFreeLockSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinIsFreeLockSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-free-lock
|
|
func (b *builtinIsFreeLockSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("IS_FREE_LOCK")
|
|
}
|
|
|
|
type isIPv4FunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *isIPv4FunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinIsIPv4Sig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinIsIPv4Sig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4
|
|
func (b *builtinIsIPv4Sig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("IS_IPV4")
|
|
}
|
|
|
|
type isIPv4CompatFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *isIPv4CompatFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinIsIPv4CompatSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinIsIPv4CompatSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4-compat
|
|
func (b *builtinIsIPv4CompatSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("IS_IPV4_COMPAT")
|
|
}
|
|
|
|
type isIPv4MappedFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *isIPv4MappedFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinIsIPv4MappedSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinIsIPv4MappedSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv4-mapped
|
|
func (b *builtinIsIPv4MappedSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("IS_IPV4_MAPPED")
|
|
}
|
|
|
|
type isIPv6FunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *isIPv6FunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinIsIPv6Sig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinIsIPv6Sig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-ipv6
|
|
func (b *builtinIsIPv6Sig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("IS_IPV6")
|
|
}
|
|
|
|
type isUsedLockFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *isUsedLockFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinIsUsedLockSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinIsUsedLockSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_is-used-lock
|
|
func (b *builtinIsUsedLockSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("IS_USED_LOCK")
|
|
}
|
|
|
|
type masterPosWaitFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *masterPosWaitFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinMasterPosWaitSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinMasterPosWaitSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_master-pos-wait
|
|
func (b *builtinMasterPosWaitSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("MASTER_POS_WAIT")
|
|
}
|
|
|
|
type nameConstFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *nameConstFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinNameConstSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinNameConstSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_name-const
|
|
func (b *builtinNameConstSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("NAME_CONST")
|
|
}
|
|
|
|
type releaseAllLocksFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *releaseAllLocksFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinReleaseAllLocksSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinReleaseAllLocksSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_release-all-locks
|
|
func (b *builtinReleaseAllLocksSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("RELEASEA_ALL_LOCKS")
|
|
}
|
|
|
|
type uuidFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *uuidFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinUUIDSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinUUIDSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_uuid
|
|
func (b *builtinUUIDSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("UUID")
|
|
}
|
|
|
|
type uuidShortFunctionClass struct {
|
|
baseFunctionClass
|
|
}
|
|
|
|
func (c *uuidShortFunctionClass) getFunction(args []Expression, ctx context.Context) (builtinFunc, error) {
|
|
return &builtinUUIDShortSig{newBaseBuiltinFunc(args, ctx)}, errors.Trace(c.verifyArgs(args))
|
|
}
|
|
|
|
type builtinUUIDShortSig struct {
|
|
baseBuiltinFunc
|
|
}
|
|
|
|
// See https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html#function_uuid-short
|
|
func (b *builtinUUIDShortSig) eval(row []types.Datum) (d types.Datum, err error) {
|
|
return d, errFunctionNotExists.GenByArgs("UUID_SHORT")
|
|
}
|