Enum mz_expr::relation::MirRelationExpr
source · pub enum MirRelationExpr {
Show 15 variants
Constant {
rows: Result<Vec<(Row, Diff)>, EvalError>,
typ: RelationType,
},
Get {
id: Id,
typ: RelationType,
access_strategy: AccessStrategy,
},
Let {
id: LocalId,
value: Box<MirRelationExpr>,
body: Box<MirRelationExpr>,
},
LetRec {
ids: Vec<LocalId>,
values: Vec<MirRelationExpr>,
limits: Vec<Option<LetRecLimit>>,
body: Box<MirRelationExpr>,
},
Project {
input: Box<MirRelationExpr>,
outputs: Vec<usize>,
},
Map {
input: Box<MirRelationExpr>,
scalars: Vec<MirScalarExpr>,
},
FlatMap {
input: Box<MirRelationExpr>,
func: TableFunc,
exprs: Vec<MirScalarExpr>,
},
Filter {
input: Box<MirRelationExpr>,
predicates: Vec<MirScalarExpr>,
},
Join {
inputs: Vec<MirRelationExpr>,
equivalences: Vec<Vec<MirScalarExpr>>,
implementation: JoinImplementation,
},
Reduce {
input: Box<MirRelationExpr>,
group_key: Vec<MirScalarExpr>,
aggregates: Vec<AggregateExpr>,
monotonic: bool,
expected_group_size: Option<u64>,
},
TopK {
input: Box<MirRelationExpr>,
group_key: Vec<usize>,
order_key: Vec<ColumnOrder>,
limit: Option<MirScalarExpr>,
offset: usize,
monotonic: bool,
expected_group_size: Option<u64>,
},
Negate {
input: Box<MirRelationExpr>,
},
Threshold {
input: Box<MirRelationExpr>,
},
Union {
base: Box<MirRelationExpr>,
inputs: Vec<MirRelationExpr>,
},
ArrangeBy {
input: Box<MirRelationExpr>,
keys: Vec<Vec<MirScalarExpr>>,
},
}
Expand description
An abstract syntax tree which defines a collection.
The AST is meant to reflect the capabilities of the differential_dataflow::Collection
type,
written generically enough to avoid run-time compilation work.
derived_hash_with_manual_eq
was complaining for the wrong reason: This lint exists because
it’s bad when Eq
doesn’t agree with Hash
, which is often quite likely if one of them is
implemented manually. However, our manual implementation of Eq
will agree with the derived
one. This is because the reason for the manual implementation is not to change the semantics
from the derived one, but to avoid stack overflows.
Variants§
Constant
A constant relation containing specified rows.
The runtime memory footprint of this operator is zero.
When you would like to pattern match on this, consider using MirRelationExpr::as_const
instead, which looks behind ArrangeBy
s. You might want this matching behavior because
constant folding doesn’t remove ArrangeBy
s.
Fields
typ: RelationType
Schema of the collection.
Get
Get an existing dataflow.
The runtime memory footprint of this operator is zero.
Fields
typ: RelationType
Schema of the collection.
access_strategy: AccessStrategy
If this is a global Get, this will indicate whether we are going to read from Persist or
from an index, or from a different object in objects_to_build
. If it’s an index, then
how downstream dataflow operations will use this index is also recorded. This is filled
by prune_and_annotate_dataflow_index_imports
. Note that this is not used by the
lowering to LIR, but is used only by EXPLAIN.
Let
Introduce a temporary dataflow.
The runtime memory footprint of this operator is zero.
Fields
value: Box<MirRelationExpr>
The collection to be bound to id
.
body: Box<MirRelationExpr>
The result of the Let
, evaluated with id
bound to value
.
LetRec
Introduce mutually recursive bindings.
Each LocalId
is immediately bound to an initially empty collection
with the type of its corresponding MirRelationExpr
. Repeatedly, each
binding is evaluated using the current contents of each other binding,
and is refreshed to contain the new evaluation. This process continues
through all bindings, and repeats as long as changes continue to occur.
The resulting value of the expression is body
evaluated once in the
context of the final iterates.
A zero-binding instance can be replaced by body
.
A single-binding instance is equivalent to MirRelationExpr::Let
.
The runtime memory footprint of this operator is zero.
Fields
values: Vec<MirRelationExpr>
The collections to be bound to each id
.
limits: Vec<Option<LetRecLimit>>
Maximum number of iterations, after which we should artificially force a fixpoint.
(Whether we error or just stop is configured by LetRecLimit::return_at_limit
.)
The per-LetRec
limit that the user specified is initially copied to each binding to
accommodate slicing and merging of LetRec
s in MIR transforms (e.g., NormalizeLets
).
body: Box<MirRelationExpr>
The result of the Let
, evaluated with id
bound to value
.
Project
Project out some columns from a dataflow
The runtime memory footprint of this operator is zero.
Fields
input: Box<MirRelationExpr>
The source collection.
Map
Append new columns to a dataflow
The runtime memory footprint of this operator is zero.
Fields
input: Box<MirRelationExpr>
The source collection.
scalars: Vec<MirScalarExpr>
Expressions which determine values to append to each row.
An expression may refer to columns in input
or
expressions defined earlier in the vector
FlatMap
Like Map, but yields zero-or-more output rows per input row
The runtime memory footprint of this operator is zero.
Fields
input: Box<MirRelationExpr>
The source collection
exprs: Vec<MirScalarExpr>
The argument to the table func
Filter
Keep rows from a dataflow where all the predicates are true
The runtime memory footprint of this operator is zero.
Fields
input: Box<MirRelationExpr>
The source collection.
predicates: Vec<MirScalarExpr>
Predicates, each of which must be true.
Join
Join several collections, where some columns must be equal.
For further details consult the documentation for MirRelationExpr::join
.
The runtime memory footprint of this operator can be proportional to the sizes of all inputs and the size of all joins of prefixes. This may be reduced due to arrangements available at rendering time.
Fields
inputs: Vec<MirRelationExpr>
A sequence of input relations.
equivalences: Vec<Vec<MirScalarExpr>>
A sequence of equivalence classes of expressions on the cross product of inputs.
Each equivalence class is a list of scalar expressions, where for each class the intended interpretation is that all evaluated expressions should be equal.
Each scalar expression is to be evaluated over the cross-product of all records from all inputs. In many cases this may just be column selection from specific inputs, but more general cases exist (e.g. complex functions of multiple columns from multiple inputs, or just constant literals).
implementation: JoinImplementation
Join implementation information.
Reduce
Group a dataflow by some columns and aggregate over each group
The runtime memory footprint of this operator is at most proportional to the number of distinct records in the input and output. The actual requirements can be less: the number of distinct inputs to each aggregate, summed across each aggregate, plus the output size. For more details consult the code that builds the associated dataflow.
Fields
input: Box<MirRelationExpr>
The source collection.
group_key: Vec<MirScalarExpr>
Column indices used to form groups.
aggregates: Vec<AggregateExpr>
Expressions which determine values to append to each row, after the group keys.
TopK
Groups and orders within each group, limiting output.
The runtime memory footprint of this operator is proportional to its input and output.
Fields
input: Box<MirRelationExpr>
The source collection.
order_key: Vec<ColumnOrder>
Column indices used to order rows within groups.
limit: Option<MirScalarExpr>
Number of records to retain
Negate
Return a dataflow where the row counts are negated
The runtime memory footprint of this operator is zero.
Fields
input: Box<MirRelationExpr>
The source collection.
Threshold
Keep rows from a dataflow where the row counts are positive
The runtime memory footprint of this operator is proportional to its input and output.
Fields
input: Box<MirRelationExpr>
The source collection.
Union
Adds the frequencies of elements in contained sets.
The runtime memory footprint of this operator is zero.
Fields
base: Box<MirRelationExpr>
A source collection.
inputs: Vec<MirRelationExpr>
Source collections to union.
ArrangeBy
Technically a no-op. Used to render an index. Will be used to optimize queries
on finer grain. Each keys
item represents a different index that should be
produced from the keys
.
The runtime memory footprint of this operator is proportional to its input.
Fields
input: Box<MirRelationExpr>
The source collection
keys: Vec<Vec<MirScalarExpr>>
Columns to arrange input
by, in order of decreasing primacy
Implementations§
source§impl MirRelationExpr
impl MirRelationExpr
sourcepub fn typ(&self) -> RelationType
pub fn typ(&self) -> RelationType
Reports the schema of the relation.
This method determines the type through recursive traversal of the relation expression, drawing from the types of base collections. As such, this is not an especially cheap method, and should be used judiciously.
The relation type is computed incrementally with a recursive post-order
traversal, that accumulates the input types for the relations yet to be
visited in type_stack
.
sourcepub fn typ_with_input_types(&self, input_types: &[RelationType]) -> RelationType
pub fn typ_with_input_types(&self, input_types: &[RelationType]) -> RelationType
Reports the schema of the relation given the schema of the input relations.
input_types
is required to contain the schemas for the input relations of
the current relation in the same order as they are visited by try_visit_children
method, even though not all may be used for computing the schema of the
current relation. For example, Let
expects two input types, one for the
value relation and one for the body, in that order, but only the one for the
body is used to determine the type of the Let
relation.
It is meant to be used during post-order traversals to compute relation schemas incrementally.
sourcepub fn col_with_input_cols<'a, I>(&self, input_types: I) -> Vec<ColumnType>
pub fn col_with_input_cols<'a, I>(&self, input_types: I) -> Vec<ColumnType>
Reports the column types of the relation given the column types of the input relations.
This method delegates to try_col_with_input_cols
, panicing if an Err
variant is returned.
sourcepub fn try_col_with_input_cols<'a, I>(
&self,
input_types: I,
) -> Result<Vec<ColumnType>, String>
pub fn try_col_with_input_cols<'a, I>( &self, input_types: I, ) -> Result<Vec<ColumnType>, String>
Reports the column types of the relation given the column types of the input relations.
input_types
is required to contain the column types for the input relations of
the current relation in the same order as they are visited by try_visit_children
method, even though not all may be used for computing the schema of the
current relation. For example, Let
expects two input types, one for the
value relation and one for the body, in that order, but only the one for the
body is used to determine the type of the Let
relation.
It is meant to be used during post-order traversals to compute column types incrementally.
sourcepub fn keys_with_input_keys<'a, I, J>(
&self,
input_arities: I,
input_keys: J,
) -> Vec<Vec<usize>>
pub fn keys_with_input_keys<'a, I, J>( &self, input_arities: I, input_keys: J, ) -> Vec<Vec<usize>>
Reports the unique keys of the relation given the arities and the unique keys of the input relations.
input_arities
and input_keys
are required to contain the
corresponding info for the input relations of
the current relation in the same order as they are visited by try_visit_children
method, even though not all may be used for computing the schema of the
current relation. For example, Let
expects two input types, one for the
value relation and one for the body, in that order, but only the one for the
body is used to determine the type of the Let
relation.
It is meant to be used during post-order traversals to compute unique keys incrementally.
sourcepub fn arity(&self) -> usize
pub fn arity(&self) -> usize
The number of columns in the relation.
This number is determined from the type, which is determined recursively at non-trivial cost.
The arity is computed incrementally with a recursive post-order
traversal, that accumulates the arities for the relations yet to be
visited in arity_stack
.
sourcepub fn arity_with_input_arities<I>(&self, input_arities: I) -> usize
pub fn arity_with_input_arities<I>(&self, input_arities: I) -> usize
Reports the arity of the relation given the schema of the input relations.
input_arities
is required to contain the arities for the input relations of
the current relation in the same order as they are visited by try_visit_children
method, even though not all may be used for computing the schema of the
current relation. For example, Let
expects two input types, one for the
value relation and one for the body, in that order, but only the one for the
body is used to determine the type of the Let
relation.
It is meant to be used during post-order traversals to compute arities incrementally.
sourcepub fn num_inputs(&self) -> usize
pub fn num_inputs(&self) -> usize
The number of child relations this relation has.
sourcepub fn constant(rows: Vec<Vec<Datum<'_>>>, typ: RelationType) -> Self
pub fn constant(rows: Vec<Vec<Datum<'_>>>, typ: RelationType) -> Self
Constructs a constant collection from specific rows and schema, where each row will have a multiplicity of one.
sourcepub fn constant_diff(
rows: Vec<(Vec<Datum<'_>>, Diff)>,
typ: RelationType,
) -> Self
pub fn constant_diff( rows: Vec<(Vec<Datum<'_>>, Diff)>, typ: RelationType, ) -> Self
Constructs a constant collection from specific rows and schema, where each row can have an arbitrary multiplicity.
sourcepub fn as_const(
&self,
) -> Option<(&Result<Vec<(Row, Diff)>, EvalError>, &RelationType)>
pub fn as_const( &self, ) -> Option<(&Result<Vec<(Row, Diff)>, EvalError>, &RelationType)>
If self is a constant, return the value and the type, otherwise None
.
Looks behind ArrangeBy
s.
sourcepub fn as_const_mut(
&mut self,
) -> Option<(&mut Result<Vec<(Row, Diff)>, EvalError>, &mut RelationType)>
pub fn as_const_mut( &mut self, ) -> Option<(&mut Result<Vec<(Row, Diff)>, EvalError>, &mut RelationType)>
If self is a constant, mutably return the value and the type, otherwise None
.
Looks behind ArrangeBy
s.
sourcepub fn as_const_err(&self) -> Option<&EvalError>
pub fn as_const_err(&self) -> Option<&EvalError>
If self is a constant error, return the error, otherwise None
.
Looks behind ArrangeBy
s.
sourcepub fn is_constant_singleton(&self) -> bool
pub fn is_constant_singleton(&self) -> bool
Checks if self
is the single element collection with no columns.
sourcepub fn local_get(id: LocalId, typ: RelationType) -> Self
pub fn local_get(id: LocalId, typ: RelationType) -> Self
Constructs the expression for getting a local collection.
sourcepub fn global_get(id: GlobalId, typ: RelationType) -> Self
pub fn global_get(id: GlobalId, typ: RelationType) -> Self
Constructs the expression for getting a global collection
sourcepub fn project(self, outputs: Vec<usize>) -> Self
pub fn project(self, outputs: Vec<usize>) -> Self
Retains only the columns specified by output
.
sourcepub fn map(self, scalars: Vec<MirScalarExpr>) -> Self
pub fn map(self, scalars: Vec<MirScalarExpr>) -> Self
Append to each row the results of applying elements of scalar
.
sourcepub fn map_one(self, scalar: MirScalarExpr) -> Self
pub fn map_one(self, scalar: MirScalarExpr) -> Self
Append to each row a single scalar
.
sourcepub fn flat_map(self, func: TableFunc, exprs: Vec<MirScalarExpr>) -> Self
pub fn flat_map(self, func: TableFunc, exprs: Vec<MirScalarExpr>) -> Self
Like map
, but yields zero-or-more output rows per input row
sourcepub fn filter<I>(self, predicates: I) -> Selfwhere
I: IntoIterator<Item = MirScalarExpr>,
pub fn filter<I>(self, predicates: I) -> Selfwhere
I: IntoIterator<Item = MirScalarExpr>,
Retain only the rows satisfying each of several predicates.
sourcepub fn product(self, right: Self) -> Self
pub fn product(self, right: Self) -> Self
Form the Cartesian outer-product of rows in both inputs.
sourcepub fn join(
inputs: Vec<MirRelationExpr>,
variables: Vec<Vec<(usize, usize)>>,
) -> Self
pub fn join( inputs: Vec<MirRelationExpr>, variables: Vec<Vec<(usize, usize)>>, ) -> Self
Performs a relational equijoin among the input collections.
The sequence inputs
each describe different input collections, and the sequence variables
describes
equality constraints that some of their columns must satisfy. Each element in variable
describes a set
of pairs (input_index, column_index)
where every value described by that set must be equal.
For example, the pair (input, column)
indexes into inputs[input][column]
, extracting the input
th
input collection and for each row examining its column
th column.
§Example
use mz_repr::{Datum, ColumnType, RelationType, ScalarType};
use mz_expr::MirRelationExpr;
// A common schema for each input.
let schema = RelationType::new(vec![
ScalarType::Int32.nullable(false),
ScalarType::Int32.nullable(false),
]);
// the specific data are not important here.
let data = vec![Datum::Int32(0), Datum::Int32(1)];
// Three collections that could have been different.
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());
// Join the three relations looking for triangles, like so.
//
// Output(A,B,C) := Input0(A,B), Input1(B,C), Input2(A,C)
let joined = MirRelationExpr::join(
vec![input0, input1, input2],
vec![
vec![(0,0), (2,0)], // fields A of inputs 0 and 2.
vec![(0,1), (1,0)], // fields B of inputs 0 and 1.
vec![(1,1), (2,1)], // fields C of inputs 1 and 2.
],
);
// Technically the above produces `Output(A,B,B,C,A,C)` because the columns are concatenated.
// A projection resolves this and produces the correct output.
let result = joined.project(vec![0, 1, 3]);
sourcepub fn join_scalars(
inputs: Vec<MirRelationExpr>,
equivalences: Vec<Vec<MirScalarExpr>>,
) -> Self
pub fn join_scalars( inputs: Vec<MirRelationExpr>, equivalences: Vec<Vec<MirScalarExpr>>, ) -> Self
Constructs a join operator from inputs and required-equal scalar expressions.
sourcepub fn reduce(
self,
group_key: Vec<usize>,
aggregates: Vec<AggregateExpr>,
expected_group_size: Option<u64>,
) -> Self
pub fn reduce( self, group_key: Vec<usize>, aggregates: Vec<AggregateExpr>, expected_group_size: Option<u64>, ) -> Self
Perform a key-wise reduction / aggregation.
The group_key
argument indicates columns in the input collection that should
be grouped, and aggregates
lists aggregation functions each of which produces
one output column in addition to the keys.
sourcepub fn top_k(
self,
group_key: Vec<usize>,
order_key: Vec<ColumnOrder>,
limit: Option<MirScalarExpr>,
offset: usize,
expected_group_size: Option<u64>,
) -> Self
pub fn top_k( self, group_key: Vec<usize>, order_key: Vec<ColumnOrder>, limit: Option<MirScalarExpr>, offset: usize, expected_group_size: Option<u64>, ) -> Self
Perform a key-wise reduction order by and limit.
The group_key
argument indicates columns in the input collection that should
be grouped, the order_key
argument indicates columns that should be further
used to order records within groups, and the limit
argument constrains the
total number of records that should be produced in each group.
sourcepub fn distinct_by(self, group_key: Vec<usize>) -> Self
pub fn distinct_by(self, group_key: Vec<usize>) -> Self
Removes all but the first occurrence of each key. Columns not included
in the group_key
are discarded.
sourcepub fn union_many(inputs: Vec<Self>, typ: RelationType) -> Self
pub fn union_many(inputs: Vec<Self>, typ: RelationType) -> Self
Unions together any number inputs.
If inputs
is empty, then an empty relation of type typ
is
constructed.
sourcepub fn union(self, other: Self) -> Self
pub fn union(self, other: Self) -> Self
Produces one collection where each row is present with the sum of its frequencies in each input.
sourcepub fn arrange_by(self, keys: &[Vec<MirScalarExpr>]) -> Self
pub fn arrange_by(self, keys: &[Vec<MirScalarExpr>]) -> Self
Arranges the collection by the specified columns
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Indicates if this is a constant empty collection.
A false value does not mean the collection is known to be non-empty, only that we cannot currently determine that it is statically empty.
sourcepub fn is_negated_project(&self) -> Option<(&MirRelationExpr, &[usize])>
pub fn is_negated_project(&self) -> Option<(&MirRelationExpr, &[usize])>
If the expression is a negated project, return the input and the projection.
sourcepub fn pretty(&self) -> String
pub fn pretty(&self) -> String
Pretty-print this MirRelationExpr to a string.
sourcepub fn explain(
&self,
config: &ExplainConfig,
humanizer: Option<&dyn ExprHumanizer>,
) -> String
pub fn explain( &self, config: &ExplainConfig, humanizer: Option<&dyn ExprHumanizer>, ) -> String
Pretty-print this MirRelationExpr to a string using a custom ExplainConfig and an optionally provided ExprHumanizer.
sourcepub fn take_safely(&mut self) -> MirRelationExpr
pub fn take_safely(&mut self) -> MirRelationExpr
Take ownership of self
, leaving an empty MirRelationExpr::Constant
with the correct type.
sourcepub fn take_dangerous(&mut self) -> MirRelationExpr
pub fn take_dangerous(&mut self) -> MirRelationExpr
Take ownership of self
, leaving an empty MirRelationExpr::Constant
with an incorrect type.
This should only be used if self
is about to be dropped or otherwise overwritten.
sourcepub fn replace_using<F>(&mut self, logic: F)
pub fn replace_using<F>(&mut self, logic: F)
Replaces self
with some logic applied to self
.
sourcepub fn let_in<Body, E>(
self,
id_gen: &mut IdGen,
body: Body,
) -> Result<MirRelationExpr, E>
pub fn let_in<Body, E>( self, id_gen: &mut IdGen, body: Body, ) -> Result<MirRelationExpr, E>
Store self
in a Let
and pass the corresponding Get
to body
.
sourcepub fn anti_lookup<E>(
self,
id_gen: &mut IdGen,
keys_and_values: MirRelationExpr,
default: Vec<(Datum<'_>, ScalarType)>,
) -> Result<MirRelationExpr, E>
pub fn anti_lookup<E>( self, id_gen: &mut IdGen, keys_and_values: MirRelationExpr, default: Vec<(Datum<'_>, ScalarType)>, ) -> Result<MirRelationExpr, E>
Return every row in self
that does not have a matching row in the first columns of keys_and_values
, using default
to fill in the remaining columns
(If default
is a row of nulls, this is the ‘outer’ part of LEFT OUTER JOIN)
sourcepub fn lookup<E>(
self,
id_gen: &mut IdGen,
keys_and_values: MirRelationExpr,
default: Vec<(Datum<'static>, ScalarType)>,
) -> Result<MirRelationExpr, E>
pub fn lookup<E>( self, id_gen: &mut IdGen, keys_and_values: MirRelationExpr, default: Vec<(Datum<'static>, ScalarType)>, ) -> Result<MirRelationExpr, E>
Return:
- every row in keys_and_values
- every row in
self
that does not have a matching row in the first columns ofkeys_and_values
, usingdefault
to fill in the remaining columns (This is LEFT OUTER JOIN if:
default
is a row of null- matching rows in
keys_and_values
andself
have the same multiplicity.)
sourcepub fn contains_temporal(&self) -> bool
pub fn contains_temporal(&self) -> bool
True iff the expression contains a NullaryFunc::MzLogicalTimestamp
.
sourcepub fn try_visit_scalars_mut1<F, E>(&mut self, f: &mut F) -> Result<(), E>
pub fn try_visit_scalars_mut1<F, E>(&mut self, f: &mut F) -> Result<(), E>
Fallible visitor for the MirScalarExpr
s directly owned by this relation expression.
The f
visitor should not recursively descend into owned MirRelationExpr
s.
sourcepub fn try_visit_scalars_mut<F, E>(&mut self, f: &mut F) -> Result<(), E>
pub fn try_visit_scalars_mut<F, E>(&mut self, f: &mut F) -> Result<(), E>
Fallible mutable visitor for the MirScalarExpr
s in the MirRelationExpr
subtree
rooted at self
.
Note that this does not recurse into MirRelationExpr
subtrees within MirScalarExpr
nodes.
sourcepub fn visit_scalars_mut<F>(&mut self, f: &mut F)where
F: FnMut(&mut MirScalarExpr),
pub fn visit_scalars_mut<F>(&mut self, f: &mut F)where
F: FnMut(&mut MirScalarExpr),
Infallible mutable visitor for the MirScalarExpr
s in the MirRelationExpr
subtree
rooted at self
.
Note that this does not recurse into MirRelationExpr
subtrees within MirScalarExpr
nodes.
sourcepub fn try_visit_scalars_1<F, E>(&self, f: &mut F) -> Result<(), E>
pub fn try_visit_scalars_1<F, E>(&self, f: &mut F) -> Result<(), E>
Fallible visitor for the MirScalarExpr
s directly owned by this relation expression.
The f
visitor should not recursively descend into owned MirRelationExpr
s.
sourcepub fn try_visit_scalars<F, E>(&self, f: &mut F) -> Result<(), E>
pub fn try_visit_scalars<F, E>(&self, f: &mut F) -> Result<(), E>
Fallible immutable visitor for the MirScalarExpr
s in the MirRelationExpr
subtree
rooted at self
.
Note that this does not recurse into MirRelationExpr
subtrees within MirScalarExpr
nodes.
sourcepub fn visit_scalars<F>(&self, f: &mut F)where
F: FnMut(&MirScalarExpr),
pub fn visit_scalars<F>(&self, f: &mut F)where
F: FnMut(&MirScalarExpr),
Infallible immutable visitor for the MirScalarExpr
s in the MirRelationExpr
subtree
rooted at self
.
Note that this does not recurse into MirRelationExpr
subtrees within MirScalarExpr
nodes.
sourcepub fn destroy_carefully(&mut self)
pub fn destroy_carefully(&mut self)
Clears the contents of self
even if it’s so deep that simply dropping it would cause a
stack overflow in drop_in_place
.
Leaves self
in an unusable state, so this should only be used if self
is about to be
dropped or otherwise overwritten.
sourcepub fn debug_size_and_depth(&self) -> (usize, usize)
pub fn debug_size_and_depth(&self) -> (usize, usize)
Computes the size (total number of nodes) and maximum depth of a MirRelationExpr for debug printing purposes.
sourcepub fn could_run_expensive_function(&self) -> bool
pub fn could_run_expensive_function(&self) -> bool
The MirRelationExpr is considered potentially expensive if and only if at least one of the following conditions is true:
- It contains at least one FlatMap or a Reduce operator.
- It contains at least one MirScalarExpr with a function call.
!!!WARNING!!!: this method has an HirRelationExpr counterpart. The two should be kept in sync w.r.t. HIR ⇒ MIR lowering!
sourcepub fn hash_to_u64(&self) -> u64
pub fn hash_to_u64(&self) -> u64
Hash to an u64 using Rust’s default Hasher. (Which is a somewhat slower, but better Hasher
than what Hashable::hashed
would give us.)
source§impl MirRelationExpr
impl MirRelationExpr
sourcepub fn is_recursive(self: &MirRelationExpr) -> bool
pub fn is_recursive(self: &MirRelationExpr) -> bool
True when expr
contains a LetRec
AST node.
sourcepub fn recursive_ids(
ids: &[LocalId],
values: &[MirRelationExpr],
) -> BTreeSet<LocalId>
pub fn recursive_ids( ids: &[LocalId], values: &[MirRelationExpr], ) -> BTreeSet<LocalId>
Given the ids and values of a LetRec, it computes the subset of ids that are used across iterations. These are those ids that have a reference before they are defined, when reading all the bindings in order.
For example:
WITH MUTUALLY RECURSIVE
x(...) AS f(z),
y(...) AS g(x),
z(...) AS h(y)
...;
Here, only z
is returned, because x
and y
are referenced only within the same
iteration.
Note that if a binding references itself, that is also returned.
sourcepub fn make_nonrecursive(self: &mut MirRelationExpr)
pub fn make_nonrecursive(self: &mut MirRelationExpr)
Replaces LetRec
nodes with a stack of Let
nodes.
In each Let
binding, uses of Get
in value
that are not at strictly greater
identifiers are rewritten to be the constant collection.
This makes the computation perform exactly “one” iteration.
This was used only temporarily while developing LetRec
.
sourcepub fn collect_expirations(
id: LocalId,
expr: &MirRelationExpr,
expire_whens: &mut BTreeMap<LocalId, Vec<LocalId>>,
)
pub fn collect_expirations( id: LocalId, expr: &MirRelationExpr, expire_whens: &mut BTreeMap<LocalId, Vec<LocalId>>, )
For each Id id'
referenced in expr
, if it is larger or equal than id
, then record in
expire_whens
that when id'
is redefined, then we should expire the information that
we are holding about id
. Call do_expirations
with expire_whens
at each Id
redefinition.
IMPORTANT: Relies on the numbering of Ids to be what renumber_bindings
gives.
sourcepub fn do_expirations<I>(
redefined_id: LocalId,
expire_whens: &mut BTreeMap<LocalId, Vec<LocalId>>,
id_infos: &mut BTreeMap<LocalId, I>,
) -> Vec<(LocalId, I)>
pub fn do_expirations<I>( redefined_id: LocalId, expire_whens: &mut BTreeMap<LocalId, Vec<LocalId>>, id_infos: &mut BTreeMap<LocalId, I>, ) -> Vec<(LocalId, I)>
Call this function when id
is redefined. It modifies id_infos
by removing information
about such Ids whose information depended on the earlier definition of id
, according to
expire_whens
. Also modifies expire_whens
: it removes the currently processed entry.
source§impl MirRelationExpr
impl MirRelationExpr
sourcepub fn children(&self) -> impl DoubleEndedIterator<Item = &Self>
pub fn children(&self) -> impl DoubleEndedIterator<Item = &Self>
Iterates through references to child expressions.
sourcepub fn children_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Self>
pub fn children_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Self>
Iterates through mutable references to child expressions.
sourcepub fn visit_pre_mut<F: FnMut(&mut Self)>(&mut self, f: F)
pub fn visit_pre_mut<F: FnMut(&mut Self)>(&mut self, f: F)
Iterative pre-order visitor.
sourcepub fn post_order_vec(&self) -> Vec<&Self>
pub fn post_order_vec(&self) -> Vec<&Self>
Return a vector of references to the subtrees of this expression
in post-visit order (the last element is &self
).
source§impl MirRelationExpr
impl MirRelationExpr
fn fmt_virtual_syntax( &self, f: &mut Formatter<'_>, ctx: &mut PlanRenderingContext<'_, MirRelationExpr>, ) -> Result
fn fmt_raw_syntax( &self, f: &mut Formatter<'_>, ctx: &mut PlanRenderingContext<'_, MirRelationExpr>, ) -> Result
fn fmt_attributes( &self, f: &mut Formatter<'_>, ctx: &PlanRenderingContext<'_, MirRelationExpr>, ) -> Result
fn column_names<'a>( &'a self, ctx: &'a PlanRenderingContext<'_, MirRelationExpr>, ) -> Option<&Vec<String>>
pub fn fmt_indexed_filter<'a, T>( f: &mut Formatter<'_>, ctx: &mut PlanRenderingContext<'a, T>, coll_id: &GlobalId, idx_id: &GlobalId, constants: Option<Vec<Row>>, cse_id: Option<&LocalId>, ) -> Result
source§impl<'a> MirRelationExpr
impl<'a> MirRelationExpr
fn as_explain_single_plan( &'a mut self, context: &'a ExplainContext<'a>, ) -> Result<ExplainSinglePlan<'a, MirRelationExpr>, ExplainError>
Trait Implementations§
source§impl Arbitrary for MirRelationExpr
impl Arbitrary for MirRelationExpr
§type Parameters = ()
type Parameters = ()
arbitrary_with
accepts for configuration
of the generated Strategy
. Parameters must implement Default
.source§fn arbitrary_with((): Self::Parameters) -> Self::Strategy
fn arbitrary_with((): Self::Parameters) -> Self::Strategy
§type Strategy = BoxedStrategy<MirRelationExpr>
type Strategy = BoxedStrategy<MirRelationExpr>
Strategy
used to generate values of type Self
.source§impl Clone for MirRelationExpr
impl Clone for MirRelationExpr
source§fn clone(&self) -> MirRelationExpr
fn clone(&self) -> MirRelationExpr
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl CollectionPlan for MirRelationExpr
impl CollectionPlan for MirRelationExpr
source§impl Debug for MirRelationExpr
impl Debug for MirRelationExpr
source§impl<'de> Deserialize<'de> for MirRelationExpr
impl<'de> Deserialize<'de> for MirRelationExpr
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
source§impl DisplayText<PlanRenderingContext<'_, MirRelationExpr>> for MirRelationExpr
impl DisplayText<PlanRenderingContext<'_, MirRelationExpr>> for MirRelationExpr
EXPLAIN ... AS TEXT
support for MirRelationExpr
.
The format adheres to the following conventions:
- In general, every line corresponds to an
MirRelationExpr
node in the plan. - Non-recursive parameters of each sub-plan are written as
$key=$val
pairs on the same line. - A single non-recursive parameter can be written just as
$val
. - Exceptions in (1) can be made when virtual syntax is requested (done by
default, can be turned off with
WITH(raw_syntax)
). - Exceptions in (2) can be made when join implementations are rendered
explicitly
WITH(join_impls)
.
fn fmt_text( &self, f: &mut Formatter<'_>, ctx: &mut PlanRenderingContext<'_, MirRelationExpr>, ) -> Result
source§impl<'a> Explain<'a> for MirRelationExpr
impl<'a> Explain<'a> for MirRelationExpr
§type Context = ExplainContext<'a>
type Context = ExplainContext<'a>
§type Text = ExplainSinglePlan<'a, MirRelationExpr>
type Text = ExplainSinglePlan<'a, MirRelationExpr>
Explain::explain_text
call.§type Json = ExplainSinglePlan<'a, MirRelationExpr>
type Json = ExplainSinglePlan<'a, MirRelationExpr>
Explain::explain_json
call.§type Dot = UnsupportedFormat
type Dot = UnsupportedFormat
Explain::explain_json
call.source§fn explain_text(
&'a mut self,
context: &'a Self::Context,
) -> Result<Self::Text, ExplainError>
fn explain_text( &'a mut self, context: &'a Self::Context, ) -> Result<Self::Text, ExplainError>
source§fn explain_json(
&'a mut self,
context: &'a Self::Context,
) -> Result<Self::Json, ExplainError>
fn explain_json( &'a mut self, context: &'a Self::Context, ) -> Result<Self::Json, ExplainError>
source§fn explain(
&'a mut self,
format: &'a ExplainFormat,
context: &'a Self::Context,
) -> Result<String, ExplainError>
fn explain( &'a mut self, format: &'a ExplainFormat, context: &'a Self::Context, ) -> Result<String, ExplainError>
source§fn explain_dot(
&'a mut self,
context: &'a Self::Context,
) -> Result<Self::Dot, ExplainError>
fn explain_dot( &'a mut self, context: &'a Self::Context, ) -> Result<Self::Dot, ExplainError>
source§impl Hash for MirRelationExpr
impl Hash for MirRelationExpr
source§impl MzReflect for MirRelationExpr
impl MzReflect for MirRelationExpr
source§fn add_to_reflected_type_info(rti: &mut ReflectedTypeInfo)
fn add_to_reflected_type_info(rti: &mut ReflectedTypeInfo)
rti
. Read moresource§impl Ord for MirRelationExpr
impl Ord for MirRelationExpr
source§fn cmp(&self, other: &MirRelationExpr) -> Ordering
fn cmp(&self, other: &MirRelationExpr) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
source§impl PartialEq for MirRelationExpr
impl PartialEq for MirRelationExpr
source§impl PartialOrd for MirRelationExpr
impl PartialOrd for MirRelationExpr
source§impl Serialize for MirRelationExpr
impl Serialize for MirRelationExpr
source§impl VisitChildren<MirRelationExpr> for MirRelationExpr
impl VisitChildren<MirRelationExpr> for MirRelationExpr
source§fn visit_children<F>(&self, f: F)
fn visit_children<F>(&self, f: F)
f
to each direct child.source§fn visit_mut_children<F>(&mut self, f: F)
fn visit_mut_children<F>(&mut self, f: F)
f
to each direct child.impl Eq for MirRelationExpr
Auto Trait Implementations§
impl Freeze for MirRelationExpr
impl RefUnwindSafe for MirRelationExpr
impl Send for MirRelationExpr
impl Sync for MirRelationExpr
impl Unpin for MirRelationExpr
impl UnwindSafe for MirRelationExpr
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<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.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> 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::Request
source§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> Pointable for T
impl<T> Pointable for T
source§impl<T> PreferredContainer for T
impl<T> PreferredContainer for T
source§impl<T> ProgressEventTimestamp for T
impl<T> ProgressEventTimestamp for T
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
.source§impl<T> Visit for Twhere
T: VisitChildren<T>,
impl<T> Visit for Twhere
T: VisitChildren<T>,
source§fn visit_post<F>(&self, f: &mut F) -> Result<(), RecursionLimitError>
fn visit_post<F>(&self, f: &mut F) -> Result<(), RecursionLimitError>
self
.source§fn visit_post_nolimit<F>(&self, f: &mut F)
fn visit_post_nolimit<F>(&self, f: &mut F)
visit_post
instead.self
.
Does not enforce a recursion limit.source§fn visit_mut_post<F>(&mut self, f: &mut F) -> Result<(), RecursionLimitError>
fn visit_mut_post<F>(&mut self, f: &mut F) -> Result<(), RecursionLimitError>
self
.source§fn visit_mut_post_nolimit<F>(&mut self, f: &mut F)
fn visit_mut_post_nolimit<F>(&mut self, f: &mut F)
visit_mut_post
instead.self
.
Does not enforce a recursion limit.source§fn try_visit_post<F, E>(&self, f: &mut F) -> Result<(), E>
fn try_visit_post<F, E>(&self, f: &mut F) -> Result<(), E>
self
.source§fn try_visit_mut_post<F, E>(&mut self, f: &mut F) -> Result<(), E>
fn try_visit_mut_post<F, E>(&mut self, f: &mut F) -> Result<(), E>
self
.source§fn visit_pre<F>(&self, f: &mut F) -> Result<(), RecursionLimitError>
fn visit_pre<F>(&self, f: &mut F) -> Result<(), RecursionLimitError>
self
.source§fn visit_pre_with_context<Context, AccFun, Visitor>(
&self,
init: Context,
acc_fun: &mut AccFun,
visitor: &mut Visitor,
) -> Result<(), RecursionLimitError>
fn visit_pre_with_context<Context, AccFun, Visitor>( &self, init: Context, acc_fun: &mut AccFun, visitor: &mut Visitor, ) -> Result<(), RecursionLimitError>
self
, which also accumulates context
information along the path from the root to the current node’s parent.
acc_fun
is a similar closure as in fold
. The accumulated context is passed to the
visitor, along with the current node. Read moresource§fn visit_pre_nolimit<F>(&self, f: &mut F)
fn visit_pre_nolimit<F>(&self, f: &mut F)
visit_pre
instead.self
.
Does not enforce a recursion limit.source§fn visit_mut_pre<F>(&mut self, f: &mut F) -> Result<(), RecursionLimitError>
fn visit_mut_pre<F>(&mut self, f: &mut F) -> Result<(), RecursionLimitError>
self
.source§fn visit_mut_pre_nolimit<F>(&mut self, f: &mut F)
fn visit_mut_pre_nolimit<F>(&mut self, f: &mut F)
visit_mut_pre
instead.self
.
Does not enforce a recursion limit.source§fn try_visit_pre<F, E>(&self, f: &mut F) -> Result<(), E>
fn try_visit_pre<F, E>(&self, f: &mut F) -> Result<(), E>
self
.source§fn try_visit_mut_pre<F, E>(&mut self, f: &mut F) -> Result<(), E>
fn try_visit_mut_pre<F, E>(&mut self, f: &mut F) -> Result<(), E>
self
.source§fn visit_pre_post<F1, F2>(
&self,
pre: &mut F1,
post: &mut F2,
) -> Result<(), RecursionLimitError>
fn visit_pre_post<F1, F2>( &self, pre: &mut F1, post: &mut F2, ) -> Result<(), RecursionLimitError>
source§fn visit_pre_post_nolimit<F1, F2>(&self, pre: &mut F1, post: &mut F2)
fn visit_pre_post_nolimit<F1, F2>(&self, pre: &mut F1, post: &mut F2)
visit
instead.Visit::visit_pre
and Visit::visit_post
.
Does not enforce a recursion limit. Read moresource§fn visit_mut_pre_post<F1, F2>(
&mut self,
pre: &mut F1,
post: &mut F2,
) -> Result<(), RecursionLimitError>
fn visit_mut_pre_post<F1, F2>( &mut self, pre: &mut F1, post: &mut F2, ) -> Result<(), RecursionLimitError>
visit_mut
instead.source§fn visit_mut_pre_post_nolimit<F1, F2>(&mut self, pre: &mut F1, post: &mut F2)
fn visit_mut_pre_post_nolimit<F1, F2>(&mut self, pre: &mut F1, post: &mut F2)
visit_mut_pre_post
instead.Visit::visit_mut_pre
and Visit::visit_mut_post
.
Does not enforce a recursion limit. Read more