As part of
CDRIVER-2373, db38474 and ef63400 added a "bypassDocumentValidation" option to the insert, update, and replace with_opts functions in mongoc-bulk-operation.c. This doesn't make sense, as mongoc_bulk_operation_t already tracks bypass_document_validation on its own. The bulk-level option is set at init time and applies to all commands executed within the bulk.
If we consider inserts, we can see that mongoc_bulk_operation_insert_with_opts() calls _mongoc_bulk_insert_opts_parse() to validate the options. Assuming that the bson_t *opts argument is successfully parsed into _mongoc_bulk_insert_opts_t insert_opts, only insert_opts.validate is used later in the function. The other bypass and extra fields on that struct are completely ignored.
There are now two paths: we either append to and existing insert command or create a new one. If we append to an existing insert, we delegate to _mongoc_write_command_insert_append() and only pass the validated document. The bypass option for insert_with_opts has been ignored.
Assuming we create a new insert command, we delegate to _mongoc_write_command_init_insert and pass our empty mongoc_write_command_t command struct, the validated document and bson_t *opts, and our bulk->flags (which contains the original "ordered" and "bypassDocumentValidation" options used to create the mongoc_bulk_operation_t.
Jumping into mongoc-write-command.c, _mongoc_write_command_init_insert() delegates to _mongoc_write_command_init_bulk() to initialize a mongoc_write_command_t command. This function copies the cmd_opts (originally bson_t *opts) into the command->cmd_opts and also assigns bulk->flags to command->flags.
Further down the line, _mongoc_write_opquery() and _mongoc_write_opmsg() will both end up calling _mongoc_write_command_init(), which may end up appending "bypassDocumentValidation" into the command document again based on command->flags.
I believe there are a few errors here:
- According to the CRUD spec, the bulk write models were never intended to support a "bypassDocumentValidation" option. That option is supported only on bulkWrite() and other non-bulk methods (e.g. insertOne(), updateMany()).
- The current behavior in libmongoc is prone to appending "bypassDocumentValidation" multiple times in some cases, and disregarding the mongoc_bulk_operation_t-level option in other cases.
- In the event that an inserted document is appended to an existing insert command, the operation-level "bypassDocumentValidation" may be ignored entirely. This can be unexpected from the user's perspective, as it depends entirely on the order in which operations are added to a bulk.
Ideally, libmongoc should prohibit a "bypassDocumentValidation" option for functions that add insert, replace, and update operations to a bulk write.