mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
support duplicate field names in arrow format (#22705)
This commit is contained in:
@@ -71,7 +71,27 @@ describe('Read/Write arrow Table to DataFrame', () => {
|
||||
expect(after).toEqual(before);
|
||||
});
|
||||
|
||||
test('should parse output with dataframe', () => {
|
||||
test('should support duplicate field names', () => {
|
||||
const frame = toDataFrame({
|
||||
name: 'Hello',
|
||||
refId: 'XYZ',
|
||||
fields: [
|
||||
{ name: 'time', config: {}, type: FieldType.time, values: [1, 2, 3] },
|
||||
{ name: 'a', values: [1, 2, 3] },
|
||||
{ name: 'a', values: ['a', 'b', 'c'] },
|
||||
],
|
||||
});
|
||||
|
||||
const table = grafanaDataFrameToArrowTable(frame);
|
||||
expect(table.length).toEqual(frame.length);
|
||||
|
||||
// Now back to DataFrame
|
||||
const before = JSON.stringify(toDataFrameDTO(frame), null, 2);
|
||||
const after = JSON.stringify(toDataFrameDTO(arrowTableToDataFrame(table)), null, 2);
|
||||
expect(after).toEqual(before);
|
||||
});
|
||||
|
||||
test('should read all types', () => {
|
||||
const fullpath = path.resolve(__dirname, './__snapshots__/all_types.golden.arrow');
|
||||
const arrow = fs.readFileSync(fullpath);
|
||||
const table = Table.from([arrow]);
|
||||
|
||||
@@ -72,7 +72,7 @@ export function arrowTableToDataFrame(table: Table): ArrowDataFrame {
|
||||
}
|
||||
|
||||
fields.push({
|
||||
name: col.name,
|
||||
name: stripFieldNamePrefix(col.name),
|
||||
type,
|
||||
values,
|
||||
config: parseOptionalMeta(col.metadata.get('config')) || {},
|
||||
@@ -91,6 +91,17 @@ export function arrowTableToDataFrame(table: Table): ArrowDataFrame {
|
||||
};
|
||||
}
|
||||
|
||||
// fieldNamePrefixSep is the delimiter used with fieldNamePrefix.
|
||||
const fieldNamePrefixSep = '🦥: ';
|
||||
|
||||
function stripFieldNamePrefix(name: string): string {
|
||||
const idx = name.indexOf(fieldNamePrefixSep);
|
||||
if (idx > 0) {
|
||||
return name.substring(idx + fieldNamePrefixSep.length);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
function toArrowVector(field: Field): ArrowVector {
|
||||
// OR: Float64Vector.from([1, 2, 3]));
|
||||
|
||||
@@ -117,10 +128,17 @@ export function grafanaDataFrameToArrowTable(data: DataFrame): Table {
|
||||
if (table instanceof Table) {
|
||||
return table as Table;
|
||||
}
|
||||
// Make sure the names are unique
|
||||
const names = new Set<string>();
|
||||
|
||||
table = Table.new(
|
||||
data.fields.map(field => {
|
||||
const column = Column.new(field.name, toArrowVector(field));
|
||||
data.fields.map((field, index) => {
|
||||
let name = field.name;
|
||||
if (names.has(field.name)) {
|
||||
name = `${index}${fieldNamePrefixSep}${field.name}`;
|
||||
}
|
||||
names.add(name);
|
||||
const column = Column.new(name, toArrowVector(field));
|
||||
if (field.labels) {
|
||||
column.metadata.set('labels', JSON.stringify(field.labels));
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ Array [
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`Read/Write arrow Table to DataFrame should parse output with dataframe 1`] = `
|
||||
exports[`Read/Write arrow Table to DataFrame should read all types 1`] = `
|
||||
Object {
|
||||
"fields": Array [
|
||||
Object {
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user