mirror of
https://github.com/VictoriaMetrics/VictoriaMetrics.git
synced 2024-11-21 14:44:00 +00:00
app/vmselect/promql: hande comparisons with NaN
similar to Prometheus
Updates https://github.com/VictoriaMetrics/VictoriaMetrics/issues/150
This commit is contained in:
parent
dcce92c63c
commit
218cb4623a
4 changed files with 49 additions and 12 deletions
|
@ -416,10 +416,25 @@ func binaryOpIfnot(left, right float64) float64 {
|
|||
}
|
||||
|
||||
func binaryOpEq(left, right float64) bool {
|
||||
// Special handling for nan == nan.
|
||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/150 .
|
||||
if math.IsNaN(left) {
|
||||
return math.IsNaN(right)
|
||||
}
|
||||
|
||||
return left == right
|
||||
}
|
||||
|
||||
func binaryOpNeq(left, right float64) bool {
|
||||
// Special handling for comparison with nan.
|
||||
// See https://github.com/VictoriaMetrics/VictoriaMetrics/issues/150 .
|
||||
if math.IsNaN(left) {
|
||||
return !math.IsNaN(right)
|
||||
}
|
||||
if math.IsNaN(right) {
|
||||
return true
|
||||
}
|
||||
|
||||
return left != right
|
||||
}
|
||||
|
||||
|
|
|
@ -149,12 +149,6 @@ func scanString(s string) (string, error) {
|
|||
}
|
||||
|
||||
func scanPositiveNumber(s string) (string, error) {
|
||||
if strings.HasPrefix(s, "Inf") {
|
||||
return "Inf", nil
|
||||
}
|
||||
if strings.HasPrefix(s, "NaN") {
|
||||
return "NaN", nil
|
||||
}
|
||||
// Scan integer part. It may be empty if fractional part exists.
|
||||
i := 0
|
||||
for i < len(s) && isDecimalChar(s[i]) {
|
||||
|
@ -333,6 +327,14 @@ func scanTagFilterOpPrefix(s string) int {
|
|||
return -1
|
||||
}
|
||||
|
||||
func isInfOrNaN(s string) bool {
|
||||
if len(s) != 3 {
|
||||
return false
|
||||
}
|
||||
s = strings.ToLower(s)
|
||||
return s == "inf" || s == "nan"
|
||||
}
|
||||
|
||||
func isOffset(s string) bool {
|
||||
s = strings.ToLower(s)
|
||||
return s == "offset"
|
||||
|
@ -361,7 +363,7 @@ func isPositiveNumberPrefix(s string) bool {
|
|||
|
||||
// Check for .234 numbers
|
||||
if s[0] != '.' || len(s) < 2 {
|
||||
return strings.HasPrefix(s, "Inf") || strings.HasPrefix(s, "NaN")
|
||||
return false
|
||||
}
|
||||
return isDecimalChar(s[1])
|
||||
}
|
||||
|
|
|
@ -373,7 +373,7 @@ func (p *parser) parseSingleExpr() (expr, error) {
|
|||
}
|
||||
|
||||
func (p *parser) parseSingleExprWithoutRollupSuffix() (expr, error) {
|
||||
if isPositiveNumberPrefix(p.lex.Token) {
|
||||
if isPositiveNumberPrefix(p.lex.Token) || isInfOrNaN(p.lex.Token) {
|
||||
return p.parsePositiveNumberExpr()
|
||||
}
|
||||
if isStringPrefix(p.lex.Token) {
|
||||
|
@ -417,7 +417,7 @@ func (p *parser) parseSingleExprWithoutRollupSuffix() (expr, error) {
|
|||
}
|
||||
|
||||
func (p *parser) parsePositiveNumberExpr() (*numberExpr, error) {
|
||||
if !isPositiveNumberPrefix(p.lex.Token) {
|
||||
if !isPositiveNumberPrefix(p.lex.Token) && !isInfOrNaN(p.lex.Token) {
|
||||
return nil, fmt.Errorf(`positiveNumberExpr: unexpected token %q; want "number"`, p.lex.Token)
|
||||
}
|
||||
|
||||
|
|
|
@ -170,14 +170,34 @@ func TestParsePromQLSuccess(t *testing.T) {
|
|||
another(`-.2`, `-0.2`)
|
||||
another(`-.2E-2`, `-0.002`)
|
||||
same(`NaN`)
|
||||
another(`nan`, `NaN`)
|
||||
another(`NAN`, `NaN`)
|
||||
another(`nAN`, `NaN`)
|
||||
another(`Inf`, `+Inf`)
|
||||
another(`INF`, `+Inf`)
|
||||
another(`inf`, `+Inf`)
|
||||
another(`+Inf`, `+Inf`)
|
||||
another(`-Inf`, `-Inf`)
|
||||
another(`-inF`, `-Inf`)
|
||||
|
||||
// binaryOpExpr
|
||||
another(`NaN + 2 *3 * Inf`, `NaN`)
|
||||
another(`Inf - Inf`, `NaN`)
|
||||
another(`Inf + Inf`, `+Inf`)
|
||||
another(`nan == nan`, `NaN`)
|
||||
another(`nan ==bool nan`, `1`)
|
||||
another(`nan !=bool nan`, `0`)
|
||||
another(`nan !=bool 2`, `1`)
|
||||
another(`2 !=bool nan`, `1`)
|
||||
another(`nan >bool nan`, `0`)
|
||||
another(`nan <bool nan`, `0`)
|
||||
another(`1 ==bool nan`, `0`)
|
||||
another(`NaN !=bool 1`, `1`)
|
||||
another(`inf >=bool 2`, `1`)
|
||||
another(`-1 >bool -inf`, `1`)
|
||||
another(`-1 <bool -inf`, `0`)
|
||||
another(`nan + 2 *3 * inf`, `NaN`)
|
||||
another(`INF - Inf`, `NaN`)
|
||||
another(`Inf + inf`, `+Inf`)
|
||||
another(`1/0`, `+Inf`)
|
||||
another(`0/0`, `NaN`)
|
||||
another(`-m`, `0 - m`)
|
||||
same(`m + ignoring () n[5m]`)
|
||||
another(`M + IGNORING () N[5m]`, `M + ignoring () N[5m]`)
|
||||
|
|
Loading…
Reference in a new issue