InfluxDB: Fix for wrong query generated with template variable and non regex operator on frontend mode (#84175)

* fix for wrong query generated for influxdb. see:https://github.com/grafana/grafana/issues/81517

Signed-off-by: Syed Nihal <syed.nihal@nokia.com>

* added unit tests

Signed-off-by: Syed Nihal <syed.nihal@nokia.com>

* fixed linting

Signed-off-by: Syed Nihal <syed.nihal@nokia.com>

* addressed review comments

Signed-off-by: Syed Nihal <syed.nihal@nokia.com>

* fixed linting issue

Signed-off-by: Syed Nihal <syed.nihal@nokia.com>

---------

Signed-off-by: Syed Nihal <syed.nihal@nokia.com>
pull/84953/head
Nihal 1 year ago committed by GitHub
parent e192c0aa05
commit 15122bc71c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 49
      public/app/plugins/datasource/influxdb/influx_query_model.test.ts
  2. 17
      public/app/plugins/datasource/influxdb/influx_query_model.ts

@ -604,4 +604,53 @@ describe('InfluxQuery', () => {
});
});
});
describe('test query generated with templateVariable and non-regex operator', () => {
const testCases = [
['=', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" = \'$tempVar\') AND $timeFilter'],
['!=', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" != \'$tempVar\') AND $timeFilter'],
['Is', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" = \'$tempVar\') AND $timeFilter'],
['Is Not', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" != \'$tempVar\') AND $timeFilter'],
['>', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" > $tempVar) AND $timeFilter'],
['<', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" < $tempVar) AND $timeFilter'],
];
it.each(testCases)('should not wrap with InfluxDB regex wrapper for "%s" operator', (operator, expectedQuery) => {
const query = new InfluxQueryModel(
{
refId: 'A',
measurement: 'cpu',
policy: 'autogen',
groupBy: [],
tags: [{ key: 'value', value: '/^$tempVar$/', operator }],
},
templateSrv,
{}
);
const queryText = query.render();
expect(queryText).toBe(expectedQuery);
});
});
describe('test query generated with templateVariable and regex operator', () => {
const testCases = [
['=~', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" =~ /^$tempVar$/) AND $timeFilter'],
['!~', 'SELECT mean("value") FROM "autogen"."cpu" WHERE ("value" !~ /^$tempVar$/) AND $timeFilter'],
];
it.each(testCases)('should wrap with InfluxDB regex wrapper for "%s" operator', (operator, expectedQuery) => {
const query = new InfluxQueryModel(
{
refId: 'A',
measurement: 'cpu',
policy: 'autogen',
groupBy: [],
tags: [{ key: 'value', value: '/^$tempVar$/', operator }],
},
templateSrv,
{}
);
const queryText = query.render();
expect(queryText).toBe(expectedQuery);
});
});
});

@ -141,6 +141,17 @@ export default class InfluxQueryModel {
this.updatePersistedParts();
}
private removeRegexWrapper(str: string) {
const regex = /\/\^(.*?)\$\//; // match any string that starts with "/^" and ends with "$/", capturing the characters in between
const match = str.match(regex);
if (match && match.length > 1) {
return match[1];
} else {
return str;
}
}
private isOperatorTypeHandler(operator: string, value: string, fieldName: string) {
let textValue;
if (operator === 'Is Not') {
@ -151,7 +162,7 @@ export default class InfluxQueryModel {
// Tags should always quote
if (fieldName.endsWith('::tag')) {
textValue = "'" + value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'") + "'";
textValue = "'" + this.removeRegexWrapper(value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'")) + "'";
return {
operator: operator,
value: textValue,
@ -169,7 +180,7 @@ export default class InfluxQueryModel {
textValue = lowerValue;
} else {
// String or unrecognised: quote
textValue = "'" + value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'") + "'";
textValue = "'" + this.removeRegexWrapper(value.replace(/\\/g, '\\\\').replace(/\'/g, "\\'")) + "'";
}
return {
operator: operator,
@ -199,7 +210,7 @@ export default class InfluxQueryModel {
if (interpolate) {
value = this.templateSrv.replace(value, this.scopedVars);
}
value = this.removeRegexWrapper(value);
if (operator.startsWith('Is')) {
let r = this.isOperatorTypeHandler(operator, value, tag.key);
operator = r.operator;

Loading…
Cancel
Save