mirror of
https://github.com/prometheus/prometheus
synced 2025-01-13 02:14:08 +00:00
promql: Remove scalar/scalar comparisons.
This change is breaking, use the 'bool' modifier for such comprisons. After this change all comparisons without 'bool' will filter, and all comparisons with 'bool' will return 0/1. This makes the language more consistent and orthogonal, and ultimately easier to learn and use. If we ever figure out sane semantics for filtering scalar/scalar comparisons we can add them in, which will most likely come out of how the new vector() function is used.
This commit is contained in:
parent
965a71dc4d
commit
c36961130b
@ -60,6 +60,17 @@ func (i itemType) isAggregator() bool { return i > aggregatorsStart && i < aggre
|
|||||||
// Returns false otherwise.
|
// Returns false otherwise.
|
||||||
func (i itemType) isKeyword() bool { return i > keywordsStart && i < keywordsEnd }
|
func (i itemType) isKeyword() bool { return i > keywordsStart && i < keywordsEnd }
|
||||||
|
|
||||||
|
// isCompairsonOperator returns true if the item corresponds to a comparison operator.
|
||||||
|
// Returns false otherwise.
|
||||||
|
func (i itemType) isComparisonOperator() bool {
|
||||||
|
switch i {
|
||||||
|
case itemEQL, itemNEQ, itemLTE, itemLSS, itemGTE, itemGTR:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Constants for operator precedence in expressions.
|
// Constants for operator precedence in expressions.
|
||||||
//
|
//
|
||||||
const LowestPrec = 0 // Non-operators.
|
const LowestPrec = 0 // Non-operators.
|
||||||
|
@ -488,10 +488,7 @@ func (p *parser) expr() Expr {
|
|||||||
returnBool := false
|
returnBool := false
|
||||||
// Parse bool modifier.
|
// Parse bool modifier.
|
||||||
if p.peek().typ == itemBool {
|
if p.peek().typ == itemBool {
|
||||||
switch op {
|
if !op.isComparisonOperator() {
|
||||||
case itemEQL, itemNEQ, itemLTE, itemLSS, itemGTE, itemGTR:
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
p.errorf("bool modifier can only be used on comparison operators")
|
p.errorf("bool modifier can only be used on comparison operators")
|
||||||
}
|
}
|
||||||
p.next()
|
p.next()
|
||||||
@ -540,6 +537,9 @@ func (p *parser) expr() Expr {
|
|||||||
},
|
},
|
||||||
VectorMatching: lhs.VectorMatching,
|
VectorMatching: lhs.VectorMatching,
|
||||||
}
|
}
|
||||||
|
if op.isComparisonOperator() && !returnBool && rhs.Type() == model.ValScalar && lhs.RHS.Type() == model.ValScalar {
|
||||||
|
p.errorf("comparisons between scalars must use BOOL modifier")
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
expr = &BinaryExpr{
|
expr = &BinaryExpr{
|
||||||
Op: op,
|
Op: op,
|
||||||
@ -548,7 +548,11 @@ func (p *parser) expr() Expr {
|
|||||||
VectorMatching: vecMatching,
|
VectorMatching: vecMatching,
|
||||||
ReturnBool: returnBool,
|
ReturnBool: returnBool,
|
||||||
}
|
}
|
||||||
|
if op.isComparisonOperator() && !returnBool && rhs.Type() == model.ValScalar && expr.Type() == model.ValScalar {
|
||||||
|
p.errorf("comparisons between scalars must use BOOL modifier")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,23 +85,20 @@ var testExpr = []struct {
|
|||||||
input: "1 / 1",
|
input: "1 / 1",
|
||||||
expected: &BinaryExpr{itemDIV, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
expected: &BinaryExpr{itemDIV, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
||||||
}, {
|
}, {
|
||||||
input: "1 == 1",
|
input: "1 == bool 1",
|
||||||
expected: &BinaryExpr{itemEQL, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
expected: &BinaryExpr{itemEQL, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||||
}, {
|
}, {
|
||||||
input: "1 != 1",
|
input: "1 != bool 1",
|
||||||
expected: &BinaryExpr{itemNEQ, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
expected: &BinaryExpr{itemNEQ, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||||
}, {
|
}, {
|
||||||
input: "1 > 1",
|
input: "1 > bool 1",
|
||||||
expected: &BinaryExpr{itemGTR, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
expected: &BinaryExpr{itemGTR, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||||
}, {
|
}, {
|
||||||
input: "1 >= 1",
|
input: "1 >= bool 1",
|
||||||
expected: &BinaryExpr{itemGTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
expected: &BinaryExpr{itemGTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||||
}, {
|
}, {
|
||||||
input: "1 < 1",
|
input: "1 < bool 1",
|
||||||
expected: &BinaryExpr{itemLSS, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
expected: &BinaryExpr{itemLSS, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||||
}, {
|
|
||||||
input: "1 <= 1",
|
|
||||||
expected: &BinaryExpr{itemLTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, false},
|
|
||||||
}, {
|
}, {
|
||||||
input: "1 <= bool 1",
|
input: "1 <= bool 1",
|
||||||
expected: &BinaryExpr{itemLTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
expected: &BinaryExpr{itemLTE, &NumberLiteral{1}, &NumberLiteral{1}, nil, true},
|
||||||
@ -203,6 +200,10 @@ var testExpr = []struct {
|
|||||||
input: "1 and 1",
|
input: "1 and 1",
|
||||||
fail: true,
|
fail: true,
|
||||||
errMsg: "AND and OR not allowed in binary scalar expression",
|
errMsg: "AND and OR not allowed in binary scalar expression",
|
||||||
|
}, {
|
||||||
|
input: "1 == 1",
|
||||||
|
fail: true,
|
||||||
|
errMsg: "parse error at char 7: comparisons between scalars must use BOOL modifier",
|
||||||
}, {
|
}, {
|
||||||
input: "1 or 1",
|
input: "1 or 1",
|
||||||
fail: true,
|
fail: true,
|
||||||
|
6
promql/testdata/comparison.test
vendored
6
promql/testdata/comparison.test
vendored
@ -40,12 +40,6 @@ eval instant at 50m SUM(http_requests) BY (job) != bool SUM(http_requests) BY (j
|
|||||||
{job="app-server"} 0
|
{job="app-server"} 0
|
||||||
|
|
||||||
|
|
||||||
eval instant at 50m 0 == 1
|
|
||||||
0
|
|
||||||
|
|
||||||
eval instant at 50m 1 == 1
|
|
||||||
1
|
|
||||||
|
|
||||||
eval instant at 50m 0 == bool 1
|
eval instant at 50m 0 == bool 1
|
||||||
0
|
0
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user