From c93810f80caeeca78bf69e3b43f32e0164972e87 Mon Sep 17 00:00:00 2001 From: Joe Li Date: Wed, 29 Oct 2025 18:23:47 -0700 Subject: [PATCH] fix(explore): send database backend as string in View Query format request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The View Query modal's SQL formatting toggle was returning a 400 Bad Request error because the engine parameter was being sent as an object instead of a string to the format_sql endpoint. When the backend needs to be fetched from the dataset API, the code was assigning the entire database object {backend: "postgresql"} rather than extracting just the backend property string. Changes: - Use object destructuring to extract backend string from database object - Add comprehensive test validating complete API payload structure - Test verifies engine is sent as string, not object Fixes #35682 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../components/controls/ViewQuery.test.tsx | 26 +++++++++++++++++++ .../explore/components/controls/ViewQuery.tsx | 3 ++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/superset-frontend/src/explore/components/controls/ViewQuery.test.tsx b/superset-frontend/src/explore/components/controls/ViewQuery.test.tsx index 1340c1af1095..dbce360a173d 100644 --- a/superset-frontend/src/explore/components/controls/ViewQuery.test.tsx +++ b/superset-frontend/src/explore/components/controls/ViewQuery.test.tsx @@ -265,3 +265,29 @@ test('uses exploreBackend from Redux state when available', async () => { expect(formatCallBody.engine).toBe('postgresql'); expect(fetchMock.calls(datasetApiEndpoint)).toHaveLength(0); }); + +test('sends engine as string (not object) when fetched from dataset API', async () => { + const stateWithoutBackend = { + ...mockState(), + explore: undefined, + }; + + setup(mockProps, stateWithoutBackend); + + await waitFor(() => { + expect(fetchMock.calls(datasetApiEndpoint)).toHaveLength(1); + }); + + await waitFor(() => { + expect(fetchMock.calls(formatSqlEndpoint)).toHaveLength(1); + }); + + const formatCallBody = JSON.parse( + fetchMock.lastCall(formatSqlEndpoint)?.[1]?.body as string, + ); + + expect(formatCallBody).toEqual({ + sql: mockProps.sql, + engine: 'sqlite', + }); +}); diff --git a/superset-frontend/src/explore/components/controls/ViewQuery.tsx b/superset-frontend/src/explore/components/controls/ViewQuery.tsx index ed9cd7d9de4f..0d2dc7b685da 100644 --- a/superset-frontend/src/explore/components/controls/ViewQuery.tsx +++ b/superset-frontend/src/explore/components/controls/ViewQuery.tsx @@ -106,7 +106,8 @@ const ViewQuery: FC = props => { const response = await SupersetClient.get({ endpoint: `/api/v1/dataset/${datasetId}?q=${queryParams}`, }); - backend = response.json.result.database; + const { backend: datasetBackend } = response.json.result.database; + backend = datasetBackend; } // Format the SQL query