Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support sysdate time function #251

Merged
merged 4 commits into from
Sep 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions expression/builtin/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ var Funcs = map[string]Func{
"month": {builtinMonth, 1, 1, true, false},
"now": {builtinNow, 0, 1, false, false},
"second": {builtinSecond, 1, 1, true, false},
"sysdate": {builtinSysDate, 0, 1, false, false},
"week": {builtinWeek, 1, 2, true, false},
"weekday": {builtinWeekDay, 1, 1, true, false},
"weekofyear": {builtinWeekOfYear, 1, 1, true, false},
Expand Down
32 changes: 24 additions & 8 deletions expression/builtin/time.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,14 @@ func builtinMonth(args []interface{}, ctx map[interface{}]interface{}) (interfac
}

func builtinNow(args []interface{}, ctx map[interface{}]interface{}) (interface{}, error) {
fsp := int64(0)
// TODO: if NOW is used in stored function or trigger, NOW will return the beginning time
// of the execution.
fsp := 0
if len(args) == 1 {
var err error
fsp, err = types.ToInt64(args[0])
if err != nil {
if fsp, err = checkFsp(args[0]); err != nil {
return nil, errors.Trace(err)
}
if int(fsp) > mysql.MaxFsp {
return nil, errors.Errorf("Too big precision %d specified. Maximum is 6.", fsp)
} else if fsp < 0 {
return nil, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
}
}

t := mysql.Time{
Expand Down Expand Up @@ -297,3 +293,23 @@ func builtinYearWeek(args []interface{}, ctx map[interface{}]interface{}) (inter
year, week := t.ISOWeek()
return int64(year*100 + week), nil
}

func builtinSysDate(args []interface{}, ctx map[interface{}]interface{}) (interface{}, error) {
// SYSDATE is not the same as NOW if NOW is used in a stored function or trigger.
// But here we can just think they are the same because we don't support stored function
// and trigger now.
return builtinNow(args, ctx)
}

func checkFsp(arg interface{}) (int, error) {
fsp, err := types.ToInt64(arg)
if err != nil {
return 0, errors.Trace(err)
}
if int(fsp) > mysql.MaxFsp {
return 0, errors.Errorf("Too big precision %d specified. Maximum is 6.", fsp)
} else if fsp < 0 {
return 0, errors.Errorf("Invalid negative %d specified, must in [0, 6].", fsp)
}
return int(fsp), nil
}
19 changes: 19 additions & 0 deletions expression/builtin/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package builtin

import (
"strings"
"time"

. "github.com/pingcap/check"
mysql "github.com/pingcap/tidb/mysqldef"
Expand Down Expand Up @@ -247,3 +248,21 @@ func (s *testBuiltinSuite) TestNow(c *C) {
_, err = builtinNow([]interface{}{-2}, nil)
c.Assert(err, NotNil)
}

func (s *testBuiltinSuite) TestSysDate(c *C) {
last := time.Now()
v, err := builtinSysDate(nil, nil)
c.Assert(err, IsNil)
n, ok := v.(mysql.Time)
c.Assert(ok, IsTrue)
c.Assert(n.String(), GreaterEqual, last.Format(mysql.TimeFormat))

v, err = builtinSysDate([]interface{}{6}, nil)
c.Assert(err, IsNil)
n, ok = v.(mysql.Time)
c.Assert(ok, IsTrue)
c.Assert(n.String(), GreaterEqual, last.Format(mysql.TimeFormat))

_, err = builtinSysDate([]interface{}{-2}, nil)
c.Assert(err, NotNil)
}
15 changes: 15 additions & 0 deletions parser/parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ import (
substring "SUBSTRING"
sum "SUM"
sysVar "SYS_VAR"
sysDate "SYSDATE"
tableKwd "TABLE"
tables "TABLES"
then "THEN"
Expand Down Expand Up @@ -2257,6 +2258,20 @@ FunctionCallNonKeyword:
Len: $7.(expression.Expression),
}
}
| "SYSDATE" '(' ExpressionOpt ')'
{
args := []expression.Expression{}
if $3 != nil {
args = append(args, $3.(expression.Expression))
}
var err error
$$, err = expression.NewCall($1.(string), args, false)
if err != nil {
l := yylex.(*lexer)
l.err(err)
return 1
}
}
| "WEEKDAY" '(' Expression ')'
{
args := []expression.Expression{$3.(expression.Expression)}
Expand Down
1 change: 1 addition & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ func (s *testParserSuite) TestParser0(c *C) {
{"select current_timestamp(6)", true},
{"select now()", true},
{"select now(6)", true},
{"select sysdate(), sysdate(6)", true},
}

for _, t := range table {
Expand Down
3 changes: 3 additions & 0 deletions parser/scanner.l
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ some {s}{o}{m}{e}
start {s}{t}{a}{r}{t}
substring {s}{u}{b}{s}{t}{r}{i}{n}{g}
sum {s}{u}{m}
sysdate {s}{y}{s}{d}{a}{t}{e}
table {t}{a}{b}{l}{e}
tables {t}{a}{b}{l}{e}{s}
then {t}{h}{e}{n}
Expand Down Expand Up @@ -689,6 +690,8 @@ sys_var "@@"(({global}".")|({session}".")|{local}".")?{ident}
return substring
{sum} lval.item = string(l.val)
return sum
{sysdate} lval.item = string(l.val)
return sysDate
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sysdate or sysDate?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we define sysDate in parser, so here it is sysDate

{table} return tableKwd
{tables} lval.item = string(l.val)
return tables
Expand Down
2 changes: 1 addition & 1 deletion tidb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ func (s *testSessionSuite) TestTimeFunc(c *C) {
se := newSession(c, store, s.dbName)

last := time.Now().Format(mysql.TimeFormat)
r := mustExecSQL(c, se, "select now(), now(6), current_timestamp, current_timestamp(), current_timestamp(6)")
r := mustExecSQL(c, se, "select now(), now(6), current_timestamp, current_timestamp(), current_timestamp(6), sysdate(), sysdate(6)")
row, err := r.FirstRow()
c.Assert(err, IsNil)
for _, t := range row {
Expand Down