preparing datatable for unifying with kibana_datatable (#73654)

This commit is contained in:
Peter Pisljar 2020-08-17 15:47:37 +02:00 committed by GitHub
parent ea545312e9
commit a987cef583
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 144 additions and 81 deletions

View file

@ -41,7 +41,8 @@ export const boolean: ExpressionTypeDefinition<'boolean', boolean> = {
},
datatable: (value): Datatable => ({
type: 'datatable',
columns: [{ name: 'value', type: name }],
meta: {},
columns: [{ id: 'value', name: 'value', meta: { type: name } }],
rows: [{ value }],
}),
},

View file

@ -23,6 +23,13 @@ import { ExpressionTypeDefinition } from '../types';
import { PointSeries, PointSeriesColumn } from './pointseries';
import { ExpressionValueRender } from './render';
type State = string | number | boolean | null | undefined | SerializableState;
/** @internal **/
export interface SerializableState {
[key: string]: State | State[];
}
const name = 'datatable';
/**
@ -42,12 +49,23 @@ export type DatatableColumnType = 'string' | 'number' | 'boolean' | 'date' | 'nu
*/
export type DatatableRow = Record<string, any>;
export interface DatatableColumnMeta {
type: DatatableColumnType;
field?: string;
params?: SerializableState;
}
/**
* This type represents the shape of a column in a `Datatable`.
*/
export interface DatatableColumn {
id: string;
name: string;
type: DatatableColumnType;
meta: DatatableColumnMeta;
}
export interface DatatableMeta {
type?: string;
source?: string;
}
/**
@ -55,6 +73,7 @@ export interface DatatableColumn {
*/
export interface Datatable {
type: typeof name;
meta?: DatatableMeta;
columns: DatatableColumn[];
rows: DatatableRow[];
}
@ -103,14 +122,16 @@ export const datatable: ExpressionTypeDefinition<typeof name, Datatable, Seriali
from: {
null: () => ({
type: name,
meta: {},
rows: [],
columns: [],
}),
pointseries: (value: PointSeries) => ({
type: name,
meta: {},
rows: value.rows,
columns: map(value.columns, (val: PointSeriesColumn, colName) => {
return { name: colName, type: val.type };
return { id: colName, name: colName, meta: { type: val.type } };
}),
}),
},
@ -127,13 +148,13 @@ export const datatable: ExpressionTypeDefinition<typeof name, Datatable, Seriali
}),
pointseries: (table: Datatable): PointSeries => {
const validFields = ['x', 'y', 'color', 'size', 'text'];
const columns = table.columns.filter((column) => validFields.includes(column.name));
const columns = table.columns.filter((column) => validFields.includes(column.id));
const rows = table.rows.map((row) => pick(row, validFields));
return {
type: 'pointseries',
columns: columns.reduce<Record<string, PointSeries['columns']>>((acc, column) => {
acc[column.name] = {
type: column.type,
type: column.meta.type,
expression: column.name,
role: 'dimension',
};

View file

@ -73,7 +73,8 @@ export const num: ExpressionTypeDefinition<'num', ExpressionValueNum> = {
},
datatable: ({ value }): Datatable => ({
type: 'datatable',
columns: [{ name: 'value', type: 'number' }],
meta: {},
columns: [{ id: 'value', name: 'value', meta: { type: 'number' } }],
rows: [{ value }],
}),
},

View file

@ -55,7 +55,8 @@ export const number: ExpressionTypeDefinition<typeof name, number> = {
},
datatable: (value): Datatable => ({
type: 'datatable',
columns: [{ name: 'value', type: 'number' }],
meta: {},
columns: [{ id: 'value', name: 'value', meta: { type: 'number' } }],
rows: [{ value }],
}),
},

View file

@ -40,7 +40,8 @@ export const string: ExpressionTypeDefinition<typeof name, string> = {
},
datatable: (value): Datatable => ({
type: 'datatable',
columns: [{ name: 'value', type: 'string' }],
meta: {},
columns: [{ id: 'value', name: 'value', meta: { type: 'string' } }],
rows: [{ value }],
}),
},

View file

@ -10,7 +10,10 @@ import { getFunctionHelp } from '../../../i18n';
const noop = () => {};
interface Return extends Datatable {
columns: [{ name: 'latitude'; type: 'number' }, { name: 'longitude'; type: 'number' }];
columns: [
{ id: 'latitude'; name: 'latitude'; meta: { type: 'number' } },
{ id: 'longitude'; name: 'longitude'; meta: { type: 'number' } }
];
rows: [{ latitude: number; longitude: number }];
}
@ -30,8 +33,8 @@ export function location(): ExpressionFunctionDefinition<'location', null, {}, P
return resolve({
type: 'datatable',
columns: [
{ name: 'latitude', type: 'number' },
{ name: 'longitude', type: 'number' },
{ id: 'latitude', name: 'latitude', meta: { type: 'number' } },
{ id: 'longitude', name: 'longitude', meta: { type: 'number' } },
],
rows: [{ latitude, longitude }],
});

View file

@ -16,24 +16,29 @@ const testTable: Datatable = {
type: 'datatable',
columns: [
{
id: 'name',
name: 'name',
type: 'string',
meta: { type: 'string' },
},
{
id: 'time',
name: 'time',
type: 'date',
meta: { type: 'date' },
},
{
id: 'price',
name: 'price',
type: 'number',
meta: { type: 'number' },
},
{
id: 'quantity',
name: 'quantity',
type: 'number',
meta: { type: 'number' },
},
{
id: 'in_stock',
name: 'in_stock',
type: 'boolean',
meta: { type: 'boolean' },
},
],
rows: [
@ -107,24 +112,29 @@ const stringTable: Datatable = {
type: 'datatable',
columns: [
{
id: 'name',
name: 'name',
type: 'string',
meta: { type: 'string' },
},
{
id: 'time',
name: 'time',
type: 'string',
meta: { type: 'string' },
},
{
id: 'price',
name: 'price',
type: 'string',
meta: { type: 'string' },
},
{
id: 'quantity',
name: 'quantity',
type: 'string',
meta: { type: 'string' },
},
{
id: 'in_stock',
name: 'in_stock',
type: 'string',
meta: { type: 'string' },
},
],
rows: [

View file

@ -38,7 +38,7 @@ describe('alterColumn', () => {
const arbitraryRowIndex = 6;
expect(newColumn.name).not.toBe(originalColumn.name);
expect(newColumn.type).not.toBe(originalColumn.type);
expect(newColumn.meta.type).not.toBe(originalColumn.meta.type);
expect(typeof dateToString.rows[arbitraryRowIndex].timeISO).toBe('string');
expect(new Date(dateToString.rows[arbitraryRowIndex].timeISO)).toEqual(
new Date(testTable.rows[arbitraryRowIndex].time)
@ -60,7 +60,7 @@ describe('alterColumn', () => {
it('converts the column to the specified type', () => {
const dateToString = fn(testTable, { column: 'time', type: 'string', name: 'timeISO' });
expect(typeof dateToString.columns[timeColumnIndex].type).toBe('string');
expect(typeof dateToString.columns[timeColumnIndex].meta.type).toBe('string');
expect(typeof dateToString.rows[timeColumnIndex].timeISO).toBe('string');
expect(new Date(dateToString.rows[timeColumnIndex].timeISO)).toEqual(
new Date(testTable.rows[timeColumnIndex].time)
@ -69,10 +69,10 @@ describe('alterColumn', () => {
it('does not change column if type is not specified', () => {
const unconvertedColumn = fn(testTable, { column: 'price', name: 'foo' });
const originalType = testTable.columns[priceColumnIndex].type;
const originalType = testTable.columns[priceColumnIndex].meta.type;
const arbitraryRowIndex = 2;
expect(unconvertedColumn.columns[priceColumnIndex].type).toBe(originalType);
expect(unconvertedColumn.columns[priceColumnIndex].meta.type).toBe(originalType);
expect(typeof unconvertedColumn.rows[arbitraryRowIndex].foo).toBe(originalType);
});
@ -99,7 +99,7 @@ describe('alterColumn', () => {
const arbitraryRowIndex = 5;
expect(newColumn.name).not.toBe(originalColumn.name);
expect(newColumn.type).not.toBe(originalColumn.type);
expect(newColumn.meta.type).not.toBe(originalColumn.meta.type);
expect(typeof overwriteName.rows[arbitraryRowIndex].name).toBe('string');
expect(new Date(overwriteName.rows[arbitraryRowIndex].name)).toEqual(
new Date(testTable.rows[arbitraryRowIndex].time)
@ -122,7 +122,7 @@ describe('alterColumn', () => {
const numberToString = fn(testTable, { column: 'price', type: 'string' });
expect(numberToString.columns[priceColumnIndex]).toHaveProperty('name', 'price');
expect(numberToString.columns[priceColumnIndex]).toHaveProperty('type', 'string');
expect(numberToString.columns[priceColumnIndex].meta).toHaveProperty('type', 'string');
expect(typeof numberToString.rows[arbitraryRowIndex].price).toBe('string');
expect(numberToString.rows[arbitraryRowIndex].price).toBe(
@ -132,7 +132,7 @@ describe('alterColumn', () => {
const stringToNumber = fn(numberToString, { column: 'price', type: 'number' });
expect(stringToNumber.columns[priceColumnIndex]).toHaveProperty('name', 'price');
expect(stringToNumber.columns[priceColumnIndex]).toHaveProperty('type', 'number');
expect(stringToNumber.columns[priceColumnIndex].meta).toHaveProperty('type', 'number');
expect(typeof stringToNumber.rows[arbitraryRowIndex].price).toBe('number');
@ -146,7 +146,7 @@ describe('alterColumn', () => {
const dateToString = fn(testTable, { column: 'time', type: 'string' });
expect(dateToString.columns[timeColumnIndex]).toHaveProperty('name', 'time');
expect(dateToString.columns[timeColumnIndex]).toHaveProperty('type', 'string');
expect(dateToString.columns[timeColumnIndex].meta).toHaveProperty('type', 'string');
expect(typeof dateToString.rows[arbitraryRowIndex].time).toBe('string');
expect(new Date(dateToString.rows[arbitraryRowIndex].time)).toEqual(
@ -156,7 +156,7 @@ describe('alterColumn', () => {
const stringToDate = fn(dateToString, { column: 'time', type: 'date' });
expect(stringToDate.columns[timeColumnIndex]).toHaveProperty('name', 'time');
expect(stringToDate.columns[timeColumnIndex]).toHaveProperty('type', 'date');
expect(stringToDate.columns[timeColumnIndex].meta).toHaveProperty('type', 'date');
expect(new Date(stringToDate.rows[timeColumnIndex].time)).toBeInstanceOf(Date);
expect(new Date(stringToDate.rows[timeColumnIndex].time)).toEqual(
@ -169,7 +169,7 @@ describe('alterColumn', () => {
const arbitraryRowIndex = 1;
expect(dateToNumber.columns[timeColumnIndex]).toHaveProperty('name', 'time');
expect(dateToNumber.columns[timeColumnIndex]).toHaveProperty('type', 'number');
expect(dateToNumber.columns[timeColumnIndex].meta).toHaveProperty('type', 'number');
expect(typeof dateToNumber.rows[arbitraryRowIndex].time).toBe('number');
expect(dateToNumber.rows[arbitraryRowIndex].time).toEqual(
@ -179,7 +179,7 @@ describe('alterColumn', () => {
const numberToDate = fn(dateToNumber, { column: 'time', type: 'date' });
expect(numberToDate.columns[timeColumnIndex]).toHaveProperty('name', 'time');
expect(numberToDate.columns[timeColumnIndex]).toHaveProperty('type', 'date');
expect(numberToDate.columns[timeColumnIndex].meta).toHaveProperty('type', 'date');
expect(new Date(numberToDate.rows[arbitraryRowIndex].time)).toBeInstanceOf(Date);
expect(new Date(numberToDate.rows[arbitraryRowIndex].time)).toEqual(
@ -192,7 +192,7 @@ describe('alterColumn', () => {
const arbitraryRowIndex = 7;
expect(booleanToNumber.columns[inStockColumnIndex]).toHaveProperty('name', 'in_stock');
expect(booleanToNumber.columns[inStockColumnIndex]).toHaveProperty('type', 'number');
expect(booleanToNumber.columns[inStockColumnIndex].meta).toHaveProperty('type', 'number');
expect(typeof booleanToNumber.rows[arbitraryRowIndex].in_stock).toBe('number');
expect(booleanToNumber.rows[arbitraryRowIndex].in_stock).toEqual(
@ -202,7 +202,7 @@ describe('alterColumn', () => {
const numberToBoolean = fn(booleanToNumber, { column: 'in_stock', type: 'boolean' });
expect(numberToBoolean.columns[inStockColumnIndex]).toHaveProperty('name', 'in_stock');
expect(numberToBoolean.columns[inStockColumnIndex]).toHaveProperty('type', 'boolean');
expect(numberToBoolean.columns[inStockColumnIndex].meta).toHaveProperty('type', 'boolean');
expect(typeof numberToBoolean.rows[arbitraryRowIndex].in_stock).toBe('boolean');
expect(numberToBoolean.rows[arbitraryRowIndex].in_stock).toEqual(
@ -216,7 +216,7 @@ describe('alterColumn', () => {
expect(stringToNull.columns[nameColumnIndex]).toHaveProperty('name', 'name');
expect(stringToNull.columns[nameColumnIndex]).toHaveProperty('type', 'null');
expect(stringToNull.columns[nameColumnIndex].meta).toHaveProperty('type', 'null');
expect(stringToNull.rows[arbitraryRowIndex].name).toBe(null);
});

View file

@ -57,14 +57,14 @@ export function alterColumn(): ExpressionFunctionDefinition<
}
const name = args.name || column.name;
const type = args.type || column.type;
const type = args.type || column.meta.type;
const columns = input.columns.reduce((all: DatatableColumn[], col) => {
if (col.name !== args.name) {
if (col.name !== column.name) {
all.push(col);
} else {
all.push({ name, type });
all.push({ id: name, name, meta: { type } });
}
}
return all;
@ -76,7 +76,7 @@ export function alterColumn(): ExpressionFunctionDefinition<
handler = (function getHandler() {
switch (type) {
case 'string':
if (column.type === 'date') {
if (column.meta.type === 'date') {
return (v: string) => new Date(v).toISOString();
}
return String;

View file

@ -13,19 +13,19 @@ describe('as', () => {
it('returns a datatable with a single column and single row', () => {
expect(fn('foo', { name: 'bar' })).toEqual({
type: 'datatable',
columns: [{ name: 'bar', type: 'string' }],
columns: [{ id: 'bar', name: 'bar', meta: { type: 'string' } }],
rows: [{ bar: 'foo' }],
});
expect(fn(2, { name: 'num' })).toEqual({
type: 'datatable',
columns: [{ name: 'num', type: 'number' }],
columns: [{ id: 'num', name: 'num', meta: { type: 'number' } }],
rows: [{ num: 2 }],
});
expect(fn(true, { name: 'bool' })).toEqual({
type: 'datatable',
columns: [{ name: 'bool', type: 'boolean' }],
columns: [{ id: 'bool', name: 'bool', meta: { type: 'boolean' } }],
rows: [{ bool: true }],
});
});

View file

@ -34,8 +34,9 @@ export function asFn(): ExpressionFunctionDefinition<'as', Input, Arguments, Dat
type: 'datatable',
columns: [
{
id: args.name,
name: args.name,
type: getType(input),
meta: { type: getType(input) },
},
],
rows: [

View file

@ -14,13 +14,17 @@ describe('mapColumn', () => {
const fn = functionWrapper(mapColumn);
it('returns a datatable with a new column with the values from mapping a function over each row in a datatable', () => {
return fn(testTable, { name: 'pricePlusTwo', expression: pricePlusTwo }).then((result) => {
return fn(testTable, {
id: 'pricePlusTwo',
name: 'pricePlusTwo',
expression: pricePlusTwo,
}).then((result) => {
const arbitraryRowIndex = 2;
expect(result.type).toBe('datatable');
expect(result.columns).toEqual([
...testTable.columns,
{ name: 'pricePlusTwo', type: 'number' },
{ id: 'pricePlusTwo', name: 'pricePlusTwo', meta: { type: 'number' } },
]);
expect(result.columns[result.columns.length - 1]).toHaveProperty('name', 'pricePlusTwo');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('pricePlusTwo');
@ -35,7 +39,7 @@ describe('mapColumn', () => {
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(testTable.columns.length);
expect(result.columns[nameColumnIndex]).toHaveProperty('name', 'name');
expect(result.columns[nameColumnIndex]).toHaveProperty('type', 'number');
expect(result.columns[nameColumnIndex].meta).toHaveProperty('type', 'number');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('name', 202);
});
});
@ -45,7 +49,7 @@ describe('mapColumn', () => {
expect(result.type).toBe('datatable');
expect(result.columns).toHaveLength(1);
expect(result.columns[0]).toHaveProperty('name', 'name');
expect(result.columns[0]).toHaveProperty('type', 'null');
expect(result.columns[0].meta).toHaveProperty('type', 'null');
});
});
@ -56,7 +60,7 @@ describe('mapColumn', () => {
const arbitraryRowIndex = 8;
expect(result.columns[emptyColumnIndex]).toHaveProperty('name', 'empty');
expect(result.columns[emptyColumnIndex]).toHaveProperty('type', 'null');
expect(result.columns[emptyColumnIndex].meta).toHaveProperty('type', 'null');
expect(result.rows[arbitraryRowIndex]).toHaveProperty('empty', null);
});
});

View file

@ -59,7 +59,7 @@ export function mapColumn(): ExpressionFunctionDefinition<
return Promise.all(rowPromises).then((rows) => {
const existingColumnIndex = columns.findIndex(({ name }) => name === args.name);
const type = rows.length ? getType(rows[0][args.name]) : 'null';
const newColumn = { name: args.name, type };
const newColumn = { id: args.name, name: args.name, meta: { type } };
if (existingColumnIndex === -1) {
columns.push(newColumn);

View file

@ -16,7 +16,7 @@ const averagePrice = (datatable) => {
return Promise.resolve({
type: 'datatable',
columns: [{ name: 'average_price', type: 'number' }],
columns: [{ id: 'average_price', name: 'average_price', meta: { type: 'number' } }],
rows: [{ average_price: average }],
});
};
@ -26,7 +26,7 @@ const doublePrice = (datatable) => {
return Promise.resolve({
type: 'datatable',
columns: [{ name: 'double_price', type: 'number' }],
columns: [{ id: 'double_price', name: 'double_price', meta: { type: 'number' } }],
rows: newRows,
});
};
@ -34,7 +34,7 @@ const doublePrice = (datatable) => {
const rowCount = (datatable) => {
return Promise.resolve({
type: 'datatable',
columns: [{ name: 'row_count', type: 'number' }],
columns: [{ id: 'row_count', name: 'row_count', meta: { type: 'number' } }],
rows: [
{
row_count: datatable.rows.length,
@ -53,10 +53,10 @@ describe('ply', () => {
(result) => {
expect(result.type).toBe('datatable');
expect(result.columns).toEqual([
{ name: 'name', type: 'string' },
{ name: 'in_stock', type: 'boolean' },
{ name: 'average_price', type: 'number' },
{ name: 'row_count', type: 'number' },
{ id: 'name', name: 'name', meta: { type: 'string' } },
{ id: 'in_stock', name: 'in_stock', meta: { type: 'boolean' } },
{ id: 'average_price', name: 'average_price', meta: { type: 'number' } },
{ id: 'row_count', name: 'row_count', meta: { type: 'number' } },
]);
expect(result.rows[arbitaryRowIndex]).toHaveProperty('average_price');
expect(result.rows[arbitaryRowIndex]).toHaveProperty('row_count');
@ -75,7 +75,7 @@ describe('ply', () => {
expect(result).toEqual({
type: 'datatable',
rows: [{ row_count: testTable.rows.length }],
columns: [{ name: 'row_count', type: 'number' }],
columns: [{ id: 'row_count', name: 'row_count', meta: { type: 'number' } }],
})
);
});

View file

@ -15,7 +15,10 @@ describe('staticColumn', () => {
const result = fn(testTable, { name: 'foo', value: 'bar' });
expect(result.type).toBe('datatable');
expect(result.columns).toEqual([...testTable.columns, { name: 'foo', type: 'string' }]);
expect(result.columns).toEqual([
...testTable.columns,
{ id: 'foo', name: 'foo', meta: { type: 'string' } },
]);
expect(result.rows.every((row) => typeof row.foo === 'string')).toBe(true);
expect(result.rows.every((row) => row.foo === 'bar')).toBe(true);
});
@ -33,7 +36,10 @@ describe('staticColumn', () => {
const result = fn(testTable, { name: 'empty' });
expect(result.type).toBe('datatable');
expect(result.columns).toEqual([...testTable.columns, { name: 'empty', type: 'null' }]);
expect(result.columns).toEqual([
...testTable.columns,
{ id: 'empty', name: 'empty', meta: { type: 'null' } },
]);
expect(result.rows.every((row) => row.empty === null)).toBe(true);
});
@ -41,7 +47,7 @@ describe('staticColumn', () => {
const result = fn(emptyTable, { name: 'empty', value: 1 });
expect(result.type).toBe('datatable');
expect(result.columns).toEqual([{ name: 'empty', type: 'number' }]);
expect(result.columns).toEqual([{ id: 'empty', name: 'empty', meta: { type: 'number' } }]);
expect(result.rows.length).toBe(0);
});
});

View file

@ -48,7 +48,7 @@ export function staticColumn(): ExpressionFunctionDefinition<
const type = getType(args.value) as DatatableColumnType;
const columns = [...input.columns];
const existingColumnIndex = columns.findIndex(({ name }) => name === args.name);
const newColumn = { name: args.name, type };
const newColumn = { id: args.name, name: args.name, meta: { type } };
if (existingColumnIndex > -1) {
columns[existingColumnIndex] = newColumn;

View file

@ -50,26 +50,26 @@ export function demodata(): ExpressionFunctionDefinition<
if (args.type === DemoRows.CI) {
set = {
columns: [
{ name: '@timestamp', type: 'date' },
{ name: 'time', type: 'date' },
{ name: 'cost', type: 'number' },
{ name: 'username', type: 'string' },
{ name: 'price', type: 'number' },
{ name: 'age', type: 'number' },
{ name: 'country', type: 'string' },
{ name: 'state', type: 'string' },
{ name: 'project', type: 'string' },
{ name: 'percent_uptime', type: 'number' },
{ id: '@timestamp', name: '@timestamp', meta: { type: 'date' } },
{ id: 'time', name: 'time', meta: { type: 'date' } },
{ id: 'cost', name: 'cost', meta: { type: 'number' } },
{ id: 'username', name: 'username', meta: { type: 'string' } },
{ id: 'price', name: 'price', meta: { type: 'number' } },
{ id: 'age', name: 'age', meta: { type: 'number' } },
{ id: 'country', name: 'country', meta: { type: 'string' } },
{ id: 'state', name: 'state', meta: { type: 'string' } },
{ id: 'project', name: 'project', meta: { type: 'string' } },
{ id: 'percent_uptime', name: 'percent_uptime', meta: { type: 'number' } },
],
rows: sortBy(demoRows, 'time'),
};
} else if (args.type === DemoRows.SHIRTS) {
set = {
columns: [
{ name: 'size', type: 'string' },
{ name: 'color', type: 'string' },
{ name: 'price', type: 'number' },
{ name: 'cut', type: 'string' },
{ id: 'size', name: 'size', meta: { type: 'string' } },
{ id: 'color', name: 'color', meta: { type: 'string' } },
{ id: 'price', name: 'price', meta: { type: 'number' } },
{ id: 'cut', name: 'cut', meta: { type: 'string' } },
],
rows: demoRows,
};

View file

@ -20,5 +20,5 @@ export function getFieldType(columns: DatatableColumn[], field?: string): string
}
const realField = unquoteString(field);
const column = columns.find((dataTableColumn) => dataTableColumn.name === realField);
return column ? column.type : 'null';
return column ? column.meta.type : 'null';
}

View file

@ -41,7 +41,7 @@ const getIcon = (type: IconType) => {
const getColumnName = (col: DatatableColumn) => (typeof col === 'string' ? col : col.name);
const getColumnType = (col: DatatableColumn) => col.type || null;
const getColumnType = (col: DatatableColumn) => col.meta?.type || null;
const getFormattedValue = (val: any, type: any) => {
if (type === 'date') {

View file

@ -135,10 +135,13 @@ export function timelionFunctionFactory(initialize: InitializeArguments): () =>
return {
type: 'datatable',
meta: {
source: 'timelion',
},
columns: [
{ name: '@timestamp', type: 'date' },
{ name: 'value', type: 'number' },
{ name: 'label', type: 'string' },
{ id: '@timestamp', name: '@timestamp', meta: { type: 'date' } },
{ id: 'value', name: 'value', meta: { type: 'number' } },
{ id: 'label', name: 'label', meta: { type: 'string' } },
],
rows,
};

View file

@ -53,7 +53,11 @@ describe('query_es_sql', () => {
const result = await queryEsSQL(api, baseArgs);
const expectedColumns = response.columns.map((c) => ({ name: c.name, type: 'string' }));
const expectedColumns = response.columns.map((c) => ({
id: c.name,
name: c.name,
meta: { type: 'string' },
}));
const columnNames = expectedColumns.map((c) => c.name);
const expectedRows = response.rows.map((r) => zipObject(columnNames, r));

View file

@ -53,7 +53,11 @@ export const queryEsSQL = async (
});
const columns = response.columns.map(({ name, type }) => {
return { name: sanitizeName(name), type: normalizeType(type) };
return {
id: sanitizeName(name),
name: sanitizeName(name),
meta: { type: normalizeType(type) },
};
});
const columnNames = map(columns, 'name');
let rows = response.rows.map((row) => zipObject(columnNames, row));
@ -82,6 +86,9 @@ export const queryEsSQL = async (
return {
type: 'datatable',
meta: {
type: 'essql',
},
columns,
rows,
};