node-sqlite icon indicating copy to clipboard operation
node-sqlite copied to clipboard

I get wrong values from the database when using node-sqlite

Open sam1919 opened this issue 14 years ago • 2 comments

I have a table column where I store large numbers (seconds since 1970).

The bigints are stored correctly (I checked it on the sqlite console) but with the sqlite driver I get negative(!) values. What's wrong here?

sqlite3 console: sqlite> SELECT date FROM seen WHERE user='root' COLLATE NOCASE; 1296333940003

node-sqlite: { date: -746187876 }

I also tried "BIGINT UNSIGNED" with the same (wrong) result.

sam1919 avatar Jan 29 '11 21:01 sam1919

Hi Sam,

It seems your 'seconds' values are actually in milliseconds. If you SELECT date/1000 you should get correct results until 2038 or so ;)

I have committed a "fix" for this issue in changeset 20ed195db941163848313f74755d77ec0c0f6084. The cause was the node-sqlite code calling sqlite3_column_int rather than sqlite3_column_int64.

Sadly there is no support for 64bit integers in Node JS (that I know of) so the numbers are represented as doubles ... so you only get 52 bits of precision.

We could consider using a BigNum library for these values...

ghost avatar Jan 30 '11 02:01 ghost

Sam, what you're running into is an unfortunate cross-section of limitations present both in JavaSript and SQLite. SQLite's type affinity is forcing the driver to interpret the value in your select as an INTEGER column type. As Steven mentioned, JavaScript doesn't support very large integers. Because SQLite stores everything under the hood as strings, you could simply request your data as TEXT using CAST:

sqlite = require('./sqlite');
common = require('./tests/lib/common.js');

db = new sqlite.Database();

db.open(":memory:", function (error) {
  if (error) {
    console.log("Tonight. You.");
    throw error;
  }

  common.createTable
    ( db
    , 'a'
    , [ { name: 'b', type: 'INTEGER' } ]
    , function (error) {
        insertRow();
      }
    );

  function insertRow() {
    db.execute
      ( "INSERT INTO a VALUES (1296333940003)"
      , function (error, rows) {
          if (error) throw error;
          readRow2();
        }
      );
  }

  function readRow1() {
    db.execute
      ( "SELECT b FROM A"
      , function (error, rows) {
          if (error) throw error;
          console.dir(rows);
        }
      );
  }

  function readRow2() {
    db.execute
      ( "SELECT CAST(b AS TEXT) FROM A"
      , function (error, rows) {
          if (error) throw error;
          console.dir(rows);
        }
      );
  }
});


[ { b: '1296333940003' } ]

orlandov avatar Jan 31 '11 06:01 orlandov