fn f_up()

in datafusion/optimizer/src/simplify_expressions/guarantees.rs [63:199]


    fn f_up(&mut self, expr: Expr) -> Result<Transformed<Expr>> {
        if self.guarantees.is_empty() {
            return Ok(Transformed::no(expr));
        }

        match &expr {
            Expr::IsNull(inner) => match self.guarantees.get(inner.as_ref()) {
                Some(NullableInterval::Null { .. }) => Ok(Transformed::yes(lit(true))),
                Some(NullableInterval::NotNull { .. }) => {
                    Ok(Transformed::yes(lit(false)))
                }
                _ => Ok(Transformed::no(expr)),
            },
            Expr::IsNotNull(inner) => match self.guarantees.get(inner.as_ref()) {
                Some(NullableInterval::Null { .. }) => Ok(Transformed::yes(lit(false))),
                Some(NullableInterval::NotNull { .. }) => Ok(Transformed::yes(lit(true))),
                _ => Ok(Transformed::no(expr)),
            },
            Expr::Between(Between {
                expr: inner,
                negated,
                low,
                high,
            }) => {
                if let (Some(interval), Expr::Literal(low), Expr::Literal(high)) = (
                    self.guarantees.get(inner.as_ref()),
                    low.as_ref(),
                    high.as_ref(),
                ) {
                    let expr_interval = NullableInterval::NotNull {
                        values: Interval::try_new(low.clone(), high.clone())?,
                    };

                    let contains = expr_interval.contains(*interval)?;

                    if contains.is_certainly_true() {
                        Ok(Transformed::yes(lit(!negated)))
                    } else if contains.is_certainly_false() {
                        Ok(Transformed::yes(lit(*negated)))
                    } else {
                        Ok(Transformed::no(expr))
                    }
                } else {
                    Ok(Transformed::no(expr))
                }
            }

            Expr::BinaryExpr(BinaryExpr { left, op, right }) => {
                // The left or right side of expression might either have a guarantee
                // or be a literal. Either way, we can resolve them to a NullableInterval.
                let left_interval = self
                    .guarantees
                    .get(left.as_ref())
                    .map(|interval| Cow::Borrowed(*interval))
                    .or_else(|| {
                        if let Expr::Literal(value) = left.as_ref() {
                            Some(Cow::Owned(value.clone().into()))
                        } else {
                            None
                        }
                    });
                let right_interval = self
                    .guarantees
                    .get(right.as_ref())
                    .map(|interval| Cow::Borrowed(*interval))
                    .or_else(|| {
                        if let Expr::Literal(value) = right.as_ref() {
                            Some(Cow::Owned(value.clone().into()))
                        } else {
                            None
                        }
                    });

                match (left_interval, right_interval) {
                    (Some(left_interval), Some(right_interval)) => {
                        let result =
                            left_interval.apply_operator(op, right_interval.as_ref())?;
                        if result.is_certainly_true() {
                            Ok(Transformed::yes(lit(true)))
                        } else if result.is_certainly_false() {
                            Ok(Transformed::yes(lit(false)))
                        } else {
                            Ok(Transformed::no(expr))
                        }
                    }
                    _ => Ok(Transformed::no(expr)),
                }
            }

            // Columns (if interval is collapsed to a single value)
            Expr::Column(_) => {
                if let Some(interval) = self.guarantees.get(&expr) {
                    Ok(Transformed::yes(interval.single_value().map_or(expr, lit)))
                } else {
                    Ok(Transformed::no(expr))
                }
            }

            Expr::InList(InList {
                expr: inner,
                list,
                negated,
            }) => {
                if let Some(interval) = self.guarantees.get(inner.as_ref()) {
                    // Can remove items from the list that don't match the guarantee
                    let new_list: Vec<Expr> = list
                        .iter()
                        .filter_map(|expr| {
                            if let Expr::Literal(item) = expr {
                                match interval
                                    .contains(NullableInterval::from(item.clone()))
                                {
                                    // If we know for certain the value isn't in the column's interval,
                                    // we can skip checking it.
                                    Ok(interval) if interval.is_certainly_false() => None,
                                    Ok(_) => Some(Ok(expr.clone())),
                                    Err(e) => Some(Err(e)),
                                }
                            } else {
                                Some(Ok(expr.clone()))
                            }
                        })
                        .collect::<Result<_, DataFusionError>>()?;

                    Ok(Transformed::yes(Expr::InList(InList {
                        expr: inner.clone(),
                        list: new_list,
                        negated: *negated,
                    })))
                } else {
                    Ok(Transformed::no(expr))
                }
            }

            _ => Ok(Transformed::no(expr)),
        }
    }