mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
InfluxDB: Add new truthiness operators (Is and Is Not) to InfluxQL Query Builder (#77923)
* InfluxDB: Add new truthiness operators (`Is` and `Is Not`) to InfluxQL Editor for use with boolean fields * InfluxDB: Make the front-end aware of the new operators so that translation between raw and builder works * Chore: Add tests * feat: identify type of field value to allow other types to work with Is/Is Not Tags: always quote Integer: Don't quote Float: Don't quote Boolean: Don't quote String: Quote * Chore: Add test-cases for type inference * Update front-end to infer type for operators Is and Is Not * chore: Add front-end tests * chore: add additional front-end tests * chore: fix failing lint test * chore: fix tests (run prettier)
This commit is contained in:
@@ -67,6 +67,45 @@ func (query *Query) renderTags() []string {
|
||||
}
|
||||
}
|
||||
|
||||
isOperatorTypeHandler := func(tag *Tag) (string, string) {
|
||||
// Attempt to identify the type of the supplied value
|
||||
var lowerValue = strings.ToLower(tag.Value)
|
||||
var r = regexp.MustCompile(`^(-?)[0-9\.]+$`)
|
||||
var textValue string
|
||||
var operator string
|
||||
|
||||
// Perform operator replacements
|
||||
switch tag.Operator {
|
||||
case "Is":
|
||||
operator = "="
|
||||
case "Is Not":
|
||||
operator = "!="
|
||||
default:
|
||||
// This should never happen
|
||||
operator = "="
|
||||
}
|
||||
|
||||
// Always quote tag values
|
||||
if strings.HasSuffix(tag.Key, "::tag") {
|
||||
textValue = fmt.Sprintf("'%s'", strings.ReplaceAll(tag.Value, `\`, `\\`))
|
||||
return textValue, operator
|
||||
}
|
||||
|
||||
// Try and discern the type of fields
|
||||
if lowerValue == "true" || lowerValue == "false" {
|
||||
// boolean, don't quote, but make lowercase
|
||||
textValue = lowerValue
|
||||
} else if r.MatchString(tag.Value) {
|
||||
// Integer or float, don't quote
|
||||
textValue = tag.Value
|
||||
} else {
|
||||
// String (or unknown) - quote
|
||||
textValue = fmt.Sprintf("'%s'", strings.ReplaceAll(tag.Value, `\`, `\\`))
|
||||
}
|
||||
|
||||
return textValue, operator
|
||||
}
|
||||
|
||||
// quote value unless regex or number
|
||||
var textValue string
|
||||
switch tag.Operator {
|
||||
@@ -74,6 +113,8 @@ func (query *Query) renderTags() []string {
|
||||
textValue = tag.Value
|
||||
case "<", ">", ">=", "<=":
|
||||
textValue = tag.Value
|
||||
case "Is", "Is Not":
|
||||
textValue, tag.Operator = isOperatorTypeHandler(tag)
|
||||
default:
|
||||
textValue = fmt.Sprintf("'%s'", strings.ReplaceAll(tag.Value, `\`, `\\`))
|
||||
}
|
||||
|
||||
@@ -239,6 +239,47 @@ func TestInfluxdbQueryBuilder(t *testing.T) {
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" <= 10001`)
|
||||
})
|
||||
|
||||
t.Run("can render boolean equality tags", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "false", Key: "key"}}}
|
||||
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = false`)
|
||||
})
|
||||
|
||||
t.Run("can render boolean inequality tags", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is Not", Value: "true", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" != true`)
|
||||
})
|
||||
|
||||
t.Run("can correct case of boolean tags", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "False", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = false`)
|
||||
})
|
||||
|
||||
t.Run("can use strings with Is", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "A string", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = 'A string'`)
|
||||
})
|
||||
|
||||
t.Run("can use integers with Is", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "123", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = 123`)
|
||||
})
|
||||
|
||||
t.Run("can use negative integers with Is", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "-123", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = -123`)
|
||||
})
|
||||
|
||||
t.Run("can use floats with Is", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "1.23", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = 1.23`)
|
||||
})
|
||||
|
||||
t.Run("can use negative floats with Is", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "Is", Value: "-1.23", Key: "key"}}}
|
||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" = -1.23`)
|
||||
})
|
||||
|
||||
t.Run("can render string tags", func(t *testing.T) {
|
||||
query := &Query{Tags: []*Tag{{Operator: "=", Value: "value", Key: "key"}}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user