@@ -139,7 +139,12 @@ mongoc_bulkwriteopts_destroy (mongoc_bulkwriteopts_t *self)
139
139
typedef enum { MODEL_OP_INSERT , MODEL_OP_UPDATE , MODEL_OP_DELETE } model_op_t ;
140
140
typedef struct {
141
141
model_op_t op ;
142
- bson_iter_t id_iter ;
142
+ // `id_loc` locates the "_id" field of an insert document.
143
+ struct {
144
+ size_t op_start ; // Offset in `mongoc_bulkwrite_t::ops` to the BSON for the insert op: { "document": ... }
145
+ size_t op_len ; // Length of insert op.
146
+ uint32_t id_offset ; // Offset in the insert op to the "_id" field.
147
+ } id_loc ;
143
148
char * ns ;
144
149
} modeldata_t ;
145
150
@@ -277,19 +282,14 @@ mongoc_bulkwrite_append_insertone (mongoc_bulkwrite_t *self,
277
282
persisted_id_offset += existing_id_offset ;
278
283
}
279
284
280
- BSON_ASSERT (_mongoc_buffer_append (& self -> ops , bson_get_data (& op ), op .len ));
281
-
282
- // Store an iterator to the document's `_id` in the persisted payload:
283
- bson_iter_t persisted_id_iter ;
284
- {
285
- BSON_ASSERT (mcommon_in_range_size_t_unsigned (op .len ));
286
- size_t start = self -> ops .len - (size_t ) op .len ;
287
- BSON_ASSERT (bson_iter_init_from_data_at_offset (
288
- & persisted_id_iter , self -> ops .data + start , (size_t ) op .len , persisted_id_offset , strlen ("_id" )));
289
- }
285
+ size_t op_start = self -> ops .len ; // Save location of `op` to retrieve `_id` later.
286
+ BSON_ASSERT (mcommon_in_range_size_t_unsigned (op .len ));
287
+ BSON_ASSERT (_mongoc_buffer_append (& self -> ops , bson_get_data (& op ), (size_t ) op .len ));
290
288
291
289
self -> n_ops ++ ;
292
- modeldata_t md = {.op = MODEL_OP_INSERT , .id_iter = persisted_id_iter , .ns = bson_strdup (ns )};
290
+ modeldata_t md = {.op = MODEL_OP_INSERT ,
291
+ .id_loc = {.op_start = op_start , .op_len = (size_t ) op .len , .id_offset = persisted_id_offset },
292
+ .ns = bson_strdup (ns )};
293
293
_mongoc_array_append_val (& self -> arrayof_modeldata , md );
294
294
bson_destroy (& op );
295
295
return true;
@@ -1340,7 +1340,8 @@ static bool
1340
1340
_bulkwritereturn_apply_result (mongoc_bulkwritereturn_t * self ,
1341
1341
const bson_t * result ,
1342
1342
size_t ops_doc_offset ,
1343
- const mongoc_array_t * arrayof_modeldata )
1343
+ const mongoc_array_t * arrayof_modeldata ,
1344
+ const mongoc_buffer_t * ops )
1344
1345
{
1345
1346
BSON_ASSERT_PARAM (self );
1346
1347
BSON_ASSERT_PARAM (result );
@@ -1458,7 +1459,10 @@ _bulkwritereturn_apply_result (mongoc_bulkwritereturn_t *self,
1458
1459
break ;
1459
1460
}
1460
1461
case MODEL_OP_INSERT : {
1461
- _bulkwriteresult_set_insertresult (self -> res , & md -> id_iter , models_idx );
1462
+ bson_iter_t id_iter ;
1463
+ BSON_ASSERT (bson_iter_init_from_data_at_offset (
1464
+ & id_iter , ops -> data + md -> id_loc .op_start , md -> id_loc .op_len , md -> id_loc .id_offset , strlen ("_id" )));
1465
+ _bulkwriteresult_set_insertresult (self -> res , & id_iter , models_idx );
1462
1466
break ;
1463
1467
}
1464
1468
default :
@@ -1903,7 +1907,8 @@ mongoc_bulkwrite_execute (mongoc_bulkwrite_t *self, const mongoc_bulkwriteopts_t
1903
1907
// Iterate over cursor results.
1904
1908
const bson_t * result ;
1905
1909
while (mongoc_cursor_next (reply_cursor , & result )) {
1906
- if (!_bulkwritereturn_apply_result (& ret , result , ops_doc_offset , & self -> arrayof_modeldata )) {
1910
+ if (!_bulkwritereturn_apply_result (
1911
+ & ret , result , ops_doc_offset , & self -> arrayof_modeldata , & self -> ops )) {
1907
1912
goto batch_fail ;
1908
1913
}
1909
1914
}
0 commit comments