Skip to content

Commit 12c3739

Browse files
committed
feat: Add EXPLAIN and EXPLAIN ANALYZE support to federated queries
When federating EXPLAIN or EXPLAIN ANALYZE queries, the SQL generator now correctly prefixes the unparsed federated query with EXPLAIN or EXPLAIN ANALYZE respectively. This ensures that remote databases receive the full query intent including the EXPLAIN directive. Changes: - Import Explain from datafusion::logical_expr - Detect LogicalPlan::Explain variant in VirtualExecutionPlan::final_sql() - Extract the inner plan from EXPLAIN and apply all rewrites and optimizations - Prefix the final SQL with 'EXPLAIN ' or 'EXPLAIN ANALYZE ' based on the analyze flag - Maintain all existing table rewrites, logical optimizations, and AST transformations
1 parent bff287a commit 12c3739

1 file changed

Lines changed: 32 additions & 11 deletions

File tree

  • datafusion-federation/src/sql

datafusion-federation/src/sql/mod.rs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use datafusion::{
1717
config::ConfigOptions,
1818
error::{DataFusionError, Result},
1919
execution::{context::SessionState, TaskContext},
20-
logical_expr::{Extension, LogicalPlan},
20+
logical_expr::{Explain, Extension, LogicalPlan},
2121
optimizer::{eliminate_nested_union::EliminateNestedUnion, Analyzer, AnalyzerRule, Optimizer},
2222
physical_expr::EquivalenceProperties,
2323
physical_plan::{
@@ -180,16 +180,37 @@ impl VirtualExecutionPlan {
180180
}
181181

182182
fn final_sql(&self) -> Result<String> {
183-
let plan = self.plan.clone();
184-
let known_rewrites = collect_known_rewrites(&plan)?;
185-
let plan = RewriteTableScanAnalyzer::rewrite(plan, &known_rewrites)?;
186-
let (logical_optimizers, ast_analyzers) = gather_analyzers(&plan)?;
187-
let plan = apply_logical_optimizers(plan, logical_optimizers)?;
188-
let ast = self.plan_to_statement(&plan)?;
189-
let ast = self.rewrite_with_executor_ast_analyzer(ast)?;
190-
let mut ast = apply_ast_analyzers(ast, ast_analyzers)?;
191-
RewriteMultiTableReference::rewrite(&mut ast, known_rewrites);
192-
Ok(ast.to_string())
183+
// Check if this is an EXPLAIN or EXPLAIN ANALYZE query
184+
if let LogicalPlan::Explain(explain) = &self.plan {
185+
let plan = explain.plan.as_ref().clone();
186+
let known_rewrites = collect_known_rewrites(&plan)?;
187+
let plan = RewriteTableScanAnalyzer::rewrite(plan, &known_rewrites)?;
188+
let (logical_optimizers, ast_analyzers) = gather_analyzers(&plan)?;
189+
let plan = apply_logical_optimizers(plan, logical_optimizers)?;
190+
let ast = self.plan_to_statement(&plan)?;
191+
let ast = self.rewrite_with_executor_ast_analyzer(ast)?;
192+
let mut ast = apply_ast_analyzers(ast, ast_analyzers)?;
193+
RewriteMultiTableReference::rewrite(&mut ast, known_rewrites);
194+
195+
// Prefix with EXPLAIN or EXPLAIN ANALYZE
196+
let prefix = if explain.analyze {
197+
"EXPLAIN ANALYZE "
198+
} else {
199+
"EXPLAIN "
200+
};
201+
Ok(format!("{}{}", prefix, ast.to_string()))
202+
} else {
203+
let plan = self.plan.clone();
204+
let known_rewrites = collect_known_rewrites(&plan)?;
205+
let plan = RewriteTableScanAnalyzer::rewrite(plan, &known_rewrites)?;
206+
let (logical_optimizers, ast_analyzers) = gather_analyzers(&plan)?;
207+
let plan = apply_logical_optimizers(plan, logical_optimizers)?;
208+
let ast = self.plan_to_statement(&plan)?;
209+
let ast = self.rewrite_with_executor_ast_analyzer(ast)?;
210+
let mut ast = apply_ast_analyzers(ast, ast_analyzers)?;
211+
RewriteMultiTableReference::rewrite(&mut ast, known_rewrites);
212+
Ok(ast.to_string())
213+
}
193214
}
194215

195216
fn rewrite_with_executor_ast_analyzer(

0 commit comments

Comments
 (0)