This is an automated email from the ASF dual-hosted git repository.

justinpark pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 4f42928b34d fix(sqllab): Skip progress bar on no data (#37652)
4f42928b34d is described below

commit 4f42928b34d03dc8252d2401177861e59e7660c7
Author: JUST.in DO IT <[email protected]>
AuthorDate: Thu Feb 5 10:38:37 2026 -0800

    fix(sqllab): Skip progress bar on no data (#37652)
---
 .../SqlLab/components/SouthPane/Results.test.tsx   | 34 ++++++++++++++++++++++
 .../src/SqlLab/components/SouthPane/Results.tsx    | 34 ++++++++++++----------
 .../src/SqlLab/reducers/sqlLab.test.js             | 22 ++++++++++++++
 superset-frontend/src/SqlLab/reducers/sqlLab.ts    |  7 +++++
 4 files changed, 81 insertions(+), 16 deletions(-)

diff --git a/superset-frontend/src/SqlLab/components/SouthPane/Results.test.tsx 
b/superset-frontend/src/SqlLab/components/SouthPane/Results.test.tsx
index 8663685f58b..2f559f2414d 100644
--- a/superset-frontend/src/SqlLab/components/SouthPane/Results.test.tsx
+++ b/superset-frontend/src/SqlLab/components/SouthPane/Results.test.tsx
@@ -22,6 +22,11 @@ import { denormalizeTimestamp } from '@superset-ui/core';
 import { LOCALSTORAGE_MAX_QUERY_AGE_MS } from 'src/SqlLab/constants';
 import Results from './Results';
 
+jest.mock('@superset-ui/core', () => ({
+  ...jest.requireActual('@superset-ui/core'),
+  isFeatureEnabled: (flag: string) => flag === 'SQLLAB_BACKEND_PERSISTENCE',
+}));
+
 const mockedProps = {
   queryEditorId: defaultQueryEditor.id,
   latestQueryId: 'LCly_kkIN',
@@ -43,6 +48,11 @@ const mockedExpiredProps = {
   latestQueryId: 'expired_query_id',
 };
 
+const mockedNoStoredResultsProps = {
+  ...mockedEmptyProps,
+  latestQueryId: 'no_stored_results_query_id',
+};
+
 const latestQueryProgressMsg = 'LATEST QUERY MESSAGE - LCly_kkIN';
 const expireDateTime = Date.now() - LOCALSTORAGE_MAX_QUERY_AGE_MS - 1;
 
@@ -103,6 +113,19 @@ const mockState = {
         sqlEditorId: defaultQueryEditor.id,
         sql: 'select * from table4',
       },
+      no_stored_results_query_id: {
+        cached: false,
+        changed_on: denormalizeTimestamp(new Date().toISOString()),
+        db: 'main',
+        dbId: 1,
+        id: 'no_stored_results_query_id',
+        startDttm: Date.now(),
+        sqlEditorId: defaultQueryEditor.id,
+        sql: 'select * from table5',
+        state: 'success',
+        resultsKey: null,
+        results: null,
+      },
     },
   },
 };
@@ -132,3 +155,14 @@ test('should pass latest query down to ResultSet 
component', async () => {
   });
   expect(getByText(latestQueryProgressMsg)).toBeVisible();
 });
+
+test('Renders alert when query succeeded but has no stored results', async () 
=> {
+  const { getByText } = render(<Results {...mockedNoStoredResultsProps} />, {
+    useRedux: true,
+    initialState: mockState,
+  });
+  const alertText = getByText(
+    /no stored results found, you need to re-run your query/i,
+  );
+  expect(alertText).toBeVisible();
+});
diff --git a/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx 
b/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx
index 77345a05073..14d76300fd4 100644
--- a/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx
+++ b/superset-frontend/src/SqlLab/components/SouthPane/Results.tsx
@@ -83,25 +83,27 @@ const Results: FC<Props> = ({
     !latestQuery.resultsKey &&
     !latestQuery.results;
 
+  if (hasNoStoredResults) {
+    return (
+      <Alert
+        type="info"
+        message={t('No stored results found, you need to re-run your query')}
+      />
+    );
+  }
+
   return (
     <>
       <QueryStatusBar key={latestQueryId} query={latestQuery} />
-      {hasNoStoredResults ? (
-        <Alert
-          type="info"
-          message={t('No stored results found, you need to re-run your query')}
-        />
-      ) : (
-        <ResultSet
-          search
-          queryId={latestQuery.id}
-          database={databases[latestQuery.dbId]}
-          displayLimit={displayLimit}
-          defaultQueryLimit={defaultQueryLimit}
-          showSql
-          showSqlInline
-        />
-      )}
+      <ResultSet
+        search
+        queryId={latestQuery.id}
+        database={databases[latestQuery.dbId]}
+        displayLimit={displayLimit}
+        defaultQueryLimit={defaultQueryLimit}
+        showSql
+        showSqlInline
+      />
     </>
   );
 };
diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.test.js 
b/superset-frontend/src/SqlLab/reducers/sqlLab.test.js
index fedca09e391..67d60056a83 100644
--- a/superset-frontend/src/SqlLab/reducers/sqlLab.test.js
+++ b/superset-frontend/src/SqlLab/reducers/sqlLab.test.js
@@ -572,6 +572,28 @@ describe('sqlLabReducer', () => {
     test('should refresh queries when polling returns empty', () => {
       newState = sqlLabReducer(newState, actions.refreshQueries({}));
     });
+    test('should set state to fetching when sync query succeeds without 
results', () => {
+      const syncQuery = {
+        ...query,
+        id: 'sync-query',
+        state: QueryState.Pending,
+        runAsync: false,
+        results: null,
+      };
+      newState = sqlLabReducer(
+        {
+          ...newState,
+          queries: { 'sync-query': syncQuery },
+        },
+        actions.refreshQueries({
+          'sync-query': {
+            ...syncQuery,
+            state: QueryState.Success,
+          },
+        }),
+      );
+      expect(newState.queries['sync-query'].state).toBe(QueryState.Fetching);
+    });
   });
   // eslint-disable-next-line no-restricted-globals -- TODO: Migrate from 
describe blocks
   describe('CLEAR_INACTIVE_QUERIES', () => {
diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.ts 
b/superset-frontend/src/SqlLab/reducers/sqlLab.ts
index a63a34b2eea..e3f51e3d0c3 100644
--- a/superset-frontend/src/SqlLab/reducers/sqlLab.ts
+++ b/superset-frontend/src/SqlLab/reducers/sqlLab.ts
@@ -759,6 +759,13 @@ export default function sqlLabReducer(
                   ? prevState
                   : currentState,
             };
+            if (
+              newQueries[id].state === QueryState.Success &&
+              newQueries[id].runAsync === false &&
+              !newQueries[id].results
+            ) {
+              newQueries[id].state = QueryState.Fetching;
+            }
             if (
               shallowEqual(
                 omit(newQueries[id], ['extra']),

Reply via email to