Merge pull request #7765 from influxdata/js-7553-modulo-operator
Add modulo operator to the query languagepull/7990/head
commit
5395bd3bcf
|
@ -4,6 +4,7 @@
|
|||
|
||||
- [#7776](https://github.com/influxdata/influxdb/issues/7776): Add system information to /debug/vars.
|
||||
- [#7948](https://github.com/influxdata/influxdb/pull/7948): Reduce memory allocations by reusing gzip.Writers across requests
|
||||
- [#7553](https://github.com/influxdata/influxdb/issues/7553): Add modulo operator to the query language.
|
||||
|
||||
## v1.2.1 [unreleased]
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"regexp"
|
||||
"regexp/syntax"
|
||||
"sort"
|
||||
|
@ -4301,6 +4302,11 @@ func evalBinaryExpr(expr *BinaryExpr, m map[string]interface{}) interface{} {
|
|||
return float64(0)
|
||||
}
|
||||
return lhs / rhs
|
||||
case MOD:
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return math.Mod(lhs, rhs)
|
||||
}
|
||||
case int64:
|
||||
// Try as a float64 to see if a float cast is required.
|
||||
|
@ -4332,6 +4338,8 @@ func evalBinaryExpr(expr *BinaryExpr, m map[string]interface{}) interface{} {
|
|||
return float64(0)
|
||||
}
|
||||
return lhs / rhs
|
||||
case MOD:
|
||||
return math.Mod(lhs, rhs)
|
||||
}
|
||||
} else {
|
||||
rhs, ok := rhs.(int64)
|
||||
|
@ -4370,6 +4378,13 @@ func evalBinaryExpr(expr *BinaryExpr, m map[string]interface{}) interface{} {
|
|||
return float64(0)
|
||||
}
|
||||
return lhs / rhs
|
||||
case MOD:
|
||||
if !ok {
|
||||
return nil
|
||||
} else if rhs == 0 {
|
||||
return int64(0)
|
||||
}
|
||||
return lhs % rhs
|
||||
}
|
||||
}
|
||||
case string:
|
||||
|
@ -4709,6 +4724,11 @@ func reduceBinaryExprIntegerLHS(op Token, lhs *IntegerLiteral, rhs Expr) Expr {
|
|||
return &NumberLiteral{Val: 0}
|
||||
}
|
||||
return &NumberLiteral{Val: float64(lhs.Val) / float64(rhs.Val)}
|
||||
case MOD:
|
||||
if rhs.Val == 0 {
|
||||
return &IntegerLiteral{Val: 0}
|
||||
}
|
||||
return &IntegerLiteral{Val: lhs.Val % rhs.Val}
|
||||
case EQ:
|
||||
return &BooleanLiteral{Val: lhs.Val == rhs.Val}
|
||||
case NEQ:
|
||||
|
@ -4775,6 +4795,8 @@ func reduceBinaryExprNumberLHS(op Token, lhs *NumberLiteral, rhs Expr) Expr {
|
|||
return &NumberLiteral{Val: 0}
|
||||
}
|
||||
return &NumberLiteral{Val: lhs.Val / rhs.Val}
|
||||
case MOD:
|
||||
return &NumberLiteral{Val: math.Mod(lhs.Val, rhs.Val)}
|
||||
case EQ:
|
||||
return &BooleanLiteral{Val: lhs.Val == rhs.Val}
|
||||
case NEQ:
|
||||
|
@ -4801,6 +4823,8 @@ func reduceBinaryExprNumberLHS(op Token, lhs *NumberLiteral, rhs Expr) Expr {
|
|||
return &NumberLiteral{Val: 0}
|
||||
}
|
||||
return &NumberLiteral{Val: lhs.Val / float64(rhs.Val)}
|
||||
case MOD:
|
||||
return &NumberLiteral{Val: math.Mod(lhs.Val, float64(rhs.Val))}
|
||||
case EQ:
|
||||
return &BooleanLiteral{Val: lhs.Val == float64(rhs.Val)}
|
||||
case NEQ:
|
||||
|
|
|
@ -1175,6 +1175,10 @@ func TestReduce(t *testing.T) {
|
|||
{in: `foo(bar(2 + 3), 4)`, out: `foo(bar(5), 4)`},
|
||||
{in: `4 / 0`, out: `0.000`},
|
||||
{in: `1 / 2`, out: `0.500`},
|
||||
{in: `2 % 3`, out: `2`},
|
||||
{in: `5 % 2`, out: `1`},
|
||||
{in: `2 % 0`, out: `0`},
|
||||
{in: `2.5 % 0`, out: `NaN`},
|
||||
{in: `4 = 4`, out: `true`},
|
||||
{in: `4 <> 4`, out: `false`},
|
||||
{in: `6 > 4`, out: `true`},
|
||||
|
|
|
@ -65,6 +65,8 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) {
|
|||
return MUL, pos, ""
|
||||
case '/':
|
||||
return DIV, pos, ""
|
||||
case '%':
|
||||
return MOD, pos, ""
|
||||
case '=':
|
||||
if ch1, _ := s.r.read(); ch1 == '~' {
|
||||
return EQREGEX, pos, ""
|
||||
|
|
|
@ -34,6 +34,7 @@ func TestScanner_Scan(t *testing.T) {
|
|||
{s: `-`, tok: influxql.SUB},
|
||||
{s: `*`, tok: influxql.MUL},
|
||||
{s: `/`, tok: influxql.DIV},
|
||||
{s: `%`, tok: influxql.MOD},
|
||||
|
||||
// Logical operators
|
||||
{s: `AND`, tok: influxql.AND},
|
||||
|
|
|
@ -3,6 +3,7 @@ package influxql
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
@ -1482,6 +1483,8 @@ func floatBinaryExprFunc(op Token) interface{} {
|
|||
}
|
||||
return lhs / rhs
|
||||
}
|
||||
case MOD:
|
||||
return func(lhs, rhs float64) float64 { return math.Mod(lhs, rhs) }
|
||||
case EQ:
|
||||
return func(lhs, rhs float64) bool { return lhs == rhs }
|
||||
case NEQ:
|
||||
|
@ -1513,6 +1516,13 @@ func integerBinaryExprFunc(op Token) interface{} {
|
|||
}
|
||||
return float64(lhs) / float64(rhs)
|
||||
}
|
||||
case MOD:
|
||||
return func(lhs, rhs int64) int64 {
|
||||
if rhs == 0 {
|
||||
return int64(0)
|
||||
}
|
||||
return lhs % rhs
|
||||
}
|
||||
case EQ:
|
||||
return func(lhs, rhs int64) bool { return lhs == rhs }
|
||||
case NEQ:
|
||||
|
|
|
@ -36,6 +36,7 @@ const (
|
|||
SUB // -
|
||||
MUL // *
|
||||
DIV // /
|
||||
MOD // %
|
||||
|
||||
AND // AND
|
||||
OR // OR
|
||||
|
|
Loading…
Reference in New Issue