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

aggregation $concat expression is inconsistent in type checking with all other string expressions

    • Query Optimization

      $concat expression tests if all arguments passed to it are of type String and then calls coerceToString before concatenating them.

      All other expressions that expect a string just call coerceToString on the argument(s) and rely on that to throw an error if the conversion is impossible.

      I think all string-expecting expressions should be consistent - if the passed in value can be coerced to string then do that.

      db.foo.aggregate({$project:{dateToString:{$substr:["$d",0,4]},_id:0}})
      { "dateToString" : "2017" }
      db.foo.aggregate({$project:{dateToString:{$toUpper:"$d"},_id:0}})
      { "dateToString" : "2017-08-01T17:29:05" }
      db.foo.aggregate({$project:{dateToString:{$toLower:"$d"},_id:0}})
      { "dateToString" : "2017-08-01t17:29:05" }
      db.foo.aggregate({$project:{dateToString:{$concat:["$d","_"]},_id:0}})
      assert: command failed: {
      	"ok" : 0,
      	"errmsg" : "$concat only supports strings, not date",
      	"code" : 16702,
      	"codeName" : "Location16702",
      	"$clusterTime" : {
      		"clusterTime" : Timestamp(1501608545, 1),
      		"signature" : {
      			"hash" : BinData(0,"y9mqIQNK2OhW40Hm2VIctAxrgcQ="),
      			"keyId" : NumberLong("6448521287567409154")
      		}
      	},
      	"operationTime" : Timestamp(1501608545, 1)
      } : aggregate failed
      _getErrorWithCode@src/mongo/shell/utils.js:25:13
      doassert@src/mongo/shell/assert.js:16:14
      assert.commandWorked@src/mongo/shell/assert.js:403:5
      DB.prototype._runAggregate@src/mongo/shell/db.js:250:9
      DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1269:12
      @(shell):1:1
      
      2017-08-01T10:48:52.841-0700 E QUERY    [thread1] Error: command failed: {
      	"ok" : 0,
      	"errmsg" : "$concat only supports strings, not date",
      	"code" : 16702,
      	"codeName" : "Location16702",
      	"$clusterTime" : {
      		"clusterTime" : Timestamp(1501608545, 1),
      		"signature" : {
      			"hash" : BinData(0,"y9mqIQNK2OhW40Hm2VIctAxrgcQ="),
      			"keyId" : NumberLong("6448521287567409154")
      		}
      	},
      	"operationTime" : Timestamp(1501608545, 1)
      } : aggregate failed :
      _getErrorWithCode@src/mongo/shell/utils.js:25:13
      doassert@src/mongo/shell/assert.js:16:14
      assert.commandWorked@src/mongo/shell/assert.js:403:5
      DB.prototype._runAggregate@src/mongo/shell/db.js:250:9
      DBCollection.prototype.aggregate@src/mongo/shell/collection.js:1269:12
      @(shell):1:1
      

      I can work-around by wrapping what's passed to $concat in {{$substr:[ <expr>, 0, 99999]]] but it seems silly and inconsistent.

            Assignee:
            backlog-query-optimization [DO NOT USE] Backlog - Query Optimization
            Reporter:
            asya.kamsky@mongodb.com Asya Kamsky
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: