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

Method applied_to

src/sql/src/plan/lowering.rs:243–948  ·  view source on GitHub ↗

Return a `MirRelationExpr` which evaluates `self` once for each row of `get_outer`. For uncorrelated `self`, this should be the cross-product between `get_outer` and `self`. When `self` references columns of `get_outer`, much more work needs to occur. The `col_map` argument contains mappings to some of the columns of `get_outer`, though perhaps not all of them. It should be used as the basis of

(
        self,
        id_gen: &mut mz_ore::id_gen::IdGen,
        get_outer: MirRelationExpr,
        col_map: &ColumnMap,
        cte_map: &mut CteMap,
        context: &Context,
    )

Source from the content-addressed store, hash-verified

241 /// The `get_outer` expression should be a `Get` with no duplicate rows, describing the distinct
242 /// assignment of values to outer rows.
243 fn applied_to(
244 self,
245 id_gen: &mut mz_ore::id_gen::IdGen,
246 get_outer: MirRelationExpr,
247 col_map: &ColumnMap,
248 cte_map: &mut CteMap,
249 context: &Context,
250 ) -> Result<MirRelationExpr, PlanError> {
251 maybe_grow(|| {
252 use MirRelationExpr as SR;
253
254 use HirRelationExpr::*;
255
256 if let MirRelationExpr::Get { .. } = &get_outer {
257 } else {
258 panic!(
259 "get_outer: expected a MirRelationExpr::Get, found\n{}",
260 get_outer.pretty(),
261 );
262 }
263 assert_eq!(col_map.len(), get_outer.arity());
264 Ok(match self {
265 Constant { rows, typ } => {
266 // Constant expressions are not correlated with `get_outer`, and should be cross-products.
267 get_outer.product(SR::Constant {
268 rows: Ok(rows.into_iter().map(|row| (row, Diff::ONE)).collect()),
269 typ: ReprRelationType::from(&typ),
270 })
271 }
272 Get { id, typ } => match id {
273 mz_expr::Id::Local(local_id) => {
274 let cte_desc = cte_map.get(&local_id).unwrap();
275 let get_cte = SR::Get {
276 id: mz_expr::Id::Local(cte_desc.new_id.clone()),
277 typ: cte_desc.relation_type.clone(),
278 access_strategy: AccessStrategy::UnknownOrLocal,
279 };
280 if get_outer == cte_desc.outer_relation {
281 // If the CTE was applied to the same exact relation, we can safely
282 // return a `Get` relation.
283 get_cte
284 } else {
285 // Otherwise, the new outer relation may contain more columns from some
286 // intermediate scope placed between the definition of the CTE and this
287 // reference of the CTE and/or more operations applied on top of the
288 // outer relation.
289 //
290 // An example of the latter is the following query:
291 //
292 // SELECT *
293 // FROM x,
294 // LATERAL(WITH a(m) as (SELECT max(y.a) FROM y WHERE y.a < x.a)
295 // SELECT (SELECT m FROM a) FROM y) b;
296 //
297 // When the CTE is lowered, the outer relation is `Get x`. But then,
298 // the reference of the CTE is applied to `Distinct(Join(Get x, Get y), x.*)`
299 // which has the same cardinality as `Get x`.
300 //

Callers 5

lowerMethod · 0.80
apply_scalar_subqueryFunction · 0.80
attempt_left_join_magicFunction · 0.80

Calls 15

maybe_growFunction · 0.85
branchFunction · 0.85
attempt_left_join_magicFunction · 0.85
attempt_outer_equijoinFunction · 0.85
apply_scalar_subqueryFunction · 0.85
unwrapMethod · 0.80
let_inMethod · 0.80
map_oneMethod · 0.80
output_arityMethod · 0.80
is_correlatedMethod · 0.80
enter_scopeMethod · 0.80

Tested by

no test coverage detected