find_one_and_update ignores upsert:false option

XMLWordPrintableJSON

    • Type: Bug
    • Resolution: Fixed
    • Priority: Unknown
    • 4.4.0, 4.3.1
    • Affects Version/s: 4.2.0, 4.3.0
    • Component/s: None
    • None
    • None
    • C Drivers
    • Not Needed
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      The collection::find_one_and_update function appears to ignore the upsert:false option supplied via options::find_one_and_replace.

      Environment

      Mongo CXX driver version: 4.3.0.

      macOS 26.3.1, AARCH64.

      Xcode 26.5 and associated clang version (Apple clang version 21.0.0).

      Mongo 8.0.3 (Docker image)

      How to Reproduce

      The following inserts a new document when, if I understand correctly, it should insert nothing (no-op):

      {{    __    }}mongocxx::instance inst{};
          __    }}mongocxx::client client{mongocxx::uri{"mongodb://localhost:27017";
      {{    __    }}auto coll = client["testdb"]["upsert_test"];
      {{    __    }}coll.drop();
      {{    __    }}coll.insert_one(bsoncxx::from_json(R"({"_id": "x", "field": "original"})"));

      {{    __    }}mongocxx::options::find_one_and_update opts;
      {{    __    }}opts.upsert(false);
      {{    __    }}coll.find_one_and_update(
      {{    __    }}    bsoncxx::from_json(R"({"_id": "nonexistent"})"),
          __    }}    bsoncxx::from_json(R"({"$set": {"field": "new")"),
      {{    __    }}    opts);

      Additional Background

      I could be mistaken, but I believe the bug is in find_one_and_update_impl in collection.cpp.  Specifically, this line:
          if (options.upsert()) {
              flags = static_cast<mongoc_find_and_modify_flags_t>(flags | MONGOC_FIND_AND_MODIFY_UPSERT);
          }
      If I'm understanding correctly, the upsert() function returns an optional, which means the upsert flag will get set if the optional has any value (true or false) rather than setting the flag when the optional has a value and that value is true.

            Assignee:
            Ezra Chung
            Reporter:
            Wes Janik
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: