Re: ON CONFLICT DO SELECT (take 3)

From: jian he <jian(dot)universality(at)gmail(dot)com>
To: Viktor Holmberg <v(at)viktorh(dot)net>
Cc: Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org, Marko Tiikkaja <marko(at)joh(dot)to>, Andreas Karlsson <andreas(at)proxel(dot)se>
Subject: Re: ON CONFLICT DO SELECT (take 3)
Date: 2025-11-25 08:33:17
Message-ID: CACJufxGaSLpweeQfmFyxTAAOQqe-z_RWzMKWiPmH+GTn-u=cVQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Mon, Nov 24, 2025 at 11:23 PM Viktor Holmberg <v(at)viktorh(dot)net> wrote:
>
> It did not. But this will.
> For some reason, in this bit:
>
> ‘''
> LockTupleMode lockmode;
> ….
> case LCS_FORUPDATE:
> lockmode = LockTupleExclusive;
> break;
> case LCS_NONE:
> elog(ERROR, "unexpected lock strength %d", lockStrength);
> }
>
> if (!ExecOnConflictLockRow(context, existing, conflictTid,
> resultRelInfo->ri_RelationDesc, lockmode, false))
> return false;
> ‘''
>
> GCC gives warning "error: ‘lockmode’ may be used uninitialized”. But if I switch the final exhaustive “case" to a “default” the warning goes away. Strange, if anyone know how to fix let me know. But also I don’t think it’s a big deal.

hi.
you can search ``/* keep compiler quiet */`` within the codebase.

after
``elog(ERROR, "unexpected lock strength %d", lockStrength);``
you can add
``
lockmode = LockTupleExclusive;
break;
``

in doc/src/sgml/mvcc.sgml:
<para>
<command>INSERT</command> with an <literal>ON CONFLICT DO
NOTHING</literal> clause may have insertion not proceed for a row due to
the outcome of another transaction whose effects are not visible
to the <command>INSERT</command> snapshot. Again, this is only
the case in Read Committed mode.
</para>
I think we need to add something after the above quoted paragraph.

doc/src/sgml/ref/create_view.sgml, some places also need to be updated, I think.
see text ON CONFLICT UPDATE in there.

I added some dummy tests on src/test/regress/sql/triggers.sql.
also did some minor doc changes.

please check the attached v16.
v16-0001: rebase and combine v15-0001, v15-0002, v15-0003, v15-0004 together.
v16-0002: using INJECTION_POINT to test the case when
ExecOnConflictSelect->ExecOnConflictLockRow returns false.

v16-0002, I use
```
if (!ExecOnConflictLockRow(context, existing, conflictTid,
resultRelInfo->ri_RelationDesc,
lockmode, false))
{
INJECTION_POINT("exec-onconflictselect-after-lockrow", NULL);
elog(INFO, "this part is reached");
return false;
}
```
to demomate that ExecOnConflictLockRow is reachable.
obviously, ``elog(INFO, "this part is reached");`` needs to be removed later.

--
jian
https://www.enterprisedb.com/

Attachment Content-Type Size
v16-0002-ON-CONFLICT-DO-SELECT-misc-fix.patch text/x-patch 11.1 KB
v16-0001-ON-CONFLICT-DO-SELECT.patch text/x-patch 129.5 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Chao Li 2025-11-25 08:50:29 Re: pg_waldump: support decoding of WAL inside tarfile
Previous Message Zhijie Hou (Fujitsu) 2025-11-25 08:33:10 RE: How can end users know the cause of LR slot sync delays?