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
SQLite INTEGER columns are 64-bit, but the module converts through 32-bit calls in both directions:
bindParameter()usessqlite3_bind_int(..., mp_obj_get_int(value))— binding any Python int past 2^31−1 raises OverflowError (on 32-bitmp_int_tbuilds). Epoch-millisecond timestamps, the most common thing to store, cannot be bound at all.usqlite_column_value()usessqlite3_column_int()— reading a stored 64-bit value silently wraps to 32 bits. No error, just wrong data:SELECTreturns a different number than was inserted with SQL literals or by another tool.Repro:
Fix is two lines —
sqlite3_bind_int64+mp_obj_get_ll, andsqlite3_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