diff --git a/superset-frontend/packages/superset-ui-core/src/connection/callApi/parseResponse.ts b/superset-frontend/packages/superset-ui-core/src/connection/callApi/parseResponse.ts index 52dc3480841..931aeecbdd8 100644 --- a/superset-frontend/packages/superset-ui-core/src/connection/callApi/parseResponse.ts +++ b/superset-frontend/packages/superset-ui-core/src/connection/callApi/parseResponse.ts @@ -57,11 +57,20 @@ export default async function parseResponse( const json = JSONbig.parse(rawData); const result: JsonResponse = { response, - // `json-bigint` could not handle floats well, see sidorares/json-bigint#62 - // TODO: clean up after json-bigint>1.0.1 is released - json: cloneDeepWith(json, (value: any) => - value?.isInteger?.() === false ? Number(value) : undefined, - ), + json: cloneDeepWith(json, (value: any) => { + // `json-bigint` could not handle floats well, see sidorares/json-bigint#62 + // TODO: clean up after json-bigint>1.0.1 is released + if (value?.isInteger?.() === false) { + return Number(value); + } + if ( + value?.isGreaterThan?.(Number.MAX_SAFE_INTEGER) || + value?.isLessThan?.(Number.MIN_SAFE_INTEGER) + ) { + return BigInt(value); + } + return undefined; + }), }; return result as ReturnType; } diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts b/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts index 4a5f2a68590..49fc4b4363c 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/types/Query.ts @@ -31,7 +31,7 @@ import { Maybe } from '../../types'; import { PostProcessingRule } from './PostProcessing'; import { JsonObject } from '../../connection'; import { TimeGranularity } from '../../time-format'; -import { GenericDataType } from './QueryResponse'; +import { GenericDataType, DataRecordValue } from './QueryResponse'; export type BaseQueryObjectFilterClause = { col: QueryFormColumn; @@ -41,13 +41,13 @@ export type BaseQueryObjectFilterClause = { export type BinaryQueryObjectFilterClause = BaseQueryObjectFilterClause & { op: BinaryOperator; - val: string | number | boolean; + val: DataRecordValue; formattedVal?: string; }; export type SetQueryObjectFilterClause = BaseQueryObjectFilterClause & { op: SetOperator; - val: (string | number | boolean)[]; + val: DataRecordValue[]; formattedVal?: string[]; }; diff --git a/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts b/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts index b2a3c08cdfe..2e8943cff17 100644 --- a/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts +++ b/superset-frontend/packages/superset-ui-core/src/query/types/QueryResponse.ts @@ -33,7 +33,7 @@ export enum GenericDataType { /** * Primitive types for data field values. */ -export type DataRecordValue = number | string | boolean | Date | null; +export type DataRecordValue = number | string | boolean | Date | null | bigint; export interface DataRecord { [key: string]: DataRecordValue; diff --git a/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.test.ts b/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.test.ts index 6e4f07df4b8..0afd7e850f4 100644 --- a/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.test.ts +++ b/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.test.ts @@ -60,4 +60,12 @@ test('finestTemporalGrain', () => { expect(localTimeFormatter(new Date('2003-01-01 00:00:00Z').getTime())).toBe( '2002-12-31 19:00', ); + + const bigIntFormatter = finestTemporalGrain([ + BigInt(1234567890123456789n), + BigInt(1234567890123456789n), + ]); + expect(bigIntFormatter(new Date('2003-01-01 00:00:00Z').getTime())).toBe( + '2003', + ); }); diff --git a/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts b/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts index c03b7ec1593..c3213f1cf93 100644 --- a/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts +++ b/superset-frontend/packages/superset-ui-core/src/time-format/formatters/finestTemporalGrain.ts @@ -48,7 +48,11 @@ export default function finestTemporalGrain( } = useLocalTime ? localTimeUtils : utcUtils; let formatFunc = formatYear; + values.forEach((value: any) => { + if (typeof value === 'bigint') { + return; + } if (formatFunc === formatYear && isNotFirstMonth(value)) { formatFunc = formatMonth; } diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx index d7882ccdb6c..d95ae633af0 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx +++ b/superset-frontend/plugins/plugin-chart-echarts/src/BigNumber/BigNumberViz.tsx @@ -98,6 +98,7 @@ class BigNumberVis extends PureComponent { !formatTime || !showTimestamp || typeof timestamp === 'string' || + typeof timestamp === 'bigint' || typeof timestamp === 'boolean' ) return null; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/transformProps.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/transformProps.ts index 69e55ef26bc..fe508f53af1 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/transformProps.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/transformProps.ts @@ -153,7 +153,7 @@ export default function transformProps( if (!value) { return NULL_STRING; } - if (typeof value === 'boolean') { + if (typeof value === 'boolean' || typeof value === 'bigint') { return String(value); } return value; diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts index 02adce8cc57..294437c7454 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts @@ -183,7 +183,7 @@ export class EchartsChartPlugin< super({ ...restProps, metadata: new ChartMetadata({ - parseMethod: 'json', + parseMethod: 'json-bigint', ...metadata, }), }); diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts b/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts index bbf222a2a5a..ef10fb9d3ba 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/utils/series.ts @@ -363,7 +363,7 @@ export function formatSeriesName( if (name === undefined || name === null) { return NULL_STRING; } - if (typeof name === 'boolean') { + if (typeof name === 'boolean' || typeof name === 'bigint') { return name.toString(); } if (name instanceof Date || coltype === GenericDataType.Temporal) { diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/index.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/index.test.ts index 7061dc89076..da0e8d2cb10 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/test/index.test.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/test/index.test.ts @@ -125,6 +125,6 @@ test('@superset-ui/plugin-chart-echarts-parsemethod-validation', () => { ]; plugins.forEach(plugin => { - expect(plugin.metadata.parseMethod).toEqual('json'); + expect(plugin.metadata.parseMethod).toEqual('json-bigint'); }); }); diff --git a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx index a0eb3b0185b..8b88ebba695 100644 --- a/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx +++ b/superset-frontend/src/filters/components/Select/SelectFilterPlugin.test.tsx @@ -238,4 +238,25 @@ describe('SelectFilterPlugin', () => { // One call for the search term and other for the empty search expect(setDataMask).toHaveBeenCalledTimes(2); }); + + test('Select big int value', async () => { + const bigValue = 1100924931345932234n; + render( + // @ts-ignore + , + ); + userEvent.click(screen.getByRole('combobox')); + expect(await screen.findByRole('combobox')).toBeInTheDocument(); + await userEvent.type(screen.getByRole('combobox'), '1'); + expect(screen.queryByLabelText(String(bigValue))).toBeInTheDocument(); + }); }); diff --git a/superset-frontend/src/filters/utils.ts b/superset-frontend/src/filters/utils.ts index 859f68f9cea..e08f5b93b77 100644 --- a/superset-frontend/src/filters/utils.ts +++ b/superset-frontend/src/filters/utils.ts @@ -117,6 +117,9 @@ export function getDataRecordFormatter({ if (typeof value === 'string') { return value; } + if (typeof value === 'bigint') { + return String(value); + } if (timeFormatter && dtype === GenericDataType.Temporal) { return timeFormatter(value); }