MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / action

Method action

src/transform/src/predicate_pushdown.rs:159–799  ·  view source on GitHub ↗

Predicate pushdown This method looks for opportunities to push predicates toward sources of data. Primarily, this is the `Filter` expression, and moving its predicates through the operators it contains. In addition, the method accumulates the intersection of predicates applied to each `Get` expression, so that the predicate can then be pushed through to a `Let` binding, or to the external source

(
        &self,
        relation: &mut MirRelationExpr,
        get_predicates: &mut BTreeMap<Id, BTreeSet<MirScalarExpr>>,
    )

Source from the content-addressed store, hash-verified

157 /// then be pushed through to a `Let` binding, or to the external
158 /// source of the data if the `Get` binds to another view.
159 pub fn action(
160 &self,
161 relation: &mut MirRelationExpr,
162 get_predicates: &mut BTreeMap<Id, BTreeSet<MirScalarExpr>>,
163 ) -> Result<(), TransformError> {
164 self.checked_recur(|_| {
165 // In the case of Filter or Get we have specific work to do;
166 // otherwise we should recursively descend.
167 match relation {
168 MirRelationExpr::Filter { input, predicates } => {
169 // Reduce the predicates to determine as best as possible
170 // whether they are literal errors before working with them.
171 let input_type = input.typ();
172 for predicate in predicates.iter_mut() {
173 predicate.reduce(&input_type.column_types);
174 }
175
176 // It can be helpful to know if there are any non-literal errors,
177 // as this is justification for not pushing down literal errors.
178 let all_errors = predicates.iter().all(|p| p.is_literal_err());
179 // Depending on the type of `input` we have different
180 // logic to apply to consider pushing `predicates` down.
181 match &mut **input {
182 MirRelationExpr::Let { body, .. }
183 | MirRelationExpr::LetRec { body, .. } => {
184 // Push all predicates to the body.
185 **body = body
186 .take_dangerous()
187 .filter(std::mem::replace(predicates, Vec::new()));
188
189 self.action(input, get_predicates)?;
190 }
191 MirRelationExpr::Get { id, .. } => {
192 // We can report the predicates upward in `get_predicates`,
193 // but we are not yet able to delete them from the
194 // `Filter`.
195 get_predicates
196 .entry(*id)
197 .or_insert_with(|| predicates.iter().cloned().collect())
198 .retain(|p| predicates.contains(p));
199 }
200 MirRelationExpr::Join {
201 inputs,
202 equivalences,
203 ..
204 } => {
205 // We want to scan `predicates` for any that can
206 // 1) become join variable constraints
207 // 2) apply to individual elements of `inputs`.
208 // Figuring out the set of predicates that belong to
209 // the latter group requires 1) knowing which predicates
210 // are in the former group and 2) that the variable
211 // constraints be in canonical form.
212 // Thus, there is a first scan across `predicates` to
213 // populate the join variable constraints
214 // and a second scan across the remaining predicates
215 // to see which ones can become individual elements of
216 // `inputs`.

Callers 1

Calls 15

takeFunction · 0.85
checked_recurMethod · 0.80
allMethod · 0.80
take_dangerousMethod · 0.80
lookup_inputsMethod · 0.80
visit_mut_postMethod · 0.80
support_intoMethod · 0.80
is_subsetMethod · 0.80
partitionMethod · 0.80
take_safelyMethod · 0.80
typ_with_input_typesMethod · 0.80

Tested by

no test coverage detected