Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vYdH2-009R5R-1W for pgsql-bugs@arkaria.postgresql.org; Thu, 25 Dec 2025 04:48:29 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vYdH0-006dDG-24 for pgsql-bugs@arkaria.postgresql.org; Thu, 25 Dec 2025 04:48:27 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vYdH0-006dD8-0K for pgsql-bugs@lists.postgresql.org; Thu, 25 Dec 2025 04:48:27 +0000 Received: from mail-ej1-x62c.google.com ([2a00:1450:4864:20::62c]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vYdGy-002VEi-2p for pgsql-bugs@lists.postgresql.org; Thu, 25 Dec 2025 04:48:25 +0000 Received: by mail-ej1-x62c.google.com with SMTP id a640c23a62f3a-b8010b8f078so862892266b.0 for ; Wed, 24 Dec 2025 20:48:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766638101; x=1767242901; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=2omiuiJq9FyXuO2+1q45Y5hmZPKuVfTcz7g6wRAxdyQ=; b=MZovai1npsiKQJKPD8INbwSXmf3mY8T99E86zRw2q2YxZqy44fghOVzltjKPcoKhOO e2AI6GJMoGkTUXOjY2ioR0skBaqxLmtgT/ewvwu9YtOhzsJmGcU8q67/JgUPnlmQx2Eu jJ4V4gc1Gcb59qAk8ySUdpupzHOs8egMvm3xzY+KSwF8CK6Mek4u20ggIwh/J9yxSRNx 5oHotfaoZAQXRYZmkfQNPdo5g2gACjgLyl+D7Pk9cJJ71gyBG74u5KT9G7cvbafaATaY Ke0NVjln65C6SYzLxTjLfh1FtewKvsuI0HUYKj7QuTqZHygJoTRj3+R5j25KQvUu63V6 xTgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766638101; x=1767242901; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=2omiuiJq9FyXuO2+1q45Y5hmZPKuVfTcz7g6wRAxdyQ=; b=J7qwCSTZFwJifYLPci99Y8iRTnbwXmjc/Cs2+xrUo3j9rkmLCnsNMtLwgDb5RZLPai dMfGD0d2FRRVKy8A55gJ7kCnecpcgknAqPN74+/lsOBLgIBtdkQZ03IR3b8AYE4jRnG5 idCpJpDgcBupYNhOVd5huPMQgOPAELE5IsDOhQPeDgvBOJPgHr8M9XBF61ErtoLLh2aE evWHEKMR1gUWqmUG03tcGmuqEXPubyfUy1QEDMVDGqX+MjA2izzXLJ8dgTO/tMA6HhqY dZmW6pCXoSmHf/iazmVgwPm3UvsXEVPUQJUCgg+ECL9N4FuI2/L6GFbs/TbzNJJlrjDW H2cw== X-Forwarded-Encrypted: i=1; AJvYcCXHmAEOmYt5h6tlmbcMO7p9cFFmCmhNge66truOcmjPDN8cKx10eMyfYqE4B5WNGaueArkHGOxFFkkZ@lists.postgresql.org X-Gm-Message-State: AOJu0YxsrDt12JZQv6Myr/6PbHWaBNRagPJtgnF3Pznew/EzJVCR7vK7 hIWmwy2XRSBM94ZjODz67RErbTvhaEPqxKe7Q/GR5ZztlD2Y08DPIagxY/vDTKcAbE/e0OgV5Tj NZuEXEoo3MBBdF40HQ/8u4asJToCgeCw= X-Gm-Gg: AY/fxX7Cs/g4ltQtyHUKXcAoWWWpUGV3qaEZC6Zy6WfiBwAKYjgRIKX93La93ojSS3e 0Lz95twgSFLoPCOntBB3qQbAEE8QXazrGFSjKl7uWyMHHO1OyesyoG9WAkNpg2il8VieB8wX44y xZPxw4p7HqdjQlsPxybFIKR4cqgysxbNYo/uXNZGkRB576qBPnjfDKKeKunwq1a1YIDsRj7irrH xdvgbCvvqoKprFJ1k7WnQJwqWzyW7LErtWUC6zuIk/hamv+OuG9g0Bd/tntKFNdXVQbPQSDvmXH B18k0jRRK15Ljg== X-Google-Smtp-Source: AGHT+IE4YuuFDZWfpgcjr9TihZX25Joiin31S/jWIaXoGGogOyn5wITPPQYEraOksiXa/P+Opr/ckCxJVjF1MLsnTSE= X-Received: by 2002:a17:907:1b22:b0:b80:11fd:793b with SMTP id a640c23a62f3a-b8036f5ac36mr1793304266b.19.1766638101247; Wed, 24 Dec 2025 20:48:21 -0800 (PST) MIME-Version: 1.0 References: <19355-57d7d52ea4980dc6@postgresql.org> <868ff2a518820c8864b6d28510294b2457a126af.camel@cybertec.at> In-Reply-To: From: Tender Wang Date: Thu, 25 Dec 2025 12:48:08 +0800 X-Gm-Features: AQt7F2py2Yneq26a8aLIgfGOWePDoNE9AmoVhRmQyYr7IdQx3j-KNEvpbIi7ZNM Message-ID: Subject: Re: BUG #19355: Attempt to insert data unexpectedly during concurrent update To: Dean Rasheed Cc: Amit Langote , Bh W , Laurenz Albe , pgsql-bugs@lists.postgresql.org Content-Type: multipart/alternative; boundary="00000000000078bd7d0646bf7cbe" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --00000000000078bd7d0646bf7cbe Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Dean Rasheed =E4=BA=8E2025=E5=B9=B412=E6=9C=8825= =E6=97=A5=E5=91=A8=E5=9B=9B 07:12=E5=86=99=E9=81=93=EF=BC=9A > On Wed, 24 Dec 2025 at 12:07, Tender Wang wrote: > > > > I did some debugging, and I found that: > > In add_rte_to_flat_rtable(), the RTE of value was not added into > glob->AllRelids, because below codes: > > ..... > > the estate->es_unpruned_relids equals with result->unprunableRelids > contains. So the rowMark was skipped incorrectly. > > > > I did a quick fix as the attached patch. > > Any thoughts? > > Yes. However, it's not sufficient to only add RTE_VALUES RTEs to what > gets included in PlannerGlobal.allRelids. Rowmarks can be attached to > other kinds of RTEs. An obvious example is an RTE_SUBQUERY RTE that is > an actual subquery that did not come from a view. So, for this > approach to work robustly, it really should include *all* RTEs in > PlannerGlobal.allRelids. > Yes, it is. I can reproduce the same with a subquery as below: merge into t1 using (select a from (values(1,1),(2,2) as t4(a,b)) as t3(a) on (t1.a =3D t3.a) when matched then update set b =3D t1.b + 1 when not matched then insert (a,b) values (1,1); or merge into t1 using (select generate_series(1,2) as a) as t3 on (t1.a =3D t3.a) when matched then update set b =3D t1.b + 1 when not matched then insert (a,b) values (1,1); All reported the same error. My approach obviously can not cover all cases. > > I took a slightly different approach, which was to change the test in > InitPlan() (and also in ExecInitLockRows() and ExecInitModifyTable()) > to only ignore rowmarks for pruned relations that are plain > RTE_RELATION relations, since those are the only relations that are > ever actually pruned. So rowmarks attached to any other kind of RTE > are not ignored. I also added an isolation test case. > I failed to apply your patch, some errors, like "error: git apply: bad git-diff - expected /dev/null on line 2" or "Patch format detection failed." I looked through the patch. It worked for me. > I'm somewhat conflicted as to which approach is better. I think maybe > there is less chance of other unintended side-effects if the set of > RTEs included in PlannerGlobal.allRelids, unprunableRelids, and > es_unpruned_relids is not changed. However, as it stands, > PlannerGlobal.allRelids is misnamed (it should probably have been > called "relationRelids", in line with the "relationOids" field). > Making it actually include all RTEs would solve that. > ..... /* * RT indexes of all relation RTEs in finalrtable (RTE_RELATION and * RTE_SUBQUERY RTEs of views) */ Bitmapset *allRelids; ...... Per the comment, I guess Amit didn't plan to include all RTEs in his design= . --=20 Thanks, Tender Wang --00000000000078bd7d0646bf7cbe Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


Dean Rasheed &l= t;dean.a.rasheed@gmail.com&= gt; =E4=BA=8E2025=E5=B9=B412=E6=9C=8825=E6=97=A5=E5=91=A8=E5=9B=9B 07:12=E5= =86=99=E9=81=93=EF=BC=9A
On Wed, 24 Dec 2025 at 12:07, Tender Wang <tndrwang@gmail.com> wrote:
>
> I did some debugging, and I found that:
> In=C2=A0 add_rte_to_flat_rtable(),=C2=A0 the RTE of value was not adde= d into glob->AllRelids, because below codes:
> .....
> the estate->es_unpruned_relids equals with result->unprunableRel= ids contains. So the rowMark was skipped incorrectly.
>
> I did a quick fix as the attached patch.
> Any thoughts?

Yes. However, it's not sufficient to only add RTE_VALUES RTEs to what gets included in PlannerGlobal.allRelids. Rowmarks can be attached to
other kinds of RTEs. An obvious example is an RTE_SUBQUERY RTE that is
an actual subquery that did not come from a view. So, for this
approach to work robustly, it really should include *all* RTEs in
PlannerGlobal.allRelids.

Yes,=C2=A0 it = is. I can reproduce the same with a subquery as below:

= merge into t1 using (select a from (values(1,1),(2,2) as t4(a,b)) as t3(a) = on (t1.a =3D t3.a)
when matched then
=C2=A0 =C2=A0 =C2=A0 update set = b =3D t1.b + 1
when not matched then
=C2=A0 =C2=A0 =C2=A0 insert= (a,b) values (1,1);
or
merge into t1 using (select generate= _series(1,2) as a) as t3 =C2=A0on (t1.a =3D t3.a)
when matched then
= =C2=A0 =C2=A0 =C2=A0 update set b =3D t1.b + 1
when not matched then
=
=C2=A0 =C2=A0 =C2=A0 insert (a,b) values (1,1);
=C2=A0
=
All reported the same error. My approach obviously can not cover all c= ases.

I took a slightly different approach, which was to change the test in
InitPlan() (and also in ExecInitLockRows() and ExecInitModifyTable())
to only ignore rowmarks for pruned relations that are plain
RTE_RELATION relations, since those are the only relations that are
ever actually pruned. So rowmarks attached to any other kind of RTE
are not ignored. I also added an isolation test case.
=
I failed to apply your patch, some errors, like "error:= git apply: bad git-diff - expected /dev/null on line 2"
or = "Patch format detection failed."
=C2=A0I looked through= the patch. It worked for me.


I'm somewhat conflicted as to which approach is better. I think maybe there is less chance of other unintended side-effects if the set of
RTEs included in PlannerGlobal.allRelids, unprunableRelids, and
es_unpruned_relids is not changed. However, as it stands,
PlannerGlobal.allRelids is misnamed (it should probably have been
called "relationRelids", in line with the "relationOids"= ; field).
Making it actually include all RTEs would solve that.
= .....
=C2=A0/*
* RT indexes of all relation RTEs in finalr= table (RTE_RELATION and
* RTE_SUBQUERY RTEs of views)
*/
Bitmapset =C2=A0*allRelids;
......
Per the comment, I guess Amit didn&#= 39;t plan to include all RTEs in his design.
=C2=A0

--
Thanks,
Tender Wang
--00000000000078bd7d0646bf7cbe--