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

Fix SBE stage builder to not use lambda closures

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 6.3.0-rc0
    • Affects Version/s: None
    • Component/s: None
    • Labels:
    • Query Execution
    • Fully Compatible
    • ALL
    • QE 2023-02-06, QE 2023-02-20
    • 135
    • 5

      Fix SBE stage builder to not use lambda closures. Lambda closures are not supported and any translation that relies on lambda closures works by a pure coincidence, and may stop working at any time.

       

      As part of fixing/verifying the fix, we should add asserts/verificiation when compiling EExpression that rejects compilation of accessing closure variables. Possibly by:

      a) verifying the EExpression itself

      b) by asserting during lambda compilation that there are no unbound variables leaking out of lambda body. This could be done by asserting that the collection of frames in empty inside CodeFragment::appendNoStack

       

      Example of  expression with lambda capture. l2.0 is used inside the nested lambda:

      traverseP(s7, lambda(l1.0) { makeBsonObj(MakeObjSpec(keep, ["_id"], ["b"]), l1.0,
      [j0]     let [
      [j0]         l2.0 = s6
      [j0]     ]
      [j0]     in
      [j0]         let [
      [j0]             l7.0 = s4
      [j0]         ]
      [j0]         in
      [j0]             if (typeMatch(l7.0, 1088ll) ?: true)
      [j0]             then null
      [j0]             else
      [j0]                 if isArray(l7.0)
      [j0]                 then traverseP(l7.0, lambda(l3.0) {
      [j0]                     if (coerceToBool(
      [j0]                         let [
      [j0]                             l6.0 =
      [j0]                                 let [
      [j0]                                     l4.0 = s5
      [j0]                                     l4.1 = l3.0
      [j0]                                 ]
      [j0]                                 in
      [j0]                                     if ((typeMatch(l4.0, 1088ll) ?: true) || (typeMatch(l4.1, 1088ll) ?: true))
      [j0]                                     then null
      [j0]                                     else
      [j0]                                         if ((!(isNumber(l4.0)) && !(isDate(l4.0))) || (!(isNumber(l4.1)) && !(isDate(l4.1))))
      [j0]                                         then fail(4974201, "only numbers and dates are allowed in an $add expression")
      [j0]                                         else
      [j0]                                             let [
      [j0]                                                 l5.0 = l4.0
      [j0]                                                 l5.1 = l4.1
      [j0]                                             ]
      [j0]                                             in
      [j0]                                                 if (isDate(l5.0) && isDate(l5.1))
      [j0]                                                 then fail(4974202, "only one date allowed in an $add expression")
      [j0]                                                 else (l5.0 + l5.1)
      [j0]
      [j0]                             l6.1 = l2.0
      [j0]                         ]
      [j0]                         in (((l6.0 <=> l6.1) >= 0) ?: ((exists(l6.0) && typeMatch(l6.0, -65ll)) >= (exists(l6.1) && typeMatch(l6.1, -65ll))))
      [j0]                    ) ?: false)
      [j0]                     then l3.0
      [j0]                     else Nothing
      [j0]                 }, 1)
      [j0]                 else fail(5073201, "input to $filter must be an array")
      [j0] ) }, Nothing) 

      This expression comes from a projection generated by test: https://github.com/10gen/mongo/blob/master/jstests/aggregation/expressions/filter.js#L105

       

      There could be other code paths that generate such expression.

       

       

            Assignee:
            andrew.paroski@mongodb.com Drew Paroski
            Reporter:
            anna.wawrzyniak@mongodb.com Anna Wawrzyniak
            Votes:
            0 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated:
              Resolved: