1515// specific language governing permissions and limitations
1616// under the License.
1717
18- use std:: {
19- any:: Any ,
20- fmt:: Formatter ,
21- sync:: Arc ,
22- } ;
18+ use std:: { any:: Any , fmt:: Formatter , sync:: Arc } ;
2319
24- use arrow:: {
25- array:: StringArray ,
26- datatypes:: SchemaRef ,
27- record_batch:: RecordBatch ,
28- } ;
20+ use arrow:: { array:: StringArray , datatypes:: SchemaRef , record_batch:: RecordBatch } ;
2921use datafusion:: {
3022 execution:: TaskContext ,
23+ physical_expr:: EquivalenceProperties ,
3124 physical_plan:: {
25+ displayable,
3226 execution_plan:: { Boundedness , EmissionType } ,
3327 memory:: MemoryStream ,
34- ExecutionPlan , Partitioning ,
35- PlanProperties , DisplayAs , DisplayFormatType ,
36- SendableRecordBatchStream , displayable,
28+ DisplayAs , DisplayFormatType , ExecutionPlan , Partitioning , PlanProperties ,
29+ SendableRecordBatchStream ,
3730 } ,
38- physical_expr:: EquivalenceProperties ,
3931} ;
4032
4133/// Custom distributed EXPLAIN execution plan that also returns distributed plan and stages
@@ -96,7 +88,10 @@ impl DistributedExplainExec {
9688 let mut result = String :: new ( ) ;
9789 for ( i, stage) in stages. iter ( ) . enumerate ( ) {
9890 result. push_str ( & format ! ( "Stage {}:\n " , stage. stage_id) ) ;
99- result. push_str ( & format ! ( " Partition Groups: {:?}\n " , stage. partition_groups) ) ;
91+ result. push_str ( & format ! (
92+ " Partition Groups: {:?}\n " ,
93+ stage. partition_groups
94+ ) ) ;
10095 result. push_str ( & format ! ( " Full Partitions: {}\n " , stage. full_partitions) ) ;
10196 result. push_str ( " Plan:\n " ) ;
10297 let plan_display = format ! ( "{}" , displayable( stage. plan. as_ref( ) ) . indent( true ) ) ;
@@ -150,13 +145,13 @@ impl ExecutionPlan for DistributedExplainExec {
150145 _context : Arc < TaskContext > ,
151146 ) -> datafusion:: error:: Result < SendableRecordBatchStream > {
152147 let schema = self . schema . clone ( ) ;
153-
148+
154149 // Create the result data with our 4 plan types
155150 let plan_types = StringArray :: from ( vec ! [
156- "logical_plan" ,
157- "physical_plan" ,
158- "distributed_plan" ,
159- "distributed_stages"
151+ "logical_plan" ,
152+ "physical_plan" ,
153+ "distributed_plan" ,
154+ "distributed_stages" ,
160155 ] ) ;
161156 let plans = StringArray :: from ( vec ! [
162157 self . logical_plan. as_str( ) ,
@@ -165,14 +160,13 @@ impl ExecutionPlan for DistributedExplainExec {
165160 self . distributed_stages. as_str( ) ,
166161 ] ) ;
167162
168- let batch = RecordBatch :: try_new (
169- schema. clone ( ) ,
170- vec ! [ Arc :: new( plan_types) , Arc :: new( plans) ] ,
171- ) . map_err ( |e| datafusion:: error:: DataFusionError :: ArrowError ( e, None ) ) ?;
163+ let batch =
164+ RecordBatch :: try_new ( schema. clone ( ) , vec ! [ Arc :: new( plan_types) , Arc :: new( plans) ] )
165+ . map_err ( |e| datafusion:: error:: DataFusionError :: ArrowError ( e, None ) ) ?;
172166
173167 // Use MemoryStream which is designed for DataFusion execution plans
174168 let stream = MemoryStream :: try_new ( vec ! [ batch] , schema, None ) ?;
175-
169+
176170 Ok ( Box :: pin ( stream) )
177171 }
178172
@@ -182,16 +176,20 @@ impl ExecutionPlan for DistributedExplainExec {
182176}
183177
184178/// Check if this is an EXPLAIN query (but not EXPLAIN ANALYZE)
185- ///
179+ ///
186180/// This function distinguishes between:
187181/// - EXPLAIN queries (returns true) - show plan information only
188182/// - EXPLAIN ANALYZE queries (returns false) - execute and show runtime stats
189183/// - Regular queries (returns false) - normal query execution
190184pub fn is_explain_query ( query : & str ) -> bool {
191185 let query_upper = query. trim ( ) . to_uppercase ( ) ;
192186 // Must start with "EXPLAIN" followed by whitespace or end of string
193- let is_explain = query_upper. starts_with ( "EXPLAIN" ) &&
194- ( query_upper. len ( ) == 7 || query_upper. chars ( ) . nth ( 7 ) . is_some_and ( |c| c. is_whitespace ( ) ) ) ;
187+ let is_explain = query_upper. starts_with ( "EXPLAIN" )
188+ && ( query_upper. len ( ) == 7
189+ || query_upper
190+ . chars ( )
191+ . nth ( 7 )
192+ . is_some_and ( |c| c. is_whitespace ( ) ) ) ;
195193 let is_explain_analyze = query_upper. starts_with ( "EXPLAIN ANALYZE" ) ;
196194 is_explain && !is_explain_analyze
197195}
@@ -223,7 +221,7 @@ mod tests {
223221 // Test edge cases
224222 assert ! ( !is_explain_query( "" ) ) ;
225223 assert ! ( !is_explain_query( " " ) ) ;
226- assert ! ( !is_explain_query( "EXPLAINSELECT" ) ) ; // No space
224+ assert ! ( !is_explain_query( "EXPLAINSELECT" ) ) ; // No space
227225 assert ! ( is_explain_query( "EXPLAIN" ) ) ; // Just EXPLAIN
228226 }
229227}
0 commit comments