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

Copy-paste A to B in shell; A != B

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.2.1
    • Component/s: Shell
    • None
    • ALL
    • Hide

      A short demonstration:

      // insert a document into a new table with an integer
      db.demo.insert({"bar": NumberInt(1)})
      //--> WriteResult({ "nInserted" : 1 })
      
      // good so far
      db.demo.find()
      //--> { "_id" : ObjectId("56b4c8127c635f488e84d88c"), "bar" : 1 }
      
      // confirm the field is of type int
      // ref: https://docs.mongodb.org/manual/reference/operator/query/type
      db.demo.count({"bar": {"$type": 16}})
      //--> 1
      
      // copy-paste the doc from the second query into a second table
      db.demo2.insert({ "_id" : ObjectId("56b4c8127c635f488e84d88c"), "bar" : 1 })
      //--> WriteResult({ "nInserted" : 1 })
      
      // The data has changed!
      db.demo2.count({"bar": {"$type": 16}})
      //--> 0
      
      // This no-longer-equivalent doc instead has a double :(
      db.demo2.count({"bar": {"$type": 1}})
      //--> 1
      
      Show
      A short demonstration: // insert a document into a new table with an integer db.demo.insert({ "bar" : NumberInt(1)}) //--> WriteResult({ "nInserted" : 1 }) // good so far db.demo.find() //--> { "_id" : ObjectId( "56b4c8127c635f488e84d88c" ), "bar" : 1 } // confirm the field is of type int // ref: https://docs.mongodb.org/manual/reference/ operator /query/type db.demo.count({ "bar" : { "$type" : 16}}) //--> 1 // copy-paste the doc from the second query into a second table db.demo2.insert({ "_id" : ObjectId( "56b4c8127c635f488e84d88c" ), "bar" : 1 }) //--> WriteResult({ "nInserted" : 1 }) // The data has changed! db.demo2.count({ "bar" : { "$type" : 16}}) //--> 0 // This no-longer-equivalent doc instead has a double :( db.demo2.count({ "bar" : { "$type" : 1}}) //--> 1

      When using the mongo shell, copying a query result into an insert will not yield the same document. In particular, types can change: integer fields will be casted to doubles. To put it simply, if you copy-paste A to B, A ! = B. Yikes!

      This was a big surprise to me, and contrasts with other types like object ids and timestamps, which are printed with their wrapping functions. Offhand, I see two options for fixing this:

      Option 1: If the shell has a default type interpretation (doubles), non-doubles should be printed in query results wrapped in their function (`NumberInt`). This is consistent with the other aforementioned types, and would make copy-paste work correctly.

      Option 2: Queries in the shell could interpret integers as integers, rather than casting everything to a double. I like this option less, as it's a breaking change to shell behavior and could lead to similarly unintuitive behavior for other use cases.

            Assignee:
            Unassigned Unassigned
            Reporter:
            NathanielKofalt Nathaniel Kofalt
            Votes:
            0 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: