Re: ON CONFLICT DO SELECT (take 3)
Viktor Holmberg <v@viktorh.net>
From: "v@viktorh.net" <v@viktorh.net>
To: Dean Rasheed <dean.a.rasheed@gmail.com>,
jian he <jian.universality@gmail.com>
Cc: pgsql-hackers@postgresql.org
Date: 2025-11-17T22:06:59Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Add support for INSERT ... ON CONFLICT DO SELECT.
- 88327092ff06 19 (unreleased) landed
-
doc: Fix statement about ON CONFLICT and deferrable constraints.
- f188bc5145b5 15.16 landed
- 4c4fa53b9d2d 14.21 landed
- 8348004b54a7 16.12 landed
- 7a02ac28ab11 17.8 landed
- e9443a55265f 19 (unreleased) landed
- ae627d8a3cb0 18.2 landed
-
Fix ON CONFLICT ON CONSTRAINT during REINDEX CONCURRENTLY
- 2bc7e886fc1b 19 (unreleased) cited
Attachments
- v11-0001-Add-support-for-ON-CONFLICT-DO-SELECT-FOR.patch (application/octet-stream) patch v11-0001
- v11-0002-ON-CONFLICT-DO-SELCT-Fixes-after-review.patch (application/octet-stream) patch v11-0002
>> I did some simple tests, found out that
>> SELECT FOR UPDATE, the lock mechanism seems to be working as intended.
>> We can add some tests on contrib/pgrowlocks to demonstrate that.
Test added.
>> infer_arbiter_indexes
>> ereport(ERROR,
>> (errcode(ERRCODE_WRONG_OBJECT_TYPE),
>> errmsg("ON CONFLICT DO UPDATE not supported
>> with exclusion constraints")));
>> I guess this works for ON CONFLICT SELECT?
>> we can leave some comments on the function infer_arbiter_indexes,
>> and also add some tests on src/test/regress/sql/constraints.sql after line 570.
Good catch. In fact it did “work” as in "not crash" - but I think it shouldn’t.
With exclusion constraints, a single insert can conflict with multiple rows.
I assumed that’s why DO UPDATE doesn’t work with it - because it’d update multiple rows.
For the same reason, I think DO SELECT shouldn’t work either, as you could then
get multiple rows back for a single insert.
I guess in both cases you could make it so it updates/selects all conflicting rows - but I’d
really prefer to leave it as an error. If someone actually wants this to work with exclusion
constraints the error can always be removed in a future version. But if we add a multi-row-return
then we are locked in forever.
>> changing
>> OnConflictSetState
>> to
>> OnConflictActionState
>> could make it a separate patch.
Skipping this for now, let me know if you strongly object.
>> all these 3 patches can be merged together, I think.
Ok done. But these review fixes are separate for ease of review. Before merging they should
be folded in to the main/first commit.
>> "/* DO NOTHING or UPDATE? */"
>> this comment needs to be changed?
Done
>> ----------------------------------------
>> src/backend/rewrite/rewriteHandler.c
>> parsetree->onConflict->action == ONCONFLICT_UPDATE
>> maybe we also need to do some logic to the ONCONFLICT_SELECT
>> (I didn't check this part deeply)
Yes, this needed to be fixed to make updatable views work. Done.
>> If you compare it with the result above, it seems the updatable view behaves
>> inconsistent with ON CONFLICT DO SELECT versus ON CONFLICT DO UPDATE.
Yes, it was wrong. Nice catch. Fixed now I think, and test added.
I believe this new patch addresses all the issues found by Jian. I hope another review won’t find quite so much dirt!