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 } }