Skip to content

Commit 6cd124c

Browse files
authored
Allow hint for unacknowledged writes if supported by server (#837)
JAVA-4275
1 parent 069a6c7 commit 6cd124c

File tree

30 files changed

+3519
-1635
lines changed

30 files changed

+3519
-1635
lines changed

driver-core/src/main/com/mongodb/internal/operation/FindAndDeleteOperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
import static com.mongodb.internal.operation.DocumentHelper.putIfNotNull;
3939
import static com.mongodb.internal.operation.DocumentHelper.putIfNotZero;
4040
import static com.mongodb.internal.operation.OperationHelper.validateCollation;
41-
import static com.mongodb.internal.operation.OperationHelper.validateHint;
41+
import static com.mongodb.internal.operation.OperationHelper.validateHintForFindAndModify;
4242
import static java.util.concurrent.TimeUnit.MILLISECONDS;
4343

4444
/**
@@ -277,7 +277,7 @@ private BsonDocument createCommand(final SessionContext sessionContext, final Se
277277
commandDocument.put("collation", collation.asDocument());
278278
}
279279
if (hint != null || hintString != null) {
280-
validateHint(connectionDescription, getWriteConcern());
280+
validateHintForFindAndModify(connectionDescription, getWriteConcern());
281281
if (hint != null) {
282282
commandDocument.put("hint", hint.toBsonDocument(BsonDocument.class, null));
283283
} else {

driver-core/src/main/com/mongodb/internal/operation/FindAndReplaceOperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
import static com.mongodb.internal.operation.DocumentHelper.putIfNotZero;
4444
import static com.mongodb.internal.operation.DocumentHelper.putIfTrue;
4545
import static com.mongodb.internal.operation.OperationHelper.validateCollation;
46-
import static com.mongodb.internal.operation.OperationHelper.validateHint;
46+
import static com.mongodb.internal.operation.OperationHelper.validateHintForFindAndModify;
4747
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsAtLeastVersionThreeDotTwo;
4848
import static java.util.concurrent.TimeUnit.MILLISECONDS;
4949

@@ -378,7 +378,7 @@ private BsonDocument createCommand(final SessionContext sessionContext, final Se
378378
commandDocument.put("collation", collation.asDocument());
379379
}
380380
if (hint != null || hintString != null) {
381-
validateHint(connectionDescription, getWriteConcern());
381+
validateHintForFindAndModify(connectionDescription, getWriteConcern());
382382
if (hint != null) {
383383
commandDocument.put("hint", hint.toBsonDocument(BsonDocument.class, null));
384384
} else {

driver-core/src/main/com/mongodb/internal/operation/FindAndUpdateOperation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
import static com.mongodb.internal.operation.DocumentHelper.putIfNotZero;
4646
import static com.mongodb.internal.operation.DocumentHelper.putIfTrue;
4747
import static com.mongodb.internal.operation.OperationHelper.validateCollation;
48-
import static com.mongodb.internal.operation.OperationHelper.validateHint;
48+
import static com.mongodb.internal.operation.OperationHelper.validateHintForFindAndModify;
4949
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsAtLeastVersionThreeDotTwo;
5050
import static java.util.concurrent.TimeUnit.MILLISECONDS;
5151

@@ -452,7 +452,7 @@ private BsonDocument createCommand(final SessionContext sessionContext, final Se
452452
commandDocument.put("arrayFilters", new BsonArray(arrayFilters));
453453
}
454454
if (hint != null || hintString != null) {
455-
validateHint(connectionDescription, getWriteConcern());
455+
validateHintForFindAndModify(connectionDescription, getWriteConcern());
456456
if (hint != null) {
457457
commandDocument.put("hint", hint.toBsonDocument(BsonDocument.class, null));
458458
} else {

driver-core/src/main/com/mongodb/internal/operation/OperationHelper.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import static com.mongodb.internal.async.ErrorHandlingResultCallback.errorHandlingCallback;
6666
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsAtLeastVersionThreeDotFour;
6767
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsAtLeastVersionThreeDotTwo;
68+
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionFourDotFour;
6869
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionFourDotTwo;
6970
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionThreeDotFour;
7071
import static com.mongodb.internal.operation.ServerVersionHelper.serverIsLessThanVersionThreeDotSix;
@@ -161,17 +162,27 @@ private static void validateWriteRequestHint(final ConnectionDescription connect
161162
if (serverIsLessThanVersionThreeDotFour(connectionDescription)) {
162163
throw new IllegalArgumentException(format("Hint not supported by wire version: %s",
163164
connectionDescription.getMaxWireVersion()));
164-
} else if ((request instanceof DeleteRequest || request instanceof UpdateRequest) && !writeConcern.isAcknowledged()) {
165-
throw new MongoClientException("Specifying hints with an unacknowledged WriteConcern is not supported");
165+
}
166+
if (!writeConcern.isAcknowledged()) {
167+
if (request instanceof UpdateRequest && serverIsLessThanVersionFourDotTwo(connectionDescription)) {
168+
throw new IllegalArgumentException(format("Hint not supported by wire version: %s",
169+
connectionDescription.getMaxWireVersion()));
170+
}
171+
if (request instanceof DeleteRequest && serverIsLessThanVersionFourDotFour(connectionDescription)) {
172+
throw new IllegalArgumentException(format("Hint not supported by wire version: %s",
173+
connectionDescription.getMaxWireVersion()));
174+
}
166175
}
167176
}
168177

169-
static void validateHint(final ConnectionDescription connectionDescription, final WriteConcern writeConcern) {
178+
static void validateHintForFindAndModify(final ConnectionDescription connectionDescription, final WriteConcern writeConcern) {
170179
if (serverIsLessThanVersionFourDotTwo(connectionDescription)) {
171180
throw new IllegalArgumentException(format("Hint not supported by wire version: %s",
172181
connectionDescription.getMaxWireVersion()));
173-
} else if (!writeConcern.isAcknowledged()) {
174-
throw new MongoClientException("Specifying hints with an unacknowledged WriteConcern is not supported");
182+
}
183+
if (!writeConcern.isAcknowledged() && serverIsLessThanVersionFourDotFour(connectionDescription)) {
184+
throw new IllegalArgumentException(format("Hint not supported by wire version: %s",
185+
connectionDescription.getMaxWireVersion()));
175186
}
176187
}
177188

driver-core/src/test/functional/com/mongodb/internal/operation/MixedBulkWriteOperationSpecification.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ class MixedBulkWriteOperationSpecification extends OperationFunctionalSpecificat
12771277
execute(operation, async)
12781278

12791279
then:
1280-
thrown(MongoClientException)
1280+
thrown(IllegalArgumentException)
12811281

12821282
where:
12831283
async << [true, false]
Lines changed: 269 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,269 @@
1+
{
2+
"description": "bulkWrite-deleteMany-hint-unacknowledged",
3+
"schemaVersion": "1.0",
4+
"createEntities": [
5+
{
6+
"client": {
7+
"id": "client0",
8+
"observeEvents": [
9+
"commandStartedEvent"
10+
]
11+
}
12+
},
13+
{
14+
"database": {
15+
"id": "database0",
16+
"client": "client0",
17+
"databaseName": "db0"
18+
}
19+
},
20+
{
21+
"collection": {
22+
"id": "collection0",
23+
"database": "database0",
24+
"collectionName": "coll0",
25+
"collectionOptions": {
26+
"writeConcern": {
27+
"w": 0
28+
}
29+
}
30+
}
31+
}
32+
],
33+
"initialData": [
34+
{
35+
"collectionName": "coll0",
36+
"databaseName": "db0",
37+
"documents": [
38+
{
39+
"_id": 1,
40+
"x": 11
41+
},
42+
{
43+
"_id": 2,
44+
"x": 22
45+
},
46+
{
47+
"_id": 3,
48+
"x": 33
49+
}
50+
]
51+
}
52+
],
53+
"tests": [
54+
{
55+
"description": "Unacknowledged deleteMany with hint string fails with client-side error on pre-4.4 server",
56+
"runOnRequirements": [
57+
{
58+
"maxServerVersion": "4.2.99"
59+
}
60+
],
61+
"operations": [
62+
{
63+
"object": "collection0",
64+
"name": "bulkWrite",
65+
"arguments": {
66+
"requests": [
67+
{
68+
"deleteMany": {
69+
"filter": {
70+
"_id": {
71+
"$gt": 1
72+
}
73+
},
74+
"hint": "_id_"
75+
}
76+
}
77+
]
78+
},
79+
"expectError": {
80+
"isClientError": true
81+
}
82+
}
83+
],
84+
"expectEvents": [
85+
{
86+
"client": "client0",
87+
"events": []
88+
}
89+
]
90+
},
91+
{
92+
"description": "Unacknowledged deleteMany with hint document fails with client-side error on pre-4.4 server",
93+
"runOnRequirements": [
94+
{
95+
"maxServerVersion": "4.2.99"
96+
}
97+
],
98+
"operations": [
99+
{
100+
"object": "collection0",
101+
"name": "bulkWrite",
102+
"arguments": {
103+
"requests": [
104+
{
105+
"deleteMany": {
106+
"filter": {
107+
"_id": {
108+
"$gt": 1
109+
}
110+
},
111+
"hint": {
112+
"_id": 1
113+
}
114+
}
115+
}
116+
]
117+
},
118+
"expectError": {
119+
"isClientError": true
120+
}
121+
}
122+
],
123+
"expectEvents": [
124+
{
125+
"client": "client0",
126+
"events": []
127+
}
128+
]
129+
},
130+
{
131+
"description": "Unacknowledged deleteMany with hint string on 4.4+ server",
132+
"runOnRequirements": [
133+
{
134+
"minServerVersion": "4.4.0"
135+
}
136+
],
137+
"operations": [
138+
{
139+
"object": "collection0",
140+
"name": "bulkWrite",
141+
"arguments": {
142+
"requests": [
143+
{
144+
"deleteMany": {
145+
"filter": {
146+
"_id": {
147+
"$gt": 1
148+
}
149+
},
150+
"hint": "_id_"
151+
}
152+
}
153+
]
154+
},
155+
"expectResult": {
156+
"$$unsetOrMatches": {
157+
"acknowledged": {
158+
"$$unsetOrMatches": false
159+
}
160+
}
161+
}
162+
}
163+
],
164+
"expectEvents": [
165+
{
166+
"client": "client0",
167+
"events": [
168+
{
169+
"commandStartedEvent": {
170+
"command": {
171+
"delete": "coll0",
172+
"deletes": [
173+
{
174+
"q": {
175+
"_id": {
176+
"$gt": 1
177+
}
178+
},
179+
"hint": {
180+
"$$type": [
181+
"string",
182+
"object"
183+
]
184+
},
185+
"limit": 0
186+
}
187+
],
188+
"writeConcern": {
189+
"w": 0
190+
}
191+
}
192+
}
193+
}
194+
]
195+
}
196+
]
197+
},
198+
{
199+
"description": "Unacknowledged deleteMany with hint document on 4.4+ server",
200+
"runOnRequirements": [
201+
{
202+
"minServerVersion": "4.4.0"
203+
}
204+
],
205+
"operations": [
206+
{
207+
"object": "collection0",
208+
"name": "bulkWrite",
209+
"arguments": {
210+
"requests": [
211+
{
212+
"deleteMany": {
213+
"filter": {
214+
"_id": {
215+
"$gt": 1
216+
}
217+
},
218+
"hint": {
219+
"_id": 1
220+
}
221+
}
222+
}
223+
]
224+
},
225+
"expectResult": {
226+
"$$unsetOrMatches": {
227+
"acknowledged": {
228+
"$$unsetOrMatches": false
229+
}
230+
}
231+
}
232+
}
233+
],
234+
"expectEvents": [
235+
{
236+
"client": "client0",
237+
"events": [
238+
{
239+
"commandStartedEvent": {
240+
"command": {
241+
"delete": "coll0",
242+
"deletes": [
243+
{
244+
"q": {
245+
"_id": {
246+
"$gt": 1
247+
}
248+
},
249+
"hint": {
250+
"$$type": [
251+
"string",
252+
"object"
253+
]
254+
},
255+
"limit": 0
256+
}
257+
],
258+
"writeConcern": {
259+
"w": 0
260+
}
261+
}
262+
}
263+
}
264+
]
265+
}
266+
]
267+
}
268+
]
269+
}

0 commit comments

Comments
 (0)