[SERVER-40185] stitch lib handles initialization for upserted doc differently than server when update is a replacement Created: 18/Mar/19  Updated: 29/Oct/23  Resolved: 12/Apr/19

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: None
Fix Version/s: 4.1.11

Type: Bug Priority: Major - P3
Reporter: Michael O'Brien Assignee: Justin Seyster
Resolution: Fixed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
Backwards Compatibility: Fully Compatible
Operating System: ALL
Sprint: Query 2019-04-22
Participants:

 Description   

With an empty data set, running an update operation against the server to perform a document replacement uses the _id in the query to initialize it:

local:PRIMARY> db.test.update({$and:[{_id: 1000}]}, {foo:10000}, {upsert:true})

WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : 1000 })

local:PRIMARY> db.test.find()

{{

{ "_id" : 1000, "foo" : 10000 }

}}

 

However doing the equivalent operation through the stitch library doesn't seem to take into account the query when initializing the upserted doc in the same manner. Here is a failing test case:

 
	t.Run("upsert with a compound expression query should initialize upserted doc correctly with replacement", func(t *testing.T) {
		matcher, err := stitchmongo.NewMatcher(bson.D{{"$and", []interface{}{
			bson.D{{"_id", 1000}},
		}}})
		u.So(t, err, gc.ShouldBeNil)
		defer matcher.Close()
		updater, err := stitchmongo.NewUpdater(
			bson.D{{"z", 3}},
			matcher,
		)
		u.So(t, err, gc.ShouldBeNil)
		defer updater.Close()
		result, err := updater.ApplyUpsert()
		u.So(t, err, gc.ShouldBeNil)
		u.So(t, result.UpdatedDocument, gc.ShouldResemble, bson.D{{"_id", 1000}, {"z", 3}})
		u.So(t, result.IsReplacement, gc.ShouldBeTrue)
	})
 
 

Interestignly though the same operation does work equivalently to the server when the update uses $ modifiers instead. For example, the following test passes:

	t.Run("upsert with a compound expression query should initialize upserted doc correctly with update modifiers", func(t *testing.T) {
		matcher, err := stitchmongo.NewMatcher(bson.D{{"$and", []interface{}{
			bson.D{{"_id", 1000}},
			bson.D{{"x", 50}},
		}}})
		u.So(t, err, gc.ShouldBeNil)
		defer matcher.Close()
		updater, err := stitchmongo.NewUpdater(
			bson.D{{"$set", bson.D{{"z", 3}}}},
			matcher,
		)
		u.So(t, err, gc.ShouldBeNil)
		defer updater.Close()
		result, err := updater.ApplyUpsert()
		u.So(t, err, gc.ShouldBeNil)
		u.So(t, result.UpdatedDocument, gc.ShouldResemble, bson.D{{"_id", 1000}, {"x", 50}, {"z", 3}})
		u.So(t, result.IsReplacement, gc.ShouldBeFalse)
	})



 Comments   
Comment by Githook User [ 12/Apr/19 ]

Author:

{'email': 'justin.seyster@mongodb.com', 'name': 'Justin Seyster', 'username': 'jseyster'}

Message: SERVER-40185 Replacement upsert in Stitch Lib takes '_id' from query.
Branch: master
https://github.com/mongodb/mongo/commit/b99be34f9db7416259e49dcf741719bc7f20908d

Generated at Thu Feb 08 04:54:17 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.