buildUpsertQuery modifies the query to evaluate the @if condition defined in Conditional Upsert.
(qc *queryContext)
| 872 | // buildUpsertQuery modifies the query to evaluate the |
| 873 | // @if condition defined in Conditional Upsert. |
| 874 | func buildUpsertQuery(qc *queryContext) (string, error) { |
| 875 | if qc.req.Query == "" || len(qc.gmuList) == 0 { |
| 876 | return qc.req.Query, nil |
| 877 | } |
| 878 | |
| 879 | qc.condVars = make([]string, len(qc.req.Mutations)) |
| 880 | |
| 881 | var upsertQB strings.Builder |
| 882 | x.Check2(upsertQB.WriteString(strings.TrimSuffix(qc.req.Query, "}"))) |
| 883 | |
| 884 | for i, gmu := range qc.gmuList { |
| 885 | isCondUpsert := strings.TrimSpace(gmu.Cond) != "" |
| 886 | if isCondUpsert { |
| 887 | if err := validateCondValue(gmu.Cond); err != nil { |
| 888 | return "", err |
| 889 | } |
| 890 | |
| 891 | qc.condVars[i] = fmt.Sprintf("__dgraph_upsertcheck_%v__", strconv.Itoa(i)) |
| 892 | qc.uidRes[qc.condVars[i]] = nil |
| 893 | // @if in upsert is same as @filter in the query |
| 894 | cond := strings.Replace(gmu.Cond, "@if", "@filter", 1) |
| 895 | |
| 896 | // Add dummy query to evaluate the @if directive, ok to use uid(0) because |
| 897 | // dgraph doesn't check for existence of UIDs until we query for other predicates. |
| 898 | // Here, we are only querying for uid predicate in the dummy query. |
| 899 | // |
| 900 | // For example if - mu.Query = { |
| 901 | // me(...) {...} |
| 902 | // } |
| 903 | // |
| 904 | // Then, upsertQuery = { |
| 905 | // me(...) {...} |
| 906 | // __dgraph_0__ as var(func: uid(0)) @filter(...) |
| 907 | // } |
| 908 | // |
| 909 | // The variable __dgraph_0__ will - |
| 910 | // * be empty if the condition is true |
| 911 | // * have 1 UID (the 0 UID) if the condition is false |
| 912 | x.Check2(upsertQB.WriteString(qc.condVars[i])) |
| 913 | x.Check2(upsertQB.WriteString(` as var(func: uid(0)) `)) |
| 914 | x.Check2(upsertQB.WriteString(cond)) |
| 915 | x.Check2(upsertQB.WriteString("\n")) |
| 916 | } |
| 917 | } |
| 918 | |
| 919 | x.Check2(upsertQB.WriteString(`}`)) |
| 920 | return upsertQB.String(), nil |
| 921 | } |
| 922 | |
| 923 | // updateMutations updates the mutation and replaces uid(var) and val(var) with |
| 924 | // their values or a blank node, in case of an upsert. |
no test coverage detected