[v9.4.x] Prometheus: Table format throwing error on empty result (#63062)

Prometheus: Table format throwing error on empty result (#63053)

* fix bug in prometheus table view which is throwing error when a query returns no results

(cherry picked from commit 79b750a4b2)

Co-authored-by: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com>
This commit is contained in:
Grot (@grafanabot)
2023-02-07 16:10:00 -05:00
committed by GitHub
co-authored by Galen Kistler
parent 3c7cfecf50
commit 87497a1afc
2 changed files with 46 additions and 3 deletions
@@ -721,6 +721,47 @@ describe('Prometheus Result Transformer', () => {
expect(tableDf.fields[2].values.get(0)).toBe('value2');
expect(tableDf.fields[3].name).toBe('Value');
});
// Queries do not always return results
it('transforms dataFrame and empty dataFrame mock responses to table dataFrames', () => {
const value1 = 'value1';
const value2 = 'value2';
const dataframes = [
new MutableDataFrame({
refId: 'A',
fields: [
{ name: 'time', type: FieldType.time, values: [6, 5, 4] },
{
name: 'value',
type: FieldType.number,
values: [6, 5, 4],
labels: { label1: value1, label2: value2 },
},
],
}),
new MutableDataFrame({
refId: 'B',
fields: [],
}),
];
const transformedTableDataFrames = transformDFToTable(dataframes);
// Expect the first query to still return valid results
expect(transformedTableDataFrames[0].fields.length).toBe(4);
expect(transformedTableDataFrames[0].fields[0].name).toBe('Time');
expect(transformedTableDataFrames[0].fields[1].name).toBe('label1');
expect(transformedTableDataFrames[0].fields[1].values.get(0)).toBe(value1);
expect(transformedTableDataFrames[0].fields[2].name).toBe('label2');
expect(transformedTableDataFrames[0].fields[2].values.get(0)).toBe(value2);
expect(transformedTableDataFrames[0].fields[3].name).toBe('Value #A');
// Expect the invalid/empty results not to throw an error and to return empty arrays
expect(transformedTableDataFrames[1].fields[1].labels).toBe(undefined);
expect(transformedTableDataFrames[1].fields[1].name).toBe('Value #B');
expect(transformedTableDataFrames[1].fields[1].values.toArray()).toEqual([]);
expect(transformedTableDataFrames[1].fields[0].values.toArray()).toEqual([]);
});
});
describe('transform', () => {
@@ -196,7 +196,7 @@ export function transformDFToTable(dfs: DataFrame[]): DataFrame[] {
// Fill labelsFields with labels from dataFrames
dataFramesByRefId[refId].forEach((df) => {
const frameValueField = df.fields[1];
const promLabels = frameValueField.labels ?? {};
const promLabels = frameValueField?.labels ?? {};
Object.keys(promLabels)
.sort()
@@ -216,8 +216,10 @@ export function transformDFToTable(dfs: DataFrame[]): DataFrame[] {
// Fill valueField, timeField and labelFields with values
dataFramesByRefId[refId].forEach((df) => {
df.fields[0].values.toArray().forEach((value) => timeField.values.add(value));
df.fields[1].values.toArray().forEach((value) => {
const timeFields = df.fields[0]?.values ?? new ArrayVector();
const dataFields = df.fields[1]?.values ?? new ArrayVector();
timeFields.toArray().forEach((value) => timeField.values.add(value));
dataFields.toArray().forEach((value) => {
valueField.values.add(parseSampleValue(value));
const labelsForField = df.fields[1].labels ?? {};
labelFields.forEach((field) => field.values.add(getLabelValue(labelsForField, field.name)));