Skip to content

64-bit INTEGERs: reads silently truncate to 32 bits, binds past 2^31 raise OverflowError #43

Description

@UKTailwind

SQLite INTEGER columns are 64-bit, but the module converts through 32-bit calls in both directions:

  • bindParameter() uses sqlite3_bind_int(..., mp_obj_get_int(value)) — binding any Python int past 2^31−1 raises OverflowError (on 32-bit mp_int_t builds). Epoch-millisecond timestamps, the most common thing to store, cannot be bound at all.
  • usqlite_column_value() uses sqlite3_column_int() — reading a stored 64-bit value silently wraps to 32 bits. No error, just wrong data: SELECT returns a different number than was inserted with SQL literals or by another tool.

Repro:

db.execute("CREATE TABLE t (v INTEGER)")
db.execute("INSERT INTO t VALUES (1753305600123)")   # SQL literal: stores fine
db.execute("SELECT v FROM t").fetchone()             # returns wrapped garbage
db.execute("INSERT INTO t VALUES (?)", (1753305600123,))  # OverflowError

Fix is two lines — sqlite3_bind_int64 + mp_obj_get_ll, and sqlite3_column_int64 + mp_obj_new_int_from_ll — included in PR #41 with a roundtrip test (tests/test_fix456.py) covering ±2^62, negatives, and the 2^31 boundary.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions