Loki: strip out backticks in query editor line filter (#79340)

* pull in @svennergr's solution to switch delimiter on existence of backtick

---------

Co-authored-by: Sven Grossmann <sven.grossmann@grafana.com>
This commit is contained in:
Galen Kistler
2023-12-20 15:33:58 +02:00
committed by GitHub
co-authored by Sven Grossmann
parent 16dffaf501
commit 0db19a7924
2 changed files with 23 additions and 4 deletions
@@ -144,6 +144,10 @@ describe('getLineFilterRenderer', () => {
id: '__line_contains_case_insensitive',
params: ['ERrOR'],
};
const MOCK_MODEL_BACKTICKS = {
id: '__line_contains',
params: ['`error`'],
};
const MOCK_DEF = undefined as unknown as QueryBuilderOperationDef;
@@ -159,6 +163,11 @@ describe('getLineFilterRenderer', () => {
expect(lineFilterRenderer(MOCK_MODEL, MOCK_DEF, MOCK_INNER_EXPR)).toBe('{job="grafana"} !~ `error`');
});
it('lineFilterRenderer returns the correct query for line contains, containing backticks', () => {
const lineFilterRenderer = getLineFilterRenderer('!~');
expect(lineFilterRenderer(MOCK_MODEL_BACKTICKS, MOCK_DEF, MOCK_INNER_EXPR)).toBe('{job="grafana"} !~ "`error`"');
});
it('lineFilterRenderer returns the correct query for line contains case insensitive', () => {
const lineFilterRenderer = getLineFilterRenderer('!~', true);
expect(lineFilterRenderer(MOCK_MODEL_INSENSITIVE, MOCK_DEF, MOCK_INNER_EXPR)).toBe(
@@ -10,6 +10,7 @@ import {
QueryWithOperations,
VisualQueryModeller,
} from '../../prometheus/querybuilder/shared/types';
import { escapeLabelValueInExactSelector } from '../languageUtils';
import { FUNCTIONS } from '../syntax';
import { LokiOperationId, LokiOperationOrder, LokiVisualQuery, LokiVisualQueryOperationCategory } from './types';
@@ -294,13 +295,22 @@ export function addNestedQueryHandler(def: QueryBuilderOperationDef, query: Loki
export function getLineFilterRenderer(operation: string, caseInsensitive?: boolean) {
return function lineFilterRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {
if (caseInsensitive) {
return `${innerExpr} ${operation} \`(?i)${model.params.join('` or `(?i)')}\``;
const hasBackticks = model.params.some((param) => typeof param === 'string' && param.includes('`'));
const delimiter = hasBackticks ? '"' : '`';
let params;
if (hasBackticks) {
params = model.params.map((param) =>
typeof param === 'string' ? escapeLabelValueInExactSelector(param) : param
);
} else {
params = model.params;
}
return `${innerExpr} ${operation} \`${model.params.join('` or `')}\``;
if (caseInsensitive) {
return `${innerExpr} ${operation} ${delimiter}(?i)${params.join(`${delimiter} or ${delimiter}(?i)`)}${delimiter}`;
}
return `${innerExpr} ${operation} ${delimiter}${params.join(`${delimiter} or ${delimiter}`)}${delimiter}`;
};
}
function getRangeVectorParamDef(): QueryBuilderOperationParamDef {
return {
name: 'Range',