Class SelectionComplement
Not ¬p. A selection keeps a row only when its predicate is TRUE, so the
rows it drops are those where the predicate is FALSE or UNKNOWN — and
¬UNKNOWN is UNKNOWN, which a selection also drops. So σ ¬p keeps
strictly fewer rows than R − σ p (R), and the gap is every row where
p could not be decided:
R = [(1, 10), (2, 500), (3, NULL)]
R − σ amount > 100 (R) → (1, 10), (3, NULL)
σ ¬(amount > 100) (R) → (1, 10) ← the NULL row is lost
σ complement(amount > 100)(R) → (1, 10), (3, NULL)
The correction is ¬p ∨ p IS UNKNOWN, and the second disjunct is a null
test over the predicate's own truth value: a ConditionOperand evaluates to
NULL exactly when the predicate it wraps is UNKNOWN, which is the one place the
engine's third truth value becomes data.
The node is built directly, never as a call to IsNull.
The function catalogue is discovered, so a library claiming that name at a higher
priority would silently change what a rewrite built on it means — which is the
hazard FunctionAccessGuardTest exists for. A predicate node needs no
catalogue and cannot be shadowed.
The result is deliberately not simplified here. PRED-001 and
friends run in the simplify phase, which is over by the time the rules that
need this reach it, and a complement that folded itself would be a second
simplifier to keep in step with the first.
-
Method Summary