@@ -8,7 +8,7 @@ use asap_executor::{
88 runtime:: { Limits , RunContext , Scope } ,
99 values:: { Batch , Value } ,
1010} ;
11- use common:: compile_physical_asap_dag;
11+ use common:: { compile_physical_asap_dag, selected_dag } ;
1212use futures:: { executor:: block_on, StreamExt } ;
1313use planner_types:: ir:: export:: PhysicalASAPDAG ;
1414use planner_types:: physical:: execution_data_state:: lift_plain;
@@ -1225,42 +1225,42 @@ fn histogram_quantile_rejects_equal_output_label_sets() {
12251225 assert ! ( error. contains( "same labelset" ) , "{error}" ) ;
12261226}
12271227
1228- // Candidate search keeps a classic histogram_quantile whole and exact, even
1229- // for an approximate target, and the selected DAG compiles and executes.
1228+ // The stage pipeline keeps a classic histogram_quantile exact, with no sketch,
1229+ // even for an approximate target. Over raw buckets it keeps the whole
1230+ // expression, which compiles and executes; under a `sum by (le)` it may keep
1231+ // the sum as an exact accumulator, which this whole-expression harness does
1232+ // not bind.
12301233#[ test]
12311234fn histogram_quantile_selection_keeps_the_exact_fallback ( ) {
1232- use asap_logical_optimizer:: {
1233- accuracy:: DefaultAccuracyModel , default_strategies, search_workload_with_targets,
1234- Replacement ,
1235- } ;
1236- use asap_plan_selection:: cost:: cost_model:: DefaultCostModel ;
1235+ use planner_types:: ir:: { schema:: FieldDataType , ASAPOp , OperatorNode } ;
12371236 let samples = buckets ( & [ ( "job=a" , HISTOGRAM ) ] ) ;
12381237 for target in [ AccuracyTarget :: Exact , AccuracyTarget :: Epsilon ( 0.01 ) ] {
1239- for query in [
1240- "histogram_quantile(0.5, x_bucket)" ,
1241- "histogram_quantile(0.5, sum by (le, job) (x_bucket))" ,
1238+ for ( query, whole) in [
1239+ ( "histogram_quantile(0.5, x_bucket)" , true ) ,
1240+ (
1241+ "histogram_quantile(0.5, sum by (le, job) (x_bucket))" ,
1242+ false ,
1243+ ) ,
12421244 ] {
12431245 let root =
12441246 promql_rows:: with_series_identity ( & parse_with ( query, target. clone ( ) ) ) . unwrap ( ) ;
1245- let space = search_workload_with_targets (
1246- vec ! [ ( query, root. clone( ) , Some ( target. clone( ) ) ) ] ,
1247- & default_strategies ( ) ,
1248- & DefaultAccuracyModel ,
1249- ) ;
1250- let planned = & space. roots [ 0 ] . 1 ;
1251- let candidates = & space. candidates_for_target ( planned) . unwrap ( ) . candidates ;
1247+ let selected = selected_dag ( root. clone ( ) , target. clone ( ) ) ;
12521248 assert ! (
1253- candidates. iter( ) . all( |c| matches!( & c. replacement,
1254- Replacement :: SubDAG ( node) if !node. contains_asap( ) && node. operator == root. operator) ) ,
1255- "{query}: {candidates:?}"
1249+ !OperatorNode :: reachable( & selected)
1250+ . iter( )
1251+ . any( |node| matches!(
1252+ & node. operator,
1253+ planner_types:: ir:: Operator :: ASAP ( ASAPOp :: SummaryAgg {
1254+ family: FieldDataType :: Sketch ( ..) ,
1255+ ..
1256+ } )
1257+ ) ) ,
1258+ "{query}: {selected:?}"
12561259 ) ;
1257- let selected = asap_plan_selection:: candidate_selection:: global_selection (
1258- & space,
1259- & DefaultCostModel ,
1260- )
1261- . assemble_selected_dag ( planned)
1262- . unwrap ( )
1263- . unwrap ( ) ;
1260+ if !whole {
1261+ continue ;
1262+ }
1263+ assert ! ( !selected. contains_asap( ) , "{query}: {selected:?}" ) ;
12641264 let dag = compile_physical_asap_dag ( & selected) . unwrap ( ) ;
12651265 let rows = evaluate_dag ( & root, & dag, & [ ( "x_bucket" , & samples) ] , 60 ) . unwrap ( ) ;
12661266 let values: Vec < _ > = rows. iter ( ) . map ( |( _, _, v) | * v) . collect ( ) ;
0 commit comments