pub struct EquivalenceProperties {
pub eq_group: EquivalenceGroup,
pub oeq_class: OrderingEquivalenceClass,
pub constants: Vec<ConstExpr>,
/* 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<ConstExpr>
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 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 clear_per_partition_constants(&mut self)
pub fn clear_per_partition_constants(&mut self)
Removes constant expressions that may change across partitions. This method should be used when data from different partitions are merged.
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>,
) -> Result<()>
pub fn add_equal_conditions( &mut self, left: &Arc<dyn PhysicalExpr>, right: &Arc<dyn PhysicalExpr>, ) -> Result<()>
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 = ConstExpr>,
) -> Self
pub fn add_constants( self, constants: impl IntoIterator<Item = ConstExpr>, ) -> 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 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_properties(&self, expr: Arc<dyn PhysicalExpr>) -> ExprProperties
pub fn get_expr_properties(&self, expr: Arc<dyn PhysicalExpr>) -> ExprProperties
Retrieves the properties for a given physical expression.
This function constructs an ExprProperties
object for the given
expression, which encapsulates information about the expression’s
properties, including its SortProperties
and Interval
.
§Parameters
expr
: AnArc<dyn PhysicalExpr>
representing the physical expression for which ordering information is sought.
§Returns
Returns an ExprProperties
object containing the ordering and range
information for the given expression.
sourcepub fn with_new_schema(self, schema: SchemaRef) -> Result<Self>
pub fn with_new_schema(self, schema: SchemaRef) -> Result<Self>
Transforms this EquivalenceProperties
into a new EquivalenceProperties
by mapping columns in the original schema to columns in the new schema
by index.
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)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