Coverage for python/lsst/daf/relation/_operations/_deduplication.py: 66%
25 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-13 10:03 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2023-07-13 10:03 +0000
1# This file is part of daf_relation.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22from __future__ import annotations
24__all__ = ("Deduplication",)
26import dataclasses
27from typing import TYPE_CHECKING, Literal, final
29from .._operation_relations import UnaryOperationRelation
30from .._unary_operation import UnaryCommutator, UnaryOperation
32if TYPE_CHECKING:
33 from .._relation import Relation
36@final
37@dataclasses.dataclass(frozen=True)
38class Deduplication(UnaryOperation):
39 """A relation operation that removes duplicate rows."""
41 @property
42 def is_count_invariant(self) -> Literal[False]:
43 # Docstring inherited.
44 return False
46 @property
47 def is_empty_invariant(self) -> Literal[True]:
48 # Docstring inherited.
49 return True
51 def __str__(self) -> str:
52 return "deduplicate"
54 def applied_min_rows(self, target: Relation) -> int:
55 # Docstring inherited.
56 return 1
58 def commute(self, current: UnaryOperationRelation) -> UnaryCommutator:
59 # Docstring inherited.
60 # Deduplication does not commute through Projection, but this is a bit
61 # more defensive to guard against what a Projection does that's
62 # problematic, rather than just checking isinstance(Projection).
63 if not current.columns >= current.target.columns:
64 return UnaryCommutator(
65 first=None,
66 second=current.operation,
67 done=False,
68 messages=(
69 "deduplication columns would change from "
70 f"{set(current.columns)} to {set(current.target.columns)}",
71 ),
72 )
73 if current.operation.is_count_dependent:
74 return UnaryCommutator(
75 first=None,
76 second=current.operation,
77 done=False,
78 messages=(f"{current.operation} is count-dependent",),
79 )
80 return UnaryCommutator(self, current.operation)