Duplicate insert into a clustered collection whose _id contains a Decimal128 throws a KeyString format error

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: 7.0.0, 8.0.0, 8.2.0, 9.0.0-rc0, 8.3.0
    • Component/s: None
    • None
    • Storage Execution
    • ALL
    • Hide
        const conn = MongoRunner.runMongod({});
        const coll = conn.getDB("test").c;
        assert.commandWorked(conn.getDB("test").createCollection(
            "c", {clusteredIndex: {key: {_id: 1}, name: "id", unique: true}}));
        assert.commandWorked(coll.insert({_id: NumberDecimal("1.13")}));
        // Expected: DuplicateKey (11000). Actual: Location50810.
        assert.writeErrorWithCode(coll.insert({_id: NumberDecimal("1.13")}), 50810);
        MongoRunner.stopMongod(conn);
      
      Show
      const conn = MongoRunner.runMongod({}); const coll = conn.getDB( "test" ).c; assert.commandWorked(conn.getDB( "test" ).createCollection( "c" , {clusteredIndex: {key: {_id: 1}, name: "id" , unique: true }})); assert.commandWorked(coll.insert({_id: NumberDecimal( "1.13" )})); // Expected: DuplicateKey (11000). Actual: Location50810. assert.writeErrorWithCode(coll.insert({_id: NumberDecimal( "1.13" )}), 50810); MongoRunner.stopMongod(conn);
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      When an insert produces a DuplicateKey error on a clustered collection whose _id is a Decimal128, the server throws an uncaught KeyString format error, either 50810 for values >=1 or 50825 for values < 1.

      Root cause

      A clustered collection's RecordId is the KeyString encoding of _id with the TypeBits intentionally discarded, the type information lives only in the document body as mentioned on this comment.

      When there is a write conflict, to produce a user-friendly duplicate-key message, the insert path decodes the existing RecordId back to BSON. That decode runs with an empty TypeBits that is represents of kInt. When the values carry decimal-format markers then we throw in toBsonValue().

            Assignee:
            Unassigned
            Reporter:
            Ernesto Rodriguez Reina
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: