I'm having an issue that I can only assume is a 32-bit integer overflow issue. I'm running on 64-bit Linux boxes with the 64-bit builds of MongoDB v1.6.3.
Here's the deal:
I have a collection used for logging and aggregate counters. I'm using an upsert with $inc to increment these counters. When the counters get over 2^31, it rolls over to negative.
I've been able to reproduce it with the ruby driver:
require 'rubygems'
require 'mongo'
mongo = Mongo::Connection.new "localhost"
db = mongo.db "test"
db.collection('junk').drop
(0..20).each do |i|
db.collection('junk').update({:name=>'luke'}, {"$inc"=>{:total=>123456789}}, {:upsert=>true})
puts db.collection('junk').find({}, {:fields=>{:_id=>0}}).to_a.inspect
end
and that outputs: (I've bolded the line where it flips negative)
[
{"name"=>"luke", "total"=>123456789}]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
[
]
I suspect that initially MongoDB is storing the integer using the 4-byte integer data type, but when my upsert increments it, it isn't converted to the 8-byte integer.
Just for fun, I tried upserting a large number and it indeed is stored just fine (I suspect it is created as an 8-byte integer):
db.collection('junk').drop
db.collection('junk').update({:name=>'luke'}, {"$inc"=>{:total=>9999999999999}}, {:upsert=>true})
puts db.collection('junk').find({}, {:fields=>{:_id=>0}}).to_a.inspect
and that outputs (which is clearly an 8-byte integer):
[
{"name"=>"luke", "total"=>9999999999999}]