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

SBE stage builder is broken for SORT when SORT comes before FETCH

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 4.9.0
    • Affects Version/s: None
    • Component/s: Querying
    • Labels:
      None
    • Fully Compatible
    • ALL
    • Hide

      After starting a server with test commands enabled:

      MongoDB Enterprise > db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true})
      { "was" : true, "ok" : 1 }
      MongoDB Enterprise > db.c.drop()
      true
      MongoDB Enterprise > db.c.createIndex({a: 1, b: 1})
      {
      	"createdCollectionAutomatically" : true,
      	"numIndexesBefore" : 1,
      	"numIndexesAfter" : 2,
      	"ok" : 1
      }
      MongoDB Enterprise > db.c.find({a: {$gt: 0}}).sort({b: 1, a: 1}).explain()
      uncaught exception: Error: explain failed: {
      	"ok" : 0,
      	"errmsg" : "undefined slot accessor:7021802381092324643",
      	"code" : 4822848,
      	"codeName" : "Location4822848"
      } :
      _getErrorWithCode@src/mongo/shell/utils.js:25:13
      throwOrReturn@src/mongo/shell/explainable.js:25:19
      constructor/this.finish@src/mongo/shell/explain_query.js:176:24
      DBQuery.prototype.explain@src/mongo/shell/query.js:534:12
      @(shell):1:1
      

      From the logs, the SBE plan looks something like this:

      {"t":{"$date":"2020-07-15T19:01:32.199-04:00"},"s":"D5", "c":"QUERY",    "id":4822860, "ctx":"conn1","msg":"SBE plan","attr":{"slots":"$$RESULT=s10 $$RID=s11 ","stages":"nlj [] [s1]
          left
              sort [s6, s8, s1] [s7564601]
              traverse s8 s9 s5 {if (s9 <=> s8 < 0, s9, s8)}
              in
                  project [s9 = s5]
                  limit 1
                  coscan
              from
                  traverse s6 s7 s4 {if (s7 <=> s6 < 0, s7, s6)}
                  in
                      project [s7 = s4]
                      limit 1
                      coscan
                  from
                      project [s4 = getField (s7564601, \"b\"), s5 = getField (s7564601, \"a\")]
                      nlj [] [s2, s3]
                          left
                              project [s3 = KS(33FFFFFFFFFFFFFFFFF0FE04), s2 = KS(29F0FE04)]
                              limit 1
                              coscan
                          right
                              ixseek s2 s3 s1 [] @\"65d12415-21b9-449d-adb7-b1d00de77f64\" @\"a_1_b_1\" true
          right
              limit 1
              seek s1 s10 s11 [] @\"65d12415-21b9-449d-adb7-b1d00de77f64\"
      "}}
      
      Show
      After starting a server with test commands enabled: MongoDB Enterprise > db.adminCommand({setParameter: 1, internalQueryEnableSlotBasedExecutionEngine: true }) { "was" : true , "ok" : 1 } MongoDB Enterprise > db.c.drop() true MongoDB Enterprise > db.c.createIndex({a: 1, b: 1}) { "createdCollectionAutomatically" : true , "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } MongoDB Enterprise > db.c.find({a: {$gt: 0}}).sort({b: 1, a: 1}).explain() uncaught exception: Error: explain failed: { "ok" : 0, "errmsg" : "undefined slot accessor:7021802381092324643" , "code" : 4822848, "codeName" : "Location4822848" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 throwOrReturn@src/mongo/shell/explainable.js:25:19 constructor/ this .finish@src/mongo/shell/explain_query.js:176:24 DBQuery.prototype.explain@src/mongo/shell/query.js:534:12 @(shell):1:1 From the logs, the SBE plan looks something like this: {"t":{"$date":"2020-07-15T19:01:32.199-04:00"},"s":"D5", "c":"QUERY", "id":4822860, "ctx":"conn1","msg":"SBE plan","attr":{"slots":"$$RESULT=s10 $$RID=s11 ","stages":"nlj [] [s1] left sort [s6, s8, s1] [s7564601] traverse s8 s9 s5 {if (s9 <=> s8 < 0, s9, s8)} in project [s9 = s5] limit 1 coscan from traverse s6 s7 s4 {if (s7 <=> s6 < 0, s7, s6)} in project [s7 = s4] limit 1 coscan from project [s4 = getField (s7564601, \"b\"), s5 = getField (s7564601, \"a\")] nlj [] [s2, s3] left project [s3 = KS(33FFFFFFFFFFFFFFFFF0FE04), s2 = KS(29F0FE04)] limit 1 coscan right ixseek s2 s3 s1 [] @\"65d12415-21b9-449d-adb7-b1d00de77f64\" @\"a_1_b_1\" true right limit 1 seek s1 s10 s11 [] @\"65d12415-21b9-449d-adb7-b1d00de77f64\" "}}
    • Query 2020-10-05, Query 2020-10-19, Query 2020-11-02, Query 2020-11-16

      When the SBE stage builder creates an SBE for a QuerySolution tree where a SORT happens before FETCH, the resulting plan is incorrect and fails, probably during the prepare() step with an "undefined slot accessor" error. It appears that we are attempting to use a bogus slot id (note the "s7564601" in the SBE plan below).

      After looking at this with justin.seyster, we are guessing that the slot id comes from assuming that _data.resultSlot was initialized by buildFetch(), but in this scenario buildFetch() hasn't been called yet.

            Assignee:
            andrew.paroski@mongodb.com Drew Paroski
            Reporter:
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: