You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by be...@apache.org on 2026/10/13 17:54:35 UTC
(superset) branch sl-oauth2 updated: Encode catalog/schema
This is an automated email from the ASF dual-hosted git repository.
betodealmeida pushed a commit to branch sl-oauth2
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/sl-oauth2 by this push:
new 6dbc3e64e45 Encode catalog/schema
6dbc3e64e45 is described below
commit 6dbc3e64e45888587b458275d1420bcb28251cb7
Author: Beto Dealmeida <bd...@netflix.com>
AuthorDate: Mon Oct 12 14:21:30 2026 -0400
Encode catalog/schema
---
.../src/hooks/apiResources/schemas.test.ts | 4 +-
.../src/hooks/apiResources/schemas.ts | 2 +-
.../src/hooks/apiResources/tables.test.ts | 52 ++++++++++++++++++++++
superset-frontend/src/hooks/apiResources/tables.ts | 5 ++-
4 files changed, 58 insertions(+), 5 deletions(-)
diff --git a/superset-frontend/src/hooks/apiResources/schemas.test.ts b/superset-frontend/src/hooks/apiResources/schemas.test.ts
index 29ff80c2598..4954a9c6911 100644
--- a/superset-frontend/src/hooks/apiResources/schemas.test.ts
+++ b/superset-frontend/src/hooks/apiResources/schemas.test.ts
@@ -330,10 +330,10 @@ describe('useSchemas hook', () => {
test('returns correct schema list by a catalog', async () => {
const dbId = '1';
- const expectCatalog = 'catalog3';
+ const expectCatalog = 'demo%2Emetrics';
const schemaApiRoute = `glob:*/api/v1/database/*/schemas/*`;
fetchMock.get(schemaApiRoute, ({ url }) =>
- url.includes(`catalog:${expectCatalog}`)
+ url.includes(`catalog:demo%252Emetrics`)
? fakeApiResult3
: fakeApiResult2,
);
diff --git a/superset-frontend/src/hooks/apiResources/schemas.ts b/superset-frontend/src/hooks/apiResources/schemas.ts
index 912023dda69..5f928be7d70 100644
--- a/superset-frontend/src/hooks/apiResources/schemas.ts
+++ b/superset-frontend/src/hooks/apiResources/schemas.ts
@@ -46,7 +46,7 @@ const schemaApi = api.injectEndpoints({
// TODO: Would be nice to add pagination in a follow-up. Needs endpoint changes.
urlParams: {
force: forceRefresh,
- ...(catalog !== undefined && { catalog }),
+ ...(catalog !== undefined && { catalog: encodeURIComponent(catalog) }),
},
transformResponse: ({ json }: JsonResponse) =>
json.result.sort().map((value: string) => ({
diff --git a/superset-frontend/src/hooks/apiResources/tables.test.ts b/superset-frontend/src/hooks/apiResources/tables.test.ts
index 55fb45d3ccc..ebeeb4b6fc2 100644
--- a/superset-frontend/src/hooks/apiResources/tables.test.ts
+++ b/superset-frontend/src/hooks/apiResources/tables.test.ts
@@ -197,6 +197,58 @@ describe('useTables hook', () => {
expect(result.current.data).toEqual(expectedHasMoreData);
});
+ test('fetches tables separately for catalogs with the same schema', async () => {
+ const dbId = 'db1';
+ const schema = 'main';
+ const tableApiRoute = `glob:*/api/v1/database/${dbId}/tables/?q=*`;
+ const firstResult = {
+ count: 1,
+ result: [
+ {
+ value: 'demo.metrics.main.download_session',
+ label: 'demo.metrics.main.download_session',
+ type: 'table',
+ },
+ ],
+ };
+ const secondResult = {
+ count: 1,
+ result: [
+ {
+ value: 'shared.main.thumb_report',
+ label: 'shared.main.thumb_report',
+ type: 'table',
+ },
+ ],
+ };
+ fetchMock.get(tableApiRoute, ({ url }) =>
+ url.includes('shared') ? secondResult : firstResult,
+ );
+ fetchMock.get(`glob:*/api/v1/database/${dbId}/schemas/*`, {
+ result: [schema],
+ });
+
+ const { result, rerender } = renderHook(
+ ({ catalog }) => useTables({ dbId, catalog, schema }),
+ {
+ initialProps: { catalog: 'demo%2Emetrics' },
+ wrapper: createWrapper({ useRedux: true, store }),
+ },
+ );
+ await waitFor(() =>
+ expect(result.current.data?.options).toEqual(firstResult.result),
+ );
+ expect(fetchMock.callHistory.calls(tableApiRoute)[0].url).toContain(
+ 'demo%252Emetrics',
+ );
+
+ rerender({ catalog: 'shared' });
+ await waitFor(() =>
+ expect(result.current.data?.options).toEqual(secondResult.result),
+ );
+ expect(fetchMock.callHistory.calls(tableApiRoute).length).toBe(2);
+ });
+
test('returns cached data without api request', async () => {
const expectDbId = 'db1';
const expectedSchema = 'schema1';
diff --git a/superset-frontend/src/hooks/apiResources/tables.ts b/superset-frontend/src/hooks/apiResources/tables.ts
index c3c07db9218..9589cee850d 100644
--- a/superset-frontend/src/hooks/apiResources/tables.ts
+++ b/superset-frontend/src/hooks/apiResources/tables.ts
@@ -110,15 +110,16 @@ const tableApi = api.injectEndpoints({
urlParams: {
force: forceRefresh,
schema_name: schema ? encodeURIComponent(schema) : '',
- ...(catalog && { catalog_name: catalog }),
+ ...(catalog && { catalog_name: encodeURIComponent(catalog) }),
},
transformResponse: ({ json }: QueryResponse) => ({
options: json.result,
hasMore: json.count > json.result.length,
}),
}),
- serializeQueryArgs: ({ queryArgs: { dbId, schema } }) => ({
+ serializeQueryArgs: ({ queryArgs: { dbId, catalog, schema } }) => ({
dbId,
+ catalog,
schema,
}),
}),