Uploaded image for project: 'C Driver'
  1. C Driver
  2. CDRIVER-2738

Bulk functions for insert, update, and replace should not support bypassDocumentValidation option

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 1.13.0
    • Affects Version/s: 1.10.0
    • Component/s: libmongoc

      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.

            Assignee:
            jesse@mongodb.com A. Jesse Jiryu Davis
            Reporter:
            jmikola@mongodb.com Jeremy Mikola
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: