ReviewOS

stacks/bun-query-builder

A schema.unix() attribute is generated as integer on Postgres, so millisecond timestamps overflow it

#1194
Closed glennmichael123 opened this 7 days ago ·
7 days ago

What happens

An attribute validated with schema.unix() (a Unix timestamp in @stacksjs/validation) is generated as integer on PostgreSQL. Millisecond timestamps (Date.now(), date.getTime(), ~1.7e12) overflow it:

INSERT INTO "print_devices" (..., "last_ping", ...) VALUES (...)
PostgresError: integer out of range

SQLite never shows it: its INTEGER is 64-bit.

Where

unix is not a case in either normalizer, so it falls through to "no opinion" and the column ends up integer:

  • packages/bun-query-builder/src/column-types.ts normalizeAttributeType
  • packages/bun-query-builder/src/migrations.ts, the rule-based normalizer (the case 'number': block around L628)

Stacks' own legacy mapper already says the opposite: storage/framework/core/database/src/validators.ts returns bigint for unix.

Repro

Stacks' PrintDevice model, lastPing: { validation: { rule: schema.unix() }, factory: faker => faker.date.recent().getTime() }, buddy migrate:regenerate postgres (bun-query-builder 0.3.20):

"last_ping" integer default 0,

then buddy seed fails on print_devices with integer out of range.

Proposed fix

Recognise unix in both normalizers and map it to bigint, so a declared timestamp gets a column wide enough for it. This is not the number question the comments there settle: number stays integer, and the model is right to say unix when it means a timestamp.

Found during the Stacks dashboard sweep against a seeded PostgreSQL database (stacksjs/stacks#2995 has the setup).

Sign in to comment on this issue.