in datafusion/physical-expr/src/expressions/binary.rs [468:568]
fn propagate_constraints(
&self,
interval: &Interval,
children: &[&Interval],
) -> Result<Option<Vec<Interval>>> {
// Get children intervals.
let left_interval = children[0];
let right_interval = children[1];
if self.op.eq(&Operator::And) {
if interval.eq(&Interval::CERTAINLY_TRUE) {
// A certainly true logical conjunction can only derive from possibly
// true operands. Otherwise, we prove infeasibility.
Ok((!left_interval.eq(&Interval::CERTAINLY_FALSE)
&& !right_interval.eq(&Interval::CERTAINLY_FALSE))
.then(|| vec![Interval::CERTAINLY_TRUE, Interval::CERTAINLY_TRUE]))
} else if interval.eq(&Interval::CERTAINLY_FALSE) {
// If the logical conjunction is certainly false, one of the
// operands must be false. However, it's not always possible to
// determine which operand is false, leading to different scenarios.
// If one operand is certainly true and the other one is uncertain,
// then the latter must be certainly false.
if left_interval.eq(&Interval::CERTAINLY_TRUE)
&& right_interval.eq(&Interval::UNCERTAIN)
{
Ok(Some(vec![
Interval::CERTAINLY_TRUE,
Interval::CERTAINLY_FALSE,
]))
} else if right_interval.eq(&Interval::CERTAINLY_TRUE)
&& left_interval.eq(&Interval::UNCERTAIN)
{
Ok(Some(vec![
Interval::CERTAINLY_FALSE,
Interval::CERTAINLY_TRUE,
]))
}
// If both children are uncertain, or if one is certainly false,
// we cannot conclusively refine their intervals. In this case,
// propagation does not result in any interval changes.
else {
Ok(Some(vec![]))
}
} else {
// An uncertain logical conjunction result can not shrink the
// end-points of its children.
Ok(Some(vec![]))
}
} else if self.op.eq(&Operator::Or) {
if interval.eq(&Interval::CERTAINLY_FALSE) {
// A certainly false logical disjunction can only derive from certainly
// false operands. Otherwise, we prove infeasibility.
Ok((!left_interval.eq(&Interval::CERTAINLY_TRUE)
&& !right_interval.eq(&Interval::CERTAINLY_TRUE))
.then(|| vec![Interval::CERTAINLY_FALSE, Interval::CERTAINLY_FALSE]))
} else if interval.eq(&Interval::CERTAINLY_TRUE) {
// If the logical disjunction is certainly true, one of the
// operands must be true. However, it's not always possible to
// determine which operand is true, leading to different scenarios.
// If one operand is certainly false and the other one is uncertain,
// then the latter must be certainly true.
if left_interval.eq(&Interval::CERTAINLY_FALSE)
&& right_interval.eq(&Interval::UNCERTAIN)
{
Ok(Some(vec![
Interval::CERTAINLY_FALSE,
Interval::CERTAINLY_TRUE,
]))
} else if right_interval.eq(&Interval::CERTAINLY_FALSE)
&& left_interval.eq(&Interval::UNCERTAIN)
{
Ok(Some(vec![
Interval::CERTAINLY_TRUE,
Interval::CERTAINLY_FALSE,
]))
}
// If both children are uncertain, or if one is certainly true,
// we cannot conclusively refine their intervals. In this case,
// propagation does not result in any interval changes.
else {
Ok(Some(vec![]))
}
} else {
// An uncertain logical disjunction result can not shrink the
// end-points of its children.
Ok(Some(vec![]))
}
} else if self.op.supports_propagation() {
Ok(
propagate_comparison(&self.op, interval, left_interval, right_interval)?
.map(|(left, right)| vec![left, right]),
)
} else {
Ok(
propagate_arithmetic(&self.op, interval, left_interval, right_interval)?
.map(|(left, right)| vec![left, right]),
)
}
}