diff --git a/pkg/tsdb/influxdb/models/query.go b/pkg/tsdb/influxdb/models/query.go index fc6024fe074..0620e5d3b02 100644 --- a/pkg/tsdb/influxdb/models/query.go +++ b/pkg/tsdb/influxdb/models/query.go @@ -14,9 +14,7 @@ import ( var ( regexpOperatorPattern = regexp.MustCompile(`^\/.*\/$`) regexpMeasurementPattern = regexp.MustCompile(`^\/.*\/$`) - regexMatcherSimple = regexp.MustCompile(`^/(.*)/$`) regexMatcherWithStartEndPattern = regexp.MustCompile(`^/\^(.*)\$/$`) - mustEscapeCharsMatcher = regexp.MustCompile(`[\\^$*+?.()|[\]{}\/]`) ) func (query *Query) Build(queryContext *backend.QueryDataRequest) (string, error) { @@ -112,7 +110,7 @@ func (query *Query) renderTags() []string { var textValue string switch tag.Operator { case "=~", "!~", "": - textValue = escape(tag.Value) + textValue = tag.Value case "<", ">", ">=", "<=": textValue = removeRegexWrappers(tag.Value, `'`) case "Is", "Is Not": @@ -258,44 +256,3 @@ func removeRegexWrappers(wrappedValue string, wrapper string) string { return value } - -func escape(unescapedValue string) string { - pipe := `|` - beginning := `/^` - ending := `$/` - value := unescapedValue - substitute := `\$0` - fullMatch := false - - // get the value only in between /^...$/ - matches := regexMatcherWithStartEndPattern.FindStringSubmatch(unescapedValue) - if len(matches) > 1 { - // full match. the value is like /^value$/ - value = matches[1] - fullMatch = true - } - - if !fullMatch { - // get the value only in between /.../ - matches = regexMatcherSimple.FindStringSubmatch(unescapedValue) - if len(matches) > 1 { - value = matches[1] - beginning = `/` - ending = `/` - } - } - - // split them with pipe | - parts := strings.Split(value, pipe) - for i, v := range parts { - // escape each item - parts[i] = mustEscapeCharsMatcher.ReplaceAllString(v, substitute) - } - - // stitch them to each other - escaped := make([]byte, 0, 64) - escaped = append(escaped, beginning...) - escaped = append(escaped, strings.Join(parts, pipe)...) - escaped = append(escaped, ending...) - return string(escaped) -} diff --git a/pkg/tsdb/influxdb/models/query_test.go b/pkg/tsdb/influxdb/models/query_test.go index 35c8bbd9f22..235de42360e 100644 --- a/pkg/tsdb/influxdb/models/query_test.go +++ b/pkg/tsdb/influxdb/models/query_test.go @@ -304,30 +304,6 @@ func TestInfluxdbQueryBuilder(t *testing.T) { require.Equal(t, query.renderMeasurement(), ` FROM "policy"./apa/`) }) - t.Run("can render regexp tags", func(t *testing.T) { - query := &Query{Tags: []*Tag{{Operator: "=~", Value: `/etc/hosts|/etc/hostname`, Key: "key"}}} - - require.Equal(t, `"key" =~ /^\/etc\/hosts|\/etc\/hostname$/`, strings.Join(query.renderTags(), "")) - }) - - t.Run("can render regexp tags 2", func(t *testing.T) { - query := &Query{Tags: []*Tag{{Operator: "=~", Value: `/^/etc/hosts$/`, Key: "key"}}} - - require.Equal(t, `"key" =~ /^\/etc\/hosts$/`, strings.Join(query.renderTags(), "")) - }) - - t.Run("can render regexp tags 3", func(t *testing.T) { - query := &Query{Tags: []*Tag{{Operator: "=~", Value: `/etc/hosts`, Key: "key"}}} - - require.Equal(t, `"key" =~ /^\/etc\/hosts$/`, strings.Join(query.renderTags(), "")) - }) - - t.Run("can render regexp tags with dots in values", func(t *testing.T) { - query := &Query{Tags: []*Tag{{Operator: "=~", Value: `/etc/resolv.conf`, Key: "key"}}} - - require.Equal(t, `"key" =~ /^\/etc\/resolv\.conf$/`, strings.Join(query.renderTags(), "")) - }) - t.Run("can render single quoted tag value when regexed value has been sent", func(t *testing.T) { query := &Query{Tags: []*Tag{{Operator: ">", Value: `/^12.2$/`, Key: "key"}}} diff --git a/public/app/plugins/datasource/influxdb/datasource.ts b/public/app/plugins/datasource/influxdb/datasource.ts index e63e002e7b3..daa4e18ae8b 100644 --- a/public/app/plugins/datasource/influxdb/datasource.ts +++ b/public/app/plugins/datasource/influxdb/datasource.ts @@ -257,7 +257,12 @@ export default class InfluxDatasource extends DataSourceWithBackend + this.interpolateQueryExpr(value, variable, tag.value) + ), }; }); } @@ -286,7 +291,6 @@ export default class InfluxDatasource extends DataSourceWithBackend { const qData = fetchMock.mock.calls[0][0].data.queries[0].query; expect(qData).toBe(qe); }); + + it('should interpolate variable inside a regex pattern', () => { + const query: InfluxQuery = { + refId: 'A', + tags: [ + { + key: 'key', + operator: '=~', + value: '/^.*-$var1$/', + }, + ], + }; + const res = ds.applyVariables(query, {}); + const expected = `/^.*-var1$/`; + expect(res.tags?.[0].value).toEqual(expected); + }); }); describe('metric find query', () => {