@@ -18,6 +18,7 @@ use graph::data::schema::ApiSchema;
18
18
use graph:: prelude:: { info, o, q, r, s, BlockNumber , CheapClone , Logger , TryFromValue } ;
19
19
20
20
use crate :: introspection:: introspection_schema;
21
+ use crate :: query:: ext:: ValueExt ;
21
22
use crate :: query:: { ast as qast, ext:: BlockConstraint } ;
22
23
use crate :: schema:: ast as sast;
23
24
use crate :: {
@@ -214,7 +215,7 @@ impl Query {
214
215
let start = Instant :: now ( ) ;
215
216
// Use an intermediate struct so we can modify the query before
216
217
// enclosing it in an Arc
217
- let raw_query = RawQuery {
218
+ let mut raw_query = RawQuery {
218
219
schema,
219
220
variables,
220
221
selection_set,
@@ -226,6 +227,7 @@ impl Query {
226
227
// overflow from invalid queries.
227
228
let complexity = raw_query. check_complexity ( max_complexity, max_depth) ?;
228
229
raw_query. validate_fields ( ) ?;
230
+ raw_query. expand_variables ( ) ?;
229
231
230
232
let query = Self {
231
233
schema : raw_query. schema ,
@@ -726,4 +728,97 @@ impl RawQuery {
726
728
errors
727
729
} )
728
730
}
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
+ }
729
824
}
0 commit comments