CBR heuristicCE tasserts for $mod divisor LLONG_MIN

    • Type: Bug
    • Resolution: Unresolved
    • Priority: Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Query Optimization
    • ALL
    • Hide
      /**
       * Reproduces a heuristic CBR tassert for a valid $mod predicate whose divisor is LLONG_MIN.
       *
       * The heuristic estimator computes 1.0 / std::abs(divisor). Since std::abs(LLONG_MIN)
       * overflows a signed long long, the computed selectivity can become negative and trip the
       * SelectivityType validity assertion.
       *
       * @tags: [
       *   requires_fcv_83,
       * ]
       */
      
      const conn = MongoRunner.runMongod({
          setParameter: {
              featureFlagCostBasedRanker: true,
              internalQueryCBRCEMode: "heuristicCE",
              internalQueryFrameworkControl: "forceClassicEngine",
          },
      });
      const testDB = conn.getDB(jsTestName());
      const coll = testDB.mod_llong_min_heuristic_ce_crash;
      coll.drop();
      assert.commandWorked(coll.insertMany([
          {_id: 0, a: 0, b: NumberLong("0")},
          {_id: 1, a: 1, b: NumberLong("1")},
          {_id: 2, a: 1, b: NumberLong("-9223372036854775808")},
      ]));
      
      assert.commandWorked(coll.createIndex({a: 1}));
      assert.commandWorked(coll.createIndex({b: 1}));
      const query = {
          a: 1,
          b: {$mod: [NumberLong("-9223372036854775808"), NumberLong("0")]},
      };
      
      // WILL FAIL: 9274201 "Invalid Selectivity value < minValue: (-1.0842e-19 < 0)"
      assert.commandWorked(testDB.runCommand({find: coll.getName(), filter: query}));
      MongoRunner.stopMongod(conn);
       
      Show
      /**  * Reproduces a heuristic CBR tassert for a valid $mod predicate whose divisor is LLONG_MIN.  *  * The heuristic estimator computes 1.0 / std::abs(divisor). Since std::abs(LLONG_MIN)  * overflows a signed long long , the computed selectivity can become negative and trip the  * SelectivityType validity assertion.  *  * @tags: [  *   requires_fcv_83,  * ]  */ const conn = MongoRunner.runMongod({     setParameter: {         featureFlagCostBasedRanker: true ,         internalQueryCBRCEMode: "heuristicCE" ,         internalQueryFrameworkControl: "forceClassicEngine" ,     }, }); const testDB = conn.getDB(jsTestName()); const coll = testDB.mod_llong_min_heuristic_ce_crash; coll.drop(); assert .commandWorked(coll.insertMany([     {_id: 0, a: 0, b: NumberLong( "0" )},     {_id: 1, a: 1, b: NumberLong( "1" )},     {_id: 2, a: 1, b: NumberLong( "-9223372036854775808" )}, ])); assert .commandWorked(coll.createIndex({a: 1})); assert .commandWorked(coll.createIndex({b: 1})); const query = {     a: 1,     b: {$mod: [NumberLong( "-9223372036854775808" ), NumberLong( "0" )]}, }; // WILL FAIL: 9274201 "Invalid Selectivity value < minValue: (-1.0842e-19 < 0)" assert .commandWorked(testDB.runCommand({find: coll.getName(), filter: query})); MongoRunner.stopMongod(conn);
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      With non-default internalQueryCBRCEMode: "heuristicCE", a valid $mod query can fail with assertion 9274201 when the divisor is NumberLong("-9223372036854775808").

      The heuristic estimator computes selectivity using std::abs() on the signed $mod divisor. For LLONG_MIN, the absolute value is not representable as long long, so this can produce a negative selectivity. 

      This is not severe because heuristicCE is not the default CBR mode. This appears related to SERVER-99958, but that fix did not cover the LLONG_MIN edge case.

       

            Assignee:
            Unassigned
            Reporter:
            Max Verbinnen
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: