-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
fix(postgres/mssql/saphana): include primary key in upsert when explicitly provided #11820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…typeorm#11556) When using upsert() with a primary key as the conflict path, PostgreSQL now correctly updates existing rows instead of creating duplicates. This aligns PostgreSQL behavior with MSSQL by including auto-increment primary keys in INSERT statements when users explicitly provide ID values.
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to b39fa41
Previous suggestionsSuggestions up to commit 4f9e3a9
Suggestions up to commit 842661f
Suggestions up to commit 97ee592
|
|||||||||||||||||||||||||||||||||||||||||
|
Hello! Why did you close the PR? |
|
I noticed that the tests I added were failing for both SAP and MSSQL, so I temporarily closed the PR because it seems like some adjustments are needed. I also have a few personal commitments at the moment, so I’ll revisit and fix the issues as soon as I can! |
commit: |
Test Failures AnalysisWhile adding tests for #11556, I discovered two pre-existing bugs in the MERGE INTO implementation that were previously untested. Based on my analysis, these failures appear to be not caused by my changes but were revealed by the new test case. However, I acknowledge that I might be missing something in my analysis. If my changes are indeed causing these issues, I'm happy to investigate further and provide a more comprehensive fix. Bug 1: SAP HANA - Missing column in MERGE sourceTest Case
Error MessageRoot CauseIn However, Flow of the issue:
Why it wasn't caught before
Evidence that this is pre-existingI tested by reverting my changes completely: git stash
# Run test with original code
npm run test:fast -- --grep "should upsert with primary key as conflict path"Result: Same failure occurs, confirming this is not caused by my changes. Proposed FixAdd SAP to the condition at line 749 in !(
(this.connection.driver.options.type === "mssql" ||
this.connection.driver.options.type === "sap" || // Add SAP
DriverUtils.isPostgresFamily(this.connection.driver)) &&
this.isOverridingAutoIncrementBehavior(column)
)Bug 2: MSSQL - DEFAULT not allowed for IDENTITY columns in MERGETest CaseSame test: Error MessageEnvironment: CI Linux environment (ubuntu-18) Root CauseIn if (
(column.isGenerated && column.generationStrategy === "uuid" && ...) ||
(column.isGenerated && column.generationStrategy !== "uuid") // ← Problem
) {
expression += `DEFAULT` // ← Uses DEFAULT even when user provided explicit value
}The issue:
Why it wasn't caught before
Proposed FixIn if (
(column.isGenerated &&
column.generationStrategy === "uuid" &&
this.connection.driver.isUUIDGenerationSupported()) ||
(column.isGenerated &&
column.generationStrategy !== "uuid" &&
!this.isOverridingAutoIncrementBehavior(column)) // Add this check
) {
expression += `DEFAULT`
} else {
expression += `${mergeSourceAlias}.${this.escape(column.databaseName)}`
}SummaryMy Changes (in this PR)// src/query-builder/InsertQueryBuilder.ts:748-753
!(
- this.connection.driver.options.type === "mssql" &&
+ (this.connection.driver.options.type === "mssql" ||
+ DriverUtils.isPostgresFamily(this.connection.driver)) &&
this.isOverridingAutoIncrementBehavior(column)
)What my changes do:
What my changes DON'T do:
The Real IssuesBoth test failures are caused by pre-existing bugs in the MERGE INTO implementation:
These bugs existed before my changes but were never caught because:
Next StepsI see a few options: Option A: Fix all bugs in this PR
Option B: Fix SAP only in this PR
Option C: Separate PRs
Verification RequestI want to be completely sure my analysis is correct. If reviewers spot anything I'm missing or if my changes are actually causing these issues, please let me know. I'm happy to:
The last thing I want is to introduce bugs while fixing another issue. Your feedback is greatly appreciated! |
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨No code suggestions found for the PR. |
|
If you don’t mind, could you please take a look at the issue when you have a moment? |
gioboa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some tests failed, I merged develop into this branch to align it and trigger the tests
gioboa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few tests are failing, can you verify them please? @CHOIJEWON
|
comment: #11820 (comment) I’m not sure if my previous comment might have been missed, but I did some analysis on why the tests are failing. |
gioboa
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, option A is the best one I guess.
Btw we can't merge a PR with failed tests, the button is disabled 🙈
Thanks for your great help 🙏🚀
Both SAP HANA and MSSQL do not allow inserting explicit values into
IDENTITY columns. This commit fixes MERGE INTO upsert when using
primary keys or other identity columns as conflict paths.
The fix ensures identity columns are:
1. Included in USING clause (needed for ON clause conflict detection)
2. Set to DEFAULT in INSERT clause (instead of explicit values)
Changes:
- createMergeIntoSourceExpression: Add conflict path columns to USING
clause even when auto-generated (for ON clause matching)
- createMergeIntoInsertValuesExpression: Check isOverridingAutoIncrementBehavior
before inserting values, use DEFAULT for identity columns
Fixes errors:
- SAP HANA: 'cannot insert generated identity column field id'
- MSSQL: 'Cannot insert explicit value for identity column when IDENTITY_INSERT is OF'
…lumns Fixes 'DEFAULT not allowed for IDENTITY columns in MERGE' error when explicitly providing values for auto-increment primary keys in MERGE queries. This mirrors the existing IDENTITY_INSERT handling in createInsertExpression() for consistency. The SET IDENTITY_INSERT wrapper is only applied when: - Using MSSQL driver - Entity has metadata - User explicitly provides values for identity columns
PR Reviewer Guide 🔍Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||
|
The PR has been updated! |
Description of change
Fixes #11556
This PR addresses multiple related issues with upsert operations when using identity/auto-increment columns as conflict
paths across PostgreSQL, MSSQL, and SAP HANA.
🐛 Problems
1. PostgreSQL: Duplicate Rows on Primary Key Upsert
When using
upsert()with a primary key as the conflict path in PostgreSQL, the method creates duplicate rows insteadof updating existing ones.
Reproduction:
2. SAP HANA/MSSQL: Identity Columns as Conflict Paths Fail
MERGE INTO queries fail when using identity columns as conflict paths:
cannot insert generated identity column field idCannot insert explicit value for identity column when IDENTITY_INSERT is OFF3. MSSQL: IDENTITY_INSERT Not Applied to MERGE Queries
When explicitly providing values for identity columns in MERGE queries:
DEFAULT not allowed for IDENTITY columns in MERGESET IDENTITY_INSERTwas only applied to INSERT queries, not MERGE💡 Root Causes
Issue 1: PostgreSQL Auto-Increment Exclusion
In
getInsertedColumns(), auto-increment primary keys were filtered out for PostgreSQL, even when users explicitlyprovided values. This caused the ON CONFLICT clause to fail.
Issue 2: MERGE INTO Source Missing Conflict Columns
In
createMergeIntoSourceExpression(), identity columns were excluded from the USING clause, preventing the ON clausefrom matching correctly.
Additionally,
createMergeIntoInsertValuesExpression()tried to insert explicit values into identity columns, which isprohibited in SAP HANA and MSSQL.
Issue 3: Missing IDENTITY_INSERT for MERGE
The
createMergeExpression()method lacked the IDENTITY_INSERT wrapper that was already present increateInsertExpression().✅ Solutions
Fix 1: Include Primary Keys in PostgreSQL Upserts
Applied the same
isOverridingAutoIncrementBehavior()logic used for MSSQL to PostgreSQL:Fix 2: Support Identity Columns in MERGE Conflict Paths
2a. Include conflict columns in USING clause:
2b. Use DEFAULT for identity columns in INSERT values:
Fix 3: Add IDENTITY_INSERT to MERGE Queries
Mirrors the existing IDENTITY_INSERT handling from
createInsertExpression():🧪 Testing
New test case added:
Test results:
🔍 Impact Analysis
Affected Drivers
Breaking Changes
None. These are bug fixes that enable previously broken functionality.
Pull-Request Checklist
masterbranchFixes #11556