Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 38 additions & 4 deletions datafusion/physical-expr/src/physical_expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,49 @@ pub trait PhysicalExpr: Send + Sync + Display + Debug + PartialEq<dyn Any> {
children: Vec<Arc<dyn PhysicalExpr>>,
) -> Result<Arc<dyn PhysicalExpr>>;

/// Computes bounds for the expression using interval arithmetic.
/// Computes the output interval for the expression, given the input
/// intervals.
///
/// # Arguments
///
/// * `children` are the intervals for the children (inputs) of this
/// expression.
///
/// # Example
///
/// If the expression is `a + b`, and the input intervals are `a: [1, 2]`
/// and `b: [3, 4]`, then the output interval would be `[4, 6]`.
fn evaluate_bounds(&self, _children: &[&Interval]) -> Result<Interval> {
not_impl_err!("Not implemented for {self}")
}

/// Updates/shrinks bounds for the expression using interval arithmetic.
/// Updates bounds for child expressions, given a known interval for this
/// expression.
///
/// This is used to propagate constraints down through an
/// expression tree.
///
/// # Arguments
///
/// * `interval` is the currently known interval for this expression.
/// * `children` are the current intervals for the children of this expression
///
/// # Returns
///
/// A Vec of new intervals for the children, in order.
///
/// If constraint propagation reveals an infeasibility, returns [None] for
/// the child causing infeasibility. If none of the children intervals
/// change, may return an empty vector instead of cloning `children`.
/// the child causing infeasibility.
///
/// If none of the child intervals change as a result of propagation, may
/// return an empty vector instead of cloning `children`.
///
/// # Example
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@metesynnada and @berkaysynnada -- I would appreciate it if you could double check this example. I think this is the kind of thing propagate_constraints can do, but I am not 100% sure I got the example correct

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example you gave is clear and correct, thank you ☺️
For more detail:

  • For plus operation, specifically, we would first do
  • [a_lower, a_upper] <- ([expression_lower, expression_upper] - [b_lower, b_upper]) ∩ [a_lower, a_upper], and then
  • [b_lower, b_upper] <- ([expression_lower, expression_upper] - [a_lower, a_upper]) ∩ [b_lower, b_upper].

///
/// If the expression is `a + b`, the current `interval` is `[4, 5] and the
/// inputs are given [`a: [0, 2], `b: [-∞, 4]]`, then propagation would
/// would return `[a: [0, 2], b: [2, 4]]` as `b` must be at least 2 to
/// make the output at least `4`.
fn propagate_constraints(
&self,
_interval: &Interval,
Expand Down