Merge pull request #1255 from influxdb/date-parsing

Add date-only parsing
pull/1256/head
Ben Johnson 2014-12-21 11:02:12 -07:00
commit 6a19a8130d
5 changed files with 30 additions and 13 deletions

View File

@ -810,7 +810,7 @@ type TimeLiteral struct {
// String returns a string representation of the literal.
func (l *TimeLiteral) String() string {
return `"` + l.Val.UTC().Format(TimeFormat) + `"`
return `"` + l.Val.UTC().Format(DateTimeFormat) + `"`
}
// DurationLiteral represents a duration literal.

View File

@ -199,11 +199,11 @@ func TestTimeRange(t *testing.T) {
min, max := influxql.TimeRange(expr)
// Compare with expected min/max.
if min := min.Format(influxql.TimeFormat); tt.min != min {
if min := min.Format(influxql.DateTimeFormat); tt.min != min {
t.Errorf("%d. %s: unexpected min:\n\nexp=%s\n\ngot=%s\n\n", i, tt.expr, tt.min, min)
continue
}
if max := max.Format(influxql.TimeFormat); tt.max != max {
if max := max.Format(influxql.DateTimeFormat); tt.max != max {
t.Errorf("%d. %s: unexpected max:\n\nexp=%s\n\ngot=%s\n\n", i, tt.expr, tt.max, max)
continue
}

View File

@ -60,7 +60,7 @@ func (p *Planner) Plan(stmt *SelectStatement) (*Executor, error) {
max = now
}
if max.Before(min) {
return nil, fmt.Errorf("invalid time range: %s - %s", min.Format(TimeFormat), max.Format(TimeFormat))
return nil, fmt.Errorf("invalid time range: %s - %s", min.Format(DateTimeFormat), max.Format(DateTimeFormat))
}
e.min, e.max = min, max

View File

@ -10,8 +10,13 @@ import (
"time"
)
// TimeFormat represents the format for time literals.
const TimeFormat = "2006-01-02 15:04:05.999999"
const (
// DateFormat represents the format for date literals.
DateFormat = "2006-01-02"
// DateTimeFormat represents the format for date time literals.
DateTimeFormat = "2006-01-02 15:04:05.999999"
)
// Parser represents an InfluxQL parser.
type Parser struct {
@ -852,10 +857,16 @@ func (p *Parser) parseUnaryExpr() (Expr, error) {
}
case STRING:
// If literal looks like a date time then parse it as a time literal.
if isTimeString(lit) {
t, err := time.Parse(TimeFormat, lit)
if isDateTimeString(lit) {
t, err := time.Parse(DateTimeFormat, lit)
if err != nil {
return nil, &ParseError{Message: "unable to parse time", Pos: pos}
return nil, &ParseError{Message: "unable to parse datetime", Pos: pos}
}
return &TimeLiteral{Val: t}, nil
} else if isDateString(lit) {
t, err := time.Parse(DateFormat, lit)
if err != nil {
return nil, &ParseError{Message: "unable to parse date", Pos: pos}
}
return &TimeLiteral{Val: t}, nil
}
@ -1034,10 +1045,14 @@ func split(s string) (a []rune) {
return
}
// isTimeString returns true if the string looks like a time literal.
func isTimeString(s string) bool { return timeStringRegexp.MatchString(s) }
// isDateString returns true if the string looks like a datetime literal.
func isDateString(s string) bool { return dateStringRegexp.MatchString(s) }
var timeStringRegexp = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?$`)
// isDateTimeString returns true if the string looks like a datetime literal.
func isDateTimeString(s string) bool { return dateTimeStringRegexp.MatchString(s) }
var dateStringRegexp = regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`)
var dateTimeStringRegexp = regexp.MustCompile(`^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}(?:\.\d+)?$`)
// ErrInvalidDuration is returned when parsing a malformatted duration.
var ErrInvalidDuration = errors.New("invalid duration")

View File

@ -349,7 +349,9 @@ func TestParser_ParseExpr(t *testing.T) {
{s: `false`, expr: &influxql.BooleanLiteral{Val: false}},
{s: `my_ident`, expr: &influxql.VarRef{Val: "my_ident"}},
{s: `"2000-01-01 00:00:00"`, expr: &influxql.TimeLiteral{Val: mustParseTime("2000-01-01T00:00:00Z")}},
{s: `"2000-01-32 00:00:00"`, err: `unable to parse time at line 1, char 1`},
{s: `"2000-01-32 00:00:00"`, err: `unable to parse datetime at line 1, char 1`},
{s: `"2000-01-01"`, expr: &influxql.TimeLiteral{Val: mustParseTime("2000-01-01T00:00:00Z")}},
{s: `"2000-01-99"`, err: `unable to parse date at line 1, char 1`},
// Simple binary expression
{