Skip to content

Commit 198901c

Browse files
committed
CDRIVER-2017 fix bulk-op validation logic
1 parent b525917 commit 198901c

File tree

2 files changed

+546
-22
lines changed

2 files changed

+546
-22
lines changed

src/mongoc/mongoc-bulk-operation.c

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,28 @@ mongoc_bulk_operation_destroy (mongoc_bulk_operation_t *bulk) /* IN */
119119
(((_write_cmd->type) == (_write_cmd_type)) && \
120120
(_write_cmd)->n_documents < MONGOC_DEFAULT_WRITE_BATCH_SIZE)
121121

122+
/* already failed, e.g. a bad call to mongoc_bulk_operation_insert? */
123+
#define BULK_EXIT_IF_PRIOR_ERROR \
124+
do { \
125+
if (bulk->result.error.domain) { \
126+
EXIT; \
127+
} \
128+
} while (0)
129+
130+
#define BULK_RETURN_IF_PRIOR_ERROR \
131+
do { \
132+
if (bulk->result.error.domain) {\
133+
if (error != &bulk->result.error) {\
134+
bson_set_error (error, \
135+
MONGOC_ERROR_COMMAND, \
136+
MONGOC_ERROR_COMMAND_INVALID_ARG, \
137+
"Bulk operation is invalid from prior error: %s", \
138+
bulk->result.error.message); \
139+
}; \
140+
return false; \
141+
}; \
142+
} while (0)
143+
122144

