Skip to content

Instantly share code, notes, and snippets.

@kylebrandt
Created April 1, 2025 18:33
Show Gist options
  • Save kylebrandt/e96c08ce08db9188978d72bd30fa38c7 to your computer and use it in GitHub Desktop.
Save kylebrandt/e96c08ce08db9188978d72bd30fa38c7 to your computer and use it in GitHub Desktop.
Can't implement FunctionProvider
package sql
import (
"context"
"time"
mysql "github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/types"
)
type timeRangeKey struct{}
type TimeRange struct {
From time.Time
To time.Time
}
func WithTimeRange(ctx context.Context, from, to time.Time) context.Context {
return context.WithValue(ctx, timeRangeKey{}, TimeRange{From: from, To: to})
}
func GetTimeRange(ctx context.Context) (TimeRange, bool) {
tr, ok := ctx.Value(timeRangeKey{}).(TimeRange)
return tr, ok
}
//
// Expressions for time_from() and time_to()
//
type TimeFromExpr struct{}
func (e *TimeFromExpr) Resolved() bool { return true }
func (e *TimeFromExpr) IsNullable() bool { return false }
func (e *TimeFromExpr) Children() []mysql.Expression { return nil }
func (e *TimeFromExpr) WithChildren(...mysql.Expression) (mysql.Expression, error) {
return e, nil
}
func (e *TimeFromExpr) String() string { return "time_from()" }
func (e *TimeFromExpr) Type() mysql.Type { return types.Timestamp }
func (e *TimeFromExpr) Eval(ctx *mysql.Context, _ mysql.Row) (interface{}, error) {
if tr, ok := GetTimeRange(ctx.Context); ok {
return tr.From, nil
}
return nil, nil
}
type TimeToExpr struct{}
func (e *TimeToExpr) Resolved() bool { return true }
func (e *TimeToExpr) IsNullable() bool { return false }
func (e *TimeToExpr) Children() []mysql.Expression { return nil }
func (e *TimeToExpr) WithChildren(...mysql.Expression) (mysql.Expression, error) {
return e, nil
}
func (e *TimeToExpr) String() string { return "time_to()" }
func (e *TimeToExpr) Type() mysql.Type { return types.Timestamp }
func (e *TimeToExpr) Eval(ctx *mysql.Context, _ mysql.Row) (interface{}, error) {
if tr, ok := GetTimeRange(ctx.Context); ok {
return tr.To, nil
}
return nil, nil
}
//
// sql.Function implementations
//
type timeFromFunction struct{}
func (*timeFromFunction) isFunction() {}
func (f *timeFromFunction) FunctionName() string {
return "time_from"
}
func (f *timeFromFunction) NewInstance(args []mysql.Expression) (mysql.Expression, error) {
return &TimeFromExpr{}, nil
}
type timeToFunction struct{}
func (*timeToFunction) isFunction() {}
func (f *timeToFunction) FunctionName() string {
return "time_to"
}
func (f *timeToFunction) NewInstance(args []mysql.Expression) (mysql.Expression, error) {
return &TimeToExpr{}, nil
}
//
// FunctionProvider to register both functions
//
type TimeFuncProvider struct{}
func (p *TimeFuncProvider) Function(ctx *mysql.Context, name string) (mysql.Function, bool) {
switch name {
case "time_from":
return &timeFromFunction{}, true
case "time_to":
return &timeToFunction{}, true
default:
return nil, false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment