mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
InfluxDB: Add support for >= and <= comparison operators to IQL Query Builder (#77917)
* InfluxDB: Add support for `>=` and `<=` comparison operators to InfluxQL Query Builder * Add front-end support for the new operators This ensures that the query translates correctly between raw and builder mode * Chore: add test for new operators * chore: add front-end tests * fix: don't skip quoting on `<>` This preserves the pre-existing behaviour, fixing a failing test * chore: fix tests
This commit is contained in:
@@ -72,7 +72,7 @@ func (query *Query) renderTags() []string {
|
|||||||
switch tag.Operator {
|
switch tag.Operator {
|
||||||
case "=~", "!~":
|
case "=~", "!~":
|
||||||
textValue = tag.Value
|
textValue = tag.Value
|
||||||
case "<", ">":
|
case "<", ">", ">=", "<=":
|
||||||
textValue = tag.Value
|
textValue = tag.Value
|
||||||
default:
|
default:
|
||||||
textValue = fmt.Sprintf("'%s'", strings.ReplaceAll(tag.Value, `\`, `\\`))
|
textValue = fmt.Sprintf("'%s'", strings.ReplaceAll(tag.Value, `\`, `\\`))
|
||||||
|
|||||||
@@ -228,6 +228,17 @@ func TestInfluxdbQueryBuilder(t *testing.T) {
|
|||||||
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" > 10001`)
|
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" > 10001`)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("can render number greater than or equal to condition tags", func(t *testing.T) {
|
||||||
|
query := &Query{Tags: []*Tag{{Operator: ">=", Value: "10001", Key: "key"}}}
|
||||||
|
|
||||||
|
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" >= 10001`)
|
||||||
|
})
|
||||||
|
t.Run("can render number less than or equal to condition tags", func(t *testing.T) {
|
||||||
|
query := &Query{Tags: []*Tag{{Operator: "<=", Value: "10001", Key: "key"}}}
|
||||||
|
|
||||||
|
require.Equal(t, strings.Join(query.renderTags(), ""), `"key" <= 10001`)
|
||||||
|
})
|
||||||
|
|
||||||
t.Run("can render string tags", func(t *testing.T) {
|
t.Run("can render string tags", func(t *testing.T) {
|
||||||
query := &Query{Tags: []*Tag{{Operator: "=", Value: "value", Key: "key"}}}
|
query := &Query{Tags: []*Tag{{Operator: "=", Value: "value", Key: "key"}}}
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import { toSelectableValue } from '../utils/toSelectableValue';
|
|||||||
import { AddButton } from './AddButton';
|
import { AddButton } from './AddButton';
|
||||||
import { Seg } from './Seg';
|
import { Seg } from './Seg';
|
||||||
|
|
||||||
type KnownOperator = '=' | '!=' | '<>' | '<' | '>' | '=~' | '!~';
|
type KnownOperator = '=' | '!=' | '<>' | '<' | '>' | '>=' | '<=' | '=~' | '!~';
|
||||||
const knownOperators: KnownOperator[] = ['=', '!=', '<>', '<', '>', '=~', '!~'];
|
const knownOperators: KnownOperator[] = ['=', '!=', '<>', '<', '>', '>=', '<=', '=~', '!~'];
|
||||||
|
|
||||||
type KnownCondition = 'AND' | 'OR';
|
type KnownCondition = 'AND' | 'OR';
|
||||||
const knownConditions: KnownCondition[] = ['AND', 'OR'];
|
const knownConditions: KnownCondition[] = ['AND', 'OR'];
|
||||||
|
|||||||
@@ -206,6 +206,44 @@ describe('InfluxQuery', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('query with greater-than-or-equal-to condition', () => {
|
||||||
|
it('should use >=', () => {
|
||||||
|
const query = new InfluxQueryModel(
|
||||||
|
{
|
||||||
|
refId: 'A',
|
||||||
|
measurement: 'cpu',
|
||||||
|
policy: 'autogen',
|
||||||
|
groupBy: [],
|
||||||
|
tags: [{ key: 'value', value: '5', operator: '>=' }],
|
||||||
|
},
|
||||||
|
templateSrv,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
const queryText = query.render();
|
||||||
|
expect(queryText).toBe('SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" >= 5) AND $timeFilter');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('query with less-than-or-equal-to condition', () => {
|
||||||
|
it('should use <=', () => {
|
||||||
|
const query = new InfluxQueryModel(
|
||||||
|
{
|
||||||
|
refId: 'A',
|
||||||
|
measurement: 'cpu',
|
||||||
|
policy: 'autogen',
|
||||||
|
groupBy: [],
|
||||||
|
tags: [{ key: 'value', value: '5', operator: '<=' }],
|
||||||
|
},
|
||||||
|
templateSrv,
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
const queryText = query.render();
|
||||||
|
expect(queryText).toBe('SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" <= 5) AND $timeFilter');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('series with groupByTag', () => {
|
describe('series with groupByTag', () => {
|
||||||
it('should generate correct query', () => {
|
it('should generate correct query', () => {
|
||||||
const query = new InfluxQueryModel(
|
const query = new InfluxQueryModel(
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ export default class InfluxQueryModel {
|
|||||||
if (interpolate) {
|
if (interpolate) {
|
||||||
value = this.templateSrv.replace(value, this.scopedVars);
|
value = this.templateSrv.replace(value, this.scopedVars);
|
||||||
}
|
}
|
||||||
if (operator !== '>' && operator !== '<') {
|
if ((!operator.startsWith('>') && !operator.startsWith('<')) || operator === '<>') {
|
||||||
value = "'" + value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'") + "'";
|
value = "'" + value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'") + "'";
|
||||||
}
|
}
|
||||||
} else if (interpolate) {
|
} else if (interpolate) {
|
||||||
|
|||||||
Reference in New Issue
Block a user