github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/sql/sem/tree/function_name.go (about) 1 // Copyright 2016 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package tree 12 13 import ( 14 "fmt" 15 16 "github.com/cockroachdb/cockroach/pkg/sql/sessiondata" 17 "github.com/cockroachdb/cockroach/pkg/util/log" 18 "github.com/cockroachdb/errors" 19 ) 20 21 // Function names are used in expressions in the FuncExpr node. 22 // General syntax: 23 // [ <context-prefix> . ] <function-name> 24 // 25 // The other syntax nodes hold a mutable ResolvableFunctionReference 26 // attribute. This is populated during parsing with an 27 // UnresolvedName, and gets assigned a FunctionDefinition upon the 28 // first call to its Resolve() method. 29 30 // ResolvableFunctionReference implements the editable reference cell 31 // of a FuncExpr. The FunctionRerence is updated by the Normalize() 32 // method. 33 type ResolvableFunctionReference struct { 34 FunctionReference 35 } 36 37 // Format implements the NodeFormatter interface. 38 func (fn *ResolvableFunctionReference) Format(ctx *FmtCtx) { 39 ctx.FormatNode(fn.FunctionReference) 40 } 41 func (fn *ResolvableFunctionReference) String() string { return AsString(fn) } 42 43 // Resolve checks if the function name is already resolved and 44 // resolves it as necessary. 45 func (fn *ResolvableFunctionReference) Resolve( 46 searchPath sessiondata.SearchPath, 47 ) (*FunctionDefinition, error) { 48 switch t := fn.FunctionReference.(type) { 49 case *FunctionDefinition: 50 return t, nil 51 case *UnresolvedName: 52 fd, err := t.ResolveFunction(searchPath) 53 if err != nil { 54 return nil, err 55 } 56 fn.FunctionReference = fd 57 return fd, nil 58 default: 59 return nil, errors.AssertionFailedf("unknown function name type: %+v (%T)", 60 fn.FunctionReference, fn.FunctionReference, 61 ) 62 } 63 } 64 65 // WrapFunction creates a new ResolvableFunctionReference 66 // holding a pre-resolved function. Helper for grammar rules. 67 func WrapFunction(n string) ResolvableFunctionReference { 68 fd, ok := FunDefs[n] 69 if !ok { 70 panic(errors.AssertionFailedf("function %s() not defined", log.Safe(n))) 71 } 72 return ResolvableFunctionReference{fd} 73 } 74 75 // FunctionReference is the common interface to UnresolvedName and QualifiedFunctionName. 76 type FunctionReference interface { 77 fmt.Stringer 78 NodeFormatter 79 functionReference() 80 } 81 82 func (*UnresolvedName) functionReference() {} 83 func (*FunctionDefinition) functionReference() {}