Skip to content
This repository has been archived by the owner on Jan 28, 2021. It is now read-only.

Commit

Permalink
Merge pull request #654 from mcuadros/date-func
Browse files Browse the repository at this point in the history
sql/expression: new date function
  • Loading branch information
ajnavarro authored Apr 12, 2019
2 parents 217cb4d + 0516134 commit bb5fe96
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ We support and actively test against certain third-party clients to ensure compa
|`DATE_ADD(date, interval)`|Adds the interval to the given date.|
|`DATE_SUB(date, interval)`|Subtracts the interval from the given date.|
|`DAY(date)`|Synonym for DAYOFMONTH().|
|`DATE(date)`|Returns the date part of the given date.|
|`DAYOFMONTH(date)`|Return the day of the month (0-31).|
|`DAYOFWEEK(date)`|Returns the day of the week of the given date.|
|`DAYOFYEAR(date)`|Returns the day of the year of the given date.|
Expand Down
2 changes: 2 additions & 0 deletions SUPPORTED.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@
- FROM_BASE64

## Time functions
- DATE
- DAY
- WEEKDAY
- DAYOFMONTH
- DAYOFWEEK
- DAYOFYEAR
- HOUR
Expand Down
1 change: 1 addition & 0 deletions sql/expression/function/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var Defaults = []sql.Function{
sql.FunctionN{Name: "substring", Fn: NewSubstring},
sql.FunctionN{Name: "mid", Fn: NewSubstring},
sql.FunctionN{Name: "substr", Fn: NewSubstring},
sql.Function1{Name: "date", Fn: NewDate},
sql.Function1{Name: "year", Fn: NewYear},
sql.Function1{Name: "month", Fn: NewMonth},
sql.Function1{Name: "day", Fn: NewDay},
Expand Down
36 changes: 36 additions & 0 deletions sql/expression/function/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -573,3 +573,39 @@ func (n *Now) Eval(*sql.Context, sql.Row) (interface{}, error) {
func (n *Now) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
return f(n)
}

// Date a function takes the DATE part out from a datetime expression.
type Date struct {
expression.UnaryExpression
}

// NewDate returns a new Date node.
func NewDate(date sql.Expression) sql.Expression {
return &Date{expression.UnaryExpression{Child: date}}
}

func (d *Date) String() string { return fmt.Sprintf("DATE(%s)", d.Child) }

// Type implements the Expression interface.
func (d *Date) Type() sql.Type { return sql.Text }

// Eval implements the Expression interface.
func (d *Date) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
return getDatePart(ctx, d.UnaryExpression, row, func(v interface{}) interface{} {
if v == nil {
return nil
}

return v.(time.Time).Format("2006-01-02")
})
}

// TransformUp implements the sql.Expression interface.
func (d *Date) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
child, err := d.Child.TransformUp(f)
if err != nil {
return nil, err
}

return f(NewDate(child))
}
31 changes: 31 additions & 0 deletions sql/expression/function/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,34 @@ func TestNow(t *testing.T) {
require.NoError(err)
require.Equal(date, result)
}

func TestDate(t *testing.T) {
f := NewDate(expression.NewGetField(0, sql.Text, "foo", false))
ctx := sql.NewEmptyContext()

testCases := []struct {
name string
row sql.Row
expected interface{}
err bool
}{
{"null date", sql.NewRow(nil), nil, false},
{"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false},
{"date as string", sql.NewRow(stringDate), "2007-01-02", false},
{"date as time", sql.NewRow(time.Now()), time.Now().Format("2006-01-02"), false},
{"date as unix timestamp", sql.NewRow(int64(tsDate)), "2009-11-22", false},
}

for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
require := require.New(t)
val, err := f.Eval(ctx, tt.row)
if tt.err {
require.Error(err)
} else {
require.NoError(err)
require.Equal(tt.expected, val)
}
})
}
}

0 comments on commit bb5fe96

Please sign in to comment.