@@ -2230,3 +2230,328 @@ func TestInvalidAliasUids(t *testing.T) {
22302230 _ , err := mutationWithTs (m1 , "application/rdf" , false , true , 0 )
22312231 require .Contains (t , "query alias [uids] not allowed" , err .Error ())
22322232}
2233+
2234+ func TestMultipleMutation (t * testing.T ) {
2235+ require .NoError (t , dropAll ())
2236+ require .NoError (t , alterSchema (`email: string @index(exact) .` ))
2237+
2238+ m1 := `
2239+ upsert {
2240+ query {
2241+ q(func: eq(email, "email@company.io")) {
2242+ v as uid
2243+ }
2244+ }
2245+
2246+ mutation @if(not(eq(len(v), 0))) {
2247+ set {
2248+ uid(v) <name> "not_name" .
2249+ uid(v) <email> "not_email@company.io" .
2250+ }
2251+ }
2252+
2253+ mutation @if(eq(len(v), 0)) {
2254+ set {
2255+ _:user <name> "name" .
2256+ _:user <email> "email@company.io" .
2257+ }
2258+ }
2259+ }`
2260+ mr , err := mutationWithTs (m1 , "application/rdf" , false , true , 0 )
2261+ require .NoError (t , err )
2262+ require .True (t , len (mr .keys ) == 0 )
2263+ require .Equal (t , []string {"1-email" , "1-name" }, mr .preds )
2264+ result := QueryResult {}
2265+ require .NoError (t , json .Unmarshal (mr .data , & result ))
2266+ require .Equal (t , 0 , len (result .Q ))
2267+
2268+ q1 := `
2269+ {
2270+ q(func: eq(email, "email@company.io")) {
2271+ name
2272+ }
2273+ }`
2274+ res , _ , err := queryWithTs (q1 , "application/graphql+-" , "" , 0 )
2275+ expectedRes := `
2276+ {
2277+ "data": {
2278+ "q": [{
2279+ "name": "name"
2280+ }]
2281+ }
2282+ }`
2283+ require .NoError (t , err )
2284+ testutil .CompareJSON (t , res , expectedRes )
2285+
2286+ // This time the other mutation will get executed
2287+ _ , err = mutationWithTs (m1 , "application/rdf" , false , true , 0 )
2288+ require .NoError (t , err )
2289+
2290+ q2 := `
2291+ {
2292+ q(func: eq(email, "not_email@company.io")) {
2293+ name
2294+ }
2295+ }`
2296+ res , _ , err = queryWithTs (q2 , "application/graphql+-" , "" , 0 )
2297+ require .NoError (t , err )
2298+
2299+ expectedRes = `
2300+ {
2301+ "data": {
2302+ "q": [{
2303+ "name": "not_name"
2304+ }]
2305+ }
2306+ }`
2307+ require .NoError (t , err )
2308+ testutil .CompareJSON (t , res , expectedRes )
2309+ }
2310+
2311+ func TestMultiMutationWithoutIf (t * testing.T ) {
2312+ require .NoError (t , dropAll ())
2313+ require .NoError (t , alterSchema (`email: string @index(exact) .` ))
2314+
2315+ m1 := `
2316+ upsert {
2317+ query {
2318+ me(func: eq(email, "email@company.io")) {
2319+ v as uid
2320+ }
2321+ }
2322+
2323+ mutation @if(not(eq(len(v), 0))) {
2324+ set {
2325+ uid(v) <name> "not_name" .
2326+ uid(v) <email> "not_email@company.io" .
2327+ }
2328+ }
2329+
2330+ mutation @if(eq(len(v), 0)) {
2331+ set {
2332+ _:user <name> "name" .
2333+ }
2334+ }
2335+
2336+ mutation {
2337+ set {
2338+ _:user <email> "email@company.io" .
2339+ }
2340+ }
2341+
2342+ mutation {
2343+ set {
2344+ _:other <name> "other" .
2345+ _:other <email> "other@company.io" .
2346+ }
2347+ }
2348+ }`
2349+ mr , err := mutationWithTs (m1 , "application/rdf" , false , true , 0 )
2350+ require .NoError (t , err )
2351+ require .True (t , len (mr .keys ) == 0 )
2352+ require .Equal (t , []string {"1-email" , "1-name" }, mr .preds )
2353+
2354+ q1 := `
2355+ {
2356+ q(func: has(email)) {
2357+ name
2358+ }
2359+ }`
2360+ res , _ , err := queryWithTs (q1 , "application/graphql+-" , "" , 0 )
2361+ expectedRes := `
2362+ {
2363+ "data": {
2364+ "q": [{
2365+ "name": "name"
2366+ },
2367+ {
2368+ "name": "other"
2369+ }]
2370+ }
2371+ }`
2372+ require .NoError (t , err )
2373+ testutil .CompareJSON (t , res , expectedRes )
2374+ }
2375+
2376+ func TestMultiMutationCount (t * testing.T ) {
2377+ require .NoError (t , dropAll ())
2378+ require .NoError (t , alterSchema (`
2379+ email: string @index(exact) .
2380+ count: int .` ))
2381+
2382+ m1 := `
2383+ upsert {
2384+ query {
2385+ q(func: eq(email, "email@company.io")) {
2386+ v as uid
2387+ c as count
2388+ nc as math(c+1)
2389+ }
2390+ }
2391+
2392+ mutation @if(eq(len(v), 0)) {
2393+ set {
2394+ uid(v) <name> "name" .
2395+ uid(v) <email> "email@company.io" .
2396+ uid(v) <count> "1" .
2397+ }
2398+ }
2399+
2400+ mutation @if(not(eq(len(v), 0))) {
2401+ set {
2402+ uid(v) <count> val(nc) .
2403+ }
2404+ }
2405+ }`
2406+ mr , err := mutationWithTs (m1 , "application/rdf" , false , true , 0 )
2407+ require .NoError (t , err )
2408+ require .True (t , len (mr .keys ) == 0 )
2409+ require .Equal (t , []string {"1-count" , "1-email" , "1-name" }, mr .preds )
2410+
2411+ q1 := `
2412+ {
2413+ q(func: has(email)) {
2414+ count
2415+ }
2416+ }`
2417+ res , _ , err := queryWithTs (q1 , "application/graphql+-" , "" , 0 )
2418+ expectedRes := `
2419+ {
2420+ "data": {
2421+ "q": [{
2422+ "count": 1
2423+ }]
2424+ }
2425+ }`
2426+ require .NoError (t , err )
2427+ testutil .CompareJSON (t , res , expectedRes )
2428+
2429+ // second time
2430+ mr , err = mutationWithTs (m1 , "application/rdf" , false , true , 0 )
2431+ require .NoError (t , err )
2432+ require .True (t , len (mr .keys ) == 0 )
2433+ require .Equal (t , []string {"1-count" }, mr .preds )
2434+
2435+ res , _ , err = queryWithTs (q1 , "application/graphql+-" , "" , 0 )
2436+ expectedRes = `
2437+ {
2438+ "data": {
2439+ "q": [{
2440+ "count": 2
2441+ }]
2442+ }
2443+ }`
2444+ require .NoError (t , err )
2445+ testutil .CompareJSON (t , res , expectedRes )
2446+ }
2447+
2448+ func TestMultipleMutationMerge (t * testing.T ) {
2449+ require .NoError (t , dropAll ())
2450+ require .NoError (t , alterSchema (`
2451+ name: string @index(term) .
2452+ email: [string] @index(exact) @upsert .` ))
2453+
2454+ m1 := `
2455+ {
2456+ set {
2457+ _:user1 <name> "user1" .
2458+ _:user1 <email> "user_email1@company1.io" .
2459+ _:user2 <name> "user2" .
2460+ _:user2 <email> "user_email2@company1.io" .
2461+ }
2462+ }`
2463+ mr , err := mutationWithTs (m1 , "application/rdf" , false , true , 0 )
2464+ require .NoError (t , err )
2465+ require .True (t , len (mr .keys ) == 0 )
2466+ require .Equal (t , []string {"1-email" , "1-name" }, mr .preds )
2467+
2468+ q1 := `
2469+ {
2470+ q(func: has(name)) {
2471+ uid
2472+ }
2473+ }`
2474+ res , _ , err := queryWithTs (q1 , "application/graphql+-" , "" , 0 )
2475+ require .NoError (t , err )
2476+ var result struct {
2477+ Data struct {
2478+ Q []struct {
2479+ UID string `json:"uid"`
2480+ } `json:"q"`
2481+ } `json:"data"`
2482+ }
2483+ require .NoError (t , json .Unmarshal ([]byte (res ), & result ))
2484+ require .Equal (t , 2 , len (result .Data .Q ))
2485+
2486+ m2 := `
2487+ upsert {
2488+ query {
2489+ # filter is needed to ensure that we do not get same UIDs in u1 and u2
2490+ q1(func: eq(email, "user_email1@company1.io")) @filter(not(eq(email, "user_email2@company1.io"))) {
2491+ u1 as uid
2492+ }
2493+
2494+ q2(func: eq(email, "user_email2@company1.io")) @filter(not(eq(email, "user_email1@company1.io"))) {
2495+ u2 as uid
2496+ }
2497+
2498+ q3(func: eq(email, "user_email1@company1.io")) @filter(eq(email, "user_email2@company1.io")) {
2499+ u3 as uid
2500+ }
2501+ }
2502+
2503+ # case when both emails do not exist
2504+ mutation @if(eq(len(u1), 0) AND eq(len(u2), 0) AND eq(len(u3), 0)) {
2505+ set {
2506+ _:user <name> "user" .
2507+ _:user <email> "user_email1@company1.io" .
2508+ _:user <email> "user_email2@company1.io" .
2509+ }
2510+ }
2511+
2512+ # case when email1 exists but email2 does not
2513+ mutation @if(eq(len(u1), 1) AND eq(len(u2), 0) AND eq(len(u3), 0)) {
2514+ set {
2515+ uid(u1) <email> "user_email2@company1.io" .
2516+ }
2517+ }
2518+
2519+ # case when email1 does not exist but email2 exists
2520+ mutation @if(eq(len(u1), 0) AND eq(len(u2), 1) AND eq(len(u3), 0)) {
2521+ set {
2522+ uid(u2) <email> "user_email1@company1.io" .
2523+ }
2524+ }
2525+
2526+ # case when both emails exist and needs merging
2527+ mutation @if(eq(len(u1), 1) AND eq(len(u2), 1) AND eq(len(u3), 0)) {
2528+ set {
2529+ _:user <name> "user" .
2530+ _:user <email> "user_email1@company1.io" .
2531+ _:user <email> "user_email2@company1.io" .
2532+ }
2533+
2534+ delete {
2535+ uid(u1) <name> * .
2536+ uid(u1) <email> * .
2537+ uid(u2) <name> * .
2538+ uid(u2) <email> * .
2539+ }
2540+ }
2541+ }`
2542+ mr , err = mutationWithTs (m2 , "application/rdf" , false , true , 0 )
2543+ require .NoError (t , err )
2544+ require .True (t , len (mr .keys ) == 0 )
2545+ require .Equal (t , []string {"1-email" , "1-name" }, mr .preds )
2546+
2547+ res , _ , err = queryWithTs (q1 , "application/graphql+-" , "" , 0 )
2548+ require .NoError (t , err )
2549+ require .NoError (t , json .Unmarshal ([]byte (res ), & result ))
2550+ require .Equal (t , 1 , len (result .Data .Q ))
2551+
2552+ // Now, data is all correct. So, following mutation should be no-op
2553+ mr , err = mutationWithTs (m2 , "application/rdf" , false , true , 0 )
2554+ require .NoError (t , err )
2555+ require .True (t , len (mr .keys ) == 0 )
2556+ require .Equal (t , 0 , len (mr .preds ))
2557+ }
0 commit comments