From 7e13882a1ab8c2aef36280992af1687e5458d48d Mon Sep 17 00:00:00 2001 From: jcolladokuri Date: Tue, 16 Sep 2025 08:48:52 -0700 Subject: [PATCH] Prometheus: Fix ad hoc filters when using explore table column filtering (#111141) * add support for ad hoc filtering from explore * fix test * remove helper function and keep check in if statement --- .../grafana-prometheus/src/add_label_to_query.test.ts | 9 +++++++++ packages/grafana-prometheus/src/add_label_to_query.ts | 11 ++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/grafana-prometheus/src/add_label_to_query.test.ts b/packages/grafana-prometheus/src/add_label_to_query.test.ts index a57f9294938..7e70312e643 100644 --- a/packages/grafana-prometheus/src/add_label_to_query.test.ts +++ b/packages/grafana-prometheus/src/add_label_to_query.test.ts @@ -66,6 +66,15 @@ describe('addLabelToQuery()', () => { ); }); + it('should modify existing labels if the operator is different', () => { + expect(addLabelToQuery(addLabelToQuery('foo{x="yy"}', 'bar', 'baz', '!='), 'bar', 'baz', '=')).toBe( + 'foo{x="yy", bar="baz"}' + ); + expect(addLabelToQuery(addLabelToQuery('foo{x="yy"}', 'bar', 'baz', '='), 'bar', 'baz', '!=')).toBe( + 'foo{x="yy", bar!="baz"}' + ); + }); + it('should not remove filters', () => { expect(addLabelToQuery('{x="y"} |="yy"', 'bar', 'baz')).toBe('{x="y", bar="baz"} |="yy"'); expect(addLabelToQuery('{x="y"} |="yy" !~"xx"', 'bar', 'baz')).toBe('{x="y", bar="baz"} |="yy" !~"xx"'); diff --git a/packages/grafana-prometheus/src/add_label_to_query.ts b/packages/grafana-prometheus/src/add_label_to_query.ts index 06e82fcbf00..a4df4206366 100644 --- a/packages/grafana-prometheus/src/add_label_to_query.ts +++ b/packages/grafana-prometheus/src/add_label_to_query.ts @@ -79,8 +79,17 @@ function addFilter( const start = query.substring(prev, match.from); const end = isLast ? query.substring(match.to) : ''; - if (!labelExists(match.query.labels, filter)) { + const labelToMatch = labelExists(match.query.labels, filter); + if (labelToMatch) { + // if label exists, check the operator, if it is different, update it. // We don't want to add duplicate labels. + if (labelToMatch.op !== filter.op) { + match.query.labels = match.query.labels.map((label) => + label.label === filter.label && label.value === filter.value ? filter : label + ); + } + } else { + // label does not exist, add as is. match.query.labels.push(filter); } const newLabels = renderQuery(match.query);