make timefilter macro aware of pg version

This commit is contained in:
Sven Klemm
2018-04-15 18:38:20 +02:00
parent 1161c7bc3e
commit 9b61ffb48a
2 changed files with 70 additions and 7 deletions

View File

@ -79,11 +79,19 @@ func (m *PostgresMacroEngine) evaluateMacro(name string, args []string) (string,
} }
return fmt.Sprintf("extract(epoch from %s) as \"time\"", args[0]), nil return fmt.Sprintf("extract(epoch from %s) as \"time\"", args[0]), nil
case "__timeFilter": case "__timeFilter":
// dont use to_timestamp in this macro for redshift compatibility #9566
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], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil
pg_version := m.Query.DataSource.JsonData.Get("postgresVersion").MustInt(0)
if pg_version >= 80100 {
// postgres has to_timestamp(double) starting with 8.1
return fmt.Sprintf("%s BETWEEN to_timestamp(%d) AND to_timestamp(%d)", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil
}
// dont use to_timestamp in this macro for redshift compatibility #9566
return fmt.Sprintf("%s BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", args[0], m.TimeRange.GetFromAsSecondsEpoch(), m.TimeRange.GetToAsSecondsEpoch()), nil
case "__timeFrom": case "__timeFrom":
return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil return fmt.Sprintf("to_timestamp(%d)", m.TimeRange.GetFromAsSecondsEpoch()), nil
case "__timeTo": case "__timeTo":

View File

@ -6,14 +6,27 @@ import (
"testing" "testing"
"time" "time"
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/tsdb" "github.com/grafana/grafana/pkg/tsdb"
. "github.com/smartystreets/goconvey/convey" . "github.com/smartystreets/goconvey/convey"
) )
func TestMacroEngine(t *testing.T) { func TestMacroEngine(t *testing.T) {
Convey("MacroEngine", t, func() { Convey("MacroEngine", t, func() {
engine := &PostgresMacroEngine{} engine := NewPostgresMacroEngine()
query := &tsdb.Query{} // datasource with no pg version specified
ds := &models.DataSource{Id: 1, Type: "postgres", JsonData: simplejson.New()}
// datasource with postgres 8.0 configured
ds_80 := &models.DataSource{Id: 2, Type: "postgres", JsonData: simplejson.New()}
ds_80.JsonData.Set("postgresVersion", 80000)
// datasource with postgres 8.1 configured
ds_81 := &models.DataSource{Id: 3, Type: "postgres", JsonData: simplejson.New()}
ds_81.JsonData.Set("postgresVersion", 80100)
query := &tsdb.Query{RefId: "A", DataSource: ds}
query_80 := &tsdb.Query{RefId: "A", DataSource: ds_80}
query_81 := &tsdb.Query{RefId: "A", DataSource: ds_81}
Convey("Given a time range between 2018-04-12 00:00 and 2018-04-12 00:05", func() { 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) from := time.Date(2018, 4, 12, 18, 0, 0, 0, time.UTC)
@ -38,7 +51,21 @@ 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, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix())) So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFilter function for postgres 8.0", func() {
sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFilter function for postgres 8.1", func() {
sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeFrom function", func() { Convey("interpolate __timeFrom function", func() {
@ -102,7 +129,21 @@ 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, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix())) So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFilter function for 8.0", func() {
sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFilter function for 8.1", func() {
sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeFrom function", func() { Convey("interpolate __timeFrom function", func() {
@ -150,7 +191,21 @@ 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, fmt.Sprintf("WHERE extract(epoch from time_column) BETWEEN %d AND %d", from.Unix(), to.Unix())) So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFilter function for 8.0", func() {
sql, err := engine.Interpolate(query_80, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN 'epoch'::timestamptz + %d * '1s'::interval AND 'epoch'::timestamptz + %d * '1s'::interval", from.Unix(), to.Unix()))
})
Convey("interpolate __timeFilter function for 8.1", func() {
sql, err := engine.Interpolate(query_81, timeRange, "WHERE $__timeFilter(time_column)")
So(err, ShouldBeNil)
So(sql, ShouldEqual, fmt.Sprintf("WHERE time_column BETWEEN to_timestamp(%d) AND to_timestamp(%d)", from.Unix(), to.Unix()))
}) })
Convey("interpolate __timeFrom function", func() { Convey("interpolate __timeFrom function", func() {