expression, planner: check function exists with schema name (#46767)

close pingcap/tidb#46744
This commit is contained in:
Hangjie Mo
2023-09-08 14:50:13 +08:00
committed by GitHub
parent c6eb7bb7b1
commit fa0c5ced65
9 changed files with 22 additions and 15 deletions

View File

@ -1916,6 +1916,11 @@ error = '''
Illegal mix of collations for operation '%s'
'''
["expression:1305"]
error = '''
%s %s does not exist
'''
["expression:1365"]
error = '''
Division by 0

View File

@ -423,7 +423,7 @@ type desDecryptFunctionClass struct {
}
func (c *desDecryptFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_DECRYPT")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_DECRYPT")
}
type desEncryptFunctionClass struct {
@ -431,7 +431,7 @@ type desEncryptFunctionClass struct {
}
func (c *desEncryptFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_ENCRYPT")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "DES_ENCRYPT")
}
type encodeFunctionClass struct {
@ -486,7 +486,7 @@ type encryptFunctionClass struct {
}
func (c *encryptFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "ENCRYPT")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "ENCRYPT")
}
type oldPasswordFunctionClass struct {
@ -494,7 +494,7 @@ type oldPasswordFunctionClass struct {
}
func (c *oldPasswordFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "OLD_PASSWORD")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "OLD_PASSWORD")
}
type passwordFunctionClass struct {

View File

@ -466,7 +466,7 @@ type defaultFunctionClass struct {
}
func (c *defaultFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "DEFAULT")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "DEFAULT")
}
type inetAtonFunctionClass struct {
@ -1084,7 +1084,7 @@ type masterPosWaitFunctionClass struct {
}
func (c *masterPosWaitFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "MASTER_POS_WAIT")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "MASTER_POS_WAIT")
}
type nameConstFunctionClass struct {
@ -1308,7 +1308,7 @@ type uuidShortFunctionClass struct {
}
func (c *uuidShortFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", "UUID_SHORT")
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", "UUID_SHORT")
}
type vitessHashFunctionClass struct {

View File

@ -166,7 +166,7 @@ func TestDisplayName(t *testing.T) {
func newFunctionForTest(ctx sessionctx.Context, funcName string, args ...Expression) (Expression, error) {
fc, ok := funcs[funcName]
if !ok {
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", funcName)
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", funcName)
}
funcArgs := make([]Expression, len(args))
copy(funcArgs, args)

View File

@ -1086,7 +1086,7 @@ func getSignatureByPB(ctx sessionctx.Context, sigCode tipb.ScalarFuncSig, tp *ti
f = &builtinInternalFromBinarySig{base}
default:
e = errFunctionNotExists.GenWithStackByArgs("FUNCTION", sigCode)
e = ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", sigCode)
return nil, e
}
f.setPbCode(sigCode)

View File

@ -41,9 +41,9 @@ var (
ErrInvalidJSONForFuncIndex = dbterror.ClassExpression.NewStd(mysql.ErrInvalidJSONValueForFuncIndex)
ErrDataOutOfRangeFuncIndex = dbterror.ClassExpression.NewStd(mysql.ErrDataOutOfRangeFunctionalIndex)
ErrFuncIndexDataIsTooLong = dbterror.ClassExpression.NewStd(mysql.ErrFunctionalIndexDataIsTooLong)
ErrFunctionNotExists = dbterror.ClassExpression.NewStd(mysql.ErrSpDoesNotExist)
// All the un-exported errors are defined here:
errFunctionNotExists = dbterror.ClassExpression.NewStd(mysql.ErrSpDoesNotExist)
errZlibZData = dbterror.ClassExpression.NewStd(mysql.ErrZlibZData)
errZlibZBuf = dbterror.ClassExpression.NewStd(mysql.ErrZlibZBuf)
errIncorrectArgs = dbterror.ClassExpression.NewStd(mysql.ErrWrongArguments)

View File

@ -3717,15 +3717,14 @@ func TestNotExistFunc(t *testing.T) {
// current db is empty
tk.MustGetErrMsg("SELECT xxx(1)", "[planner:1046]No database selected")
tk.MustGetErrMsg("SELECT yyy()", "[planner:1046]No database selected")
tk.MustGetErrMsg("SELECT T.upper(1)", "[expression:1305]FUNCTION t.upper does not exist")
// current db is not empty
tk.MustExec("use test")
tk.MustGetErrMsg("SELECT xxx(1)", "[expression:1305]FUNCTION test.xxx does not exist")
tk.MustGetErrMsg("SELECT yyy()", "[expression:1305]FUNCTION test.yyy does not exist")
tk.MustExec("use test")
tk.MustGetErrMsg("SELECT t.upper(1)", "[expression:1305]FUNCTION t.upper does not exist")
tk.MustGetErrMsg("SELECT timestampliteral(rand())", "[expression:1305]FUNCTION test.timestampliteral does not exist")
}

View File

@ -214,7 +214,7 @@ func newFunctionImpl(ctx sessionctx.Context, fold int, funcName string, retType
if db == "" {
return nil, errors.Trace(ErrNoDB)
}
return nil, errFunctionNotExists.GenWithStackByArgs("FUNCTION", db+"."+funcName)
return nil, ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", db+"."+funcName)
}
noopFuncsMode := ctx.GetSessionVars().NoopFuncsMode
if noopFuncsMode != variable.OnInt {

View File

@ -354,7 +354,10 @@ func (p *preprocessor) Enter(in ast.Node) (out ast.Node, skipChildren bool) {
if node.FnName.L == ast.NextVal || node.FnName.L == ast.LastVal || node.FnName.L == ast.SetVal {
p.flag |= inSequenceFunction
}
// not support procedure right now.
if node.Schema.L != "" {
p.err = expression.ErrFunctionNotExists.GenWithStackByArgs("FUNCTION", node.Schema.L+"."+node.FnName.L)
}
case *ast.BRIEStmt:
if node.Kind == ast.BRIEKindRestore {
p.flag |= inCreateOrDropTable