pub struct EquivalenceProperties {
pub eq_group: EquivalenceGroup,
pub oeq_class: OrderingEquivalenceClass,
pub constants: Vec<Arc<dyn PhysicalExpr>>,
/* private fields */
}
Expand description
A EquivalenceProperties
object stores useful information related to a schema.
Currently, it keeps track of:
- Equivalent expressions, e.g expressions that have same value.
- Valid sort expressions (orderings) for the schema.
- Constants expressions (e.g expressions that are known to have constant values).
Consider table below:
┌-------┐
| a | b |
|---|---|
| 1 | 9 |
| 2 | 8 |
| 3 | 7 |
| 5 | 5 |
└---┴---┘
where both a ASC
and b DESC
can describe the table ordering. With
EquivalenceProperties
, we can keep track of these different valid sort
expressions and treat a ASC
and b DESC
on an equal footing.
Similarly, consider the table below:
┌-------┐
| a | b |
|---|---|
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 5 | 5 |
└---┴---┘
where columns a
and b
always have the same value. We keep track of such
equivalences inside this object. With this information, we can optimize
things like partitioning. For example, if the partition requirement is
Hash(a)
and output partitioning is Hash(b)
, then we can deduce that
the existing partitioning satisfies the requirement.
Fields§
§eq_group: EquivalenceGroup
Collection of equivalence classes that store expressions with the same value.
oeq_class: OrderingEquivalenceClass
Equivalent sort expressions for this table.
constants: Vec<Arc<dyn PhysicalExpr>>
Expressions whose values are constant throughout the table.
TODO: We do not need to track constants separately, they can be tracked
inside eq_groups
as Literal
expressions.
Implementations§
source§impl EquivalenceProperties
impl EquivalenceProperties
sourcepub fn new_with_orderings(schema: SchemaRef, orderings: &[LexOrdering]) -> Self
pub fn new_with_orderings(schema: SchemaRef, orderings: &[LexOrdering]) -> Self
Creates a new EquivalenceProperties
object with the given orderings.
sourcepub fn oeq_class(&self) -> &OrderingEquivalenceClass
pub fn oeq_class(&self) -> &OrderingEquivalenceClass
Returns a reference to the ordering equivalence class within.
sourcepub fn eq_group(&self) -> &EquivalenceGroup
pub fn eq_group(&self) -> &EquivalenceGroup
Returns a reference to the equivalence group within.
sourcepub fn constants(&self) -> &[Arc<dyn PhysicalExpr>]
pub fn constants(&self) -> &[Arc<dyn PhysicalExpr>]
Returns a reference to the constant expressions
sourcepub fn output_ordering(&self) -> Option<LexOrdering>
pub fn output_ordering(&self) -> Option<LexOrdering>
Returns the output ordering of the properties.
sourcepub fn normalized_oeq_class(&self) -> OrderingEquivalenceClass
pub fn normalized_oeq_class(&self) -> OrderingEquivalenceClass
Returns the normalized version of the ordering equivalence class within. Normalization removes constants and duplicates as well as standardizing expressions according to the equivalence group within.
sourcepub fn extend(self, other: Self) -> Self
pub fn extend(self, other: Self) -> Self
Extends this EquivalenceProperties
with the other
object.
sourcepub fn clear_orderings(&mut self)
pub fn clear_orderings(&mut self)
Clears (empties) the ordering equivalence class within this object. Call this method when existing orderings are invalidated.
sourcepub fn add_ordering_equivalence_class(
&mut self,
other: OrderingEquivalenceClass
)
pub fn add_ordering_equivalence_class( &mut self, other: OrderingEquivalenceClass )
Extends this EquivalenceProperties
by adding the orderings inside the
ordering equivalence class other
.
sourcepub fn add_new_orderings(
&mut self,
orderings: impl IntoIterator<Item = LexOrdering>
)
pub fn add_new_orderings( &mut self, orderings: impl IntoIterator<Item = LexOrdering> )
Adds new orderings into the existing ordering equivalence class.
sourcepub fn add_equivalence_group(&mut self, other_eq_group: EquivalenceGroup)
pub fn add_equivalence_group(&mut self, other_eq_group: EquivalenceGroup)
Incorporates the given equivalence group to into the existing equivalence group within.
sourcepub fn add_equal_conditions(
&mut self,
left: &Arc<dyn PhysicalExpr>,
right: &Arc<dyn PhysicalExpr>
)
pub fn add_equal_conditions( &mut self, left: &Arc<dyn PhysicalExpr>, right: &Arc<dyn PhysicalExpr> )
Adds a new equality condition into the existing equivalence group. If the given equality defines a new equivalence class, adds this new equivalence class to the equivalence group.
sourcepub fn add_constants(
self,
constants: impl IntoIterator<Item = Arc<dyn PhysicalExpr>>
) -> Self
pub fn add_constants( self, constants: impl IntoIterator<Item = Arc<dyn PhysicalExpr>> ) -> Self
Track/register physical expressions with constant values.
sourcepub fn with_reorder(self, sort_exprs: Vec<PhysicalSortExpr>) -> Self
pub fn with_reorder(self, sort_exprs: Vec<PhysicalSortExpr>) -> Self
Updates the ordering equivalence group within assuming that the table
is re-sorted according to the argument sort_exprs
. Note that constants
and equivalence classes are unchanged as they are unaffected by a re-sort.
sourcepub fn ordering_satisfy(&self, given: LexOrderingRef<'_>) -> bool
pub fn ordering_satisfy(&self, given: LexOrderingRef<'_>) -> bool
Checks whether the given ordering is satisfied by any of the existing orderings.
sourcepub fn ordering_satisfy_requirement(&self, reqs: LexRequirementRef<'_>) -> bool
pub fn ordering_satisfy_requirement(&self, reqs: LexRequirementRef<'_>) -> bool
Checks whether the given sort requirements are satisfied by any of the existing orderings.
sourcepub fn requirements_compatible(
&self,
given: LexRequirementRef<'_>,
reference: LexRequirementRef<'_>
) -> bool
pub fn requirements_compatible( &self, given: LexRequirementRef<'_>, reference: LexRequirementRef<'_> ) -> bool
Checks whether the given`` sort requirements are equal or more specific than the
reference` sort requirements.
sourcepub fn get_finer_ordering(
&self,
lhs: LexOrderingRef<'_>,
rhs: LexOrderingRef<'_>
) -> Option<LexOrdering>
pub fn get_finer_ordering( &self, lhs: LexOrderingRef<'_>, rhs: LexOrderingRef<'_> ) -> Option<LexOrdering>
Returns the finer ordering among the orderings lhs
and rhs
, breaking
any ties by choosing lhs
.
The finer ordering is the ordering that satisfies both of the orderings.
If the orderings are incomparable, returns None
.
For example, the finer ordering among [a ASC]
and [a ASC, b ASC]
is
the latter.
sourcepub fn get_finer_requirement(
&self,
req1: LexRequirementRef<'_>,
req2: LexRequirementRef<'_>
) -> Option<LexRequirement>
pub fn get_finer_requirement( &self, req1: LexRequirementRef<'_>, req2: LexRequirementRef<'_> ) -> Option<LexRequirement>
Returns the finer ordering among the requirements lhs
and rhs
,
breaking any ties by choosing lhs
.
The finer requirements are the ones that satisfy both of the given
requirements. If the requirements are incomparable, returns None
.
For example, the finer requirements among [a ASC]
and [a ASC, b ASC]
is the latter.
sourcepub fn get_meet_ordering(
&self,
lhs: LexOrderingRef<'_>,
rhs: LexOrderingRef<'_>
) -> Option<LexOrdering>
pub fn get_meet_ordering( &self, lhs: LexOrderingRef<'_>, rhs: LexOrderingRef<'_> ) -> Option<LexOrdering>
Calculates the “meet” of the given orderings (lhs
and rhs
).
The meet of a set of orderings is the finest ordering that is satisfied
by all the orderings in that set. For details, see:
https://en.wikipedia.org/wiki/Join_and_meet
If there is no ordering that satisfies both lhs
and rhs
, returns
None
. As an example, the meet of orderings [a ASC]
and [a ASC, b ASC]
is [a ASC]
.
sourcepub fn substitute_ordering_component(
&self,
mapping: &ProjectionMapping,
sort_expr: &[PhysicalSortExpr]
) -> Result<Vec<Vec<PhysicalSortExpr>>>
pub fn substitute_ordering_component( &self, mapping: &ProjectionMapping, sort_expr: &[PhysicalSortExpr] ) -> Result<Vec<Vec<PhysicalSortExpr>>>
we substitute the ordering according to input expression type, this is a simplified version
In this case, we just substitute when the expression satisfy the following condition:
I. just have one column and is a CAST expression
TODO: Add one-to-ones analysis for monotonic ScalarFunctions.
TODO: we could precompute all the scenario that is computable, for example: atan(x + 1000) should also be substituted if
x is DESC or ASC
After substitution, we may generate more than 1 LexOrdering
. As an example,
[a ASC, b ASC]
will turn into [a ASC, b ASC], [CAST(a) ASC, b ASC]
when projection expressions a, b, CAST(a)
is applied.
sourcepub fn substitute_oeq_class(
&mut self,
mapping: &ProjectionMapping
) -> Result<()>
pub fn substitute_oeq_class( &mut self, mapping: &ProjectionMapping ) -> Result<()>
In projection, supposed we have a input function ‘A DESC B DESC’ and the output shares the same expression with A and B, we could surely use the ordering of the original ordering, However, if the A has been changed, for example, A-> Cast(A, Int64) or any other form, it is invalid if we continue using the original ordering Since it would cause bug in dependency constructions, we should substitute the input order in order to get correct dependency map, happen in issue 8838: https://github.com/apache/datafusion/issues/8838
sourcepub fn project_expr(
&self,
expr: &Arc<dyn PhysicalExpr>,
projection_mapping: &ProjectionMapping
) -> Option<Arc<dyn PhysicalExpr>>
pub fn project_expr( &self, expr: &Arc<dyn PhysicalExpr>, projection_mapping: &ProjectionMapping ) -> Option<Arc<dyn PhysicalExpr>>
Projects argument expr
according to projection_mapping
, taking
equivalences into account.
For example, assume that columns a
and c
are always equal, and that
projection_mapping
encodes following mapping:
a -> a1
b -> b1
Then, this function projects a + b
to Some(a1 + b1)
, c + b
to
Some(a1 + b1)
and d
to None
, meaning that it cannot be projected.
sourcepub fn project(
&self,
projection_mapping: &ProjectionMapping,
output_schema: SchemaRef
) -> Self
pub fn project( &self, projection_mapping: &ProjectionMapping, output_schema: SchemaRef ) -> Self
Projects the equivalences within according to projection_mapping
and output_schema
.
sourcepub fn find_longest_permutation(
&self,
exprs: &[Arc<dyn PhysicalExpr>]
) -> (LexOrdering, Vec<usize>)
pub fn find_longest_permutation( &self, exprs: &[Arc<dyn PhysicalExpr>] ) -> (LexOrdering, Vec<usize>)
Returns the longest (potentially partial) permutation satisfying the
existing ordering. For example, if we have the equivalent orderings
[a ASC, b ASC]
and [c DESC]
, with exprs
containing [c, b, a, d]
,
then this function returns ([a ASC, b ASC, c DESC], [2, 1, 0])
.
This means that the specification [a ASC, b ASC, c DESC]
is satisfied
by the existing ordering, and [a, b, c]
resides at indices: 2, 1, 0
inside the argument exprs
(respectively). For the mathematical
definition of “partial permutation”, see:
https://en.wikipedia.org/wiki/Permutation#k-permutations_of_n
sourcepub fn is_expr_constant(&self, expr: &Arc<dyn PhysicalExpr>) -> bool
pub fn is_expr_constant(&self, expr: &Arc<dyn PhysicalExpr>) -> bool
sourcepub fn get_expr_ordering(&self, expr: Arc<dyn PhysicalExpr>) -> ExprOrdering
pub fn get_expr_ordering(&self, expr: Arc<dyn PhysicalExpr>) -> ExprOrdering
Retrieves the ordering information for a given physical expression.
This function constructs an ExprOrdering
object for the provided
expression, which encapsulates information about the expression’s
ordering, including its SortProperties
.
§Arguments
expr
: AnArc<dyn PhysicalExpr>
representing the physical expression for which ordering information is sought.
§Returns
Returns an ExprOrdering
object containing the ordering information for
the given expression.
Trait Implementations§
source§impl Clone for EquivalenceProperties
impl Clone for EquivalenceProperties
source§fn clone(&self) -> EquivalenceProperties
fn clone(&self) -> EquivalenceProperties
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl Freeze for EquivalenceProperties
impl !RefUnwindSafe for EquivalenceProperties
impl Send for EquivalenceProperties
impl Sync for EquivalenceProperties
impl Unpin for EquivalenceProperties
impl !UnwindSafe for EquivalenceProperties
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more