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() {}