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

Method optimize

datafusion/optimizer/src/optimizer.rs:365–495  ·  view source on GitHub ↗

Optimizes the logical plan by applying optimizer rules, and invoking observer function after each call

(
        &self,
        plan: LogicalPlan,
        config: &dyn OptimizerConfig,
        mut observer: F,
    )

Source from the content-addressed store, hash-verified

363 /// Optimizes the logical plan by applying optimizer rules, and
364 /// invoking observer function after each call
365 pub fn optimize<F>(
366 &self,
367 plan: LogicalPlan,
368 config: &dyn OptimizerConfig,
369 mut observer: F,
370 ) -> Result<LogicalPlan>
371 where
372 F: FnMut(&LogicalPlan, &dyn OptimizerRule),
373 {
374 // verify LP is valid, before the first LP optimizer pass.
375 plan.check_invariants(InvariantLevel::Executable)
376 .map_err(|e| e.context("Invalid input plan before LP Optimizers"))?;
377
378 let start_time = Instant::now();
379 let options = config.options();
380 let mut new_plan = plan;
381
382 let mut previous_plans = HashSet::with_capacity(16);
383 previous_plans.insert(LogicalPlanSignature::new(&new_plan));
384
385 let starting_schema = Arc::clone(new_plan.schema());
386
387 let mut i = 0;
388 while i < options.optimizer.max_passes {
389 log_plan(&format!("Optimizer input (pass {i})"), &new_plan);
390
391 for rule in &self.rules {
392 // If skipping failed rules, copy plan before attempting to rewrite
393 // as rewriting is destructive
394 let prev_plan = options
395 .optimizer
396 .skip_failed_rules
397 .then(|| new_plan.clone());
398
399 let starting_schema = Arc::clone(new_plan.schema());
400
401 let result = match rule.apply_order() {
402 // optimizer handles recursion
403 Some(apply_order) => new_plan.rewrite_with_subqueries(
404 &mut Rewriter::new(apply_order, rule.as_ref(), config),
405 ),
406 // rule handles recursion itself
407 None => {
408 rule.rewrite(new_plan, config)
409 },
410 }
411 .and_then(|tnr| {
412 // run checks optimizer invariant checks, per optimizer rule applied
413 assert_valid_optimization(&tnr.data, &starting_schema)
414 .map_err(|e| e.context(format!("Check optimizer-specific invariants after optimizer rule: {}", rule.name())))?;
415
416 // run LP invariant checks only in debug mode for performance reasons
417 #[cfg(debug_assertions)]
418 tnr.data.check_invariants(InvariantLevel::Executable)
419 .map_err(|e| e.context(format!("Invalid (non-executable) plan after Optimizer rule: {}", rule.name())))?;
420
421 Ok(tnr)
422 });

Calls 14

newFunction · 0.85
log_planFunction · 0.85
contextMethod · 0.80
check_invariantsMethod · 0.45
optionsMethod · 0.45
insertMethod · 0.45
schemaMethod · 0.45
cloneMethod · 0.45
apply_orderMethod · 0.45
as_refMethod · 0.45