1- use std:: { borrow:: Cow , collections:: HashMap } ;
1+ use std:: {
2+ borrow:: Cow ,
3+ collections:: { BTreeSet , HashMap } ,
4+ } ;
25
36use bytes:: { BufMut , Bytes } ;
47use futures:: { future:: BoxFuture , stream:: FuturesUnordered , StreamExt } ;
@@ -651,6 +654,8 @@ impl<'exec> Executor<'exec> {
651654 self . client_request ,
652655 & mut headers_map,
653656 ) ?;
657+ let variable_refs =
658+ select_fetch_variables ( self . variable_values , node. variable_usages . as_ref ( ) ) ;
654659
655660 Ok ( ExecutionJob :: Fetch ( FetchJob {
656661 fetch_node_id : node. id ,
@@ -663,7 +668,7 @@ impl<'exec> Executor<'exec> {
663668 query : node. operation . document_str . as_str ( ) ,
664669 dedupe : self . dedupe_subgraph_requests ,
665670 operation_name : node. operation_name . as_deref ( ) ,
666- variables : None ,
671+ variables : variable_refs ,
667672 representations,
668673 headers : headers_map,
669674 } ,
@@ -688,3 +693,79 @@ fn condition_node_by_variables<'a>(
688693 condition_node. else_clause . as_deref ( )
689694 }
690695}
696+
697+ fn select_fetch_variables < ' a > (
698+ variable_values : & ' a Option < HashMap < String , sonic_rs:: Value > > ,
699+ variable_usages : Option < & BTreeSet < String > > ,
700+ ) -> Option < HashMap < & ' a str , & ' a sonic_rs:: Value > > {
701+ let values = variable_values. as_ref ( ) ?;
702+
703+ variable_usages. map ( |variable_usages| {
704+ variable_usages
705+ . iter ( )
706+ . filter_map ( |var_name| {
707+ values
708+ . get_key_value ( var_name. as_str ( ) )
709+ . map ( |( key, value) | ( key. as_str ( ) , value) )
710+ } )
711+ . collect ( )
712+ } )
713+ }
714+
715+ #[ cfg( test) ]
716+ mod tests {
717+ use super :: select_fetch_variables;
718+ use sonic_rs:: Value ;
719+ use std:: collections:: { BTreeSet , HashMap } ;
720+
721+ fn value_from_number ( n : i32 ) -> Value {
722+ sonic_rs:: from_str ( & n. to_string ( ) ) . unwrap ( )
723+ }
724+
725+ #[ test]
726+ fn select_fetch_variables_only_used_variables ( ) {
727+ let mut variable_values_map = HashMap :: new ( ) ;
728+ variable_values_map. insert ( "used" . to_string ( ) , value_from_number ( 1 ) ) ;
729+ variable_values_map. insert ( "unused" . to_string ( ) , value_from_number ( 2 ) ) ;
730+ let variable_values = Some ( variable_values_map) ;
731+
732+ let mut usages = BTreeSet :: new ( ) ;
733+ usages. insert ( "used" . to_string ( ) ) ;
734+
735+ let selected = select_fetch_variables ( & variable_values, Some ( & usages) ) . unwrap ( ) ;
736+
737+ assert_eq ! ( selected. len( ) , 1 ) ;
738+ assert ! ( selected. contains_key( "used" ) ) ;
739+ assert ! ( !selected. contains_key( "unused" ) ) ;
740+ }
741+
742+ #[ test]
743+ fn select_fetch_variables_ignores_missing_usage_entries ( ) {
744+ let mut variable_values_map = HashMap :: new ( ) ;
745+ variable_values_map. insert ( "present" . to_string ( ) , value_from_number ( 3 ) ) ;
746+ let variable_values = Some ( variable_values_map) ;
747+
748+ let mut usages = BTreeSet :: new ( ) ;
749+ usages. insert ( "present" . to_string ( ) ) ;
750+ usages. insert ( "missing" . to_string ( ) ) ;
751+
752+ let selected = select_fetch_variables ( & variable_values, Some ( & usages) ) . unwrap ( ) ;
753+
754+ assert_eq ! ( selected. len( ) , 1 ) ;
755+ assert ! ( selected. contains_key( "present" ) ) ;
756+ assert ! ( !selected. contains_key( "missing" ) ) ;
757+ }
758+
759+ #[ test]
760+ fn select_fetch_variables_for_no_usage_entries ( ) {
761+ let mut variable_values_map = HashMap :: new ( ) ;
762+ variable_values_map. insert ( "unused_1" . to_string ( ) , value_from_number ( 1 ) ) ;
763+ variable_values_map. insert ( "unused_2" . to_string ( ) , value_from_number ( 2 ) ) ;
764+
765+ let variable_values = Some ( variable_values_map) ;
766+
767+ let selected = select_fetch_variables ( & variable_values, None ) ;
768+
769+ assert ! ( selected. is_none( ) ) ;
770+ }
771+ }
0 commit comments