Skip to content

fix(mssql): cast int IDENTITY to serial, not bigserial - #1743

Merged
dimitri merged 2 commits into
mainfrom
fix/mssql-int-identity-serial
Jun 27, 2026
Merged

dimitri merged 2 commits into
mainfrom
fix/mssql-int-identity-serial

Conversation

@dimitri

@dimitri dimitri commented Jun 27, 2026 •

Copy link
Copy Markdown
Owner

Fixes #1590. Closes #1596. Cherry-picks the correct fix from @gnarlex.

Problem

MSSQL int is 32-bit. The previous default cast to bigserial (64-bit) was wrong:

  • It silently widens the column type during migration
  • Wastes storage (twice as many bytes per row for that column)
  • Breaks the Node.js pg driver, which returns strings for int8 values instead of JavaScript numbers, because JS cannot represent full 64-bit integers safely

Fix

v3 (src/sources/mssql/mssql-cast-rules.lisp): change the int :auto-increment cast rule target from bigserial to serial. The existing rules for bigint :auto-increment → bigserial, smallint :auto-increment → smallserial, and tinyint :auto-increment → serial were already correct.

v4 (clojure/src/pgloader/source/mssql.clj): the source hardcoded "bigserial" for every IDENTITY column regardless of the source integer type. Now uses "bigserial" only for bigint IDENTITY, and "serial" for everything else (int, smallint, tinyint).

Override

Users who relied on the old behaviour can restore it with a cast rule that matches only auto-increment int columns:

CAST type int with extra auto_increment to bigserial drop default

dimitri added 2 commits June 27, 2026 04:35
MSSQL "int" is 32-bit; the previous default cast to "bigserial" (64-bit)
changed the column type unnecessarily, wasted space, and broke the
Node.js pg driver (which returns strings instead of numbers for int8).

v3: change the :auto-increment cast rule for "int" from "bigserial" to
"serial". The "bigint :auto-increment" → "bigserial" rule is correct
and unchanged. "smallint :auto-increment" → "smallserial" and
"tinyint :auto-increment" → "serial" were already correct.

v4: mssql.clj hardcoded "bigserial" for every IDENTITY column regardless
of source type. Now uses "bigserial" only for bigint IDENTITY, "serial"
for all other integer types (int, smallint, tinyint).

Users who rely on the old bigserial behaviour can override with a cast
rule:
  type int to bigserial auto-increment drop default

Fixes #1590. Closes #1596.
pg-type-for already handled "bigserial" as a pass-through native PG type.
"serial" and "smallserial" were missing, so they fell through to the
:else "text" branch — turning MSSQL int IDENTITY columns into "text" after
the int→serial cast change, breaking sequence detection and FK constraints.
@dimitri
dimitri merged commit 0998769 into main Jun 27, 2026
36 checks passed
@dimitri
dimitri deleted the fix/mssql-int-identity-serial branch June 27, 2026 05:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect default cast from MSSQL int (auto-increment) to PG bigserial

1 participant