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 82060d379b..52dc348084 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 @@ -16,11 +16,15 @@ * specific language governing permissions and limitations * under the License. */ -import JSONbig from 'json-bigint'; +import _JSONbig from 'json-bigint'; import { cloneDeepWith } from 'lodash'; import { ParseMethod, TextResponse, JsonResponse } from '../types'; +const JSONbig = _JSONbig({ + constructorAction: 'preserve', +}); + export default async function parseResponse( apiPromise: Promise, parseMethod?: T, diff --git a/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts b/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts index e13964ecf7..b08b5b8cb8 100644 --- a/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts +++ b/superset-frontend/packages/superset-ui-core/test/connection/callApi/parseResponse.test.ts @@ -139,8 +139,12 @@ describe('parseResponse()', () => { it('resolves to big number value if `parseMethod=json-bigint`', async () => { const mockBigIntUrl = '/mock/get/bigInt'; - const mockGetBigIntPayload = - '{ "value": 9223372036854775807, "minus": { "value": -483729382918228373892, "str": "something" }, "number": 1234, "floatValue": { "plus": 0.3452211361231223, "minus": -0.3452211361231223 } }'; + const mockGetBigIntPayload = `{ + "value": 9223372036854775807, "minus": { "value": -483729382918228373892, "str": "something" }, + "number": 1234, "floatValue": { "plus": 0.3452211361231223, "minus": -0.3452211361231223 }, + "string.constructor": "data.constructor", + "constructor": "constructor" + }`; fetchMock.get(mockBigIntUrl, mockGetBigIntPayload); const responseBigNumber = await parseResponse( callApi({ url: mockBigIntUrl, method: 'GET' }), @@ -167,6 +171,10 @@ describe('parseResponse()', () => { expect(Math.abs(responseBigNumber.json.floatValue.minus)).toEqual( responseBigNumber.json.floatValue.plus, ); + expect(responseBigNumber.json['string.constructor']).toEqual( + 'data.constructor', + ); + expect(responseBigNumber.json.constructor).toEqual('constructor'); }); it('rejects if request.ok=false', async () => { diff --git a/superset-frontend/src/components/FilterableTable/index.tsx b/superset-frontend/src/components/FilterableTable/index.tsx index d731313bde..0ae4406de2 100644 --- a/superset-frontend/src/components/FilterableTable/index.tsx +++ b/superset-frontend/src/components/FilterableTable/index.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import JSONbig from 'json-bigint'; +import _JSONbig from 'json-bigint'; import React, { useEffect, useRef, useState, useMemo } from 'react'; import { getMultipleTextDimensions, styled } from '@superset-ui/core'; import { useDebounceValue } from 'src/hooks/useDebounceValue'; @@ -24,6 +24,11 @@ import { useCellContentParser } from './useCellContentParser'; import { renderResultCell } from './utils'; import { Table, TableSize } from '../Table'; +const JSONbig = _JSONbig({ + storeAsString: true, + constructorAction: 'preserve', +}); + const SCROLL_BAR_HEIGHT = 15; // This regex handles all possible number formats in javascript, including ints, floats, // exponential notation, NaN, and Infinity. diff --git a/superset/sql_parse.py b/superset/sql_parse.py index 9ef32899a5..d2e20f9cba 100644 --- a/superset/sql_parse.py +++ b/superset/sql_parse.py @@ -31,7 +31,7 @@ from jinja2 import nodes from sqlalchemy import and_ from sqlglot import exp, parse, parse_one from sqlglot.dialects import Dialects -from sqlglot.errors import SqlglotError +from sqlglot.errors import ParseError, SqlglotError from sqlglot.optimizer.scope import Scope, ScopeType, traverse_scope from sqlparse import keywords from sqlparse.lexer import Lexer diff --git a/tests/integration_tests/databases/api_tests.py b/tests/integration_tests/databases/api_tests.py index 973772a4dc..e8c2b67647 100644 --- a/tests/integration_tests/databases/api_tests.py +++ b/tests/integration_tests/databases/api_tests.py @@ -1479,7 +1479,7 @@ class TestDatabaseApi(SupersetTestCase): "indexes": [], "name": "wrong_table", "primaryKey": {"constrained_columns": None, "name": None}, - "selectStar": "SELECT\n *\nFROM wrong_table\nLIMIT 100\nOFFSET 0", + "selectStar": "SELECT *\nFROM wrong_table\nLIMIT 100\nOFFSET 0", }, ) elif example_db.backend == "mysql":