Postgres/MySQL/MSSQL: Fix so that numeric/non-string values are returned from query variables (#35411)

Fixes a problem with query variables where SQL query returning for example only 
numeric values didn't populate the query variables with values.

Fixes #35391
This commit is contained in:
Marcus Efraimsson
2021-06-09 14:18:54 +02:00
committed by GitHub
parent dc7a641978
commit bf7301e485
6 changed files with 148 additions and 185 deletions

View File

@@ -1,5 +1,4 @@
import { map } from 'lodash';
import { AnnotationEvent, DataFrame, FieldType, MetricFindValue } from '@grafana/data';
import { AnnotationEvent, DataFrame, MetricFindValue } from '@grafana/data';
import { BackendDataSourceResponse, FetchResponse, toDataQueryResponse } from '@grafana/runtime';
export default class ResponseParser {
@@ -21,16 +20,13 @@ export default class ResponseParser {
values.push({ text: '' + textField.values.get(i), value: '' + valueField.values.get(i) });
}
} else {
const textFields = frame.fields.filter((f) => f.type === FieldType.string);
if (textFields) {
values.push(
...textFields
.flatMap((f) => f.values.toArray())
.map((v) => ({
text: '' + v,
}))
);
}
values.push(
...frame.fields
.flatMap((f) => f.values.toArray())
.map((v) => ({
text: v,
}))
);
}
return Array.from(new Set(values.map((v) => v.text))).map((text) => ({
@@ -39,53 +35,6 @@ export default class ResponseParser {
}));
}
transformToKeyValueList(rows: any, textColIndex: number, valueColIndex: number): MetricFindValue[] {
const res = [];
for (let i = 0; i < rows.length; i++) {
if (!this.containsKey(res, rows[i][textColIndex])) {
res.push({ text: rows[i][textColIndex], value: rows[i][valueColIndex] });
}
}
return res;
}
transformToSimpleList(rows: any): MetricFindValue[] {
const res = [];
for (let i = 0; i < rows.length; i++) {
for (let j = 0; j < rows[i].length; j++) {
res.push(rows[i][j]);
}
}
const unique = Array.from(new Set(res));
return map(unique, (value) => {
return { text: value };
});
}
findColIndex(columns: any[], colName: string) {
for (let i = 0; i < columns.length; i++) {
if (columns[i].text === colName) {
return i;
}
}
return -1;
}
containsKey(res: any[], key: any) {
for (let i = 0; i < res.length; i++) {
if (res[i].text === key) {
return true;
}
}
return false;
}
async transformAnnotationResponse(options: any, data: BackendDataSourceResponse): Promise<AnnotationEvent[]> {
const frames = toDataQueryResponse({ data: data }).data as DataFrame[];
const frame = frames[0];

View File

@@ -121,7 +121,7 @@ describe('MySQLDatasource', () => {
});
});
describe('When performing metricFindQuery', () => {
describe('When performing metricFindQuery that returns multiple string fields', () => {
const query = 'select * from atable';
const response = {
results: {
@@ -144,7 +144,7 @@ describe('MySQLDatasource', () => {
},
};
it('should return list of all column values', async () => {
it('should return list of all string field values', async () => {
const { ds } = setupTextContext(response);
const results = await ds.metricFindQuery(query, {});
@@ -257,6 +257,44 @@ describe('MySQLDatasource', () => {
});
});
describe('When performing metricFindQuery without key, value columns', () => {
const query = 'select id, values from atable';
const response = {
results: {
tempvar: {
refId: 'tempvar',
frames: [
dataFrameToJSON(
new MutableDataFrame({
fields: [
{ name: 'id', values: [1, 2, 3] },
{ name: 'values', values: ['test1', 'test2', 'test3'] },
],
meta: {
executedQueryString: 'select id, values from atable',
},
})
),
],
},
},
};
it('should return list of all field values as text', async () => {
const { ds } = setupTextContext(response);
const results = await ds.metricFindQuery(query, {});
expect(results).toEqual([
{ text: 1 },
{ text: 2 },
{ text: 3 },
{ text: 'test1' },
{ text: 'test2' },
{ text: 'test3' },
]);
});
});
describe('When performing metricFindQuery with key, value columns and with duplicate keys', () => {
const query = 'select * from atable';
const response = {