From 887920744a9cb7601a6c1f1929a283dba76c3cb5 Mon Sep 17 00:00:00 2001 From: Jim Bosch Date: Fri, 28 Jul 2023 14:18:13 -0400 Subject: [PATCH] Add commutator for FindFirstDataset. I don't know why I previously assumed this wouldn't commute with anything; it commutes in essentially exactly the same way as a Selection (i.e. WHERE clause). --- doc/changes/DM-40184.bugfix.md | 3 +++ .../registry/queries/find_first_dataset.py | 23 ++++++++++++++++++- .../daf/butler/registry/tests/_registry.py | 1 - 3 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 doc/changes/DM-40184.bugfix.md diff --git a/doc/changes/DM-40184.bugfix.md b/doc/changes/DM-40184.bugfix.md new file mode 100644 index 0000000000..e814996cea --- /dev/null +++ b/doc/changes/DM-40184.bugfix.md @@ -0,0 +1,3 @@ +Fix a rare bug in follow-up dataset queries involving relation commutators. + +This occurred when building QuantumGraphs where a "warp" dataset type was an overall input to the pipeline and present in more than one input RUN collection. diff --git a/python/lsst/daf/butler/registry/queries/find_first_dataset.py b/python/lsst/daf/butler/registry/queries/find_first_dataset.py index b73cef6afd..78f40a2ded 100644 --- a/python/lsst/daf/butler/registry/queries/find_first_dataset.py +++ b/python/lsst/daf/butler/registry/queries/find_first_dataset.py @@ -26,7 +26,7 @@ from collections.abc import Sequence, Set from typing import final -from lsst.daf.relation import ColumnTag, Relation, RowFilter +from lsst.daf.relation import ColumnTag, Relation, RowFilter, UnaryCommutator, UnaryOperationRelation from lsst.utils.classes import cached_getter from ...core import DatasetColumnTag, DimensionKeyColumnTag @@ -73,3 +73,24 @@ def __str__(self) -> str: def applied_min_rows(self, target: Relation) -> int: # Docstring inherited. return 1 if target.min_rows else 0 + + def commute(self, current: UnaryOperationRelation) -> UnaryCommutator: + # Docstring inherited. + if not self.columns_required <= current.target.columns: + return UnaryCommutator( + first=None, + second=current.operation, + done=False, + messages=( + f"{current.target} is missing columns " + f"{set(self.columns_required - current.target.columns)}", + ), + ) + if current.operation.is_count_dependent: + return UnaryCommutator( + first=None, + second=current.operation, + done=False, + messages=(f"{current.operation} is count-dependent",), + ) + return UnaryCommutator(self, current.operation) diff --git a/python/lsst/daf/butler/registry/tests/_registry.py b/python/lsst/daf/butler/registry/tests/_registry.py index cafce6440d..dd1363fd0e 100644 --- a/python/lsst/daf/butler/registry/tests/_registry.py +++ b/python/lsst/daf/butler/registry/tests/_registry.py @@ -3428,7 +3428,6 @@ def pop_transfer(tree: Relation) -> Relation: sql.Engine, ) - @unittest.expectedFailure def test_query_find_datasets_drop_postprocessing(self) -> None: """Test that DataCoordinateQueryResults.findDatasets avoids commutator problems with the FindFirstDataset relation operation.