From 7968e218819d03cf052939964ed3dd1726867cb2 Mon Sep 17 00:00:00 2001 From: ahmah2009 Date: Wed, 4 Apr 2018 23:53:55 +0300 Subject: [PATCH] Implement floor, ceil, and round functions --- query/math.go | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/query/math.go b/query/math.go index fb96da71f9..467fc22c55 100644 --- a/query/math.go +++ b/query/math.go @@ -1,6 +1,7 @@ package query import ( + "fmt" "math" "github.com/influxdata/influxql" @@ -8,7 +9,7 @@ import ( func isMathFunction(call *influxql.Call) bool { switch call.Name { - case "sin", "cos", "tan": + case "sin", "cos", "tan", "floor", "ceil", "round": return true } return false @@ -24,6 +25,13 @@ func (MathTypeMapper) CallType(name string, args []influxql.DataType) (influxql. switch name { case "sin", "cos", "tan": return influxql.Float, nil + case "floor", "ceil", "round": + switch args[0] { + case influxql.Float, influxql.Integer, influxql.Unsigned, influxql.Unknown: + return args[0], nil + default: + return influxql.Unknown, fmt.Errorf("invalid argument type for first argument in %s(): %s", name, args[0]) + } } return influxql.Unknown, nil } @@ -46,6 +54,33 @@ func (v MathValuer) Call(name string, args []interface{}) (interface{}, bool) { return v.callTrigFunction(math.Cos, arg0) case "tan": return v.callTrigFunction(math.Tan, arg0) + case "floor": + switch arg0 := arg0.(type) { + case float64: + return math.Floor(arg0), true + case int64, uint64: + return arg0, true + default: + return nil, true + } + case "ceil": + switch arg0 := arg0.(type) { + case float64: + return math.Ceil(arg0), true + case int64, uint64: + return arg0, true + default: + return nil, true + } + case "round": + switch arg0 := arg0.(type) { + case float64: + return round(arg0), true + case int64, uint64: + return arg0, true + default: + return nil, true + } } } return nil, false @@ -63,3 +98,11 @@ func (MathValuer) callTrigFunction(fn func(x float64) float64, arg0 interface{}) } return fn(value), true } + +func round(x float64) float64 { + t := math.Trunc(x) + if math.Abs(x-t) >= 0.5 { + return t + math.Copysign(1, x) + } + return t +}