pub struct JoinInputMapper {
arities: Vec<usize>,
input_relation: Vec<usize>,
prior_arities: Vec<usize>,
}Expand description
Any column in a join expression exists in two contexts:
- It has a position relative to the result of the join (global)
- It has a position relative to the specific input it came from (local) This utility focuses on taking expressions that are in terms of the local input and re-expressing them in global terms and vice versa.
Methods in this class that take an argument equivalences are only
guaranteed to return a correct answer if equivalence classes are in
canonical form.
(See crate::relation::canonicalize::canonicalize_equivalences.)
Fields§
§arities: Vec<usize>The number of columns per input. All other fields in this struct are derived using the information in this field.
input_relation: Vec<usize>Looks up which input each column belongs to. Derived from arities.
Stored as a field to avoid recomputation.
prior_arities: Vec<usize>The sum of the arities of the previous inputs in the join. Derived from
arities. Stored as a field to avoid recomputation.
Implementations§
Source§impl JoinInputMapper
impl JoinInputMapper
Sourcepub fn new(inputs: &[MirRelationExpr]) -> Self
pub fn new(inputs: &[MirRelationExpr]) -> Self
Creates a new JoinInputMapper and calculates the mapping of global context
columns to local context columns.
Sourcepub fn new_from_input_types(types: &[SqlRelationType]) -> Self
pub fn new_from_input_types(types: &[SqlRelationType]) -> Self
Creates a new JoinInputMapper and calculates the mapping of global context
columns to local context columns. Using this method saves is more
efficient if input types have been pre-calculated
Sourcepub fn new_from_input_arities<I>(arities: I) -> Selfwhere
I: IntoIterator<Item = usize>,
pub fn new_from_input_arities<I>(arities: I) -> Selfwhere
I: IntoIterator<Item = usize>,
Creates a new JoinInputMapper and calculates the mapping of global context
columns to local context columns. Using this method saves is more
efficient if input arities have been pre-calculated
Sourcepub fn total_columns(&self) -> usize
pub fn total_columns(&self) -> usize
reports sum of the number of columns of each input
Sourcepub fn total_inputs(&self) -> usize
pub fn total_inputs(&self) -> usize
reports total numbers of inputs in the join
Sourcepub fn global_keys<'a, I>(
&self,
local_keys: I,
equivalences: &[Vec<MirScalarExpr>],
) -> Vec<Vec<usize>>
pub fn global_keys<'a, I>( &self, local_keys: I, equivalences: &[Vec<MirScalarExpr>], ) -> Vec<Vec<usize>>
Using the keys that came from each local input, figures out which keys remain unique in the larger join Currently, we only figure out a small subset of the keys that can remain unique.
Sourcepub fn input_arity(&self, index: usize) -> usize
pub fn input_arity(&self, index: usize) -> usize
returns the arity for a particular input
Sourcepub fn local_columns(&self, index: usize) -> Range<usize>
pub fn local_columns(&self, index: usize) -> Range<usize>
All column numbers in order for a particular input in the local context
Sourcepub fn global_columns(&self, index: usize) -> Range<usize>
pub fn global_columns(&self, index: usize) -> Range<usize>
All column numbers in order for a particular input in the global context
Sourcepub fn map_expr_to_local(&self, expr: MirScalarExpr) -> MirScalarExpr
pub fn map_expr_to_local(&self, expr: MirScalarExpr) -> MirScalarExpr
Takes an expression from the global context and creates a new version
where column references have been remapped to the local context.
Assumes that all columns in expr are from the same input.
Sourcepub fn map_expr_to_global(
&self,
expr: MirScalarExpr,
index: usize,
) -> MirScalarExpr
pub fn map_expr_to_global( &self, expr: MirScalarExpr, index: usize, ) -> MirScalarExpr
Takes an expression from the local context of the indexth input and
creates a new version where column references have been remapped to the
global context.
Sourcepub fn map_column_to_local(&self, column: usize) -> (usize, usize)
pub fn map_column_to_local(&self, column: usize) -> (usize, usize)
Remap column numbers from the global to the local context.
Returns a 2-tuple (<new column number>, <index of input>)
Sourcepub fn map_column_to_global(&self, column: usize, index: usize) -> usize
pub fn map_column_to_global(&self, column: usize, index: usize) -> usize
Remap a column number from a local context to the global context.
Sourcepub fn split_column_set_by_input<'a, I>(
&self,
columns: I,
) -> Vec<BTreeSet<usize>>
pub fn split_column_set_by_input<'a, I>( &self, columns: I, ) -> Vec<BTreeSet<usize>>
Takes a sequence of columns in the global context and splits it into
a Vec containing self.total_inputs() BTreeSets, each containing
the localized columns that belong to the particular input.
Sourcepub fn lookup_inputs(
&self,
expr: &MirScalarExpr,
) -> impl Iterator<Item = usize> + use<>
pub fn lookup_inputs( &self, expr: &MirScalarExpr, ) -> impl Iterator<Item = usize> + use<>
Find the sorted, dedupped set of inputs an expression references
Sourcepub fn single_input(&self, expr: &MirScalarExpr) -> Option<usize>
pub fn single_input(&self, expr: &MirScalarExpr) -> Option<usize>
Returns the index of the only input referenced in the given expression.
Sourcepub fn is_localized(&self, expr: &MirScalarExpr, index: usize) -> bool
pub fn is_localized(&self, expr: &MirScalarExpr, index: usize) -> bool
Returns whether the given expr refers to columns of only the indexth input.
Sourcepub fn find_bound_expr(
&self,
expr: &MirScalarExpr,
bound_inputs: &[usize],
equivalences: &[Vec<MirScalarExpr>],
) -> Option<MirScalarExpr>
pub fn find_bound_expr( &self, expr: &MirScalarExpr, bound_inputs: &[usize], equivalences: &[Vec<MirScalarExpr>], ) -> Option<MirScalarExpr>
Takes an expression in the global context and looks in equivalences
for an equivalent expression (also expressed in the global context) that
belongs to one or more of the inputs in bound_inputs
§Examples
use mz_repr::{Datum, SqlColumnType, SqlRelationType, SqlScalarType};
use mz_expr::{JoinInputMapper, MirRelationExpr, MirScalarExpr};
// A two-column schema common to each of the three inputs
let schema = SqlRelationType::new(vec![
SqlScalarType::Int32.nullable(false),
SqlScalarType::Int32.nullable(false),
]);
// the specific data are not important here.
let data = vec![Datum::Int32(0), Datum::Int32(1)];
let input0 = MirRelationExpr::constant(vec![data.clone()], schema.clone());
let input1 = MirRelationExpr::constant(vec![data.clone()], schema.clone());
let input2 = MirRelationExpr::constant(vec![data.clone()], schema.clone());
// [input0(#0) = input2(#1)], [input0(#1) = input1(#0) = input2(#0)]
let equivalences = vec![
vec![MirScalarExpr::column(0), MirScalarExpr::column(5)],
vec![MirScalarExpr::column(1), MirScalarExpr::column(2), MirScalarExpr::column(4)],
];
let input_mapper = JoinInputMapper::new(&[input0, input1, input2]);
assert_eq!(
Some(MirScalarExpr::column(4)),
input_mapper.find_bound_expr(&MirScalarExpr::column(2), &[2], &equivalences)
);
assert_eq!(
None,
input_mapper.find_bound_expr(&MirScalarExpr::column(0), &[1], &equivalences)
);Sourcepub fn try_localize_to_input_with_bound_expr(
&self,
expr: &mut MirScalarExpr,
index: usize,
equivalences: &[Vec<MirScalarExpr>],
) -> bool
pub fn try_localize_to_input_with_bound_expr( &self, expr: &mut MirScalarExpr, index: usize, equivalences: &[Vec<MirScalarExpr>], ) -> bool
Try to rewrite expr from the global context so that all the
columns point to the indexth input by replacing subexpressions with their
bound equivalents in the indexth input if necessary.
Returns whether the rewriting was successful.
If it returns true, then expr is in the context of the indexth input.
If it returns false, then still some subexpressions might have been rewritten. However,
expr is still in the global context.
Sourcepub fn consequence_for_input(
&self,
expr: &MirScalarExpr,
index: usize,
) -> Option<MirScalarExpr>
pub fn consequence_for_input( &self, expr: &MirScalarExpr, index: usize, ) -> Option<MirScalarExpr>
Try to find a consequence c of the given expression e for the given input.
If we return Some(c), that means
cuses only columns from the given input;- if
cdoesn’t hold on a row of the input, thenealso wouldn’t hold; - if
cholds on a row of the input, thenemight or might not hold. - and 2. means that if we have a join with predicate
ethen we can usecfor pre-filtering a join input before the join. However, 3. means thateshouldn’t be deleted from the join predicates, i.e., we can’t do a “traditional” predicate pushdown.
Note that “c is a consequence of e” is the same thing as 2., see
https://en.wikipedia.org/wiki/Contraposition
Example: For
(t1.f2 = 3 AND t2.f2 = 4) OR (t1.f2 = 5 AND t2.f2 = 6)
we find
t1.f2 = 3 OR t1.f2 = 5 for t1, and
t2.f2 = 4 OR t2.f2 = 6 for t2.
Further examples are in TPC-H Q07, Q19, and chbench Q07, Q19.
Parameters:
expr: The expressionefrom above.try_localize_to_input_with_bound_exprshould be called onexprbefore us!index: The index of the join input whose columns we will use.equivalences: Join equivalences that we can use fortry_map_to_input_with_bound_expr. If successful, the returned expression is in the local context of the specified input.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for JoinInputMapper
impl RefUnwindSafe for JoinInputMapper
impl Send for JoinInputMapper
impl Sync for JoinInputMapper
impl Unpin for JoinInputMapper
impl UnwindSafe for JoinInputMapper
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> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<T, U> OverrideFrom<Option<&T>> for Uwhere
U: OverrideFrom<T>,
impl<T, U> OverrideFrom<Option<&T>> for Uwhere
U: OverrideFrom<T>,
Source§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
Source§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();Source§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
Source§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
Source§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
Source§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
Source§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
Source§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
Source§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
Source§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
Source§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();Source§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
Source§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
Source§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
Source§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
Source§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
Source§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
Source§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
Source§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
Source§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
Source§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
Source§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling Attribute value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();Source§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
Source§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi Quirk value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();Source§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.Source§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the Condition value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<P, R> ProtoType<R> for Pwhere
R: RustType<P>,
impl<P, R> ProtoType<R> for Pwhere
R: RustType<P>,
Source§fn into_rust(self) -> Result<R, TryFromProtoError>
fn into_rust(self) -> Result<R, TryFromProtoError>
RustType::from_proto.Source§fn from_rust(rust: &R) -> P
fn from_rust(rust: &R) -> P
RustType::into_proto.Source§impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
impl<'a, S, T> Semigroup<&'a S> for Twhere
T: Semigroup<S>,
Source§fn plus_equals(&mut self, rhs: &&'a S)
fn plus_equals(&mut self, rhs: &&'a S)
std::ops::AddAssign, for types that do not implement AddAssign.