Class PredicateEvaluator
Predicate against a Row, returning a boolean result.
Handles all seven subtypes of the sealed Predicate hierarchy:
comparison, logical AND/OR/NOT, null tests, set-membership tests, and pattern
(LIKE) matches.
NULL semantics are SQL's three-valued (Kleene) logic, and the evaluator is
three-valued internally: a predicate answers PredicateEvaluator.Truth.TRUE,
PredicateEvaluator.Truth.FALSE or PredicateEvaluator.Truth.UNKNOWN.
- Any comparison (
=,!=,<, …) with a NULL operand is UNKNOWN — includingNULL = NULL. NULL ∈ setis UNKNOWN, and so isx ∈ setwhenxmatches nothing but the set holds a NULL: the answer depends on a value nobody knows.- A LIKE against a NULL is UNKNOWN.
IS NULL/IS NOT NULLare the only predicates that are never UNKNOWN — asking about the absence itself always has an answer.¬UNKNOWNis UNKNOWN, which is why a row can survive neither a predicate nor its negation.
evaluate(com.darkcollective.relix.ast.Predicate, com.darkcollective.relix.processor.Row) answers the only question an operator asks — keep this
row? — and keeps a row only when the predicate is TRUE. Every consumer (σ,
the joins, ∀, COVER) reads that boolean, so the three-valued detail stays inside
this class; the one place a truth value becomes data is a
ConditionOperand, where UNKNOWN surfaces as NULL rather than as false.
Three-valued is not a preference, it is the only reading under which the
engine agrees with itself. A σ the planner folds into a WHERE clause is
evaluated by the database, and SQL is three-valued; a two-valued engine returns
different rows for the same script depending on whether the predicate was pushed
down. NOT LIKE and ∉ were already three-valued at the leaf, so
the alternative was not "leave it alone" but "change those too, and guard every
renderer". NullSemanticsAgreementTest (relix-connectors-std) holds the
two sides together over a live database.
AND and OR still short-circuit, on the value that determines the result on its own: FALSE for AND, TRUE for OR. UNKNOWN determines nothing, so it does not.
Whether two values are equal or ordered is not decided here — that is
ValueComparator, which every operator reads, so a predicate means the
same thing in a selection as in a join condition. It is where the number rule
lives (values of different scale, 1.0 and 1, compare equal) and
where a text cell is read as the boolean or timestamp it spells.
-
Constructor Summary
ConstructorsConstructorDescriptionPredicateEvaluator(OperandEvaluator operandEvaluator) Constructs aPredicateEvaluatorusing the given operand evaluator. -
Method Summary
-
Constructor Details
-
PredicateEvaluator
Constructs aPredicateEvaluatorusing the given operand evaluator.- Parameters:
operandEvaluator- the evaluator for scalar expressions; must not benull
-
-
Method Details
-
evaluate
Evaluatespredicateagainst the givenrow.- Parameters:
predicate- the predicate to evaluate; must not benullrow- the current row; must not benull- Returns:
trueif the predicate holds,falseotherwise- Throws:
EvaluationException- if operand evaluation fails
-