@@ -487,12 +487,7 @@ def engine_adapter(self) -> EngineAdapter:
487487 @property
488488 def snapshot_evaluator (self ) -> SnapshotEvaluator :
489489 if not self ._snapshot_evaluator :
490- # Ensure virtual catalog injection (via default_catalog_per_gateway) has run before
491- # cloning adapters with with_settings(). Adapters that support virtual catalogs (e.g.
492- # ClickHouse alongside catalog-aware gateways) mutate _default_catalog during
493- # get_default_catalog_per_gateway. with_settings() forwards _default_catalog to the
494- # clone, so the mutation must happen first or the clones will miss the virtual catalog.
495- self .default_catalog_per_gateway # noqa: B018
490+ self ._ensure_virtual_catalog_injection ()
496491 self ._snapshot_evaluator = SnapshotEvaluator (
497492 {
498493 gateway : adapter .with_settings (execute_log_level = logging .INFO )
@@ -503,6 +498,15 @@ def snapshot_evaluator(self) -> SnapshotEvaluator:
503498 )
504499 return self ._snapshot_evaluator
505500
501+ def _ensure_virtual_catalog_injection (self ) -> None :
502+ """Ensure virtual catalog injection has run before adapters are cloned for SnapshotEvaluator.
503+
504+ Injection is a side effect of get_default_catalog_per_gateway. In normal usage it fires
505+ earlier (default_catalog is accessed during model loading), but this guard covers the edge
506+ case where snapshot_evaluator is accessed directly on a fresh context before any model ops.
507+ """
508+ _ = self .default_catalog_per_gateway
509+
506510 def execution_context (
507511 self ,
508512 deployability_index : t .Optional [DeployabilityIndex ] = None ,
0 commit comments