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

Commit bb5fe96

Browse files
authored
Merge pull request #654 from mcuadros/date-func
sql/expression: new date function
2 parents 217cb4d + 0516134 commit bb5fe96

File tree

5 files changed

+71
-0
lines changed

5 files changed

+71
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ We support and actively test against certain third-party clients to ensure compa
7171
|`DATE_ADD(date, interval)`|Adds the interval to the given date.|
7272
|`DATE_SUB(date, interval)`|Subtracts the interval from the given date.|
7373
|`DAY(date)`|Synonym for DAYOFMONTH().|
74+
|`DATE(date)`|Returns the date part of the given date.|
7475
|`DAYOFMONTH(date)`|Return the day of the month (0-31).|
7576
|`DAYOFWEEK(date)`|Returns the day of the week of the given date.|
7677
|`DAYOFYEAR(date)`|Returns the day of the year of the given date.|

SUPPORTED.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,10 @@
115115
- FROM_BASE64
116116

117117
## Time functions
118+
- DATE
118119
- DAY
119120
- WEEKDAY
121+
- DAYOFMONTH
120122
- DAYOFWEEK
121123
- DAYOFYEAR
122124
- HOUR

sql/expression/function/registry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var Defaults = []sql.Function{
3333
sql.FunctionN{Name: "substring", Fn: NewSubstring},
3434
sql.FunctionN{Name: "mid", Fn: NewSubstring},
3535
sql.FunctionN{Name: "substr", Fn: NewSubstring},
36+
sql.Function1{Name: "date", Fn: NewDate},
3637
sql.Function1{Name: "year", Fn: NewYear},
3738
sql.Function1{Name: "month", Fn: NewMonth},
3839
sql.Function1{Name: "day", Fn: NewDay},

sql/expression/function/time.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,3 +573,39 @@ func (n *Now) Eval(*sql.Context, sql.Row) (interface{}, error) {
573573
func (n *Now) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
574574
return f(n)
575575
}
576+
577+
// Date a function takes the DATE part out from a datetime expression.
578+
type Date struct {
579+
expression.UnaryExpression
580+
}
581+
582+
// NewDate returns a new Date node.
583+
func NewDate(date sql.Expression) sql.Expression {
584+
return &Date{expression.UnaryExpression{Child: date}}
585+
}
586+
587+
func (d *Date) String() string { return fmt.Sprintf("DATE(%s)", d.Child) }
588+
589+
// Type implements the Expression interface.
590+
func (d *Date) Type() sql.Type { return sql.Text }
591+
592+
// Eval implements the Expression interface.
593+
func (d *Date) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
594+
return getDatePart(ctx, d.UnaryExpression, row, func(v interface{}) interface{} {
595+
if v == nil {
596+
return nil
597+
}
598+
599+
return v.(time.Time).Format("2006-01-02")
600+
})
601+
}
602+
603+
// TransformUp implements the sql.Expression interface.
604+
func (d *Date) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
605+
child, err := d.Child.TransformUp(f)
606+
if err != nil {
607+
return nil, err
608+
}
609+
610+
return f(NewDate(child))
611+
}

sql/expression/function/time_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,3 +354,34 @@ func TestNow(t *testing.T) {
354354
require.NoError(err)
355355
require.Equal(date, result)
356356
}
357+
358+
func TestDate(t *testing.T) {
359+
f := NewDate(expression.NewGetField(0, sql.Text, "foo", false))
360+
ctx := sql.NewEmptyContext()
361+
362+
testCases := []struct {
363+
name string
364+
row sql.Row
365+
expected interface{}
366+
err bool
367+
}{
368+
{"null date", sql.NewRow(nil), nil, false},
369+
{"invalid type", sql.NewRow([]byte{0, 1, 2}), nil, false},
370+
{"date as string", sql.NewRow(stringDate), "2007-01-02", false},
371+
{"date as time", sql.NewRow(time.Now()), time.Now().Format("2006-01-02"), false},
372+
{"date as unix timestamp", sql.NewRow(int64(tsDate)), "2009-11-22", false},
373+
}
374+
375+
for _, tt := range testCases {
376+
t.Run(tt.name, func(t *testing.T) {
377+
require := require.New(t)
378+
val, err := f.Eval(ctx, tt.row)
379+
if tt.err {
380+
require.Error(err)
381+
} else {
382+
require.NoError(err)
383+
require.Equal(tt.expected, val)
384+
}
385+
})
386+
}
387+
}

0 commit comments

Comments
 (0)