diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx index 3cec60ded95..96d7fe3cb80 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.test.tsx @@ -65,7 +65,72 @@ describe('LokiQueryBuilder', () => { await waitFor(() => expect(screen.getByText('job')).toBeInTheDocument()); }); - it('does refetch label values with the correct timerange', async () => { + it('uses fetchLabelValues preselected labels have no equality matcher', async () => { + const props = createDefaultProps(); + props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); + props.datasource.languageProvider.fetchSeriesLabels = jest.fn(); + props.datasource.languageProvider.fetchLabelValues = jest.fn().mockReturnValue(['a', 'b']); + + const query: LokiVisualQuery = { + labels: [ + { op: '!=', label: 'cluster', value: 'cluster1' }, + { op: '=', label: 'job', value: 'grafana' }, + ], + operations: [], + }; + render(); + const labels = screen.getByText(/Label filters/); + const selects = getAllByRole(getSelectParent(labels)!, 'combobox'); + await userEvent.click(selects[5]); + expect(props.datasource.languageProvider.fetchLabelValues).toBeCalledWith('job', { timeRange: mockTimeRange }); + expect(props.datasource.languageProvider.fetchSeriesLabels).not.toBeCalled(); + }); + + it('uses fetchLabelValues preselected label have regex equality matcher with match everything value (.*)', async () => { + const props = createDefaultProps(); + props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); + props.datasource.languageProvider.fetchSeriesLabels = jest.fn(); + props.datasource.languageProvider.fetchLabelValues = jest.fn().mockReturnValue(['a', 'b']); + + const query: LokiVisualQuery = { + labels: [ + { op: '=~', label: 'cluster', value: '.*' }, + { op: '=', label: 'job', value: 'grafana' }, + ], + operations: [], + }; + render(); + const labels = screen.getByText(/Label filters/); + const selects = getAllByRole(getSelectParent(labels)!, 'combobox'); + await userEvent.click(selects[5]); + expect(props.datasource.languageProvider.fetchLabelValues).toBeCalledWith('job', { timeRange: mockTimeRange }); + expect(props.datasource.languageProvider.fetchSeriesLabels).not.toBeCalled(); + }); + + it('uses fetchSeriesLabels preselected label have regex equality matcher', async () => { + const props = createDefaultProps(); + props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); + props.datasource.languageProvider.fetchSeriesLabels = jest.fn().mockReturnValue({ job: ['a'], instance: ['b'] }); + props.datasource.languageProvider.fetchLabelValues = jest.fn(); + + const query: LokiVisualQuery = { + labels: [ + { op: '=~', label: 'cluster', value: 'cluster1|cluster2' }, + { op: '=', label: 'job', value: 'grafana' }, + ], + operations: [], + }; + render(); + const labels = screen.getByText(/Label filters/); + const selects = getAllByRole(getSelectParent(labels)!, 'combobox'); + await userEvent.click(selects[5]); + expect(props.datasource.languageProvider.fetchSeriesLabels).toBeCalledWith('{cluster=~"cluster1|cluster2"}', { + timeRange: mockTimeRange, + }); + expect(props.datasource.languageProvider.fetchLabelValues).not.toBeCalled(); + }); + + it('does refetch label values with the correct time range', async () => { const props = createDefaultProps(); props.datasource.getDataSamples = jest.fn().mockResolvedValue([]); props.datasource.languageProvider.fetchSeriesLabels = jest diff --git a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx index 652227a29ba..dd6ddbf015e 100644 --- a/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx +++ b/public/app/plugins/datasource/loki/querybuilder/components/LokiQueryBuilder.tsx @@ -81,7 +81,11 @@ export const LokiQueryBuilder = React.memo( let values; const labelsToConsider = query.labels.filter((x) => x !== forLabel); - if (labelsToConsider.length === 0) { + // If we have no equality/regex operation with .*, we can't fetch series as it will throw an error, so we fetch label values + const hasEqualityOperation = labelsToConsider.find( + (filter) => filter.op === '=' || (filter.op === '=~' && new RegExp(filter.value).test('') === false) + ); + if (labelsToConsider.length === 0 || !hasEqualityOperation) { values = await datasource.languageProvider.fetchLabelValues(forLabel.label, { timeRange }); } else { const expr = lokiQueryModeller.renderLabels(labelsToConsider);