mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Fix groupBy error caused by undefined aggregate field (#75089)
* fix aggregation field to return empty array instead of undefined in groupBy * add groupBy test scenario * remove log
This commit is contained in:
parent
4f06d362df
commit
d852aed4f3
@ -1,9 +1,10 @@
|
|||||||
import { dateTime } from '../datetime/moment_wrapper';
|
import { dateTime } from '../datetime/moment_wrapper';
|
||||||
import { DataFrameDTO, FieldType, TableData, TimeSeries } from '../types/index';
|
import { DataFrameDTO, Field, FieldType, TableData, TimeSeries } from '../types/index';
|
||||||
|
|
||||||
import { ArrayDataFrame } from './ArrayDataFrame';
|
import { ArrayDataFrame } from './ArrayDataFrame';
|
||||||
import {
|
import {
|
||||||
createDataFrame,
|
createDataFrame,
|
||||||
|
guessFieldTypeForField,
|
||||||
guessFieldTypeFromValue,
|
guessFieldTypeFromValue,
|
||||||
guessFieldTypes,
|
guessFieldTypes,
|
||||||
isDataFrame,
|
isDataFrame,
|
||||||
@ -403,3 +404,50 @@ describe('reverse DataFrame', () => {
|
|||||||
expect(rev.fields[1].nanos).toBeUndefined();
|
expect(rev.fields[1].nanos).toBeUndefined();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('guessFieldTypeForField', () => {
|
||||||
|
it('should guess types if value exists', () => {
|
||||||
|
const field: Field = {
|
||||||
|
name: 'Field',
|
||||||
|
config: {},
|
||||||
|
type: FieldType.other,
|
||||||
|
values: [1, 2, 3],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(guessFieldTypeForField(field)).toBe(FieldType.number);
|
||||||
|
|
||||||
|
field.values = [null, null, 3];
|
||||||
|
|
||||||
|
expect(guessFieldTypeForField(field)).toBe(FieldType.number);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should guess type if name suggests time values', () => {
|
||||||
|
const field: Field = {
|
||||||
|
name: 'Date',
|
||||||
|
config: {},
|
||||||
|
type: FieldType.other,
|
||||||
|
values: [1, 2, 3],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(guessFieldTypeForField(field)).toBe(FieldType.time);
|
||||||
|
|
||||||
|
field.name = 'time';
|
||||||
|
|
||||||
|
expect(guessFieldTypeForField(field)).toBe(FieldType.time);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return undefined if no values present', () => {
|
||||||
|
const field: Field = {
|
||||||
|
name: 'Val',
|
||||||
|
config: {},
|
||||||
|
type: FieldType.other,
|
||||||
|
values: [null, null],
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(guessFieldTypeForField(field)).toBe(undefined);
|
||||||
|
|
||||||
|
field.values = [];
|
||||||
|
|
||||||
|
expect(guessFieldTypeForField(field)).toBe(undefined);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -305,4 +305,66 @@ describe('GroupBy transformer', () => {
|
|||||||
expect(result[0].fields).toEqual(expected);
|
expect(result[0].fields).toEqual(expected);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should group by and skip fields that do not have values for a group', async () => {
|
||||||
|
const testSeries1 = toDataFrame({
|
||||||
|
name: 'Series1',
|
||||||
|
fields: [
|
||||||
|
{ name: 'Time', type: FieldType.time, values: [1688470200000, 1688471100000, 1688470200000, 1688471100000] },
|
||||||
|
{ name: 'Value', type: FieldType.number, values: [1, 2, 3, 4] },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const testSeries2 = toDataFrame({
|
||||||
|
name: 'Series2',
|
||||||
|
fields: [
|
||||||
|
{ name: 'Time', type: FieldType.time, values: [] },
|
||||||
|
{ name: 'Value', type: FieldType.number, values: [] },
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
const cfg: DataTransformerConfig<GroupByTransformerOptions> = {
|
||||||
|
id: DataTransformerID.groupBy,
|
||||||
|
options: {
|
||||||
|
fields: {
|
||||||
|
Series1: {
|
||||||
|
operation: GroupByOperationID.aggregate,
|
||||||
|
aggregations: [ReducerID.sum],
|
||||||
|
},
|
||||||
|
Series2: {
|
||||||
|
operation: GroupByOperationID.aggregate,
|
||||||
|
aggregations: [ReducerID.sum],
|
||||||
|
},
|
||||||
|
Time: {
|
||||||
|
operation: GroupByOperationID.groupBy,
|
||||||
|
aggregations: [],
|
||||||
|
},
|
||||||
|
Value: {
|
||||||
|
operation: GroupByOperationID.aggregate,
|
||||||
|
aggregations: [ReducerID.sum],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
await expect(transformDataFrame([cfg], [testSeries1, testSeries2])).toEmitValuesWith((received) => {
|
||||||
|
const result = received[0];
|
||||||
|
const expected: Field[] = [
|
||||||
|
{
|
||||||
|
name: 'Time',
|
||||||
|
type: FieldType.time,
|
||||||
|
values: [1688470200000, 1688471100000],
|
||||||
|
config: {},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Value (sum)',
|
||||||
|
type: FieldType.number,
|
||||||
|
values: [4, 6],
|
||||||
|
config: {},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(result[0].fields).toEqual(expected);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -135,7 +135,7 @@ export const groupByTransformer: DataTransformerInfo<GroupByTransformerOptions>
|
|||||||
for (const aggregation of aggregations) {
|
for (const aggregation of aggregations) {
|
||||||
const aggregationField: Field = {
|
const aggregationField: Field = {
|
||||||
name: `${fieldName} (${aggregation})`,
|
name: `${fieldName} (${aggregation})`,
|
||||||
values: valuesByAggregation[aggregation],
|
values: valuesByAggregation[aggregation] ?? [],
|
||||||
type: FieldType.other,
|
type: FieldType.other,
|
||||||
config: {},
|
config: {},
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user