Skip to content

Commit 577e4bb

Browse files
authored
Account for constant equivalence properties in union, tests (#12562)
1 parent 5360d20 commit 577e4bb

File tree

3 files changed

+409
-81
lines changed

3 files changed

+409
-81
lines changed

datafusion/physical-expr-common/src/sort_expr.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ impl PhysicalSortExpr {
120120
}
121121
}
122122

123+
/// Access the PhysicalSortExpr as a PhysicalExpr
124+
impl AsRef<dyn PhysicalExpr> for PhysicalSortExpr {
125+
fn as_ref(&self) -> &(dyn PhysicalExpr + 'static) {
126+
self.expr.as_ref()
127+
}
128+
}
129+
123130
impl PartialEq for PhysicalSortExpr {
124131
fn eq(&self, other: &PhysicalSortExpr) -> bool {
125132
self.options == other.options && self.expr.eq(&other.expr)

datafusion/physical-expr/src/equivalence/class.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ use datafusion_common::tree_node::{Transformed, TransformedResult, TreeNode};
3030
use datafusion_common::JoinType;
3131
use datafusion_physical_expr_common::physical_expr::format_physical_expr_list;
3232

33-
#[derive(Debug, Clone)]
3433
/// A structure representing a expression known to be constant in a physical execution plan.
3534
///
3635
/// The `ConstExpr` struct encapsulates an expression that is constant during the execution
@@ -41,9 +40,10 @@ use datafusion_physical_expr_common::physical_expr::format_physical_expr_list;
4140
///
4241
/// - `expr`: Constant expression for a node in the physical plan.
4342
///
44-
/// - `across_partitions`: A boolean flag indicating whether the constant expression is
45-
/// valid across partitions. If set to `true`, the constant expression has same value for all partitions.
46-
/// If set to `false`, the constant expression may have different values for different partitions.
43+
/// - `across_partitions`: A boolean flag indicating whether the constant
44+
/// expression is the same across partitions. If set to `true`, the constant
45+
/// expression has same value for all partitions. If set to `false`, the
46+
/// constant expression may have different values for different partitions.
4747
///
4848
/// # Example
4949
///
@@ -56,11 +56,22 @@ use datafusion_physical_expr_common::physical_expr::format_physical_expr_list;
5656
/// // create a constant expression from a physical expression
5757
/// let const_expr = ConstExpr::from(col);
5858
/// ```
59+
#[derive(Debug, Clone)]
5960
pub struct ConstExpr {
61+
/// The expression that is known to be constant (e.g. a `Column`)
6062
expr: Arc<dyn PhysicalExpr>,
63+
/// Does the constant have the same value across all partitions? See
64+
/// struct docs for more details
6165
across_partitions: bool,
6266
}
6367

68+
impl PartialEq for ConstExpr {
69+
fn eq(&self, other: &Self) -> bool {
70+
self.across_partitions == other.across_partitions
71+
&& self.expr.eq(other.expr.as_any())
72+
}
73+
}
74+
6475
impl ConstExpr {
6576
/// Create a new constant expression from a physical expression.
6677
///
@@ -74,11 +85,17 @@ impl ConstExpr {
7485
}
7586
}
7687

88+
/// Set the `across_partitions` flag
89+
///
90+
/// See struct docs for more details
7791
pub fn with_across_partitions(mut self, across_partitions: bool) -> Self {
7892
self.across_partitions = across_partitions;
7993
self
8094
}
8195

96+
/// Is the expression the same across all partitions?
97+
///
98+
/// See struct docs for more details
8299
pub fn across_partitions(&self) -> bool {
83100
self.across_partitions
84101
}
@@ -101,6 +118,31 @@ impl ConstExpr {
101118
across_partitions: self.across_partitions,
102119
})
103120
}
121+
122+
/// Returns true if this constant expression is equal to the given expression
123+
pub fn eq_expr(&self, other: impl AsRef<dyn PhysicalExpr>) -> bool {
124+
self.expr.eq(other.as_ref().as_any())
125+
}
126+
127+
/// Returns a [`Display`]able list of `ConstExpr`.
128+
pub fn format_list(input: &[ConstExpr]) -> impl Display + '_ {
129+
struct DisplayableList<'a>(&'a [ConstExpr]);
130+
impl<'a> Display for DisplayableList<'a> {
131+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
132+
let mut first = true;
133+
for const_expr in self.0 {
134+
if first {
135+
first = false;
136+
} else {
137+
write!(f, ",")?;
138+
}
139+
write!(f, "{}", const_expr)?;
140+
}
141+
Ok(())
142+
}
143+
}
144+
DisplayableList(input)
145+
}
104146
}
105147

106148
/// Display implementation for `ConstExpr`

0 commit comments

Comments
 (0)