diff --git a/public/app/plugins/datasource/influxdb/response_parser.ts b/public/app/plugins/datasource/influxdb/response_parser.ts index 56003d75a22..4ec47343825 100644 --- a/public/app/plugins/datasource/influxdb/response_parser.ts +++ b/public/app/plugins/datasource/influxdb/response_parser.ts @@ -1,4 +1,4 @@ -import { each, isArray, map } from 'lodash'; +import { each, isArray } from 'lodash'; export default class ResponseParser { parse(query: string, results: { results: any }) { @@ -15,7 +15,7 @@ export default class ResponseParser { const isValueFirst = normalizedQuery.indexOf('show field keys') >= 0 || normalizedQuery.indexOf('show retention policies') >= 0; - const res = {}; + const res = new Set(); each(influxResults.series, (serie) => { each(serie.values, (value) => { if (isArray(value)) { @@ -44,14 +44,14 @@ export default class ResponseParser { }); }); - // @ts-ignore problems with typings for this map only accepts [] but this needs to be object - return map(res, (value) => { - // @ts-ignore - return { text: value.toString() }; - }); + // NOTE: it is important to keep the order of items in the parsed output + // the same as it was in the influxdb-response. + // we use a `Set` to collect the unique-results, and `Set` iteration + // order is insertion-order, so this should be ok. + return Array.from(res).map((v) => ({ text: v })); } } -function addUnique(arr: { [x: string]: any }, value: string | number) { - arr[value] = value; +function addUnique(s: Set, value: string | number) { + s.add(value.toString()); } diff --git a/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts b/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts index aa209a21cf9..b8ddd34630e 100644 --- a/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts +++ b/public/app/plugins/datasource/influxdb/specs/response_parser.test.ts @@ -121,6 +121,39 @@ describe('influxdb response parser', () => { }); }); + describe('SELECT response where ordering matters', () => { + const query = 'SELECT "val" from "num"'; + const response = { + results: [ + { + series: [ + { + name: 'num', + columns: ['time', 'val'], + values: [ + [1620041231000, 2], + [1620041233000, 3], + [1620041235000, 4], + [1620041238000, 5], + [1620041239000, 1], + ], + }, + ], + }, + ], + }; + + it('should keep the order returned by influxdb, even for numbers', () => { + expect(parser.parse(query, response)).toStrictEqual([ + { text: '2' }, + { text: '3' }, + { text: '4' }, + { text: '5' }, + { text: '1' }, + ]); + }); + }); + describe('SHOW FIELD response', () => { const query = 'SHOW FIELD KEYS FROM "cpu"';