1
- use std:: collections:: HashMap ;
1
+ use std:: collections:: { BTreeSet , HashMap } ;
2
2
3
3
use bytes:: { BufMut , Bytes } ;
4
4
use futures:: { future:: BoxFuture , stream:: FuturesUnordered , StreamExt } ;
@@ -522,6 +522,9 @@ impl<'exec> Executor<'exec> {
522
522
node : & FetchNode ,
523
523
representations : Option < Vec < u8 > > ,
524
524
) -> Result < ExecutionJob , PlanExecutionError > {
525
+ let variable_refs =
526
+ select_fetch_variables ( self . variable_values , node. variable_usages . as_ref ( ) ) ;
527
+
525
528
Ok ( ExecutionJob :: Fetch ( FetchJob {
526
529
fetch_node_id : node. id ,
527
530
response : self
@@ -532,7 +535,7 @@ impl<'exec> Executor<'exec> {
532
535
query : node. operation . document_str . as_str ( ) ,
533
536
dedupe : self . dedupe_subgraph_requests ,
534
537
operation_name : node. operation_name . as_deref ( ) ,
535
- variables : None ,
538
+ variables : variable_refs ,
536
539
representations,
537
540
} ,
538
541
)
@@ -555,3 +558,82 @@ fn condition_node_by_variables<'a>(
555
558
condition_node. else_clause . as_deref ( )
556
559
}
557
560
}
561
+
562
+ fn select_fetch_variables < ' a > (
563
+ variable_values : & ' a Option < HashMap < String , sonic_rs:: Value > > ,
564
+ variable_usages : Option < & BTreeSet < String > > ,
565
+ ) -> Option < HashMap < & ' a str , & ' a sonic_rs:: Value > > {
566
+ let values = variable_values. as_ref ( ) ?;
567
+
568
+ match variable_usages {
569
+ Some ( variable_usages) => Some (
570
+ variable_usages
571
+ . iter ( )
572
+ . filter_map ( |var_name| {
573
+ values
574
+ . get_key_value ( var_name. as_str ( ) )
575
+ . map ( |( key, value) | ( key. as_str ( ) , value) )
576
+ } )
577
+ . collect ( ) ,
578
+ ) ,
579
+ None => None ,
580
+ }
581
+ }
582
+
583
+ #[ cfg( test) ]
584
+ mod tests {
585
+ use super :: select_fetch_variables;
586
+ use sonic_rs:: Value ;
587
+ use std:: collections:: { BTreeSet , HashMap } ;
588
+
589
+ fn value_from_number ( n : i32 ) -> Value {
590
+ sonic_rs:: from_str ( & n. to_string ( ) ) . unwrap ( )
591
+ }
592
+
593
+ #[ test]
594
+ fn select_fetch_variables_only_used_variables ( ) {
595
+ let mut variable_values_map = HashMap :: new ( ) ;
596
+ variable_values_map. insert ( "used" . to_string ( ) , value_from_number ( 1 ) ) ;
597
+ variable_values_map. insert ( "unused" . to_string ( ) , value_from_number ( 2 ) ) ;
598
+ let variable_values = Some ( variable_values_map) ;
599
+
600
+ let mut usages = BTreeSet :: new ( ) ;
601
+ usages. insert ( "used" . to_string ( ) ) ;
602
+
603
+ let selected = select_fetch_variables ( & variable_values, Some ( & usages) ) . unwrap ( ) ;
604
+
605
+ assert_eq ! ( selected. len( ) , 1 ) ;
606
+ assert ! ( selected. contains_key( "used" ) ) ;
607
+ assert ! ( !selected. contains_key( "unused" ) ) ;
608
+ }
609
+
610
+ #[ test]
611
+ fn select_fetch_variables_ignores_missing_usage_entries ( ) {
612
+ let mut variable_values_map = HashMap :: new ( ) ;
613
+ variable_values_map. insert ( "present" . to_string ( ) , value_from_number ( 3 ) ) ;
614
+ let variable_values = Some ( variable_values_map) ;
615
+
616
+ let mut usages = BTreeSet :: new ( ) ;
617
+ usages. insert ( "present" . to_string ( ) ) ;
618
+ usages. insert ( "missing" . to_string ( ) ) ;
619
+
620
+ let selected = select_fetch_variables ( & variable_values, Some ( & usages) ) . unwrap ( ) ;
621
+
622
+ assert_eq ! ( selected. len( ) , 1 ) ;
623
+ assert ! ( selected. contains_key( "present" ) ) ;
624
+ assert ! ( !selected. contains_key( "missing" ) ) ;
625
+ }
626
+
627
+ #[ test]
628
+ fn select_fetch_variables_for_no_usage_entries ( ) {
629
+ let mut variable_values_map = HashMap :: new ( ) ;
630
+ variable_values_map. insert ( "unused_1" . to_string ( ) , value_from_number ( 1 ) ) ;
631
+ variable_values_map. insert ( "unused_2" . to_string ( ) , value_from_number ( 2 ) ) ;
632
+
633
+ let variable_values = Some ( variable_values_map) ;
634
+
635
+ let selected = select_fetch_variables ( & variable_values, None ) ;
636
+
637
+ assert ! ( selected. is_none( ) ) ;
638
+ }
639
+ }
0 commit comments