123145
bool
124146
_mongoc_bulk_operation_remove_with_opts (mongoc_bulk_operation_t *bulk,
@@ -134,10 +156,7 @@ _mongoc_bulk_operation_remove_with_opts (mongoc_bulk_operation_t *bulk,
134156
BSON_ASSERT (bulk);
135157
BSON_ASSERT (selector);
136158

137-
if (bulk->result.error.domain) {
138-
/* already failed e.g. a bad call to mongoc_bulk_operation_insert */
139-
RETURN (true);
140-
}
159+
BULK_RETURN_IF_PRIOR_ERROR;
141160

142161
if (bulk->commands.len) {
143162
last = &_mongoc_array_index (
@@ -166,6 +185,10 @@ mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk,
166185
bson_t opts_dup;
167186
bson_iter_t iter;
168187

188+
ENTRY;
189+
190+
BULK_RETURN_IF_PRIOR_ERROR;
191+
169192
if (opts && bson_iter_init_find (&iter, opts, "limit")) {
170193
if ((!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) ||
171194
!bson_iter_as_int64 (&iter)) {
@@ -174,7 +197,7 @@ mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk,
174197
MONGOC_ERROR_COMMAND_INVALID_ARG,
175198
"%s expects the 'limit' option to be 1",
176199
BSON_FUNC);
177-
return false;
200+
RETURN (false);
178201
}
179202

180203
return _mongoc_bulk_operation_remove_with_opts (
@@ -190,7 +213,7 @@ mongoc_bulk_operation_remove_one_with_opts (mongoc_bulk_operation_t *bulk,
190213
bulk, selector, &opts_dup, error);
191214
bson_destroy (&opts_dup);
192215

193-
return retval;
216+
RETURN (retval);
194217
}
195218

196219
bool
@@ -203,6 +226,10 @@ mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk,
203226
bson_t opts_dup;
204227
bson_iter_t iter;
205228

229+
ENTRY;
230+
231+
BULK_RETURN_IF_PRIOR_ERROR;
232+
206233
if (opts && bson_iter_init_find (&iter, opts, "limit")) {
207234
if ((!BSON_ITER_HOLDS_INT32 (&iter) && !BSON_ITER_HOLDS_INT64 (&iter)) ||
208235
bson_iter_as_int64 (&iter)) {
@@ -211,11 +238,11 @@ mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk,
211238
MONGOC_ERROR_COMMAND_INVALID_ARG,
212239
"%s expects the 'limit' option to be 0",
213240
BSON_FUNC);
214-
return false;
241+
RETURN (false);
215242
}
216243

217-
return _mongoc_bulk_operation_remove_with_opts (
218-
bulk, selector, opts, error);
244+
RETURN (_mongoc_bulk_operation_remove_with_opts (
245+
bulk, selector, opts, error));
219246
}
220247

221248
bson_init (&opts_dup);
@@ -227,7 +254,7 @@ mongoc_bulk_operation_remove_many_with_opts (mongoc_bulk_operation_t *bulk,
227254
bulk, selector, &opts_dup, error);
228255
bson_destroy (&opts_dup);
229256

230-
return retval;
257+
RETURN (retval);
231258
}
232259

233260

@@ -238,6 +265,10 @@ mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */
238265
bson_t opts;
239266
bson_error_t *error = &bulk->result.error;
240267

268+
ENTRY;
269+
270+
BULK_EXIT_IF_PRIOR_ERROR;
271+
241272
bson_init (&opts);
242273
BSON_APPEND_INT32 (&opts, "limit", 0);
243274

@@ -249,6 +280,8 @@ mongoc_bulk_operation_remove (mongoc_bulk_operation_t *bulk, /* IN */
249280
if (error->domain) {
250281
MONGOC_WARNING ("%s", error->message);
251282
}
283+
284+
EXIT;
252285
}
253286

254287

@@ -259,6 +292,10 @@ mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */
259292
bson_t opts;
260293
bson_error_t *error = &bulk->result.error;
261294

295+
ENTRY;
296+
297+
BULK_EXIT_IF_PRIOR_ERROR;
298+
262299
bson_init (&opts);
263300
BSON_APPEND_INT32 (&opts, "limit", 1);
264301

@@ -269,6 +306,8 @@ mongoc_bulk_operation_remove_one (mongoc_bulk_operation_t *bulk, /* IN */
269306
if (error->domain) {
270307
MONGOC_WARNING ("%s", error->message);
271308
}
309+
310+
EXIT;
272311
}
273312

274313
void
@@ -305,6 +344,13 @@ mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk,
305344
BSON_ASSERT (bulk);
306345
BSON_ASSERT (document);
307346

347+
BULK_EXIT_IF_PRIOR_ERROR;
348+
349+
if (!_mongoc_validate_new_document (document, &bulk->result.error)) {
350+
MONGOC_WARNING ("%s", bulk->result.error.message);
351+
EXIT;
352+
}
353+
308354
if (bulk->commands.len) {
309355
last = &_mongoc_array_index (
310356
&bulk->commands, mongoc_write_command_t, bulk->commands.len - 1);
@@ -322,7 +368,6 @@ mongoc_bulk_operation_insert (mongoc_bulk_operation_t *bulk,
322368
bulk->operation_id,
323369
!mongoc_write_concern_is_acknowledged (bulk->write_concern));
324370

325-
_mongoc_validate_new_document (document, &bulk->result.error);
326371
_mongoc_array_append_val (&bulk->commands, command);
327372

328373
EXIT;
@@ -340,10 +385,7 @@ _mongoc_bulk_operation_replace_one_with_opts (mongoc_bulk_operation_t *bulk,
340385

341386
ENTRY;
342387

343-
if (bulk->result.error.domain) {
344-
/* already failed e.g. a bad call to mongoc_bulk_operation_insert */
345-
RETURN (true);
346-
}
388+
BULK_RETURN_IF_PRIOR_ERROR;
347389

348390
BSON_ASSERT (bulk);
349391
BSON_ASSERT (selector);
@@ -378,6 +420,8 @@ mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk,
378420
bson_t opts;
379421
bson_error_t *error = &bulk->result.error;
380422

423+
ENTRY;
424+
381425
bson_init (&opts);
382426
BSON_APPEND_BOOL (&opts, "upsert", upsert);
383427
BSON_APPEND_BOOL (&opts, "multi", false);
@@ -389,6 +433,8 @@ mongoc_bulk_operation_replace_one (mongoc_bulk_operation_t *bulk,
389433
if (error->domain) {
390434
MONGOC_WARNING ("%s", error->message);
391435
}
436+
437+
EXIT;
392438
}
393439

394440
bool
@@ -444,11 +490,13 @@ _mongoc_bulk_operation_update_with_opts (mongoc_bulk_operation_t *bulk,
444490
mongoc_write_command_t command = {0};
445491
mongoc_write_command_t *last;
446492

493+
ENTRY;
494+
447495
BSON_ASSERT (bulk);
448496
BSON_ASSERT (selector);
449497
BSON_ASSERT (document);
450498

451-
ENTRY;
499+
BULK_RETURN_IF_PRIOR_ERROR;
452500

453501
if (!_mongoc_validate_update (document, error)) {
454502
RETURN (false);
@@ -481,18 +529,20 @@ mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk,
481529
bson_t opts_dup;
482530
bson_iter_t iter;
483531

532+
ENTRY;
533+
484534
if (opts && bson_iter_init_find (&iter, opts, "multi")) {
485535
if (!BSON_ITER_HOLDS_BOOL (&iter) || bson_iter_bool (&iter)) {
486536
bson_set_error (error,
487537
MONGOC_ERROR_COMMAND,
488538
MONGOC_ERROR_COMMAND_INVALID_ARG,
489539
"%s expects the 'multi' option to be false",
490540
BSON_FUNC);
491-
return false;
541+
RETURN (false);
492542
}
493543

494-
return _mongoc_bulk_operation_update_with_opts (
495-
bulk, selector, document, opts, error);
544+
RETURN (_mongoc_bulk_operation_update_with_opts (
545+
bulk, selector, document, opts, error));
496546
}
497547

498548
bson_init (&opts_dup);
@@ -504,7 +554,7 @@ mongoc_bulk_operation_update_one_with_opts (mongoc_bulk_operation_t *bulk,
504554
bulk, selector, document, &opts_dup, error);
505555
bson_destroy (&opts_dup);
506556

507-
return retval;
557+
RETURN (retval);
508558
}
509559

510560
bool
@@ -518,14 +568,16 @@ mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
518568
bson_t opts_dup;
519569
bson_iter_t iter;
520570

571+
ENTRY;
572+
521573
if (opts && bson_iter_init_find (&iter, opts, "multi")) {
522574
if (!BSON_ITER_HOLDS_BOOL (&iter) || !bson_iter_bool (&iter)) {
523575
bson_set_error (error,
524576
MONGOC_ERROR_COMMAND,
525577
MONGOC_ERROR_COMMAND_INVALID_ARG,
526578
"%s expects the 'multi' option to be true",
527579
BSON_FUNC);
528-
return false;
580+
RETURN (false);
529581
}
530582

531583
return _mongoc_bulk_operation_update_with_opts (
@@ -541,7 +593,7 @@ mongoc_bulk_operation_update_many_with_opts (mongoc_bulk_operation_t *bulk,
541593
bulk, selector, document, &opts_dup, error);
542594
bson_destroy (&opts_dup);
543595

544-
return retval;
596+
RETURN (retval);
545597
}
546598

547599
void
@@ -553,6 +605,10 @@ mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk,
553605
bson_t opts;
554606
bson_error_t *error = &bulk->result.error;
555607

608+
ENTRY;
609+
610+
BULK_EXIT_IF_PRIOR_ERROR;
611+
556612
bson_init (&opts);
557613
BSON_APPEND_BOOL (&opts, "upsert", upsert);
558614
BSON_APPEND_BOOL (&opts, "multi", true);
@@ -565,6 +621,8 @@ mongoc_bulk_operation_update (mongoc_bulk_operation_t *bulk,
565621
if (error->domain) {
566622
MONGOC_WARNING ("%s", error->message);
567623
}
624+
625+
EXIT;
568626
}
569627

570628
void
@@ -576,6 +634,10 @@ mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk,
576634
bson_t opts;
577635
bson_error_t *error = &bulk->result.error;
578636

637+
ENTRY;
638+
639+
BULK_EXIT_IF_PRIOR_ERROR;
640+
579641
bson_init (&opts);
580642
BSON_APPEND_BOOL (&opts, "upsert", upsert);
581643
BSON_APPEND_BOOL (&opts, "multi", false);
@@ -588,6 +650,8 @@ mongoc_bulk_operation_update_one (mongoc_bulk_operation_t *bulk,
588650
if (error->domain) {
589651
MONGOC_WARNING ("%s", error->message);
590652
}
653+
654+
EXIT;
591655
}
592656

593657
uint32_t

0 commit comments

Comments
 (0)