ProcessQuery processes query part of the request (without mutations). Fills Subgraphs and Vars. It can process multiple query blocks that are part of the query..
(ctx context.Context)
| 2860 | // Fills Subgraphs and Vars. |
| 2861 | // It can process multiple query blocks that are part of the query.. |
| 2862 | func (req *Request) ProcessQuery(ctx context.Context) (err error) { |
| 2863 | span := trace.SpanFromContext(ctx) |
| 2864 | stop := x.SpanTimer(span, "query.ProcessQuery") |
| 2865 | defer stop() |
| 2866 | |
| 2867 | // Vars stores the processed variables. |
| 2868 | req.Vars = make(map[string]varValue) |
| 2869 | loopStart := time.Now() |
| 2870 | queries := req.DqlQuery.Query |
| 2871 | // first loop converts queries to SubGraph representation and populates ReadTs And Cache. |
| 2872 | for i := range queries { |
| 2873 | gq := queries[i] |
| 2874 | |
| 2875 | if gq == nil || (len(gq.UID) == 0 && gq.Func == nil && len(gq.NeedsVar) == 0 && |
| 2876 | gq.Alias != "shortest" && !gq.IsEmpty) { |
| 2877 | return errors.Errorf("Invalid query. No function used at root and no aggregation" + |
| 2878 | " or math variables found in the body.") |
| 2879 | } |
| 2880 | sg, err := ToSubGraph(ctx, gq) |
| 2881 | if err != nil { |
| 2882 | return errors.Wrapf(err, "while converting to subgraph") |
| 2883 | } |
| 2884 | sg.recurse(func(sg *SubGraph) { |
| 2885 | sg.ReadTs = req.ReadTs |
| 2886 | sg.Cache = req.Cache |
| 2887 | }) |
| 2888 | span.AddEvent("Query parsed") |
| 2889 | req.Subgraphs = append(req.Subgraphs, sg) |
| 2890 | } |
| 2891 | req.Latency.Parsing += time.Since(loopStart) |
| 2892 | |
| 2893 | execStart := time.Now() |
| 2894 | hasExecuted := make([]bool, len(req.Subgraphs)) |
| 2895 | numQueriesDone := 0 |
| 2896 | |
| 2897 | // canExecute returns true if a query block is ready to execute with all the variables |
| 2898 | // that it depends on are already populated or are defined in the same block. |
| 2899 | canExecute := func(idx int) bool { |
| 2900 | queryVars := req.DqlQuery.QueryVars[idx] |
| 2901 | for _, v := range queryVars.Needs { |
| 2902 | // here we check if this block defines the variable v. |
| 2903 | var selfDep bool |
| 2904 | for _, vd := range queryVars.Defines { |
| 2905 | if v == vd { |
| 2906 | selfDep = true |
| 2907 | break |
| 2908 | } |
| 2909 | } |
| 2910 | // The variable should be defined in this block or should have already been |
| 2911 | // populated by some other block, otherwise we are not ready to execute yet. |
| 2912 | _, ok := req.Vars[v] |
| 2913 | if !ok && !selfDep { |
| 2914 | return false |
| 2915 | } |
| 2916 | } |
| 2917 | return true |
| 2918 | } |
| 2919 |