Skip to content

[Fabric] get_current_catalog() performs unnecessary DB round-trips in set_current_catalog() #5776

@fresioAS

Description

@fresioAS

Description

FabricEngineAdapter.set_current_catalog() calls get_current_catalog() twice per invocation — once to guard against a redundant switch, and once to verify the switch succeeded:

def set_current_catalog(self, catalog_name: str) -> None:
    current_catalog = self.get_current_catalog()   # DB round-trip #1

    if current_catalog and current_catalog == catalog_name:
        return

    ...
    self._target_catalog = catalog_name
    catalog_after_switch = self.get_current_catalog()  # DB round-trip #2

get_current_catalog() is inherited from GetCurrentCatalogFromFunctionMixin and executes SELECT db_name() against the database. Because Fabric sessions are stateless, each call opens a new connection and executes a query.


Root Cause

FabricEngineAdapter already maintains _target_catalog as a thread-local attribute that is the authoritative source of truth for what catalog the current thread's connection is pointed at:

@property
def _target_catalog(self) -> t.Optional[str]:
    return self._connection_pool.get_attribute("target_catalog")

New connections are always created using this value:

connection_factory_or_pool = lambda *args, **kwargs: original_connection_factory(
    target_catalog=self._target_catalog, *args, **kwargs
)

Since _target_catalog is always consistent with the catalog used for the next connection, querying the database to determine the current catalog is redundant.


Proposed Fix

Override get_current_catalog() in FabricEngineAdapter to read from _target_catalog directly, falling back to the configured database:

def get_current_catalog(self) -> t.Optional[str]:
    return self._target_catalog or self._extra_config.get("database")

This eliminates both DB round-trips in set_current_catalog() without any loss of correctness.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions