Emits a filter as ->filter({row | <predicate>}) (PLAN §8.4):
a negative operator is not over its positive one (!($row.c == 'x'));
a Not over a group is pushed down to the leaves (De Morgan), because the
engine's NOT (… OR …) would drop NULL rows; a double negation cancels;
a Not over a comparison takes its negated operator, or is not(…) for
one without (!($row.c > 5); <= would drop NULL rows);
a negation keeps NULL rows (D4): on a column the input schema marks
nullable it is $row.c->isEmpty() || !(…), because the engine keeps them
only for columns it types [0..1] itself, and it does not after an outer
join (PLAN Appendix B). IsNotEmpty is the one negation that drops them;
And and Or are binary, folded left; a group of one rule is that rule;
values are typed literals of the column's type; enumeration values are
written EnumPath.VALUE.
Emits a filter as
->filter({row | <predicate>})(PLAN §8.4):notover its positive one (!($row.c == 'x'));NOT (… OR …)would drop NULL rows; a double negation cancels;not(…)for one without (!($row.c > 5);<=would drop NULL rows);$row.c->isEmpty() || !(…), because the engine keeps them only for columns it types [0..1] itself, and it does not after an outer join (PLAN Appendix B). IsNotEmpty is the one negation that drops them;EnumPath.VALUE.The filter must be valid for its input schema.