Skip to content

Commit 45ae442

Browse files
committed
docs
1 parent ff7ed70 commit 45ae442

File tree

3 files changed

+159
-132
lines changed

3 files changed

+159
-132
lines changed

datafusion/optimizer/src/simplify_expressions/expr_simplifier.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,58 @@ impl<S: SimplifyInfo> ExprSimplifier<S> {
152152
expr.rewrite(&mut expr_rewrite)
153153
}
154154

155-
/// Add guarantees
155+
/// Input guarantees and simplify the expression.
156+
///
157+
/// The guarantees can simplify expressions. For example, if a column is
158+
/// guaranteed to always be a certain value, it's references in the expression
159+
/// can be replaced with that literal.
160+
///
161+
/// ```rust
162+
/// use arrow::datatypes::{DataType, Field, Schema};
163+
/// use datafusion_expr::{col, lit, Expr};
164+
/// use datafusion_common::{Result, ScalarValue, ToDFSchema};
165+
/// use datafusion_physical_expr::execution_props::ExecutionProps;
166+
/// use datafusion_optimizer::simplify_expressions::{
167+
/// ExprSimplifier, SimplifyContext,
168+
/// guarantees::{Guarantee, GuaranteeBound, NullStatus}};
169+
///
170+
/// let schema = Schema::new(vec![
171+
/// Field::new("x", DataType::Int64, false),
172+
/// Field::new("y", DataType::UInt32, false),
173+
/// Field::new("z", DataType::Int64, false),
174+
/// ])
175+
/// .to_dfschema_ref().unwrap();
176+
///
177+
/// // Create the simplifier
178+
/// let props = ExecutionProps::new();
179+
/// let context = SimplifyContext::new(&props)
180+
/// .with_schema(schema);
181+
/// let simplifier = ExprSimplifier::new(context);
182+
///
183+
/// // Expression: (x >= 3) AND (y + 2 < 10) AND (z > 5)
184+
/// let expr_x = col("x").gt_eq(lit(3_i64));
185+
/// let expr_y = (col("y") + lit(2_u32)).lt(lit(10_u32));
186+
/// let expr_z = col("z").gt(lit(5_i64));
187+
/// let expr = expr_x.and(expr_y).and(expr_z.clone());
188+
///
189+
/// let guarantees = vec![
190+
/// // x is guaranteed to be between 3 and 5
191+
/// (
192+
/// col("x"),
193+
/// Guarantee::new(
194+
/// Some(GuaranteeBound::new(ScalarValue::Int64(Some(3)), false)),
195+
/// Some(GuaranteeBound::new(ScalarValue::Int64(Some(5)), false)),
196+
/// NullStatus::NeverNull,
197+
/// )
198+
/// ),
199+
/// // y is guaranteed to be 3
200+
/// (col("y"), Guarantee::from(&ScalarValue::UInt32(Some(3)))),
201+
/// ];
202+
/// let output = simplifier.simplify_with_guarantees(expr, &guarantees).unwrap();
203+
/// // Expression becomes: true AND true AND (z > 5), which simplifies to
204+
/// // z > 5.
205+
/// assert_eq!(output, expr_z);
206+
/// ```
156207
pub fn simplify_with_guarantees<'a>(
157208
&self,
158209
expr: Expr,

datafusion/optimizer/src/simplify_expressions/guarantees.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,34 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
//! Logic to inject guarantees with expressions.
18+
//! Guarantees which can be used with [ExprSimplifier::simplify_with_guarantees()][crate::simplify_expressions::expr_simplifier::ExprSimplifier::simplify_with_guarantees].
1919
//!
20+
//! Guarantees can represent single values or possible ranges of values.
21+
//!
22+
//! ```
23+
//! use datafusion_optimizer::simplify_expressions::guarantees::{
24+
//! Guarantee, GuaranteeBound, NullStatus};
25+
//!
26+
//! // Guarantee that value is always 1_i32
27+
//! Guarantee::from(&ScalarValue::Int32(Some(1)));
28+
//! // Guarantee that value is always NULL
29+
//! Guarantee::from(&ScalarValue::Null);
30+
//! // Guarantee that value is always between 1_i32 and 10_i32 (inclusive)
31+
//! // and never null.
32+
//! Guarantee::new(
33+
//! Some(GuaranteeBound::new(ScalarValue::Int32(Some(1)), false)),
34+
//! Some(GuaranteeBound::new(ScalarValue::Int32(Some(10)), false)),
35+
//! NullStatus::NeverNull,
36+
//! );
37+
//! ```
2038
use datafusion_common::{tree_node::TreeNodeRewriter, Result, ScalarValue};
2139
use datafusion_expr::{expr::InList, lit, Between, BinaryExpr, Expr, Operator};
2240
use std::collections::HashMap;
2341

2442
/// A bound on the value of an expression.
2543
#[derive(Debug, Clone, PartialEq)]
2644
pub struct GuaranteeBound {
27-
/// The value of the bound.
45+
/// The value of the bound. If the bound is null, then there is no bound.
2846
pub bound: ScalarValue,
2947
/// If true, the bound is exclusive. If false, the bound is inclusive.
3048
/// In terms of inequalities, this means the bound is `<` or `>` rather than
@@ -40,6 +58,7 @@ impl GuaranteeBound {
4058
}
4159

4260
impl Default for GuaranteeBound {
61+
/// Default value is a closed bound at null.
4362
fn default() -> Self {
4463
Self {
4564
bound: ScalarValue::Null,
@@ -70,9 +89,11 @@ pub enum NullStatus {
7089
/// nulls.
7190
#[derive(Debug, Clone, PartialEq)]
7291
pub struct Guarantee {
73-
/// The min values that the expression can take on. If `min.bound` is
92+
/// The min values that the expression can take on. If the min is null, then
93+
/// there is no known min.
7494
pub min: GuaranteeBound,
75-
/// The max values that the expression can take on.
95+
/// The max values that the expression can take on. If the max is null,
96+
/// then there is no known max.
7697
pub max: GuaranteeBound,
7798
/// Whether the expression is expected to be either always null or never null.
7899
pub null_status: NullStatus,
@@ -97,14 +118,19 @@ impl Guarantee {
97118
self.min.bound > *value || (self.min.bound == *value && self.min.open)
98119
}
99120

121+
/// Whether values are guaranteed to be greater than or equal to the given
122+
/// value.
100123
fn greater_than_or_eq(&self, value: &ScalarValue) -> bool {
101124
self.min.bound >= *value
102125
}
103126

127+
/// Whether values are guaranteed to be less than the given value.
104128
fn less_than(&self, value: &ScalarValue) -> bool {
105129
self.max.bound < *value || (self.max.bound == *value && self.max.open)
106130
}
107131

132+
/// Whether values are guaranteed to be less than or equal to the given
133+
/// value.
108134
fn less_than_or_eq(&self, value: &ScalarValue) -> bool {
109135
self.max.bound <= *value
110136
}
@@ -136,8 +162,6 @@ impl From<&ScalarValue> for Guarantee {
136162
}
137163

138164
/// Rewrite expressions to incorporate guarantees.
139-
///
140-
///
141165
pub(crate) struct GuaranteeRewriter<'a> {
142166
guarantees: HashMap<&'a Expr, &'a Guarantee>,
143167
}

0 commit comments

Comments
 (0)