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);
|
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 fullpath = path.resolve(__dirname, './__snapshots__/all_types.golden.arrow');
|
||||||
const arrow = fs.readFileSync(fullpath);
|
const arrow = fs.readFileSync(fullpath);
|
||||||
const table = Table.from([arrow]);
|
const table = Table.from([arrow]);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ export function arrowTableToDataFrame(table: Table): ArrowDataFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fields.push({
|
fields.push({
|
||||||
name: col.name,
|
name: stripFieldNamePrefix(col.name),
|
||||||
type,
|
type,
|
||||||
values,
|
values,
|
||||||
config: parseOptionalMeta(col.metadata.get('config')) || {},
|
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 {
|
function toArrowVector(field: Field): ArrowVector {
|
||||||
// OR: Float64Vector.from([1, 2, 3]));
|
// OR: Float64Vector.from([1, 2, 3]));
|
||||||
|
|
||||||
@@ -117,10 +128,17 @@ export function grafanaDataFrameToArrowTable(data: DataFrame): Table {
|
|||||||
if (table instanceof Table) {
|
if (table instanceof Table) {
|
||||||
return table as Table;
|
return table as Table;
|
||||||
}
|
}
|
||||||
|
// Make sure the names are unique
|
||||||
|
const names = new Set<string>();
|
||||||
|
|
||||||
table = Table.new(
|
table = Table.new(
|
||||||
data.fields.map(field => {
|
data.fields.map((field, index) => {
|
||||||
const column = Column.new(field.name, toArrowVector(field));
|
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) {
|
if (field.labels) {
|
||||||
column.metadata.set('labels', JSON.stringify(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 {
|
Object {
|
||||||
"fields": Array [
|
"fields": Array [
|
||||||
Object {
|
Object {
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user