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.94.2) (envelope-from ) id 1v1DK5-005oIN-Tx for pgsql-general@arkaria.postgresql.org; Wed, 24 Sep 2025 00:25:30 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1v1DK4-0099Fw-Bt for pgsql-general@arkaria.postgresql.org; Wed, 24 Sep 2025 00:25:28 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1v1DK4-0099Fm-0z for pgsql-general@lists.postgresql.org; Wed, 24 Sep 2025 00:25:28 +0000 Received: from mail-ej1-x62b.google.com ([2a00:1450:4864:20::62b]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1v1DJz-002Wii-2t for pgsql-general@lists.postgresql.org; Wed, 24 Sep 2025 00:25:27 +0000 Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-b2e66a300cbso445599966b.3 for ; Tue, 23 Sep 2025 17:25:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1758673524; x=1759278324; 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=Z6n8UWvMrMQIFM2gF7JSYqrplfwcphK5KP/e2U89n54=; b=PsotavsS38Q3JmjsLTit08qusHccWqAoHyF1VGuc7OJXV7xK2eGzGqmHv4j6wr966L qaB5SRdQhLcETj84u4s3EFuiRH+gUBB+AejP+EVeRZ5FX/1dWLaMP+ui7sDTZBTUdUh2 Y2YvbiYmyCmfHOwm0iUsr0DBf3WsWT1EvVfmX4CEo5j/wjXYlYu7SKeSz58qSZKyzEXT oBrbLaZCms0ckMCmD+vDS5YhMUPlRKvhHbfq3mDF15N4/yJ+WyHq8K6ExpcTePaXaV4q /7JNVCoRhNNPzM4FcOSdQw/1DNZjjy2yXVMtb2VrhaoUyicr0G4QpB8T6x3IBl2G9rNk 8WTg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1758673524; x=1759278324; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=Z6n8UWvMrMQIFM2gF7JSYqrplfwcphK5KP/e2U89n54=; b=kVyFzobM9f8P+vdZ5gCfRzz/89cktfnDoUPX4HjAuc4VBvr2hVcImBEyvao5BNqB5f ZKAm/eVH95aIaV5nmh7zKr606AgUIDTjvAJYUaI91UzBuNiNpsPgjfz2oIQRnEIh7jdC o0nToSMa1Z555U74aOnxA5+FRszWTJJ4DSrQiD/89Z9Des/B2abFuopdz8XOoW+/ulLB jOcoso7EKcSJsvnHPR/cV+ab73oTLBDTlqshpiGu3YFwlafnyGn0dmupPQGHw5o37mm9 sWj6DquuavHwCFaW1v7gq52wk0nIRaF1vOpigCtY55C7+oqqKJ0l82GFOIGXHNRkUF+X 4E9A== X-Gm-Message-State: AOJu0YyccB5ZmA1oO7pkYZyV+6IqNCrEEvKslc6h5afkgNL4s4vDQw0+ syMLEUWA0FAbrppYxHHh0+hKrXc1EMctfKaY44Mh7urBK8V9ojAM/dUquWg4/wvt0WyWbP0t942 PcNZY0qSjjvuAK1LHdmLbsD8XABDAZw== X-Gm-Gg: ASbGncurC4AjV2a5i28ZHPfA3snN1Fqge5o+ZeDO1cA2Iswl3w5s7OrNLzzw8b8PXXx 8IBsQH9daP/rBLikbNzVpddDHovxK1Dw79LIfpEBOjbjJ1R/wKYBkAEmNTSSWl/IuGOrWQ2nw2/ mS+zTJzjfAh7uxBZTOrMLPqxhfe0/JCht+WAfA3lPXsCuhQFX1KoJi4k4tzEee7JhIE4aOPBVOR ZrnYlV8unkxZQ== X-Google-Smtp-Source: AGHT+IFVYQ7pGUYbeh9ky9119k/qbQNHV/EsSIkMHv17BY75NrFbggpamcO4XW48UxYdcI1uuuJSKWcInsBmoyRgEhI= X-Received: by 2002:a17:906:fd82:b0:b07:89c3:333 with SMTP id a640c23a62f3a-b3027261965mr413464366b.5.1758673523731; Tue, 23 Sep 2025 17:25:23 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Juan Rodrigo Alejandro Burgos Mella Date: Tue, 23 Sep 2025 19:25:10 -0500 X-Gm-Features: AS18NWACFQBo-pHCjB1LFaLbomyebfikdL5D6LNcfs7-DqxKAg0-BCZsSee7VeQ Message-ID: Subject: Re: How do I upsert depending on a second table? To: Samuel Marks Cc: pgsql-general@lists.postgresql.org Content-Type: multipart/alternative; boundary="000000000000a870be063f81163a" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000a870be063f81163a Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Samuel Using ON CONFLICT is a headache. It's better to use the versatility of a Trigger: you have the full record at your fingertips, and if you're going to UPDATE, you have the previous record too. There's much more control. Also, you can always count on the beloved foreign keys, which are also quite useful. Atte. JRBM El mar, 23 sept 2025 a las 15:37, Samuel Marks () escribi=C3=B3: > Attempt: > ```sql > CREATE TABLE org > ( > "name" VARCHAR(50) PRIMARY KEY, > owner VARCHAR(50) NOT NULL > ); > > CREATE TABLE repo > ( > "id" INTEGER PRIMARY KEY, > full_name VARCHAR(255) UNIQUE NOT NULL, > org VARCHAR(50) NOT NULL REFERENCES org ("name") > ); > > INSERT INTO org(name, owner) VALUES ('org0', 'user0'); > > INSERT INTO repo (id, full_name, org) > VALUES (0, 'org0/name0 by wrong user', 'org0') > ON CONFLICT (full_name) DO UPDATE > SET full_name =3D EXCLUDED.full_name, > org =3D EXCLUDED.org > WHERE EXISTS (SELECT 1 > FROM org org_tbl > WHERE org_tbl.name =3D EXCLUDED.org > AND org_tbl.owner =3D 'wrong user') > RETURNING *; > > SELECT * FROM repo WHERE id =3D 0; > ``` > > This all succeeds. It should fail because the 'wrong user' is trying > to create a new=E2=80=94or update an existing=E2=80=94repo. > > Thanks for all suggestions > > > --000000000000a870be063f81163a Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hi Samuel

Using ON CONFLICT = is a headache.=C2=A0
It's better to use the versatility of a = Trigger: you have the full record at your fingertips, and if you're goi= ng to UPDATE, you have the previous record too.=C2=A0
There's= much more control.

Also, you can always count on = the beloved foreign keys, which are also quite useful.

=
Atte.
JRBM


El mar,= 23 sept 2025 a las 15:37, Samuel Marks (<samuelmarks@gmail.com>) escribi=C3=B3:
Attempt:
```sql
CREATE TABLE org
(
=C2=A0 =C2=A0 "name"=C2=A0 =C2=A0 =C2=A0 VARCHAR(50) PRIMARY KEY,=
=C2=A0 =C2=A0 owner=C2=A0 =C2=A0 =C2=A0 =C2=A0VARCHAR(50) NOT NULL
);

CREATE TABLE repo
(
=C2=A0 =C2=A0 "id"=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0INTEGE= R PRIMARY KEY,
=C2=A0 =C2=A0 full_name=C2=A0 =C2=A0 =C2=A0 VARCHAR(255) UNIQUE NOT NULL, =C2=A0 =C2=A0 org=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 VARCHAR(50)=C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0NOT NULL REFERENCES org ("name") );

INSERT INTO org(name, owner) VALUES ('org0', 'user0');

INSERT INTO repo (id, full_name, org)
VALUES (0, 'org0/name0 by wrong user', 'org0')
ON CONFLICT (full_name) DO UPDATE
=C2=A0 =C2=A0 SET full_name =3D EXCLUDED.full_name,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 org=C2=A0 =C2=A0 =C2=A0 =C2=A0=3D EXCLUDED.org<= br> WHERE EXISTS (SELECT 1
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 FROM org org_tbl
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 WHERE org_tbl.name =3D EXCLU= DED.org
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 AND org_tbl.owner = =3D 'wrong user')
RETURNING *;

SELECT * FROM repo WHERE id =3D 0;
```

This all succeeds. It should fail because the 'wrong user' is tryin= g
to create a new=E2=80=94or update an existing=E2=80=94repo.

Thanks for all suggestions


--000000000000a870be063f81163a--