tempo: Use the correct filter separator for negative selector (#112280)

Signed-off-by: Goutham Veeramachaneni <goutham@grafana.com>
This commit is contained in:
Goutham Veeramachaneni
2025-10-21 10:31:19 +02:00
committed by GitHub
parent 7c7c9490fb
commit af2d5d98b5
2 changed files with 41 additions and 1 deletions
@@ -155,4 +155,42 @@ describe('filterToQuerySection returns the correct query section for a filter',
const result = filterToQuerySection(filter, [], lp);
expect(result).toBe('span.foo=~"bar|baz"');
});
it('filter with multiple values and != operator', () => {
const filter: TraceqlFilter = {
id: 'abc',
tag: 'foo',
operator: '!=',
value: ['bar', 'baz'],
scope: TraceqlSearchScope.Span,
};
const result = filterToQuerySection(filter, [], lp);
expect(result).toBe('(span.foo!=bar && span.foo!=baz)');
});
it('filter with multiple string values and != operator', () => {
const filter: TraceqlFilter = {
id: 'abc',
tag: 'foo',
operator: '!=',
value: ['bar', 'baz'],
scope: TraceqlSearchScope.Span,
valueType: 'string',
};
const result = filterToQuerySection(filter, [], lp);
expect(result).toBe('(span.foo!="bar" && span.foo!="baz")');
});
it('filter with multiple string values and !~ operator', () => {
const filter: TraceqlFilter = {
id: 'abc',
tag: 'foo',
operator: '!~',
value: ['bar', 'baz'],
scope: TraceqlSearchScope.Span,
valueType: 'string',
};
const result = filterToQuerySection(filter, [], lp);
expect(result).toBe('span.foo!~"bar|baz"');
});
});
@@ -81,7 +81,9 @@ export const tagHelper = (f: TraceqlFilter, filters: TraceqlFilter[]) => {
export const filterToQuerySection = (f: TraceqlFilter, filters: TraceqlFilter[], lp: TempoLanguageProvider) => {
if (Array.isArray(f.value) && f.value.length > 1 && !isRegExpOperator(f.operator!)) {
return `(${f.value.map((v) => `${scopeHelper(f, lp)}${tagHelper(f, filters)}${f.operator}${valueHelper({ ...f, value: v })}`).join(' || ')})`;
// For negative operators (!=), use && instead of ||
const joinOperator = f.operator === '!=' ? ' && ' : ' || ';
return `(${f.value.map((v) => `${scopeHelper(f, lp)}${tagHelper(f, filters)}${f.operator}${valueHelper({ ...f, value: v })}`).join(joinOperator)})`;
}
return `${scopeHelper(f, lp)}${tagHelper(f, filters)}${f.operator}${valueHelper(f)}`;