diff --git a/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx b/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx index 109b28817b2..9b025f29b53 100644 --- a/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx +++ b/public/app/plugins/datasource/loki/components/LokiOptionFields.tsx @@ -8,6 +8,7 @@ import { SelectableValue } from '@grafana/data'; import { config } from '@grafana/runtime'; import { InlineFormLabel, RadioButtonGroup, InlineField, Input, Select } from '@grafana/ui'; +import { getLokiQueryType } from '../queryUtils'; import { LokiQuery, LokiQueryType } from '../types'; export interface LokiOptionFieldsProps { @@ -51,7 +52,7 @@ export const RESOLUTION_OPTIONS: Array> = [DEFAULT_RESOL export function LokiOptionFields(props: LokiOptionFieldsProps) { const { lineLimitValue, resolution, onRunQuery, runOnBlur, onChange } = props; const query = props.query ?? {}; - let queryType = query.queryType ?? (query.instant ? LokiQueryType.Instant : LokiQueryType.Range); + const queryType = getLokiQueryType(query); function onChangeQueryLimit(value: string) { const nextQuery = { ...query, maxLines: preprocessMaxLines(value) }; diff --git a/public/app/plugins/datasource/loki/queryUtils.test.ts b/public/app/plugins/datasource/loki/queryUtils.test.ts index 5a500457397..e8e791e6b62 100644 --- a/public/app/plugins/datasource/loki/queryUtils.test.ts +++ b/public/app/plugins/datasource/loki/queryUtils.test.ts @@ -1,6 +1,6 @@ import { getHighlighterExpressionsFromQuery, - getNormalizedLokiQuery, + getLokiQueryType, isLogsQuery, isQueryWithLabelFormat, isQueryWithParser, @@ -11,6 +11,7 @@ import { requestSupportsSplitting, isQueryWithDistinct, isQueryWithRangeVariable, + getNormalizedLokiQuery, } from './queryUtils'; import { LokiQuery, LokiQueryType } from './types'; @@ -116,50 +117,69 @@ describe('getHighlighterExpressionsFromQuery', () => { }); describe('getNormalizedLokiQuery', () => { - function expectNormalized(inputProps: Object, outputQueryType: LokiQueryType) { - const input: LokiQuery = { refId: 'A', expr: 'test1', ...inputProps }; + it('removes deprecated instant property', () => { + const input: LokiQuery = { refId: 'A', expr: 'test1', instant: true }; + const output = getNormalizedLokiQuery(input); + expect(output).toStrictEqual({ refId: 'A', expr: 'test1', queryType: LokiQueryType.Instant }); + }); + + it('removes deprecated range property', () => { + const input: LokiQuery = { refId: 'A', expr: 'test1', range: true }; const output = getNormalizedLokiQuery(input); - expect(output).toStrictEqual({ refId: 'A', expr: 'test1', queryType: outputQueryType }); + expect(output).toStrictEqual({ refId: 'A', expr: 'test1', queryType: LokiQueryType.Range }); + }); + + it('removes deprecated range and instant properties if query with queryType', () => { + const input: LokiQuery = { refId: 'A', expr: 'test1', range: true, instant: false, queryType: LokiQueryType.Range }; + const output = getNormalizedLokiQuery(input); + expect(output).toStrictEqual({ refId: 'A', expr: 'test1', queryType: LokiQueryType.Range }); + }); +}); +describe('getLokiQueryType', () => { + function expectCorrectQueryType(inputProps: Object, outputQueryType: LokiQueryType) { + const input: LokiQuery = { refId: 'A', expr: 'test1', ...inputProps }; + const output = getLokiQueryType(input); + expect(output).toStrictEqual(outputQueryType); } it('handles no props case', () => { - expectNormalized({}, LokiQueryType.Range); + expectCorrectQueryType({}, LokiQueryType.Range); }); it('handles old-style instant case', () => { - expectNormalized({ instant: true, range: false }, LokiQueryType.Instant); + expectCorrectQueryType({ instant: true, range: false }, LokiQueryType.Instant); }); it('handles old-style range case', () => { - expectNormalized({ instant: false, range: true }, LokiQueryType.Range); + expectCorrectQueryType({ instant: false, range: true }, LokiQueryType.Range); }); it('handles new+old style instant', () => { - expectNormalized({ instant: true, range: false, queryType: LokiQueryType.Range }, LokiQueryType.Range); + expectCorrectQueryType({ instant: true, range: false, queryType: LokiQueryType.Range }, LokiQueryType.Range); }); it('handles new+old style range', () => { - expectNormalized({ instant: false, range: true, queryType: LokiQueryType.Instant }, LokiQueryType.Instant); + expectCorrectQueryType({ instant: false, range: true, queryType: LokiQueryType.Instant }, LokiQueryType.Instant); }); it('handles new<>old conflict (new wins), range', () => { - expectNormalized({ instant: false, range: true, queryType: LokiQueryType.Range }, LokiQueryType.Range); + expectCorrectQueryType({ instant: false, range: true, queryType: LokiQueryType.Range }, LokiQueryType.Range); }); it('handles new<>old conflict (new wins), instant', () => { - expectNormalized({ instant: true, range: false, queryType: LokiQueryType.Instant }, LokiQueryType.Instant); + expectCorrectQueryType({ instant: true, range: false, queryType: LokiQueryType.Instant }, LokiQueryType.Instant); }); it('handles invalid new, range', () => { - expectNormalized({ queryType: 'invalid' }, LokiQueryType.Range); + expectCorrectQueryType({ queryType: 'invalid' }, LokiQueryType.Range); }); it('handles invalid new, when old-range exists, use old', () => { - expectNormalized({ instant: false, range: true, queryType: 'invalid' }, LokiQueryType.Range); + expectCorrectQueryType({ instant: false, range: true, queryType: 'invalid' }, LokiQueryType.Range); }); it('handles invalid new, when old-instant exists, use old', () => { - expectNormalized({ instant: true, range: false, queryType: 'invalid' }, LokiQueryType.Instant); + expectCorrectQueryType({ instant: true, range: false, queryType: 'invalid' }, LokiQueryType.Instant); }); }); diff --git a/public/app/plugins/datasource/loki/queryUtils.ts b/public/app/plugins/datasource/loki/queryUtils.ts index a94a91df256..8035fc746fd 100644 --- a/public/app/plugins/datasource/loki/queryUtils.ts +++ b/public/app/plugins/datasource/loki/queryUtils.ts @@ -84,32 +84,32 @@ export function getHighlighterExpressionsFromQuery(input: string): string[] { return results; } -// we are migrating from `.instant` and `.range` to `.queryType` -// this function returns a new query object that: -// - has `.queryType` -// - does not have `.instant` -// - does not have `.range` export function getNormalizedLokiQuery(query: LokiQuery): LokiQuery { - // if queryType field contains invalid data we behave as if the queryType is empty + const queryType = getLokiQueryType(query); + // instant and range are deprecated, we want to remove them + const { instant, range, ...rest } = query; + return { ...rest, queryType }; +} + +export function getLokiQueryType(query: LokiQuery): LokiQueryType { + // we are migrating from `.instant` and `.range` to `.queryType` + // this function returns the correct query type const { queryType } = query; const hasValidQueryType = queryType === LokiQueryType.Range || queryType === LokiQueryType.Instant || queryType === LokiQueryType.Stream; // if queryType exists, it is respected if (hasValidQueryType) { - const { instant, range, ...rest } = query; - return rest; + return queryType; } // if no queryType, and instant===true, it's instant if (query.instant === true) { - const { instant, range, ...rest } = query; - return { ...rest, queryType: LokiQueryType.Instant }; + return LokiQueryType.Instant; } // otherwise it is range - const { instant, range, ...rest } = query; - return { ...rest, queryType: LokiQueryType.Range }; + return LokiQueryType.Range; } const tagsToObscure = ['String', 'Identifier', 'LineComment', 'Number']; diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx index 3f05e160bea..d522c9a8c2a 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilderOptions.tsx @@ -8,7 +8,7 @@ import { AutoSizeInput, RadioButtonGroup, Select } from '@grafana/ui'; import { QueryOptionGroup } from 'app/plugins/datasource/prometheus/querybuilder/shared/QueryOptionGroup'; import { preprocessMaxLines, queryTypeOptions, RESOLUTION_OPTIONS } from '../../components/LokiOptionFields'; -import { isLogsQuery } from '../../queryUtils'; +import { getLokiQueryType, isLogsQuery } from '../../queryUtils'; import { LokiQuery, LokiQueryType, QueryStats } from '../../types'; export interface Props { @@ -67,7 +67,7 @@ export const LokiQueryBuilderOptions = React.memo( onRunQuery(); } - const queryType = query.queryType ?? (query.instant ? LokiQueryType.Instant : LokiQueryType.Range); + const queryType = getLokiQueryType(query); const isLogQuery = isLogsQuery(query.expr); const isValidStep = useMemo(() => {