Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-56284

SBE $add with Date and NumberDecimal arguments trips invariant

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 5.0.0-rc0
    • Affects Version/s: None
    • Component/s: Query Execution
    • Labels:
      None
    • Fully Compatible
    • ALL
    • Hide

      Minimal reproduction with SBE on:

      db.foo.insert({a: NumberDecimal("819.5359123621083")}}})
      db.foo.aggregate([{$project: {a: {$add: [new Date("2019-01-30T07:30:10.137Z"), "$a"]}, _id: 0}}])
      

      Backtrace captured in gdb

      0x00007ffff69a1737 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0
      (gdb) bt
      #0  0x00007ffff69a1737 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0
      #1  0x000055555f185670 in mongo::breakpoint () at src/mongo/util/debugger.cpp:72
      #2  0x000055555f11da11 in mongo::invariantFailed (expr=0x55555fccc44d "Hit a MONGO_UNREACHABLE!", file=0x55555fccc428 "src/mongo/db/exec/sbe/values/value.h", line=1117) at src/mongo/util/assert_util.cpp:119
      #3  0x000055555cf1f829 in mongo::sbe::value::numericCast<long> (tag=mongo::sbe::value::TypeTags::NumberDecimal, val=140737120359477) at src/mongo/db/exec/sbe/values/value.h:1117
      #4  0x000055555cf1bad9 in mongo::sbe::vm::(anonymous namespace)::genericArithmeticOp<mongo::sbe::vm::(anonymous namespace)::Addition> (lhsTag=mongo::sbe::value::TypeTags::NumberDecimal, lhsValue=140737120359477, rhsTag=mongo::sbe::value::TypeTags::Date, rhsValue=1548833503742)
          at src/mongo/db/exec/sbe/vm/arith.cpp:178
      #5  0x000055555cf18581 in mongo::sbe::vm::ByteCode::genericAdd (this=0x7fffeb1e4f00, lhsTag=mongo::sbe::value::TypeTags::NumberDecimal, lhsValue=140737120359477, rhsTag=mongo::sbe::value::TypeTags::Date, rhsValue=1548833503742) at src/mongo/db/exec/sbe/vm/arith.cpp:376
      #6  0x000055555cf36c10 in mongo::sbe::vm::ByteCode::run (this=0x7fffeb1e4f00, code=0x7ffff053fa20) at src/mongo/db/exec/sbe/vm/vm.cpp:3253
      #7  0x000055555ced6278 in mongo::sbe::ProjectStage::getNext (this=0x7fffeb1e4e20) at src/mongo/db/exec/sbe/stages/project.cpp:86
      #8  0x000055555ceca483 in mongo::sbe::MakeObjStageBase<(mongo::sbe::MakeObjOutputType)1>::getNext (this=0x7fffeaf01c20) at src/mongo/db/exec/sbe/stages/makeobj.cpp:362
      #9  0x000055555cf095c0 in mongo::sbe::TraverseStage::traverse (this=0x7fffeaf00820, inFieldAccessor=0x7fffea110ce0, outFieldOutputAccessor=0x7fffeaf00920, level=0) at src/mongo/db/exec/sbe/stages/traverse.cpp:242
      #10 0x000055555cf08de6 in mongo::sbe::TraverseStage::getNext (this=0x7fffeaf00820) at src/mongo/db/exec/sbe/stages/traverse.cpp:152
      #11 0x000055555cbbdd81 in mongo::fetchNext (root=0x7fffeaf00820, resultSlot=0x7fffeaf00920, recordIdSlot=0x7fffeb204b00, out=0x7ffff7ebfb80, dlOut=0x0, returnOwnedBson=true) at src/mongo/db/query/plan_executor_sbe.cpp:315
      #12 0x000055555cbbd55c in mongo::PlanExecutorSBE::getNext (this=0x7ffff08b7220, out=0x7ffff7ebfb80, dlOut=0x0) at src/mongo/db/query/plan_executor_sbe.cpp:234
      #13 0x000055555c44fed9 in mongo::(anonymous namespace)::handleCursorCommand (opCtx=0x7fffea2dd020, expCtx=0x7fffea8de8a0 = {...}, nsForCursor=..., cursors=std::vector of length 1, capacity 1 = {...}, request=..., cmdObj=owned BSONObj 208 bytes @ 0x7
      

      Classic engine behavior:

      > db.foo.aggregate([{$project: {a: {$add: [new Date("2019-01-30T07:30:10.137Z"), "$a"]}, _id: 0}}])
      { "a" : ISODate("2019-01-30T07:30:10.957Z") }
      
      Show
      Minimal reproduction with SBE on: db.foo.insert({a: NumberDecimal("819.5359123621083")}}}) db.foo.aggregate([{$project: {a: {$add: [new Date("2019-01-30T07:30:10.137Z"), "$a"]}, _id: 0}}]) Backtrace captured in gdb 0x00007ffff69a1737 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0 (gdb) bt #0 0x00007ffff69a1737 in raise () from /lib/x86_64-linux-gnu/libpthread.so.0 #1 0x000055555f185670 in mongo::breakpoint () at src/mongo/util/debugger.cpp:72 #2 0x000055555f11da11 in mongo::invariantFailed (expr=0x55555fccc44d "Hit a MONGO_UNREACHABLE!", file=0x55555fccc428 "src/mongo/db/exec/sbe/values/value.h", line=1117) at src/mongo/util/assert_util.cpp:119 #3 0x000055555cf1f829 in mongo::sbe::value::numericCast<long> (tag=mongo::sbe::value::TypeTags::NumberDecimal, val=140737120359477) at src/mongo/db/exec/sbe/values/value.h:1117 #4 0x000055555cf1bad9 in mongo::sbe::vm::(anonymous namespace)::genericArithmeticOp<mongo::sbe::vm::(anonymous namespace)::Addition> (lhsTag=mongo::sbe::value::TypeTags::NumberDecimal, lhsValue=140737120359477, rhsTag=mongo::sbe::value::TypeTags::Date, rhsValue=1548833503742) at src/mongo/db/exec/sbe/vm/arith.cpp:178 #5 0x000055555cf18581 in mongo::sbe::vm::ByteCode::genericAdd (this=0x7fffeb1e4f00, lhsTag=mongo::sbe::value::TypeTags::NumberDecimal, lhsValue=140737120359477, rhsTag=mongo::sbe::value::TypeTags::Date, rhsValue=1548833503742) at src/mongo/db/exec/sbe/vm/arith.cpp:376 #6 0x000055555cf36c10 in mongo::sbe::vm::ByteCode::run (this=0x7fffeb1e4f00, code=0x7ffff053fa20) at src/mongo/db/exec/sbe/vm/vm.cpp:3253 #7 0x000055555ced6278 in mongo::sbe::ProjectStage::getNext (this=0x7fffeb1e4e20) at src/mongo/db/exec/sbe/stages/project.cpp:86 #8 0x000055555ceca483 in mongo::sbe::MakeObjStageBase<(mongo::sbe::MakeObjOutputType)1>::getNext (this=0x7fffeaf01c20) at src/mongo/db/exec/sbe/stages/makeobj.cpp:362 #9 0x000055555cf095c0 in mongo::sbe::TraverseStage::traverse (this=0x7fffeaf00820, inFieldAccessor=0x7fffea110ce0, outFieldOutputAccessor=0x7fffeaf00920, level=0) at src/mongo/db/exec/sbe/stages/traverse.cpp:242 #10 0x000055555cf08de6 in mongo::sbe::TraverseStage::getNext (this=0x7fffeaf00820) at src/mongo/db/exec/sbe/stages/traverse.cpp:152 #11 0x000055555cbbdd81 in mongo::fetchNext (root=0x7fffeaf00820, resultSlot=0x7fffeaf00920, recordIdSlot=0x7fffeb204b00, out=0x7ffff7ebfb80, dlOut=0x0, returnOwnedBson=true) at src/mongo/db/query/plan_executor_sbe.cpp:315 #12 0x000055555cbbd55c in mongo::PlanExecutorSBE::getNext (this=0x7ffff08b7220, out=0x7ffff7ebfb80, dlOut=0x0) at src/mongo/db/query/plan_executor_sbe.cpp:234 #13 0x000055555c44fed9 in mongo::(anonymous namespace)::handleCursorCommand (opCtx=0x7fffea2dd020, expCtx=0x7fffea8de8a0 = {...}, nsForCursor=..., cursors=std::vector of length 1, capacity 1 = {...}, request=..., cmdObj=owned BSONObj 208 bytes @ 0x7 Classic engine behavior: > db.foo.aggregate([{$project: {a: {$add: [new Date("2019-01-30T07:30:10.137Z"), "$a"]}, _id: 0}}]) { "a" : ISODate("2019-01-30T07:30:10.957Z") }
    • Query Execution 2021-05-03, Query Execution 2021-05-17

      This was a result of an aggregation_expression_multiversion_fuzzer run here.

      The pipeline that caused the failure was

      {"$project":{"a":{"$add":[{"$numberDecimal":"236.27711376769366"},{"$date":"2019-01-30T07:30:10.137Z"},93369,"$obj.obj.obj.num"]},"_id":0}} // 63
      

      And the offending document was

      {_id: 795, "str": "Generic Cotton", "num": NumberLong("59052"), "date": new Date("2019-10-23T11:18:26.197Z"), "array": ["hacking Trail", new Date("2019-09-28T08:32:07.826Z"), {_id: 796, "str": "Gloves", "num": NumberInt(38192), "date": new Date("2019-06-17T13:26:06.579Z"), "array": [], "obj": {_id: 797, "str": "Rubber Executive synthesizing", "num": NumberLong("3345"), "array": [new Date("2019-02-12T08:50:16.240Z"), "full-range", NaN], }, }, NumberLong("58726"), {_id: 798, "str": "Grove Minnesota", "obj": {}, }, ["Soft overriding Credit Card Account", new Date("2019-06-11T21:54:58.779Z"), new Date("2019-11-15T07:02:19.029Z")], NumberLong("43776"), {_id: 799, "num": NumberDecimal("556.1485031177453"), "date": new Date("2019-01-31T02:54:44.487Z"), "array": [NaN, new Date("2019-07-13T20:56:58.610Z"), NumberInt(87918)], }, [NumberLong("27821"), "Baht olive"], NumberDecimal("103.72360506453242")], "obj": {_id: 800, "num": NumberInt(98410), "array": null, "obj": {_id: 801, "date": new Date("2019-10-14T06:31:08.955Z"), "obj": {_id: 802, "str": null, "num": NumberDecimal("819.5359123621083"), "date": new Date("2019-04-26T02:33:00.523Z"), "array": [], }, }, }, }, // 136
      

      The invariant tripped in the logs

      Error
      
      "Invariant failure","attr":{"expr":"Hit a MONGO_UNREACHABLE!","file":"src/mongo/db/exec/sbe/values/value.h","line":1125}
       "About to run the command","attr":{"db":"fuzzer","commandArgs":{"aggregate":"fuzzer_coll","pipeline":[{"$project":{"a":{"$add":[{"$numberDecimal":"236.27711376769366"},{"$date":"2019-01-30T07:30:10.137Z"},93369,"$obj.obj.obj.num"]},"_id":0}}],"maxTimeMS":30000,"collation":{"locale":"el","strength":1},"apiVersion":"1","cursor":{},"lsid":{"id":{"$uuid":"dce47dbf-436c-4638-90ed-0a42401e5d29"}},"$db":"fuzzer"}}
       "Invariant failure","attr":{"expr":"Hit a MONGO_UNREACHABLE!","file":"src/mongo/db/exec/sbe/values/value.h","line":1125}
       "\n\n***aborting after invariant() failure\n\n"
       "Writing fatal message","attr":{"message":"Got signal: 6 (Aborted).\n"}
      

       

      Possible Cause:

      We handle this case correctly if $add is evaluated using the doubleDoubleSum() builtin. However, there is constant folding going on for this query and $add is executed using genericArithemticOp<Addition> which is trying to compute addition of a NumberDecimal and a Date. The MONGO_UNREACHABLE case is being hit when trying to cast a NumberDecimal to a long and it can't do that because of the std::is_same_v check.

      In the classic engine, we track decimal addition in 'decimalTotal' in a Decimal128 variable and then do decimal to long conversions at the end with a rounding scheme.

            Assignee:
            justin.seyster@mongodb.com Justin Seyster
            Reporter:
            eric.cox@mongodb.com Eric Cox (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: