MCPcopy Create free account
hub / github.com/apache/datafusion / routing_extract

Function routing_extract

datafusion/optimizer/src/extract_leaf_expressions.rs:291–340  ·  view source on GitHub ↗

Walks an expression tree top-down, extracting `MoveTowardsLeafNodes` sub-expressions and routing each to the correct per-input extractor.

(
    expr: Expr,
    extractors: &mut [LeafExpressionExtractor],
    input_column_sets: &[std::collections::HashSet<ColumnReference>],
)

Source from the content-addressed store, hash-verified

289/// Walks an expression tree top-down, extracting `MoveTowardsLeafNodes`
290/// sub-expressions and routing each to the correct per-input extractor.
291fn routing_extract(
292 expr: Expr,
293 extractors: &mut [LeafExpressionExtractor],
294 input_column_sets: &[std::collections::HashSet<ColumnReference>],
295) -> Result<Transformed<Expr>> {
296 expr.transform_down(|e| {
297 // Skip expressions already aliased with extracted expression pattern
298 if let Expr::Alias(alias) = &e
299 && alias.name.starts_with(EXTRACTED_EXPR_PREFIX)
300 {
301 return Ok(Transformed {
302 data: e,
303 transformed: false,
304 tnr: TreeNodeRecursion::Jump,
305 });
306 }
307
308 // Don't extract Alias nodes directly — preserve the alias and let
309 // transform_down recurse into the inner expression
310 if matches!(&e, Expr::Alias(_)) {
311 return Ok(Transformed::no(e));
312 }
313
314 match e.placement() {
315 ExpressionPlacement::MoveTowardsLeafNodes => {
316 if let Some(idx) = find_owning_input(&e, input_column_sets) {
317 let col_ref = extractors[idx].add_extracted(e)?;
318 Ok(Transformed::yes(col_ref))
319 } else {
320 // References columns from multiple inputs — cannot extract
321 Ok(Transformed::no(e))
322 }
323 }
324 ExpressionPlacement::Column => {
325 // Track columns that the parent node references so the
326 // extraction projection includes them as pass-through.
327 // Without this, the extraction projection would only
328 // contain __datafusion_extracted_N aliases, and the parent couldn't
329 // resolve its other column references.
330 if let Expr::Column(col) = &e
331 && let Some(idx) = find_owning_input(&e, input_column_sets)
332 {
333 extractors[idx].columns_needed.insert(col.clone());
334 }
335 Ok(Transformed::no(e))
336 }
337 _ => Ok(Transformed::no(e)),
338 }
339 })
340}
341
342/// Rewrites extraction pairs and column references from one qualifier
343/// space to another.

Callers 2

extract_from_planFunction · 0.85

Calls 6

find_owning_inputFunction · 0.85
transform_downMethod · 0.80
add_extractedMethod · 0.80
placementMethod · 0.45
insertMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…