fix(db2): Include identity offered a clause Db2 does not have - #267
Merged
Conversation
Tested the identity-insert matrix against the live engines rather than reading it: create a table with an identity column, write an explicit value using exactly the ceremony the app prescribes, then ask the engine to generate the *next* id and see whether it collides. Db2 was listed as `overriding`, which the data-copy path lets through. Verified on Db2 LUW 11.5 that this cannot work: `OVERRIDING SYSTEM VALUE` is **SQL0104N** in every position (before the column list, after it, on INSERT … SELECT), and a plain insert into GENERATED ALWAYS is **SQL0798N**. There is no override — so the copy started and then failed mid-run, which is the single outcome that table exists to prevent. Db2 is `unsupported` now, with the same advice Oracle gives: turn the toggle off, or make the column GENERATED BY DEFAULT (which does take an explicit value — also verified). The unit tests asserted the same wrong thing the code did, which is why this survived; they now encode what the servers actually answered. What the run confirmed as already correct: * Postgres — `OVERRIDING SYSTEM VALUE` accepted, and `resyncSequence: true` is right: after writing id 500 the generator is still behind, so the next generated id collides. That is the quiet one, and the matrix has it. * MySQL — plain insert, and the counter moves past the written value (`resyncSequence: false`). * Oracle — refuses GENERATED ALWAYS with ORA-32795, exactly as documented. * SQL Server — the session toggle only holds inside one batch; separate statements land on a different session and the insert is rejected. The migrate path already refuses `toggle` with a message saying it does not issue SET IDENTITY_INSERT, so that limit is honestly stated. * GENERATED BY DEFAULT relaxes the requirement on Postgres, Db2 and Oracle. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_147c8f56-b1ae-4f50-aa19-d544ed3f0a1c) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Tested the identity-insert capability matrix against the live engines instead
of reading it. For each dialect: create a table with an identity column, write an
explicit value using exactly the ceremony the app prescribes, then ask the engine
to generate the next id and see whether it collides.
The bug
Db2 was listed as
overriding, and the data-copy path letsoverridingthrough.Verified on Db2 LUW 11.5 that this can never work:
INSERT … (ID, NOTE) OVERRIDING SYSTEM VALUE VALUES …INSERT … SELECTThere is no override clause on Db2 LUW — that is Postgres (and Db2 for i/z-OS).
So "Include identity" started the copy and failed it mid-run, which is the one
outcome this table exists to prevent. Db2 is
unsupportednow, with the adviceOracle already gives: switch the toggle off, or make the column GENERATED BY
DEFAULT — which does accept an explicit value, also verified.
The unit tests asserted the same wrong thing as the code, which is exactly why it
survived; they now encode what the servers answered.
What the run confirmed as already correct
OVERRIDING SYSTEM VALUEaccepted, andresyncSequence: trueis right: after writing id 500 the generator is still behind it, so the next
generated id collides. That is the quiet failure mode, and the matrix has it.
(
resyncSequence: false).separate statements it lands on another session and the insert is rejected. The
migrate path already refuses
togglewith a message saying it does not issueSET IDENTITY_INSERT, so that limitation is stated honestly.
Verification
npx vitest run— 1799 passed, 95 skipped ·tsc --noEmitclean · eslint clean.🤖 Generated with Claude Code
Note
Medium Risk
Changes data-migrate and insert SQL shaping for Db2 identity columns; wrong classification could block valid copies or allow failing runs, but behavior is aligned with live Db2 LUW testing and BY DEFAULT remains supported.
Overview
Db2 LUW no longer uses Postgres-style
OVERRIDING SYSTEM VALUEfor “Include identity.” The dialect capability table now marks Db2 asunsupportedfor GENERATED ALWAYS identity writes (with user-facing guidance to turn off Include identity or use GENERATED BY DEFAULT), because live verification on Db2 LUW 11.5 shows the override clause is rejected (SQL0104N) and plain inserts into ALWAYS fail (SQL0798N).Postgres-family behavior is unchanged — only
postgres,cockroachdb, andyugabytedbstill get the overriding clause on ALWAYS; Db2 is removed from that list in tests and inbuildPeekInsertcommentary.Tests now match engine behavior: Db2 ALWAYS is expected to be refused via
identityInsertFor, while Db2 BY DEFAULT remains writable (native).Reviewed by Cursor Bugbot for commit d625edb. Bugbot is set up for automated code reviews on this repo. Configure here.