From: Jeremy Hinegardner Date: 2008-02-16T07:14:01+09:00 Subject: sqlite3-ruby 64bit bug --+HP7ph2BbKc20aGI Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hey all, It appears that I have found a bug in sqlite3-ruby relating to 64bit integer inserts. http://rubyforge.org/tracker/index.php?func=detail&aid=18087&group_id=254&atid=1043 I figured I should say something here in case someone else hits it too. There is a patch attached to the above ticket that works for me, but may not be the best solution for the issue. If you are inserting into a column, and the value is greater than a C 'int' but still a Ruby Fixnum, you will see an exception. I've attached a program that you can use to test to see if you are affected. $ ruby sqlite-64bit-test.rb Ruby : 1.8.6 (2007-09-24 patchlevel 111) [x86_64-linux] system maximumn 'int' : 1073741823 Last Fixnum : 4611686018427387903 is a Fixnum First Bignum : 4611686018427387904 is a Bignum Insert 1073741823 into sqlite : Succeeded (returned 1073741823 as a String) Insert 4611686018427387904 into sqlite : Succeeded (returned 4611686018427387904 as a String) Insert 4611686018427387903 into sqlite : Failed because integer 4611686018427387903 too big to convert to `int' enjoy, -jeremy -- ======================================================================== Jeremy Hinegardner jeremy@hinegardner.org --+HP7ph2BbKc20aGI Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="sqlite-64bit-test.rb" require 'rubygems' require 'sqlite3' require 'dl' # system max 'int' is nums = [ ] max_int = ( 2 ** ( 8 * DL::ALIGN_INT - 2 ) - 1 ) nums << max_int # first bignum is 2 ** ( bit arch of machine - 1) - ruby uses 1 bit for Fixnum # detection, then there will be one bit for the sign bits = ( 8 * DL::ALIGN_VOIDP ) - 2 nums << (first_bignum = 1 << bits) # last fixnum therefore is the number before the first bignum nums << (last_fixnum = first_bignum - 1) results = [ [ "Ruby" , "#{RUBY_VERSION} (#{RUBY_RELEASE_DATE} patchlevel #{RUBY_PATCHLEVEL}) [#{RUBY_PLATFORM}]"], [ "system maximumn 'int'" , "#{max_int}"], [ "Last Fixnum" , "#{last_fixnum} is a #{last_fixnum.class}" ], [ "First Bignum" , "#{first_bignum} is a #{first_bignum.class}" ], ] db = ::SQLite3::Database.new(":memory:") db.execute("CREATE TABLE t1(x INTEGER);") nums.each do |x| test = [ "Insert #{x} into sqlite" ] begin db.execute( "INSERT INTO t1(x) VALUES (:x)", { :x => x } ) s = db.execute("SELECT * from t1").last[0] test << "Succeeded (returned #{s} as a #{s.class})" rescue => e test << "Failed because #{e}" end results << test end results.each { |k,v| puts "#{k.ljust(40)} : #{v}" } --+HP7ph2BbKc20aGI--