Skip to content

Implementing Custom Functions, blocked by unexported method? #2922

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kylebrandt opened this issue Apr 1, 2025 · 2 comments
Closed

Implementing Custom Functions, blocked by unexported method? #2922

kylebrandt opened this issue Apr 1, 2025 · 2 comments

Comments

@kylebrandt
Copy link
Contributor

I am a bit confused about registering custom functions. RegisterFunction seems
to suggest to implement the FunctionProvider interface, but that returns
the Function interface, which has a private method isFunction to restrict implementation.

// RegisterFunction registers the functions given, adding them to the built-in functions.
// Integrators with custom functions should typically use the FunctionProvider interface instead.
func (c *Catalog) RegisterFunction(ctx *sql.Context, fns ...sql.Function) {
	for _, fn := range fns {
		err := c.builtInFunctions.Register(fn)
		if err != nil {
			panic(err)
		}
	}
}

But

// Function is a function defined by the user that can be applied in a SQL query.
type Function interface {
	// NewInstance returns a new instance of the function to evaluate against rows
	NewInstance([]Expression) (Expression, error)
	// FunctionName returns the name of this function
	FunctionName() string
	// isFunction is a private method to restrict implementations of Function
	isFunction()
}

// FunctionProvider is an interface that allows custom functions to be provided. It's usually (but not always)
// implemented by a DatabaseProvider.
type FunctionProvider interface {
	// Function returns the function with the name provided, case-insensitive
	Function(ctx *Context, name string) (Function, bool)
}
@kylebrandt
Copy link
Contributor Author

kylebrandt commented Apr 1, 2025

Update: I think maybe I should be wrapping funcs with FunctionX, e.g. FunctionN ?

@zachmu
Copy link
Member

zachmu commented Apr 1, 2025

Hi Kyle,

Yes, you have the right idea: you have to choose a FunctionX type to return from your FunctionProvider.

As for Catalog.RegisterFunction: this is an old and obsolete method from very early in development and we don't recommend using it. The correct way to implement custom function support is with a FunctionProvider, which is usually your DatabaseProvider.

Let me know if there's anything else I can tell you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants