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

Error when an agg pipeline assigns a value to the $$CURRENT builtin variable

    • Query Optimization
    • ALL

      In expressions such as $let which assign a value to a variable, the aggregation system errors when the variable name conflicts with a system variable or is otherwise illegal:

      > db.c.drop();
      > db.c.insert({_id: 1});
      
      > db.c.aggregate([{$project: {foo: {$let: {vars: {"FOO": 3}, in: "$$FOO"}}}}])
      assert: command failed: {
      	"operationTime" : Timestamp(0, 0),
      	"ok" : 0,
      	"errmsg" : "'FOO' starts with an invalid character for a user variable name",
      	"code" : 16867,
      	"codeName" : "Location16867"
      } : aggregate failed
      
      > db.c.aggregate([{$project: {foo: {$let: {vars: {"Foo": 3}, in: "$$Foo"}}}}])
      assert: command failed: {
      	"operationTime" : Timestamp(0, 0),
      	"ok" : 0,
      	"errmsg" : "'Foo' starts with an invalid character for a user variable name",
      	"code" : 16867,
      	"codeName" : "Location16867"
      } : aggregate failed
      
      > db.c.aggregate([{$project: {foo: {$let: {vars: {"%blah": 3}, in: "$$%blah"}}}}])
      assert: command failed: {
      	"operationTime" : Timestamp(0, 0),
      	"ok" : 0,
      	"errmsg" : "'%blah' starts with an invalid character for a user variable name",
      	"code" : 16867,
      	"codeName" : "Location16867"
      } : aggregate failed
      
      > db.c.aggregate([{$project: {foo: {$let: {vars: {"ROOT": 3}, in: "$$ROOT"}}}}])
      assert: command failed: {
      	"operationTime" : Timestamp(0, 0),
      	"ok" : 0,
      	"errmsg" : "'ROOT' starts with an invalid character for a user variable name",
      	"code" : 16867,
      	"codeName" : "Location16867"
      } : aggregate failed
      

      However, a user can write an agg pipeline which assigns to $$CURRENT. This should not be legal:

      > db.c.aggregate([{$project: {foo: {$let: {vars: {"CURRENT": 3}, in: "$$CURRENT"}}}}])
      { "_id" : 1, "foo" : 3 }
      

      We should also consider whether it is correct to expose $$CURRENT to user pipelines at all. Usually $$CURRENT acts as an alias for $$ROOT, but it has a special internal use in the implementation of $redact. Arguably exposing $$CURRENT is a mistake, since its special meaning is an implementation detail for the $redact stage.

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            david.storch@mongodb.com David Storch
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated: