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 1v1RBX-008fvL-70 for pgsql-general@arkaria.postgresql.org; Wed, 24 Sep 2025 15:13:35 +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 1v1RBV-00Du7a-Jq for pgsql-general@arkaria.postgresql.org; Wed, 24 Sep 2025 15:13:33 +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.94.2) (envelope-from ) id 1v1RBV-00Du7S-5Q for pgsql-general@lists.postgresql.org; Wed, 24 Sep 2025 15:13:33 +0000 Received: from fhigh-b4-smtp.messagingengine.com ([202.12.124.155]) by makus.postgresql.org with smtp (Exim 4.96) (envelope-from ) id 1v1RBT-002CXm-0A for pgsql-general@lists.postgresql.org; Wed, 24 Sep 2025 15:13:32 +0000 Received: from phl-compute-02.internal (phl-compute-02.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id BC3777A01B5; Wed, 24 Sep 2025 11:13:30 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Wed, 24 Sep 2025 11:13:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aklaver.com; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm3; t=1758726810; x=1758813210; bh=f3jZpDeS1nFMeLUoKvg/IJXiRmv2PTUXrGrKxlMaL08=; b= yyfwl0AXsie6gZw1XHmjzRbOVqa2YUhqbymZ8hcMBgzMWh4JoJK1T5WCKwTl0XDb ptXBX/RkgkLzYIlTg5qGnNr/4Y6bqEV12f03+QP5hifFcCUc/zDt2fzqVxb3GGrT ESYMvQc3aHVYa8MQOPEMQ3H/EZ1QlI5vFtrVPQ9oTxJ0U1AYHj3dhVvoFEaRh5/P 2BF6zHj4mH7QrFD89Z0iTksXMWdX2BsdCAqhlrYAFXjMTn+UfohDlrsiTzVjyuVr HpPkiA2IKy/Fks/5fxPf2MQjW1DVdKDHDp/1ltKb4iatqWDexov7ZCoiuivrVGAQ Y6iIodJKaPw1+qZ7X6CaLw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to:x-me-proxy :x-me-sender:x-me-sender:x-sasl-enc; s=fm1; t=1758726810; x= 1758813210; bh=f3jZpDeS1nFMeLUoKvg/IJXiRmv2PTUXrGrKxlMaL08=; b=D fdngyG76eXgxczFQrkCtZ3m40Pe+o5k5nBxSn2zTBidXDfSniQnzWl5uEIEDF/bj NXtZpn3GXFmok1033nQ1XofVJiXL6vJxopQtxcB+Dwl9gkxmCd+E8F50fUUiXlS3 9OApNESIuQ86BjI2LJCuGouTDyRbM+sCbe3mIehwR2O60qrYVO2l+KYU5oXe1yv4 WW091Xt/EN3U93IBrGCYgxE5FdEgMG0x5GdreEqtoL7FKBJW12aXcEbfoYH3zH55 eVJyV3bjRjWqoY+3M+LGy04bz14atKy5yA5WzbB8PT5W0FSL9fPkT9j/Cu4Kjens fId5upFxZiZ4sHz4EjwkQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdeggdeifeelgecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpefkffggfgfuvfevfhfhjggtgfesthekredttddvjeenucfhrhhomheptegurhhirghn ucfmlhgrvhgvrhcuoegrughrihgrnhdrkhhlrghvvghrsegrkhhlrghvvghrrdgtohhmqe enucggtffrrghtthgvrhhnpefhieeifeetvdeuvdevieeuueffudevtefftefhuefgjefg veehvedthedugefhjeenucffohhmrghinhepohhrghgpthgslhdrnhgrmhgvnecuvehluh hsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprggurhhirghnrdhk lhgrvhgvrhesrghklhgrvhgvrhdrtghomhdpnhgspghrtghpthhtohepfedpmhhouggvpe hsmhhtphhouhhtpdhrtghpthhtoheprhhoughrihhgohgsuhhrghhoshhmvghllhgrsehg mhgrihhlrdgtohhmpdhrtghpthhtohepshgrmhhuvghlmhgrrhhkshesghhmrghilhdrtg homhdprhgtphhtthhopehpghhsqhhlqdhgvghnvghrrghlsehlihhsthhsrdhpohhsthhg rhgvshhqlhdrohhrgh X-ME-Proxy: Feedback-ID: i76984098:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 24 Sep 2025 11:13:29 -0400 (EDT) Message-ID: <8f2e4644-eccd-49e8-b70b-b5c51c3aaa8c@aklaver.com> Date: Wed, 24 Sep 2025 08:13:29 -0700 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: How do I upsert depending on a second table? To: Juan Rodrigo Alejandro Burgos Mella , Samuel Marks Cc: pgsql-general References: Content-Language: en-US From: Adrian Klaver In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 9/23/25 23:44, Juan Rodrigo Alejandro Burgos Mella wrote: > The insert works because there is no data in the repo table that > conflicts with the entered full name. Except this part: SELECT 1/COUNT(*) FROM org WHERE name = 'org0' AND owner = 'wrong user'; will cause a divide by 0 error and abort the transaction preventing the INSERT from happening. Example: test=# begin ; BEGIN test=*# select 1/0; ERROR: division by zero test=!# select 1; ERROR: current transaction is aborted, commands ignored until end of transaction block test=!# rollback ; ROLLBACK > > JRBm > > El mar, 23 sept 2025, 23:19, Samuel Marks > escribió: > > Ok so you're thinking I give up on putting it all in one query and > instead use a transaction? - Is that the recommended way? > > ```sql > TRUNCATE repo, org; > INSERT INTO org(name, owner) VALUES ('org0', 'user0'); > ``` > > ```sql > START TRANSACTION READ WRITE; > > SELECT 1/COUNT(*) > FROM org > WHERE name = 'org0' >   AND owner = 'wrong user'; > > INSERT INTO repo (id, full_name, org) > VALUES (0, 'org0/name0 by wrong user', 'org0') > ON CONFLICT (full_name) DO UPDATE >     SET full_name = EXCLUDED.full_name, >         org       = EXCLUDED.org > RETURNING id; > > COMMIT; > ``` > > > > On Tue, Sep 23, 2025 at 7:25 PM Juan Rodrigo Alejandro Burgos Mella > > > wrote: > > > > 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ó: > >> > >> 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 = EXCLUDED.full_name, > >>         org       = EXCLUDED.org > >> WHERE EXISTS (SELECT 1 > >>               FROM org org_tbl > >>               WHERE org_tbl.name = > EXCLUDED.org > >>                 AND org_tbl.owner = 'wrong user') > >> RETURNING *; > >> > >> SELECT * FROM repo WHERE id = 0; > >> ``` > >> > >> This all succeeds. It should fail because the 'wrong user' is trying > >> to create a new—or update an existing—repo. > >> > >> Thanks for all suggestions > >> > >> > -- Adrian Klaver adrian.klaver@aklaver.com