Skip to content

Commit f8511db

Browse files
committed
Improve the datafusion explain output
1 parent 797da3f commit f8511db

File tree

1 file changed

+89
-5
lines changed

1 file changed

+89
-5
lines changed

crates/storage-query-datafusion/src/table_providers.rs

Lines changed: 89 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
// the Business Source License, use of this software will be governed
99
// by the Apache License, Version 2.0.
1010
use std::any::Any;
11-
use std::fmt::{Debug, Formatter};
11+
use std::fmt::{self, Debug, Display, Formatter};
1212
use std::ops::RangeInclusive;
1313
use std::sync::Arc;
1414

@@ -403,10 +403,36 @@ where
403403
fn fmt_as(&self, t: DisplayFormatType, f: &mut Formatter) -> std::fmt::Result {
404404
match t {
405405
DisplayFormatType::Default | DisplayFormatType::Verbose => {
406-
write!(f, "PartitionedExecutionPlan({:?})", self.scanner)
406+
write!(
407+
f,
408+
"PartitionedExecutionPlan: scanner={:?}, partitions={}, projection=[{}]",
409+
self.scanner,
410+
self.logical_partitions.len(),
411+
ProjectedColumns(&self.projected_schema),
412+
)?;
413+
if let Some(predicate) = &self.predicate {
414+
write!(f, ", predicate={predicate}")?;
415+
}
416+
if let Some(limit) = self.limit {
417+
write!(f, ", limit={limit}")?;
418+
}
419+
Ok(())
407420
}
408421
DisplayFormatType::TreeRender => {
409-
write!(f, "PartitionedExecutionPlan\nscanner={:?}", self.scanner)
422+
writeln!(f, "scanner={:?}", self.scanner)?;
423+
writeln!(f, "partitions={}", self.logical_partitions.len())?;
424+
writeln!(
425+
f,
426+
"projection=[{}]",
427+
ProjectedColumns(&self.projected_schema)
428+
)?;
429+
if let Some(predicate) = &self.predicate {
430+
writeln!(f, "predicate={predicate}")?;
431+
}
432+
if let Some(limit) = self.limit {
433+
writeln!(f, "limit={limit}")?;
434+
}
435+
Ok(())
410436
}
411437
}
412438
}
@@ -595,11 +621,69 @@ impl DisplayAs for GenericExecutionPlan {
595621
fn fmt_as(&self, t: DisplayFormatType, f: &mut Formatter) -> std::fmt::Result {
596622
match t {
597623
DisplayFormatType::Default | DisplayFormatType::Verbose => {
598-
write!(f, "GenericExecutionPlan()",)
624+
write!(
625+
f,
626+
"GenericExecutionPlan: scanner={:?}, projection=[{}]",
627+
self.scanner,
628+
ProjectedColumns(&self.projected_schema),
629+
)?;
630+
if !self.filters.is_empty() {
631+
write!(f, ", filters=[{}]", ExprList(&self.filters))?;
632+
}
633+
if let Some(limit) = self.limit {
634+
write!(f, ", limit={limit}")?;
635+
}
636+
Ok(())
599637
}
600638
DisplayFormatType::TreeRender => {
601-
write!(f, "GenericExecutionPlan()",)
639+
writeln!(f, "scanner={:?}", self.scanner)?;
640+
writeln!(
641+
f,
642+
"projection=[{}]",
643+
ProjectedColumns(&self.projected_schema)
644+
)?;
645+
if !self.filters.is_empty() {
646+
writeln!(f, "filters=[{}]", ExprList(&self.filters))?;
647+
}
648+
if let Some(limit) = self.limit {
649+
writeln!(f, "limit={limit}")?;
650+
}
651+
Ok(())
652+
}
653+
}
654+
}
655+
}
656+
657+
/// Display helper: comma-separated column names from a schema.
658+
struct ProjectedColumns<'a>(&'a SchemaRef);
659+
660+
impl Display for ProjectedColumns<'_> {
661+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
662+
let mut first = true;
663+
for field in self.0.fields() {
664+
if !first {
665+
write!(f, ", ")?;
666+
}
667+
write!(f, "{}", field.name())?;
668+
first = false;
669+
}
670+
Ok(())
671+
}
672+
}
673+
674+
/// Display helper: comma-separated logical expressions.
675+
struct ExprList<'a>(&'a [Expr]);
676+
677+
impl Display for ExprList<'_> {
678+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
679+
let mut first = true;
680+
for expr in self.0 {
681+
if !first {
682+
write!(f, ", ")?;
602683
}
684+
write!(f, "{expr}")?;
685+
first = false;
603686
}
687+
Ok(())
604688
}
605689
}

0 commit comments

Comments
 (0)