mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Arrow: toArray() on nullable values should include null values (#29520)
This commit is contained in:
parent
df0ef18731
commit
24086c63a3
@ -55,6 +55,9 @@ export function arrowTableToDataFrame(table: Table): ArrowDataFrame {
|
|||||||
case ArrowType.Decimal:
|
case ArrowType.Decimal:
|
||||||
case ArrowType.FloatingPoint: {
|
case ArrowType.FloatingPoint: {
|
||||||
type = FieldType.number;
|
type = FieldType.number;
|
||||||
|
if (col.nullCount) {
|
||||||
|
values = new WrappedColumn(col);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ArrowType.Int: {
|
case ArrowType.Int: {
|
||||||
@ -64,6 +67,9 @@ export function arrowTableToDataFrame(table: Table): ArrowDataFrame {
|
|||||||
}
|
}
|
||||||
case ArrowType.Bool: {
|
case ArrowType.Bool: {
|
||||||
type = FieldType.boolean;
|
type = FieldType.boolean;
|
||||||
|
if (col.nullCount) {
|
||||||
|
values = new WrappedColumn(col);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ArrowType.Timestamp: {
|
case ArrowType.Timestamp: {
|
||||||
@ -202,3 +208,20 @@ class NumberColumn extends FunctionalVector<number> {
|
|||||||
return Number(v);
|
return Number(v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The `toArray()` arrow function will return a native ArrayBuffer -- this works fine
|
||||||
|
// if there are no null values, but the native arrays do not support nulls. This
|
||||||
|
// class simply wraps the vector so `toArray` creates a new array
|
||||||
|
class WrappedColumn extends FunctionalVector {
|
||||||
|
constructor(private col: Column) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return this.col.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
get(index: number): number {
|
||||||
|
return this.col.get(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -265,7 +265,7 @@ Object {
|
|||||||
"labels": undefined,
|
"labels": undefined,
|
||||||
"name": "float32_values",
|
"name": "float32_values",
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"values": Array [
|
"values": Float32Array [
|
||||||
1.401298464324817e-45,
|
1.401298464324817e-45,
|
||||||
1.401298464324817e-45,
|
1.401298464324817e-45,
|
||||||
1,
|
1,
|
||||||
|
@ -24,6 +24,7 @@ import { SortedVector } from '../vector/SortedVector';
|
|||||||
import { ArrayDataFrame } from './ArrayDataFrame';
|
import { ArrayDataFrame } from './ArrayDataFrame';
|
||||||
import { getFieldDisplayName } from '../field/fieldState';
|
import { getFieldDisplayName } from '../field/fieldState';
|
||||||
import { fieldIndexComparer } from '../field/fieldComparers';
|
import { fieldIndexComparer } from '../field/fieldComparers';
|
||||||
|
import { vectorToArray } from '../vector/vectorToArray';
|
||||||
|
|
||||||
function convertTableToDataFrame(table: TableData): DataFrame {
|
function convertTableToDataFrame(table: TableData): DataFrame {
|
||||||
const fields = table.columns.map(c => {
|
const fields = table.columns.map(c => {
|
||||||
@ -444,16 +445,10 @@ export function getDataFrameRow(data: DataFrame, row: number): any[] {
|
|||||||
export function toDataFrameDTO(data: DataFrame): DataFrameDTO {
|
export function toDataFrameDTO(data: DataFrame): DataFrameDTO {
|
||||||
const fields: FieldDTO[] = data.fields.map(f => {
|
const fields: FieldDTO[] = data.fields.map(f => {
|
||||||
let values = f.values.toArray();
|
let values = f.values.toArray();
|
||||||
if (!Array.isArray(values)) {
|
// The byte buffers serialize like objects
|
||||||
// Apache arrow will pack objects into typed arrays
|
if (values instanceof Float64Array) {
|
||||||
// Float64Array, etc
|
values = vectorToArray(f.values);
|
||||||
// TODO: Float64Array could be used directly
|
|
||||||
values = [];
|
|
||||||
for (let i = 0; i < f.values.length; i++) {
|
|
||||||
values.push(f.values.get(i));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
name: f.name,
|
name: f.name,
|
||||||
type: f.type,
|
type: f.type,
|
||||||
|
@ -37,7 +37,7 @@ const emptyResults = {
|
|||||||
|
|
||||||
/* eslint-enable */
|
/* eslint-enable */
|
||||||
|
|
||||||
describe('GEL Utils', () => {
|
describe('Query Response parser', () => {
|
||||||
test('should parse output with dataframe', () => {
|
test('should parse output with dataframe', () => {
|
||||||
const res = toDataQueryResponse(resp);
|
const res = toDataQueryResponse(resp);
|
||||||
const frames = res.data;
|
const frames = res.data;
|
||||||
|
Loading…
Reference in New Issue
Block a user