aboutsummaryrefslogtreecommitdiffstats
path: root/bsfs/query/ast
diff options
context:
space:
mode:
Diffstat (limited to 'bsfs/query/ast')
-rw-r--r--bsfs/query/ast/filter_.py59
1 files changed, 47 insertions, 12 deletions
diff --git a/bsfs/query/ast/filter_.py b/bsfs/query/ast/filter_.py
index b129ded..2f0270c 100644
--- a/bsfs/query/ast/filter_.py
+++ b/bsfs/query/ast/filter_.py
@@ -252,8 +252,7 @@ class Has(FilterExpression):
class _Value(FilterExpression):
- """
- """
+ """Matches some value."""
# target value.
value: typing.Any
@@ -277,13 +276,13 @@ class Is(_Value):
class Equals(_Value):
"""Value matches exactly.
- NOTE: Value format must correspond to literal type; can be a string, a number, or a Node
+ NOTE: Value must correspond to literal type.
"""
class Substring(_Value):
"""Value matches a substring
- NOTE: value format must be a string
+ NOTE: value must be a string.
"""
@@ -295,9 +294,49 @@ class EndsWith(_Value):
"""Value ends with a given string."""
+class Distance(FilterExpression):
+ """Distance to a reference is (strictly) below a threshold. Assumes a Feature literal."""
+
+ # FIXME:
+ # (a) pass a node/predicate as anchor instead of a value.
+ # Then we don't need to materialize the reference.
+ # (b) pass a FilterExpression (_Bounded) instead of a threshold.
+ # Then, we could also query values greater than a threshold.
+
+ # reference value.
+ reference: typing.Any
+
+ # distance threshold.
+ threshold: float
+
+ # closed (True) or open (False) bound.
+ strict: bool
+
+ def __init__(
+ self,
+ reference: typing.Any,
+ threshold: float,
+ strict: bool = False,
+ ):
+ self.reference = reference
+ self.threshold = float(threshold)
+ self.strict = bool(strict)
+
+ def __repr__(self) -> str:
+ return f'{typename(self)}({self.reference}, {self.threshold}, {self.strict})'
+
+ def __hash__(self) -> int:
+ return hash((super().__hash__(), tuple(self.reference), self.threshold, self.strict))
+
+ def __eq__(self, other) -> bool:
+ return super().__eq__(other) \
+ and self.reference == other.reference \
+ and self.threshold == other.threshold \
+ and self.strict == other.strict
+
+
class _Bounded(FilterExpression):
- """
- """
+ """Value is bounded by a threshold. Assumes a Number literal."""
# bound.
threshold: float
@@ -327,15 +366,11 @@ class _Bounded(FilterExpression):
class LessThan(_Bounded):
- """Value is (strictly) smaller than threshold.
- NOTE: only on numerical literals
- """
+ """Value is (strictly) smaller than threshold. Assumes a Number literal."""
class GreaterThan(_Bounded):
- """Value is (strictly) larger than threshold
- NOTE: only on numerical literals
- """
+ """Value is (strictly) larger than threshold. Assumes a Number literal."""
class Predicate(PredicateExpression):