Commit 24086c63 by Ryan McKinley Committed by GitHub

Arrow: toArray() on nullable values should include null values (#29520)

parent df0ef187
...@@ -55,6 +55,9 @@ export function arrowTableToDataFrame(table: Table): ArrowDataFrame { ...@@ -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 { ...@@ -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> { ...@@ -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 { ...@@ -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'; ...@@ -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[] { ...@@ -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 = { ...@@ -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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment