func (d *Week) FunctionName() string {
	return "week"
}
FunctionName implements sql.FunctionExpression
package function
import (
	"fmt"
	"strings"
	"time"
	"gopkg.in/src-d/go-errors.v1"
	"github.com/dolthub/go-mysql-server/sql"
	"github.com/dolthub/go-mysql-server/sql/expression"
)
var ErrInvalidArgument = errors.NewKind("invalid argument to function %s. %s.")
var ErrInvalidArgumentType = errors.NewKind("function '%s' received invalid argument types")
var ErrTimeUnexpectedlyNil = errors.NewKind("time in function '%s' unexpectedly nil")
var ErrUnknownType = errors.NewKind("function '%s' encountered unknown type %T")
func getDate(ctx *sql.Context,
	u expression.UnaryExpression,
	row sql.Row) (interface{}, error) {
	val, err := u.Child.Eval(ctx, row)
	if err != nil {
		return nil, err
	}
	if val == nil {
		return nil, nil
	}
	date, err := sql.Datetime.ConvertWithoutRangeCheck(val)
	if err != nil {
		date = sql.Datetime.Zero().(time.Time)
	}
	return date, nil
}
func getDatePart(ctx *sql.Context,
	u expression.UnaryExpression,
	row sql.Row,
	f func(interface{}) interface{}) (interface{}, error) {
	date, err := getDate(ctx, u, row)
	if err != nil {
		return nil, err
	}
	return f(date), nil
}
type Year struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Year)(nil)
func NewYear(date sql.Expression) sql.Expression {
	return &Year{expression.UnaryExpression{Child: date}}
}
func (y *Year) FunctionName() string {
	return "year"
}
func (y *Year) String() string { return fmt.Sprintf("YEAR(%s)", y.Child) }
func (y *Year) Type() sql.Type { return sql.Int32 }
func (y *Year) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, y.UnaryExpression, row, year)
}
func (y *Year) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(y, len(children), 1)
	}
	return NewYear(children[0]), nil
}
type Month struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Month)(nil)
func NewMonth(date sql.Expression) sql.Expression {
	return &Month{expression.UnaryExpression{Child: date}}
}
func (m *Month) FunctionName() string {
	return "month"
}
func (m *Month) String() string { return fmt.Sprintf("MONTH(%s)", m.Child) }
func (m *Month) Type() sql.Type { return sql.Int32 }
func (m *Month) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, m.UnaryExpression, row, month)
}
func (m *Month) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1)
	}
	return NewMonth(children[0]), nil
}
type Day struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Day)(nil)
func NewDay(date sql.Expression) sql.Expression {
	return &Day{expression.UnaryExpression{Child: date}}
}
func (d *Day) FunctionName() string {
	return "day"
}
func (d *Day) String() string { return fmt.Sprintf("DAY(%s)", d.Child) }
func (d *Day) Type() sql.Type { return sql.Int32 }
func (d *Day) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, d.UnaryExpression, row, day)
}
func (d *Day) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1)
	}
	return NewDay(children[0]), nil
}
type Weekday struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Weekday)(nil)
func NewWeekday(date sql.Expression) sql.Expression {
	return &Weekday{expression.UnaryExpression{Child: date}}
}
func (d *Weekday) FunctionName() string {
	return "weekday"
}
func (d *Weekday) String() string { return fmt.Sprintf("WEEKDAY(%s)", d.Child) }
func (d *Weekday) Type() sql.Type { return sql.Int32 }
func (d *Weekday) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, d.UnaryExpression, row, weekday)
}
func (d *Weekday) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1)
	}
	return NewWeekday(children[0]), nil
}
type Hour struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Hour)(nil)
func NewHour(date sql.Expression) sql.Expression {
	return &Hour{expression.UnaryExpression{Child: date}}
}
func (h *Hour) FunctionName() string {
	return "hour"
}
func (h *Hour) String() string { return fmt.Sprintf("HOUR(%s)", h.Child) }
func (h *Hour) Type() sql.Type { return sql.Int32 }
func (h *Hour) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, h.UnaryExpression, row, hour)
}
func (h *Hour) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(h, len(children), 1)
	}
	return NewHour(children[0]), nil
}
type Minute struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Minute)(nil)
func NewMinute(date sql.Expression) sql.Expression {
	return &Minute{expression.UnaryExpression{Child: date}}
}
func (m *Minute) FunctionName() string {
	return "minute"
}
func (m *Minute) String() string { return fmt.Sprintf("MINUTE(%d)", m.Child) }
func (m *Minute) Type() sql.Type { return sql.Int32 }
func (m *Minute) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, m.UnaryExpression, row, minute)
}
func (m *Minute) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(m, len(children), 1)
	}
	return NewMinute(children[0]), nil
}
type Second struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*Second)(nil)
func NewSecond(date sql.Expression) sql.Expression {
	return &Second{expression.UnaryExpression{Child: date}}
}
func (s *Second) FunctionName() string {
	return "second"
}
func (s *Second) String() string { return fmt.Sprintf("SECOND(%s)", s.Child) }
func (s *Second) Type() sql.Type { return sql.Int32 }
func (s *Second) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, s.UnaryExpression, row, second)
}
func (s *Second) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(s, len(children), 1)
	}
	return NewSecond(children[0]), nil
}
type DayOfWeek struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*DayOfWeek)(nil)
func NewDayOfWeek(date sql.Expression) sql.Expression {
	return &DayOfWeek{expression.UnaryExpression{Child: date}}
}
func (d *DayOfWeek) FunctionName() string {
	return "dayofweek"
}
func (d *DayOfWeek) String() string { return fmt.Sprintf("DAYOFWEEK(%s)", d.Child) }
func (d *DayOfWeek) Type() sql.Type { return sql.Int32 }
func (d *DayOfWeek) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, d.UnaryExpression, row, dayOfWeek)
}
func (d *DayOfWeek) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1)
	}
	return NewDayOfWeek(children[0]), nil
}
type DayOfYear struct {
	expression.UnaryExpression
}
var _ sql.FunctionExpression = (*DayOfYear)(nil)
func NewDayOfYear(date sql.Expression) sql.Expression {
	return &DayOfYear{expression.UnaryExpression{Child: date}}
}
func (d *DayOfYear) FunctionName() string {
	return "dayofyear"
}
func (d *DayOfYear) String() string { return fmt.Sprintf("DAYOFYEAR(%s)", d.Child) }
func (d *DayOfYear) Type() sql.Type { return sql.Int32 }
func (d *DayOfYear) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	return getDatePart(ctx, d.UnaryExpression, row, dayOfYear)
}
func (d *DayOfYear) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	if len(children) != 1 {
		return nil, sql.ErrInvalidChildrenNumber.New(d, len(children), 1)
	}
	return NewDayOfYear(children[0]), nil
}
func datePartFunc(fn func(time.Time) int) func(interface{}) interface{} {
	return func(v interface{}) interface{} {
		if v == nil {
			return nil
		}
		return int32(fn(v.(time.Time)))
	}
}
type YearWeek struct {
	date sql.Expression
	mode sql.Expression
}
var _ sql.FunctionExpression = (*YearWeek)(nil)
func NewYearWeek(args ...sql.Expression) (sql.Expression, error) {
	if len(args) == 0 {
		return nil, sql.ErrInvalidArgumentNumber.New("YEARWEEK", "1 or more", 0)
	}
	yw := &YearWeek{date: args[0]}
	if len(args) > 1 && args[1].Resolved() && sql.IsInteger(args[1].Type()) {
		yw.mode = args[1]
	} else {
		yw.mode = expression.NewLiteral(0, sql.Int64)
	}
	return yw, nil
}
func (d *YearWeek) FunctionName() string {
	return "yearweek"
}
func (d *YearWeek) String() string { return fmt.Sprintf("YEARWEEK(%s, %d)", d.date, d.mode) }
func (d *YearWeek) Type() sql.Type { return sql.Int32 }
func (d *YearWeek) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
	date, err := getDate(ctx, expression.UnaryExpression{Child: d.date}, row)
	if err != nil {
		return nil, err
	}
	yyyy, ok := year(date).(int32)
	if !ok {
		return nil, ErrInvalidArgument.New("YEARWEEK", "invalid year")
	}
	mm, ok := month(date).(int32)
	if !ok {
		return nil, ErrInvalidArgument.New("YEARWEEK", "invalid month")
	}
	dd, ok := day(date).(int32)
	if !ok {
		return nil, ErrInvalidArgument.New("YEARWEEK", "invalid day")
	}
	mode := int64(0)
	val, err := d.mode.Eval(ctx, row)
	if err != nil {
		return nil, err
	}
	if val != nil {
		if i64, err := sql.Int64.Convert(val); err == nil {
			if mode, ok = i64.(int64); ok {
				mode %= 8  
			}
		}
	}
	yyyy, week := calcWeek(yyyy, mm, dd, weekMode(mode)|weekBehaviourYear)
	return (yyyy * 100) + week, nil
}
func (d *YearWeek) Resolved() bool {
	return d.date.Resolved() && d.mode.Resolved()
}
func (d *YearWeek) Children() []sql.Expression { return []sql.Expression{d.date, d.mode} }
func (d *YearWeek) IsNullable() bool {
	return d.date.IsNullable()
}
func (*YearWeek) WithChildren(children ...sql.Expression) (sql.Expression, error) {
	return NewYearWeek(children...)
}
type Week struct {
	date sql.Expression
	mode sql.Expression
}
var _ sql.FunctionExpression = (*Week)(nil)
func NewWeek(args ...sql.Expression) (sql.Expression, error) {
	if len(args) == 0 {
		return nil, sql.ErrInvalidArgumentNumber.New("YEARWEEK", "1 or more", 0)
	}
	w := &Week{date: args[0]}
	if len(args) > 1 && args[1].Resolved() && sql.IsInteger(args[1].Type()) {
		w.mode = args[1]
	} else {
		w.mode = expression.NewLiteral(0, sql.Int64)
	}
	return w, nil
}