commit
6a19a8130d
|
@ -810,7 +810,7 @@ type TimeLiteral struct {
|
||||||
|
|
||||||
// String returns a string representation of the literal.
|
// String returns a string representation of the literal.
|
||||||
func (l *TimeLiteral) String() string {
|
func (l *TimeLiteral) String() string {
|
||||||
return `"` + l.Val.UTC().Format(TimeFormat) + `"`
|
return `"` + l.Val.UTC().Format(DateTimeFormat) + `"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DurationLiteral represents a duration literal.
|
// DurationLiteral represents a duration literal.
|
||||||
|
|
|
@ -199,11 +199,11 @@ func TestTimeRange(t *testing.T) {
|
||||||
min, max := influxql.TimeRange(expr)
|
min, max := influxql.TimeRange(expr)
|
||||||
|
|
||||||
// Compare with expected min/max.
|
// 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)
|
t.Errorf("%d. %s: unexpected min:\n\nexp=%s\n\ngot=%s\n\n", i, tt.expr, tt.min, min)
|
||||||
continue
|
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)
|
t.Errorf("%d. %s: unexpected max:\n\nexp=%s\n\ngot=%s\n\n", i, tt.expr, tt.max, max)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ func (p *Planner) Plan(stmt *SelectStatement) (*Executor, error) {
|
||||||
max = now
|
max = now
|
||||||
}
|
}
|
||||||
if max.Before(min) {
|
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
|
e.min, e.max = min, max
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,13 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TimeFormat represents the format for time literals.
|
const (
|
||||||
const TimeFormat = "2006-01-02 15:04:05.999999"
|
// 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.
|
// Parser represents an InfluxQL parser.
|
||||||
type Parser struct {
|
type Parser struct {
|
||||||
|
@ -852,10 +857,16 @@ func (p *Parser) parseUnaryExpr() (Expr, error) {
|
||||||
}
|
}
|
||||||
case STRING:
|
case STRING:
|
||||||
// If literal looks like a date time then parse it as a time literal.
|
// If literal looks like a date time then parse it as a time literal.
|
||||||
if isTimeString(lit) {
|
if isDateTimeString(lit) {
|
||||||
t, err := time.Parse(TimeFormat, lit)
|
t, err := time.Parse(DateTimeFormat, lit)
|
||||||
if err != nil {
|
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
|
return &TimeLiteral{Val: t}, nil
|
||||||
}
|
}
|
||||||
|
@ -1034,10 +1045,14 @@ func split(s string) (a []rune) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// isTimeString returns true if the string looks like a time literal.
|
// isDateString returns true if the string looks like a datetime literal.
|
||||||
func isTimeString(s string) bool { return timeStringRegexp.MatchString(s) }
|
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.
|
// ErrInvalidDuration is returned when parsing a malformatted duration.
|
||||||
var ErrInvalidDuration = errors.New("invalid duration")
|
var ErrInvalidDuration = errors.New("invalid duration")
|
||||||
|
|
|
@ -349,7 +349,9 @@ func TestParser_ParseExpr(t *testing.T) {
|
||||||
{s: `false`, expr: &influxql.BooleanLiteral{Val: false}},
|
{s: `false`, expr: &influxql.BooleanLiteral{Val: false}},
|
||||||
{s: `my_ident`, expr: &influxql.VarRef{Val: "my_ident"}},
|
{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-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
|
// Simple binary expression
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue