@@ -18,6 +18,7 @@ use graph::data::schema::ApiSchema;
1818use graph:: prelude:: { info, o, q, r, s, BlockNumber , CheapClone , Logger , TryFromValue } ;
1919
2020use crate :: introspection:: introspection_schema;
21+ use crate :: query:: ext:: ValueExt ;
2122use crate :: query:: { ast as qast, ext:: BlockConstraint } ;
2223use crate :: schema:: ast as sast;
2324use crate :: {
@@ -214,7 +215,7 @@ impl Query {
214215 let start = Instant :: now ( ) ;
215216 // Use an intermediate struct so we can modify the query before
216217 // enclosing it in an Arc
217- let raw_query = RawQuery {
218+ let mut raw_query = RawQuery {
218219 schema,
219220 variables,
220221 selection_set,
@@ -226,6 +227,7 @@ impl Query {
226227 // overflow from invalid queries.
227228 let complexity = raw_query. check_complexity ( max_complexity, max_depth) ?;
228229 raw_query. validate_fields ( ) ?;
230+ raw_query. expand_variables ( ) ?;
229231
230232 let query = Self {
231233 schema : raw_query. schema ,
@@ -726,4 +728,97 @@ impl RawQuery {
726728 errors
727729 } )
728730 }
731+
732+ fn expand_variables ( & mut self ) -> Result < ( ) , QueryExecutionError > {
733+ fn expand_field (
734+ field : & mut q:: Field ,
735+ vars : & HashMap < String , r:: Value > ,
736+ ) -> Result < ( ) , QueryExecutionError > {
737+ expand_arguments ( & mut field. arguments , & field. position , vars) ?;
738+ expand_directives ( & mut field. directives , vars) ?;
739+ expand_selection_set ( & mut field. selection_set , vars)
740+ }
741+
742+ fn expand_selection_set (
743+ set : & mut q:: SelectionSet ,
744+ vars : & HashMap < String , r:: Value > ,
745+ ) -> Result < ( ) , QueryExecutionError > {
746+ for sel in & mut set. items {
747+ match sel {
748+ q:: Selection :: Field ( field) => expand_field ( field, vars) ?,
749+ q:: Selection :: FragmentSpread ( spread) => {
750+ expand_directives ( & mut spread. directives , vars) ?;
751+ }
752+ q:: Selection :: InlineFragment ( frag) => {
753+ expand_directives ( & mut frag. directives , vars) ?;
754+ expand_selection_set ( & mut frag. selection_set , vars) ?;
755+ }
756+ }
757+ }
758+ Ok ( ( ) )
759+ }
760+
761+ fn expand_directives (
762+ dirs : & mut Vec < q:: Directive > ,
763+ vars : & HashMap < String , r:: Value > ,
764+ ) -> Result < ( ) , QueryExecutionError > {
765+ for dir in dirs {
766+ expand_arguments ( & mut dir. arguments , & dir. position , vars) ?;
767+ }
768+ Ok ( ( ) )
769+ }
770+
771+ fn expand_arguments (
772+ args : & mut Vec < ( String , q:: Value ) > ,
773+ pos : & Pos ,
774+ vars : & HashMap < String , r:: Value > ,
775+ ) -> Result < ( ) , QueryExecutionError > {
776+ for arg in args {
777+ expand_value ( & mut arg. 1 , pos, vars) ?;
778+ }
779+ Ok ( ( ) )
780+ }
781+
782+ fn expand_value (
783+ val : & mut q:: Value ,
784+ pos : & Pos ,
785+ vars : & HashMap < String , r:: Value > ,
786+ ) -> Result < ( ) , QueryExecutionError > {
787+ match val {
788+ q:: Value :: Variable ( ref var) => {
789+ let newval = match vars. get ( var) {
790+ Some ( val) => q:: Value :: from ( val. clone ( ) ) ,
791+ None => {
792+ return Err ( QueryExecutionError :: MissingVariableError (
793+ pos. clone ( ) ,
794+ var. to_string ( ) ,
795+ ) )
796+ }
797+ } ;
798+ * val = newval;
799+ Ok ( ( ) )
800+ }
801+ q:: Value :: Int ( _)
802+ | q:: Value :: Float ( _)
803+ | q:: Value :: String ( _)
804+ | q:: Value :: Boolean ( _)
805+ | q:: Value :: Null
806+ | q:: Value :: Enum ( _) => Ok ( ( ) ) ,
807+ q:: Value :: List ( ref mut vals) => {
808+ for mut val in vals. iter_mut ( ) {
809+ expand_value ( & mut val, pos, vars) ?;
810+ }
811+ Ok ( ( ) )
812+ }
813+ q:: Value :: Object ( obj) => {
814+ for mut val in obj. values_mut ( ) {
815+ expand_value ( & mut val, pos, vars) ?;
816+ }
817+ Ok ( ( ) )
818+ }
819+ }
820+ }
821+
822+ expand_selection_set ( & mut self . selection_set , & self . variables )
823+ }
729824}
0 commit comments