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

beto pushed a commit to branch default-db-schema-dropdown
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 4c6df01353a7dca40363cd80d8223bbe4584a202
Author: Beto Dealmeida <[email protected]>
AuthorDate: Thu Dec 18 18:07:22 2025 -0500

    feat(api): add default field to catalogs and schemas API responses
    
    Add a `default` field to the `/api/v1/database/{id}/catalogs/` and
    `/api/v1/database/{id}/schemas/` endpoints. This field contains the
    default catalog/schema for the database, or null if it cannot be
    determined or is not accessible to the user.
    
    The default is retrieved from the database engine spec via
    `database.get_default_catalog()` and `database.get_default_schema()`.
    Error handling ensures the API never fails if default retrieval is slow
    or fails - it simply returns null.
    
    RBAC is respected: the default is only returned if the user has access
    to it. For the upload_allowed filter, the default is checked against
    the allowed schemas list.
    
    🤖 Generated with [Claude Code](https://claude.com/claude-code)
    
    Co-Authored-By: Claude Opus 4.5 <[email protected]>
---
 superset/databases/api.py     | 60 +++++++++++++++++++++++++++++++++++++------
 superset/databases/schemas.py | 10 ++++++++
 2 files changed, 62 insertions(+), 8 deletions(-)

diff --git a/superset/databases/api.py b/superset/databases/api.py
index b0f29c5247..f15391a6df 100644
--- a/superset/databases/api.py
+++ b/superset/databases/api.py
@@ -317,6 +317,32 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
         "changed_by": [["id", BaseFilterRelatedUsers, lambda: []]],
     }
 
+    @staticmethod
+    def _get_default_schema(
+        database: Database,
+        catalog: str | None,
+        accessible_schemas: set[str],
+        pk: int,
+    ) -> str | None:
+        """
+        Get the default schema for a database/catalog, with error handling.
+
+        Returns None if the default cannot be determined or is not accessible.
+        """
+        try:
+            default_schema = database.get_default_schema(catalog)
+            # Only include if user has access to it
+            if default_schema and default_schema not in accessible_schemas:
+                return None
+            return default_schema
+        except Exception:  # pylint: disable=broad-except
+            logger.debug(
+                "Could not get default schema for database %s, catalog %s",
+                pk,
+                catalog,
+            )
+            return None
+
     @expose("/<int:pk>/connection", methods=("GET",))
     @protect()
     @safe
@@ -726,7 +752,18 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
                 database,
                 catalogs,
             )
-            return self.response(200, result=list(catalogs))
+
+            # Get default catalog with error handling
+            default_catalog = None
+            try:
+                default_catalog = database.get_default_catalog()
+                # Only include if user has access to it
+                if default_catalog and default_catalog not in catalogs:
+                    default_catalog = None
+            except Exception:  # pylint: disable=broad-except
+                logger.debug("Could not get default catalog for database %s", 
pk)
+
+            return self.response(200, result=list(catalogs), 
default=default_catalog)
         except OperationalError:
             return self.response(
                 500,
@@ -795,23 +832,30 @@ class DatabaseRestApi(BaseSupersetModelRestApi):
                 catalog,
                 schemas,
             )
+            default_schema = self._get_default_schema(database, catalog, 
schemas, pk)
+
             if params.get("upload_allowed"):
                 if not database.allow_file_upload:
-                    return self.response(200, result=[])
+                    return self.response(200, result=[], default=None)
                 if allowed_schemas := 
database.get_schema_access_for_file_upload():
                     # some databases might return the list of schemas in 
uppercase,
                     # while the list of allowed schemas is manually inputted so
                     # could be lowercase
                     allowed_schemas = {schema.lower() for schema in 
allowed_schemas}
+                    filtered_schemas = [
+                        schema
+                        for schema in schemas
+                        if schema.lower() in allowed_schemas
+                    ]
+                    # Check if default is in filtered list
+                    if default_schema and default_schema.lower() not in 
allowed_schemas:
+                        default_schema = None
                     return self.response(
                         200,
-                        result=[
-                            schema
-                            for schema in schemas
-                            if schema.lower() in allowed_schemas
-                        ],
+                        result=filtered_schemas,
+                        default=default_schema,
                     )
-            return self.response(200, result=list(schemas))
+            return self.response(200, result=list(schemas), 
default=default_schema)
         except OperationalError:
             return self.response(
                 500, message="There was an error connecting to the database"
diff --git a/superset/databases/schemas.py b/superset/databases/schemas.py
index 105496efa4..5ca999b15b 100644
--- a/superset/databases/schemas.py
+++ b/superset/databases/schemas.py
@@ -742,12 +742,22 @@ class SchemasResponseSchema(Schema):
     result = fields.List(
         fields.String(metadata={"description": "A database schema name"})
     )
+    default = fields.String(
+        allow_none=True,
+        load_default=None,
+        metadata={"description": "The default schema for this 
database/catalog"},
+    )
 
 
 class CatalogsResponseSchema(Schema):
     result = fields.List(
         fields.String(metadata={"description": "A database catalog name"})
     )
+    default = fields.String(
+        allow_none=True,
+        load_default=None,
+        metadata={"description": "The default catalog for this database"},
+    )
 
 
 class DatabaseTablesResponse(Schema):

Reply via email to