Commit d70cacc3 by Daniel Lee Committed by GitHub

Merge pull request #11532 from ryantxu/sql-uint64

PostgreSQL should not cast all times to uint64
parents 57020149 224a0eb0
...@@ -82,11 +82,11 @@ func (m *MsSqlMacroEngine) evaluateMacro(name string, args []string) (string, er ...@@ -82,11 +82,11 @@ func (m *MsSqlMacroEngine) evaluateMacro(name string, args []string) (string, er
if len(args) == 0 { if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name) return "", fmt.Errorf("missing time column argument for macro %v", name)
} }
return fmt.Sprintf("%s >= DATEADD(s, %d, '1970-01-01') AND %s <= DATEADD(s, %d, '1970-01-01')", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%s >= DATEADD(s, %d, '1970-01-01') AND %s <= DATEADD(s, %d, '1970-01-01')", args[0], m.TimeRange.GetFromAsSecondsEpoch(), args[0], m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeFrom": case "__timeFrom":
return fmt.Sprintf("DATEADD(second, %d, '1970-01-01')", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil return fmt.Sprintf("DATEADD(second, %d, '1970-01-01')", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__timeTo": case "__timeTo":
return fmt.Sprintf("DATEADD(second, %d, '1970-01-01')", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("DATEADD(second, %d, '1970-01-01')", m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeGroup": case "__timeGroup":
if len(args) < 2 { if len(args) < 2 {
return "", fmt.Errorf("macro %v needs time column and interval", name) return "", fmt.Errorf("macro %v needs time column and interval", name)
...@@ -113,11 +113,11 @@ func (m *MsSqlMacroEngine) evaluateMacro(name string, args []string) (string, er ...@@ -113,11 +113,11 @@ func (m *MsSqlMacroEngine) evaluateMacro(name string, args []string) (string, er
if len(args) == 0 { if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name) return "", fmt.Errorf("missing time column argument for macro %v", name)
} }
return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.TimeRange.GetFromAsSecondsEpoch(), args[0], m.TimeRange.GetToAsSecondsEpoch()), nil
case "__unixEpochFrom": case "__unixEpochFrom":
return fmt.Sprintf("%d", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil return fmt.Sprintf("%d", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__unixEpochTo": case "__unixEpochTo":
return fmt.Sprintf("%d", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%d", m.TimeRange.GetToAsSecondsEpoch()), nil
default: default:
return "", fmt.Errorf("Unknown macro %v", name) return "", fmt.Errorf("Unknown macro %v", name)
} }
......
package mssql package mssql
import ( import (
"fmt"
"strconv"
"testing" "testing"
"time" "time"
...@@ -13,11 +15,15 @@ import ( ...@@ -13,11 +15,15 @@ import (
func TestMacroEngine(t *testing.T) { func TestMacroEngine(t *testing.T) {
Convey("MacroEngine", t, func() { Convey("MacroEngine", t, func() {
engine := &MsSqlMacroEngine{} engine := &MsSqlMacroEngine{}
timeRange := &tsdb.TimeRange{From: "5m", To: "now"}
query := &tsdb.Query{ query := &tsdb.Query{
Model: simplejson.New(), Model: simplejson.New(),
} }
Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() {
from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC)
to := from.Add(5 * time.Minute)
timeRange := tsdb.NewFakeTimeRange("5m", "now", to)
Convey("interpolate __time function", func() { Convey("interpolate __time function", func() {
sql, err := engine.Interpolate(query, nil, "select $__time(time_column)") sql, err := engine.Interpolate(query, nil, "select $__time(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
...@@ -43,7 +49,7 @@ func TestMacroEngine(t *testing.T) { ...@@ -43,7 +49,7 @@ func TestMacroEngine(t *testing.T) {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "WHERE time_column >= DATEADD(s, 18446744066914186738, '1970-01-01') AND time_column <= DATEADD(s, 18446744066914187038, '1970-01-01')") So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column >= DATEADD(s, %d, '1970-01-01') AND time_column <= DATEADD(s, %d, '1970-01-01')", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeGroup function", func() { Convey("interpolate __timeGroup function", func() {
...@@ -90,35 +96,132 @@ func TestMacroEngine(t *testing.T) { ...@@ -90,35 +96,132 @@ func TestMacroEngine(t *testing.T) {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select DATEADD(second, 18446744066914186738, '1970-01-01')") So(sql, ShouldEqual, fmt.Sprintf("select DATEADD(second, %d, '1970-01-01')", from.Unix()))
})
Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select DATEADD(second, %d, '1970-01-01')", to.Unix()))
})
Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.Unix(), to.Unix()))
})
Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
})
Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
Convey("Given a time range between 1960-02-01 07:00 and 1965-02-03 08:00", func() {
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
to := time.Date(1965, 2, 3, 8, 0, 0, 0, time.UTC)
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column >= DATEADD(s, %d, '1970-01-01') AND time_column <= DATEADD(s, %d, '1970-01-01')", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select DATEADD(second, %d, '1970-01-01')", from.Unix()))
}) })
Convey("interpolate __timeTo function", func() { Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select DATEADD(second, 18446744066914187038, '1970-01-01')") So(sql, ShouldEqual, fmt.Sprintf("select DATEADD(second, %d, '1970-01-01')", to.Unix()))
}) })
Convey("interpolate __unixEpochFilter function", func() { Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select time_column >= 18446744066914186738 AND time_column <= 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.Unix(), to.Unix()))
}) })
Convey("interpolate __unixEpochFrom function", func() { Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914186738") So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
}) })
Convey("interpolate __unixEpochTo function", func() { Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
Convey("Given a time range between 1960-02-01 07:00 and 1980-02-03 08:00", func() {
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
to := time.Date(1980, 2, 3, 8, 0, 0, 0, time.UTC)
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column >= DATEADD(s, %d, '1970-01-01') AND time_column <= DATEADD(s, %d, '1970-01-01')", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select DATEADD(second, %d, '1970-01-01')", from.Unix()))
})
Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select DATEADD(second, %d, '1970-01-01')", to.Unix()))
})
Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select time_column >= %d AND time_column <= %d", from.Unix(), to.Unix()))
})
Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
})
Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
}) })
}) })
} }
...@@ -77,11 +77,11 @@ func (m *MySqlMacroEngine) evaluateMacro(name string, args []string) (string, er ...@@ -77,11 +77,11 @@ func (m *MySqlMacroEngine) evaluateMacro(name string, args []string) (string, er
if len(args) == 0 { if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name) return "", fmt.Errorf("missing time column argument for macro %v", name)
} }
return fmt.Sprintf("%s >= FROM_UNIXTIME(%d) AND %s <= FROM_UNIXTIME(%d)", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%s >= FROM_UNIXTIME(%d) AND %s <= FROM_UNIXTIME(%d)", args[0], m.TimeRange.GetFromAsSecondsEpoch(), args[0], m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeFrom": case "__timeFrom":
return fmt.Sprintf("FROM_UNIXTIME(%d)", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil return fmt.Sprintf("FROM_UNIXTIME(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__timeTo": case "__timeTo":
return fmt.Sprintf("FROM_UNIXTIME(%d)", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("FROM_UNIXTIME(%d)", m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeGroup": case "__timeGroup":
if len(args) < 2 { if len(args) < 2 {
return "", fmt.Errorf("macro %v needs time column and interval", name) return "", fmt.Errorf("macro %v needs time column and interval", name)
...@@ -108,11 +108,11 @@ func (m *MySqlMacroEngine) evaluateMacro(name string, args []string) (string, er ...@@ -108,11 +108,11 @@ func (m *MySqlMacroEngine) evaluateMacro(name string, args []string) (string, er
if len(args) == 0 { if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name) return "", fmt.Errorf("missing time column argument for macro %v", name)
} }
return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.TimeRange.GetFromAsSecondsEpoch(), args[0], m.TimeRange.GetToAsSecondsEpoch()), nil
case "__unixEpochFrom": case "__unixEpochFrom":
return fmt.Sprintf("%d", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil return fmt.Sprintf("%d", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__unixEpochTo": case "__unixEpochTo":
return fmt.Sprintf("%d", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%d", m.TimeRange.GetToAsSecondsEpoch()), nil
default: default:
return "", fmt.Errorf("Unknown macro %v", name) return "", fmt.Errorf("Unknown macro %v", name)
} }
......
package mysql package mysql
import ( import (
"fmt"
"strconv"
"testing" "testing"
"time"
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
...@@ -11,7 +14,11 @@ func TestMacroEngine(t *testing.T) { ...@@ -11,7 +14,11 @@ func TestMacroEngine(t *testing.T) {
Convey("MacroEngine", t, func() { Convey("MacroEngine", t, func() {
engine := &MySqlMacroEngine{} engine := &MySqlMacroEngine{}
query := &tsdb.Query{} query := &tsdb.Query{}
timeRange := &tsdb.TimeRange{From: "5m", To: "now"}
Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() {
from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC)
to := from.Add(5 * time.Minute)
timeRange := tsdb.NewFakeTimeRange("5m", "now", to)
Convey("interpolate __time function", func() { Convey("interpolate __time function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__time(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__time(time_column)")
...@@ -27,63 +34,159 @@ func TestMacroEngine(t *testing.T) { ...@@ -27,63 +34,159 @@ func TestMacroEngine(t *testing.T) {
So(sql, ShouldEqual, "select min(UNIX_TIMESTAMP(time_column) as time_sec)") So(sql, ShouldEqual, "select min(UNIX_TIMESTAMP(time_column) as time_sec)")
}) })
Convey("interpolate __timeGroup function", func() {
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')")
So(err, ShouldBeNil)
So(sql, ShouldEqual, "GROUP BY cast(cast(UNIX_TIMESTAMP(time_column)/(300) as signed)*300 as signed)")
})
Convey("interpolate __timeGroup function with spaces around arguments", func() {
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')")
So(err, ShouldBeNil)
So(sql, ShouldEqual, "GROUP BY cast(cast(UNIX_TIMESTAMP(time_column)/(300) as signed)*300 as signed)")
})
Convey("interpolate __timeFilter function", func() { Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "WHERE time_column >= FROM_UNIXTIME(18446744066914186738) AND time_column <= FROM_UNIXTIME(18446744066914187038)") So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column >= FROM_UNIXTIME(%d) AND time_column <= FROM_UNIXTIME(%d)", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeFrom function", func() { Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select FROM_UNIXTIME(18446744066914186738)") So(sql, ShouldEqual, fmt.Sprintf("select FROM_UNIXTIME(%d)", from.Unix()))
}) })
Convey("interpolate __timeGroup function", func() { Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil)
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column,'5m')") So(sql, ShouldEqual, fmt.Sprintf("select FROM_UNIXTIME(%d)", to.Unix()))
})
Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "GROUP BY cast(cast(UNIX_TIMESTAMP(time_column)/(300) as signed)*300 as signed)") So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeGroup function with spaces around arguments", func() { Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil)
sql, err := engine.Interpolate(query, timeRange, "GROUP BY $__timeGroup(time_column , '5m')") So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
})
Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "GROUP BY cast(cast(UNIX_TIMESTAMP(time_column)/(300) as signed)*300 as signed)") So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
Convey("Given a time range between 1960-02-01 07:00 and 1965-02-03 08:00", func() {
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
to := time.Date(1965, 2, 3, 8, 0, 0, 0, time.UTC)
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column >= FROM_UNIXTIME(%d) AND time_column <= FROM_UNIXTIME(%d)", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select FROM_UNIXTIME(%d)", from.Unix()))
}) })
Convey("interpolate __timeTo function", func() { Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select FROM_UNIXTIME(18446744066914187038)") So(sql, ShouldEqual, fmt.Sprintf("select FROM_UNIXTIME(%d)", to.Unix()))
}) })
Convey("interpolate __unixEpochFilter function", func() { Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(18446744066914186738)") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914186738 >= 18446744066914186738 AND 18446744066914186738 <= 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix()))
}) })
Convey("interpolate __unixEpochFrom function", func() { Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914186738") So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
}) })
Convey("interpolate __unixEpochTo function", func() { Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
Convey("Given a time range between 1960-02-01 07:00 and 1980-02-03 08:00", func() {
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
to := time.Date(1980, 2, 3, 8, 0, 0, 0, time.UTC)
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column >= FROM_UNIXTIME(%d) AND time_column <= FROM_UNIXTIME(%d)", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select FROM_UNIXTIME(%d)", from.Unix()))
})
Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select FROM_UNIXTIME(%d)", to.Unix()))
})
Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix()))
})
Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
})
Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
}) })
} }
...@@ -83,11 +83,11 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string, ...@@ -83,11 +83,11 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string,
if len(args) == 0 { if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name) return "", fmt.Errorf("missing time column argument for macro %v", name)
} }
return fmt.Sprintf("extract(epoch from %s) BETWEEN %d AND %d", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("extract(epoch from %s) BETWEEN %d AND %d", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeFrom": case "__timeFrom":
return fmt.Sprintf("to_timestamp(%d)", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__timeTo": case "__timeTo":
return fmt.Sprintf("to_timestamp(%d)", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeGroup": case "__timeGroup":
if len(args) < 2 { if len(args) < 2 {
return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name) return "", fmt.Errorf("macro %v needs time column and interval and optional fill value", name)
...@@ -114,11 +114,11 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string, ...@@ -114,11 +114,11 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string,
if len(args) == 0 { if len(args) == 0 {
return "", fmt.Errorf("missing time column argument for macro %v", name) return "", fmt.Errorf("missing time column argument for macro %v", name)
} }
return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], uint64(m.TimeRange.GetFromAsMsEpoch()/1000), args[0], uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%s >= %d AND %s <= %d", args[0], m.TimeRange.GetFromAsSecondsEpoch(), args[0], m.TimeRange.GetToAsSecondsEpoch()), nil
case "__unixEpochFrom": case "__unixEpochFrom":
return fmt.Sprintf("%d", uint64(m.TimeRange.GetFromAsMsEpoch()/1000)), nil return fmt.Sprintf("%d", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__unixEpochTo": case "__unixEpochTo":
return fmt.Sprintf("%d", uint64(m.TimeRange.GetToAsMsEpoch()/1000)), nil return fmt.Sprintf("%d", m.TimeRange.GetToAsSecondsEpoch()), nil
default: default:
return "", fmt.Errorf("Unknown macro %v", name) return "", fmt.Errorf("Unknown macro %v", name)
} }
......
package postgres package postgres
import ( import (
"fmt"
"strconv"
"testing" "testing"
"time"
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
...@@ -11,7 +14,11 @@ func TestMacroEngine(t *testing.T) { ...@@ -11,7 +14,11 @@ func TestMacroEngine(t *testing.T) {
Convey("MacroEngine", t, func() { Convey("MacroEngine", t, func() {
engine := &PostgresMacroEngine{} engine := &PostgresMacroEngine{}
query := &tsdb.Query{} query := &tsdb.Query{}
timeRange := &tsdb.TimeRange{From: "5m", To: "now"}
Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() {
from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC)
to := from.Add(5 * time.Minute)
timeRange := tsdb.NewFakeTimeRange("5m", "now", to)
Convey("interpolate __time function", func() { Convey("interpolate __time function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__time(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__time(time_column)")
...@@ -31,14 +38,14 @@ func TestMacroEngine(t *testing.T) { ...@@ -31,14 +38,14 @@ func TestMacroEngine(t *testing.T) {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)") sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "WHERE extract(epoch from time_column) BETWEEN 18446744066914186738 AND 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeFrom function", func() { Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select to_timestamp(18446744066914186738)") So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", from.Unix()))
}) })
Convey("interpolate __timeGroup function", func() { Convey("interpolate __timeGroup function", func() {
...@@ -61,29 +68,125 @@ func TestMacroEngine(t *testing.T) { ...@@ -61,29 +68,125 @@ func TestMacroEngine(t *testing.T) {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)") sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select to_timestamp(18446744066914187038)") So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", to.Unix()))
}) })
Convey("interpolate __unixEpochFilter function", func() { Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(18446744066914186738)") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time)")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914186738 >= 18446744066914186738 AND 18446744066914186738 <= 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix()))
}) })
Convey("interpolate __unixEpochFrom function", func() { Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914186738") So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
}) })
Convey("interpolate __unixEpochTo function", func() { Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()") sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil) So(err, ShouldBeNil)
So(sql, ShouldEqual, "select 18446744066914187038") So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
Convey("Given a time range between 1960-02-01 07:00 and 1965-02-03 08:00", func() {
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
to := time.Date(1965, 2, 3, 8, 0, 0, 0, time.UTC)
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", from.Unix()))
})
Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", to.Unix()))
})
Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix()))
}) })
Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
})
Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
Convey("Given a time range between 1960-02-01 07:00 and 1980-02-03 08:00", func() {
from := time.Date(1960, 2, 1, 7, 0, 0, 0, time.UTC)
to := time.Date(1980, 2, 3, 8, 0, 0, 0, time.UTC)
timeRange := tsdb.NewTimeRange(strconv.FormatInt(from.UnixNano()/int64(time.Millisecond), 10), strconv.FormatInt(to.UnixNano()/int64(time.Millisecond), 10))
Convey("interpolate __timeFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeFrom(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", from.Unix()))
})
Convey("interpolate __timeTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__timeTo(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select to_timestamp(%d)", to.Unix()))
})
Convey("interpolate __unixEpochFilter function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFilter(time)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select time >= %d AND time <= %d", from.Unix(), to.Unix()))
})
Convey("interpolate __unixEpochFrom function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochFrom()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", from.Unix()))
})
Convey("interpolate __unixEpochTo function", func() {
sql, err := engine.Interpolate(query, timeRange, "select $__unixEpochTo()")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("select %d", to.Unix()))
})
})
}) })
} }
...@@ -15,6 +15,14 @@ func NewTimeRange(from, to string) *TimeRange { ...@@ -15,6 +15,14 @@ func NewTimeRange(from, to string) *TimeRange {
} }
} }
func NewFakeTimeRange(from, to string, now time.Time) *TimeRange {
return &TimeRange{
From: from,
To: to,
now: now,
}
}
type TimeRange struct { type TimeRange struct {
From string From string
To string To string
...@@ -25,10 +33,18 @@ func (tr *TimeRange) GetFromAsMsEpoch() int64 { ...@@ -25,10 +33,18 @@ func (tr *TimeRange) GetFromAsMsEpoch() int64 {
return tr.MustGetFrom().UnixNano() / int64(time.Millisecond) return tr.MustGetFrom().UnixNano() / int64(time.Millisecond)
} }
func (tr *TimeRange) GetFromAsSecondsEpoch() int64 {
return tr.GetFromAsMsEpoch() / 1000
}
func (tr *TimeRange) GetToAsMsEpoch() int64 { func (tr *TimeRange) GetToAsMsEpoch() int64 {
return tr.MustGetTo().UnixNano() / int64(time.Millisecond) return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
} }
func (tr *TimeRange) GetToAsSecondsEpoch() int64 {
return tr.GetToAsMsEpoch() / 1000
}
func (tr *TimeRange) MustGetFrom() time.Time { func (tr *TimeRange) MustGetFrom() time.Time {
if res, err := tr.ParseFrom(); err != nil { if res, err := tr.ParseFrom(); err != nil {
return time.Unix(0, 0) return time.Unix(0, 0)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment