Field Pruning¶
prune_fields removes or projects field-based constraints from an expression tree. Useful when a stored filter contains constraints on fields that are unavailable or irrelevant in a particular execution context.
from therismos import F, prune_fields, FieldSelection, PruneMode
age = F("age", int)
status = F("status")
dept = F("department")
expr = (age > 18) & (status == "active") & (dept == "engineering")
Prune Mode (default)¶
Removes listed fields — remaining constraints are kept:
result = prune_fields(expr, frozenset({"age"}))
# result: AllExpr(status == "active", dept == "engineering")
RESTRICT vs RELAX¶
These modes control what happens when all constraints are pruned from a sub-expression:
only_age = age > 18
# RESTRICT (default): no constraint left → exclude records
result = prune_fields(only_age, frozenset({"age"}))
# result: FALSE
# RELAX: no constraint left → include records
result = prune_fields(only_age, frozenset({"age"}), mode=PruneMode.RELAX)
# result: TRUE
Keep Mode¶
Keep only listed fields, prune everything else:
result = prune_fields(expr, frozenset({"status"}), selection=FieldSelection.KEEP)
# result: status == "active"
Polarity-Aware Substitution Under NOT¶
The substitution correctly flips semantics when a pruned leaf appears inside a NOT: