Skip to content

Commit c7e8858

Browse files
authored
Encapsulate fields of OrderingEquivalenceClass (make field non pub) (#14037)
* Complete encapsulatug `OrderingEquivalenceClass` (make fields non pub) * fix doc
1 parent 7af6aa9 commit c7e8858

File tree

4 files changed

+72
-64
lines changed

4 files changed

+72
-64
lines changed

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

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use arrow_schema::SortOptions;
3939
/// ordering. In this case, we say that these orderings are equivalent.
4040
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
4141
pub struct OrderingEquivalenceClass {
42-
pub orderings: Vec<LexOrdering>,
42+
orderings: Vec<LexOrdering>,
4343
}
4444

4545
impl OrderingEquivalenceClass {
@@ -53,24 +53,33 @@ impl OrderingEquivalenceClass {
5353
self.orderings.clear();
5454
}
5555

56-
/// Creates new ordering equivalence class from the given orderings.
56+
/// Creates new ordering equivalence class from the given orderings
57+
///
58+
/// Any redundant entries are removed
5759
pub fn new(orderings: Vec<LexOrdering>) -> Self {
5860
let mut result = Self { orderings };
5961
result.remove_redundant_entries();
6062
result
6163
}
6264

65+
/// Converts this OrderingEquivalenceClass to a vector of orderings.
66+
pub fn into_inner(self) -> Vec<LexOrdering> {
67+
self.orderings
68+
}
69+
6370
/// Checks whether `ordering` is a member of this equivalence class.
6471
pub fn contains(&self, ordering: &LexOrdering) -> bool {
6572
self.orderings.contains(ordering)
6673
}
6774

6875
/// Adds `ordering` to this equivalence class.
6976
#[allow(dead_code)]
77+
#[deprecated(
78+
since = "45.0.0",
79+
note = "use OrderingEquivalenceClass::add_new_ordering instead"
80+
)]
7081
fn push(&mut self, ordering: LexOrdering) {
71-
self.orderings.push(ordering);
72-
// Make sure that there are no redundant orderings:
73-
self.remove_redundant_entries();
82+
self.add_new_ordering(ordering)
7483
}
7584

7685
/// Checks whether this ordering equivalence class is empty.
@@ -79,6 +88,9 @@ impl OrderingEquivalenceClass {
7988
}
8089

8190
/// Returns an iterator over the equivalent orderings in this class.
91+
///
92+
/// Note this class also implements [`IntoIterator`] to return an iterator
93+
/// over owned [`LexOrdering`]s.
8294
pub fn iter(&self) -> impl Iterator<Item = &LexOrdering> {
8395
self.orderings.iter()
8496
}
@@ -95,7 +107,7 @@ impl OrderingEquivalenceClass {
95107
self.remove_redundant_entries();
96108
}
97109

98-
/// Adds new orderings into this ordering equivalence class.
110+
/// Adds new orderings into this ordering equivalence class
99111
pub fn add_new_orderings(
100112
&mut self,
101113
orderings: impl IntoIterator<Item = LexOrdering>,
@@ -110,9 +122,10 @@ impl OrderingEquivalenceClass {
110122
self.add_new_orderings([ordering]);
111123
}
112124

113-
/// Removes redundant orderings from this equivalence class. For instance,
114-
/// if we already have the ordering `[a ASC, b ASC, c DESC]`, then there is
115-
/// no need to keep ordering `[a ASC, b ASC]` in the state.
125+
/// Removes redundant orderings from this equivalence class.
126+
///
127+
/// For instance, if we already have the ordering `[a ASC, b ASC, c DESC]`,
128+
/// then there is no need to keep ordering `[a ASC, b ASC]` in the state.
116129
fn remove_redundant_entries(&mut self) {
117130
let mut work = true;
118131
while work {
@@ -198,6 +211,7 @@ impl OrderingEquivalenceClass {
198211
}
199212
}
200213

214+
/// Convert the `OrderingEquivalenceClass` into an iterator of LexOrderings
201215
impl IntoIterator for OrderingEquivalenceClass {
202216
type Item = LexOrdering;
203217
type IntoIter = IntoIter<LexOrdering>;

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ mod tests {
636636

637637
let err_msg = format!(
638638
"test_idx: {:?}, actual: {:?}, expected: {:?}, projection_mapping: {:?}",
639-
idx, orderings.orderings, expected, projection_mapping
639+
idx, orderings, expected, projection_mapping
640640
);
641641

642642
assert_eq!(orderings.len(), expected.len(), "{}", err_msg);
@@ -825,7 +825,7 @@ mod tests {
825825

826826
let err_msg = format!(
827827
"test idx: {:?}, actual: {:?}, expected: {:?}, projection_mapping: {:?}",
828-
idx, orderings.orderings, expected, projection_mapping
828+
idx, orderings, expected, projection_mapping
829829
);
830830

831831
assert_eq!(orderings.len(), expected.len(), "{}", err_msg);
@@ -971,7 +971,7 @@ mod tests {
971971

972972
let err_msg = format!(
973973
"actual: {:?}, expected: {:?}, projection_mapping: {:?}",
974-
orderings.orderings, expected, projection_mapping
974+
orderings, expected, projection_mapping
975975
);
976976

977977
assert_eq!(orderings.len(), expected.len(), "{}", err_msg);

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

Lines changed: 44 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ pub struct EquivalenceProperties {
131131
/// Expressions whose values are constant
132132
///
133133
/// TODO: We do not need to track constants separately, they can be tracked
134-
/// inside `eq_groups` as `Literal` expressions.
134+
/// inside `eq_group` as `Literal` expressions.
135135
constants: Vec<ConstExpr>,
136136
/// Schema associated with this object.
137137
schema: SchemaRef,
@@ -168,6 +168,11 @@ impl EquivalenceProperties {
168168
&self.oeq_class
169169
}
170170

171+
/// Return the inner OrderingEquivalenceClass, consuming self
172+
pub fn into_oeq_class(self) -> OrderingEquivalenceClass {
173+
self.oeq_class
174+
}
175+
171176
/// Returns a reference to the equivalence group within.
172177
pub fn eq_group(&self) -> &EquivalenceGroup {
173178
&self.eq_group
@@ -430,8 +435,8 @@ impl EquivalenceProperties {
430435
let mut new_orderings = vec![filtered_exprs.clone()];
431436

432437
// Preserve valid suffixes from existing orderings
433-
let orderings = mem::take(&mut self.oeq_class.orderings);
434-
for existing in orderings {
438+
let oeq_class = mem::take(&mut self.oeq_class);
439+
for existing in oeq_class {
435440
if self.is_prefix_of(&filtered_exprs, &existing) {
436441
let mut extended = filtered_exprs.clone();
437442
extended.extend(existing.into_iter().skip(filtered_exprs.len()));
@@ -710,8 +715,8 @@ impl EquivalenceProperties {
710715
/// Since it would cause bug in dependency constructions, we should substitute the input order in order to get correct
711716
/// dependency map, happen in issue 8838: <https://github.com/apache/datafusion/issues/8838>
712717
pub fn substitute_oeq_class(&mut self, mapping: &ProjectionMapping) -> Result<()> {
713-
let orderings = &self.oeq_class.orderings;
714-
let new_order = orderings
718+
let new_order = self
719+
.oeq_class
715720
.iter()
716721
.map(|order| self.substitute_ordering_component(mapping, order))
717722
.collect::<Result<Vec<_>>>()?;
@@ -1219,7 +1224,7 @@ impl EquivalenceProperties {
12191224

12201225
// Rewrite orderings according to new schema:
12211226
let mut new_orderings = vec![];
1222-
for ordering in self.oeq_class.orderings {
1227+
for ordering in self.oeq_class {
12231228
let new_ordering = ordering
12241229
.inner
12251230
.into_iter()
@@ -2008,16 +2013,8 @@ fn calculate_union_binary(
20082013
// Next, calculate valid orderings for the union by searching for prefixes
20092014
// in both sides.
20102015
let mut orderings = UnionEquivalentOrderingBuilder::new();
2011-
orderings.add_satisfied_orderings(
2012-
lhs.normalized_oeq_class().orderings,
2013-
lhs.constants(),
2014-
&rhs,
2015-
);
2016-
orderings.add_satisfied_orderings(
2017-
rhs.normalized_oeq_class().orderings,
2018-
rhs.constants(),
2019-
&lhs,
2020-
);
2016+
orderings.add_satisfied_orderings(lhs.normalized_oeq_class(), lhs.constants(), &rhs);
2017+
orderings.add_satisfied_orderings(rhs.normalized_oeq_class(), rhs.constants(), &lhs);
20212018
let orderings = orderings.build();
20222019

20232020
let mut eq_properties =
@@ -2156,7 +2153,7 @@ impl UnionEquivalentOrderingBuilder {
21562153

21572154
// for each equivalent ordering in properties, try and augment
21582155
// `ordering` it with the constants to match
2159-
for existing_ordering in &properties.oeq_class.orderings {
2156+
for existing_ordering in properties.oeq_class.iter() {
21602157
if let Some(augmented_ordering) = self.augment_ordering(
21612158
ordering,
21622159
constants,
@@ -2437,17 +2434,12 @@ mod tests {
24372434
Some(JoinSide::Left),
24382435
&[],
24392436
);
2440-
let orderings = &join_eq.oeq_class.orderings;
2441-
let err_msg = format!("expected: {:?}, actual:{:?}", expected, orderings);
2442-
assert_eq!(
2443-
join_eq.oeq_class.orderings.len(),
2444-
expected.len(),
2445-
"{}",
2446-
err_msg
2447-
);
2448-
for ordering in orderings {
2437+
let err_msg =
2438+
format!("expected: {:?}, actual:{:?}", expected, &join_eq.oeq_class);
2439+
assert_eq!(join_eq.oeq_class.len(), expected.len(), "{}", err_msg);
2440+
for ordering in join_eq.oeq_class {
24492441
assert!(
2450-
expected.contains(ordering),
2442+
expected.contains(&ordering),
24512443
"{}, ordering: {:?}",
24522444
err_msg,
24532445
ordering
@@ -3766,8 +3758,8 @@ mod tests {
37663758

37673759
// Check whether orderings are same.
37683760
let lhs_orderings = lhs.oeq_class();
3769-
let rhs_orderings = &rhs.oeq_class.orderings;
3770-
for rhs_ordering in rhs_orderings {
3761+
let rhs_orderings = rhs.oeq_class();
3762+
for rhs_ordering in rhs_orderings.iter() {
37713763
assert!(
37723764
lhs_orderings.contains(rhs_ordering),
37733765
"{err_msg}\nlhs: {lhs}\nrhs: {rhs}"
@@ -3843,7 +3835,7 @@ mod tests {
38433835
// Add equality condition c = concat(a, b)
38443836
eq_properties.add_equal_conditions(&col_c, &a_concat_b)?;
38453837

3846-
let orderings = eq_properties.oeq_class().orderings.clone();
3838+
let orderings = eq_properties.oeq_class();
38473839

38483840
let expected_ordering1 =
38493841
LexOrdering::from(vec![
@@ -3894,7 +3886,7 @@ mod tests {
38943886
// Add equality condition c = a * b
38953887
eq_properties.add_equal_conditions(&col_c, &a_times_b)?;
38963888

3897-
let orderings = eq_properties.oeq_class().orderings.clone();
3889+
let orderings = eq_properties.oeq_class();
38983890

38993891
// The ordering should remain unchanged since multiplication is not lex-monotonic
39003892
assert_eq!(orderings.len(), 1);
@@ -3934,7 +3926,7 @@ mod tests {
39343926
// Add equality condition c = concat(a, b)
39353927
eq_properties.add_equal_conditions(&col_c, &a_concat_b)?;
39363928

3937-
let orderings = eq_properties.oeq_class().orderings.clone();
3929+
let orderings = eq_properties.oeq_class();
39383930

39393931
let expected_ordering1 = LexOrdering::from(vec![PhysicalSortExpr::new_default(
39403932
Arc::clone(&a_concat_b),
@@ -3978,8 +3970,9 @@ mod tests {
39783970

39793971
// Should only contain b since a is constant
39803972
assert_eq!(result.oeq_class().len(), 1);
3981-
assert_eq!(result.oeq_class().orderings[0].len(), 1);
3982-
assert!(result.oeq_class().orderings[0][0].expr.eq(&col_b));
3973+
let ordering = result.oeq_class().iter().next().unwrap();
3974+
assert_eq!(ordering.len(), 1);
3975+
assert!(ordering[0].expr.eq(&col_b));
39833976

39843977
Ok(())
39853978
}
@@ -4025,13 +4018,14 @@ mod tests {
40254018

40264019
// Should only contain [a ASC, b DESC, c ASC]
40274020
assert_eq!(result.oeq_class().len(), 1);
4028-
assert_eq!(result.oeq_class().orderings[0].len(), 3);
4029-
assert!(result.oeq_class().orderings[0][0].expr.eq(&col_a));
4030-
assert!(result.oeq_class().orderings[0][0].options.eq(&asc));
4031-
assert!(result.oeq_class().orderings[0][1].expr.eq(&col_b));
4032-
assert!(result.oeq_class().orderings[0][1].options.eq(&desc));
4033-
assert!(result.oeq_class().orderings[0][2].expr.eq(&col_c));
4034-
assert!(result.oeq_class().orderings[0][2].options.eq(&asc));
4021+
let ordering = result.oeq_class().iter().next().unwrap();
4022+
assert_eq!(ordering.len(), 3);
4023+
assert!(ordering[0].expr.eq(&col_a));
4024+
assert!(ordering[0].options.eq(&asc));
4025+
assert!(ordering[1].expr.eq(&col_b));
4026+
assert!(ordering[1].options.eq(&desc));
4027+
assert!(ordering[2].expr.eq(&col_c));
4028+
assert!(ordering[2].options.eq(&asc));
40354029

40364030
Ok(())
40374031
}
@@ -4074,11 +4068,12 @@ mod tests {
40744068
assert_eq!(result.oeq_class().len(), 1);
40754069

40764070
// Verify orderings
4077-
assert_eq!(result.oeq_class().orderings[0].len(), 2);
4078-
assert!(result.oeq_class().orderings[0][0].expr.eq(&col_b));
4079-
assert!(result.oeq_class().orderings[0][0].options.eq(&asc));
4080-
assert!(result.oeq_class().orderings[0][1].expr.eq(&col_c));
4081-
assert!(result.oeq_class().orderings[0][1].options.eq(&asc));
4071+
let ordering = result.oeq_class().iter().next().unwrap();
4072+
assert_eq!(ordering.len(), 2);
4073+
assert!(ordering[0].expr.eq(&col_b));
4074+
assert!(ordering[0].options.eq(&asc));
4075+
assert!(ordering[1].expr.eq(&col_c));
4076+
assert!(ordering[1].options.eq(&asc));
40824077

40834078
Ok(())
40844079
}
@@ -4119,7 +4114,8 @@ mod tests {
41194114

41204115
// Should only contain the new ordering since options don't match
41214116
assert_eq!(result.oeq_class().len(), 1);
4122-
assert_eq!(result.oeq_class().orderings[0], new_order);
4117+
let ordering = result.oeq_class().iter().next().unwrap();
4118+
assert_eq!(ordering, &new_order);
41234119

41244120
Ok(())
41254121
}
@@ -4177,7 +4173,7 @@ mod tests {
41774173

41784174
// Should preserve the original [d ASC, a ASC] ordering
41794175
assert_eq!(result.oeq_class().len(), 1);
4180-
let ordering = &result.oeq_class().orderings[0];
4176+
let ordering = result.oeq_class().iter().next().unwrap();
41814177
assert_eq!(ordering.len(), 2);
41824178

41834179
// First expression should be either b or d (they're equivalent)

datafusion/physical-plan/src/memory.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,10 +260,8 @@ impl MemoryExec {
260260
ProjectionMapping::try_new(&proj_exprs, &self.original_schema())?;
261261
sort_information = base_eqp
262262
.project(&projection_mapping, self.schema())
263-
.oeq_class()
264-
// TODO add a take / into to avoid the clone
265-
.clone()
266-
.orderings;
263+
.into_oeq_class()
264+
.into_inner();
267265
}
268266

269267
self.sort_information = sort_information;

0 commit comments

Comments
 (0)