@@ -25,7 +25,7 @@ use datafusion::common::{config_err, exec_err, not_impl_err};
2525use datafusion:: datasource:: source:: DataSourceExec ;
2626use datafusion:: error:: { DataFusionError , Result } ;
2727use datafusion:: execution:: SessionStateBuilder ;
28- use datafusion:: physical_plan:: collect;
28+ use datafusion:: physical_plan:: { ExecutionPlan , collect} ;
2929use datafusion:: prelude:: * ;
3030use datafusion_distributed:: test_utils:: localhost:: LocalHostWorkerResolver ;
3131use datafusion_distributed:: test_utils:: work_unit_file_scan:: {
@@ -37,6 +37,7 @@ use datafusion_distributed::{
3737 display_plan_ascii, rewrite_distributed_plan_with_metrics,
3838} ;
3939use datafusion_distributed_benchmarks:: datasets:: { clickbench, register_tables, tpcds, tpch} ;
40+ use datafusion_distributed_benchmarks:: stats:: stats_estimation_q_error;
4041use std:: error:: Error ;
4142use std:: fs;
4243use std:: path:: PathBuf ;
@@ -88,14 +89,6 @@ pub struct RunOpt {
8889 #[ structopt( long) ]
8990 cardinality_task_sf : Option < f64 > ,
9091
91- /// Use children isolator UNIONs for distributing UNION operations.
92- #[ structopt( long) ]
93- children_isolator_unions : bool ,
94-
95- /// Turns on broadcast joins.
96- #[ structopt( long = "broadcast-joins" ) ]
97- broadcast_joins : bool ,
98-
9992 /// Collects metrics across network boundaries
10093 #[ structopt( long) ]
10194 collect_metrics : bool ,
@@ -216,9 +209,11 @@ impl RunOpt {
216209 "none" => None ,
217210 v => return config_err ! ( "Unknown compression type {v}" ) ,
218211 } ) ?
219- . with_distributed_children_isolator_unions ( self . children_isolator_unions ) ?
220- . with_distributed_broadcast_joins ( self . broadcast_joins ) ?
221- . with_distributed_metrics_collection ( self . collect_metrics || self . debug ) ?
212+ . with_distributed_children_isolator_unions ( true ) ?
213+ . with_distributed_broadcast_joins ( true ) ?
214+ . with_distributed_metrics_collection (
215+ self . collect_metrics || self . debug || self . dynamic ,
216+ ) ?
222217 . with_distributed_max_tasks_per_stage ( self . max_tasks_per_stage ) ?
223218 . with_distributed_user_codec ( WorkUnitFileScanCodec )
224219 . with_distributed_task_estimator ( WorkUnitFileScanTaskEstimator )
@@ -290,18 +285,44 @@ impl RunOpt {
290285 }
291286
292287 match self . execute_query ( ctx, query) . await {
293- Ok ( ( result, n_tasks) ) => {
288+ Ok ( ( result, n_tasks, physical_plan ) ) => {
294289 let elapsed = start. elapsed ( ) ;
295290 let ms = elapsed. as_secs_f64 ( ) * 1000.0 ;
296291 let row_count = result. iter ( ) . map ( |b| b. num_rows ( ) ) . sum ( ) ;
297- println ! (
298- "Query {id} iteration {i} took {ms:.1} ms and returned {row_count} rows"
299- ) ;
292+ let physical_plan = if self . dynamic || self . debug {
293+ rewrite_distributed_plan_with_metrics (
294+ physical_plan,
295+ DistributedMetricsFormat :: PerTask ,
296+ )
297+ . await ?
298+ } else {
299+ physical_plan
300+ } ;
301+ let stats_q_error = match self . dynamic {
302+ true => stats_estimation_q_error ( & physical_plan) ,
303+ false => None ,
304+ } ;
305+ if let Some ( q_error) = stats_q_error {
306+ println ! (
307+ "Query {id} iteration {i} took {ms:.1} ms, stats q-error {q_error:.2}x and returned {row_count} rows"
308+ ) ;
309+ } else {
310+ println ! (
311+ "Query {id} iteration {i} took {ms:.1} ms and returned {row_count} rows"
312+ ) ;
313+ }
314+ if self . debug {
315+ println ! (
316+ "=== Physical plan with metrics ===\n {}\n " ,
317+ display_plan_ascii( physical_plan. as_ref( ) , true )
318+ ) ;
319+ }
300320
301321 bench_query. iterations . push ( QueryIter {
302322 elapsed,
303323 row_count,
304324 n_tasks,
325+ stats_q_error,
305326 error : None ,
306327 } ) ;
307328 }
@@ -311,6 +332,7 @@ impl RunOpt {
311332 elapsed : Duration :: from_millis ( 0 ) ,
312333 row_count : 0 ,
313334 n_tasks : 0 ,
335+ stats_q_error : None ,
314336 error : Some ( err. to_string ( ) ) ,
315337 } ) ;
316338 continue ' outer;
@@ -327,7 +349,7 @@ impl RunOpt {
327349 & self ,
328350 ctx : & SessionContext ,
329351 sql : & str ,
330- ) -> Result < ( Vec < RecordBatch > , usize ) > {
352+ ) -> Result < ( Vec < RecordBatch > , usize , Arc < dyn ExecutionPlan > ) > {
331353 let plan = ctx. sql ( sql) . await ?;
332354 let ( state, plan) = plan. into_parts ( ) ;
333355
@@ -341,18 +363,7 @@ impl RunOpt {
341363 Ok ( Transformed :: no ( node) )
342364 } ) ?;
343365 let result = collect ( physical_plan. clone ( ) , state. task_ctx ( ) ) . await ?;
344- if self . debug {
345- let physical_plan = rewrite_distributed_plan_with_metrics (
346- physical_plan. clone ( ) ,
347- DistributedMetricsFormat :: PerTask ,
348- )
349- . await ?;
350- println ! (
351- "=== Physical plan with metrics ===\n {}\n " ,
352- display_plan_ascii( physical_plan. as_ref( ) , true )
353- ) ;
354- }
355- Ok ( ( result, n_tasks) )
366+ Ok ( ( result, n_tasks, physical_plan) )
356367 }
357368
358369 fn get_path ( & self ) -> Result < PathBuf > {
0 commit comments