Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1l4sp9-00070Q-Fm for pgsql-bugs@arkaria.postgresql.org; Wed, 27 Jan 2021 21:58:03 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1l4sp7-0006L2-NW for pgsql-bugs@arkaria.postgresql.org; Wed, 27 Jan 2021 21:58:01 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1l4sp6-0006Km-OP for pgsql-bugs@lists.postgresql.org; Wed, 27 Jan 2021 21:58:01 +0000 Received: from out4-smtp.messagingengine.com ([66.111.4.28]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1l4sp3-0003su-Hz for pgsql-bugs@lists.postgresql.org; Wed, 27 Jan 2021 21:57:59 +0000 Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 576435C01CF; Wed, 27 Jan 2021 16:57:56 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Wed, 27 Jan 2021 16:57:56 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=AKww4qnEhoHDAEsIG9JOGzd+jWWkx/4sLGar3kiUeMk=; b=QjTUwRkQ DyM0Mjgoc+uSRBQVLB4UuHFOfYYwgxeQV3+hTI76a/q166xTKVZF4sFDGTpIw5v4 BGqBjhUA/9kxXPV4ydaha1n4T74yhqwOO8FC1Ldio4VKWLdsk1a4jFIqWTbQSneD JqxIwMcPzVaRW4p/2djEBn5BHYv8FBlt7ixJdwucOWipLnMdPplem0d9cKEcGNmS PlWnlTKFn0x7CTRyiDvx73qLNA1hm+iRxARsfn7sGPibpQtJ85eb8TWjZwiOTbWj sExMjeTpUn40oJU6A8/oVDH39plFyeeTl8TPuIV9DQKIC/M7r6ikjFuFM+3BKkj3 q3SPy3acJa/Z2Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrvdekgdduheefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucenucfjughrpeffhffvuffkgggtugfgjggfsehmke erredtredunecuhfhrohhmpeetlhhvrghrohcujfgvrhhrvghrrgcuoegrlhhvhhgvrhhr vgesrghlvhhhrdhnohdqihhprdhorhhgqeenucggtffrrghtthgvrhhnpedvvedvgfffhe ekhfdvleefvdetfeeiueffieegieevgfehtdeftdelfefggfdtgfenucffohhmrghinhep phhoshhtghhrvghsqhhlrdhorhhgnecukfhppeduledtrdelhedrudelrddujeejnecuve hluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomheprghlvhhhvghr rhgvsegrlhhvhhdrnhhoqdhiphdrohhrgh X-ME-Proxy: Received: from perhan.alvh.no-ip.org (unknown [190.95.19.177]) by mail.messagingengine.com (Postfix) with ESMTPA id 34FB31080057; Wed, 27 Jan 2021 16:57:55 -0500 (EST) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id AED1B2A0D40; Wed, 27 Jan 2021 18:57:52 -0300 (-03) Date: Wed, 27 Jan 2021 18:57:52 -0300 From: Alvaro Herrera To: pg@pmenke.de, pgsql-bugs@lists.postgresql.org Subject: Re: BUG #16794: BEFORE UPDATE FOR EACH ROW triggers on partitioned tables can break tuple moving UPDATEs Message-ID: <20210127215752.GA18593@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="PEIAKu/WMn1b1Hv9" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20210127003504.GA17625@alvherre.pgsql> User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2021-Jan-26, Alvaro Herrera wrote: > Looked at this today, and it's not nearly as easy to fix as I hoped. > The misbehavior in corner cases seems weird enough that we should keep > the restriction ... but the way the restriction is implemented currently > is completely broken. Actually, I was misled by the fact that I had both INSERT triggers and UPDATE triggers, and they were both changing the partition keys. What I now think we should do is just remove the restrictions for UPDATE, and let the trigger do whatever; and keep what we have for INSERT, because it is useful. Things work out okay. As in the attached patch. A quick write-up: In the UPDATE case, this is the timeline: u0. The user-specified changes are carried out in the tuple. u1. BEFORE UPDATE FOR EACH ROW triggers run, *in the original partition*. We don't know yet if the tuple is okay in this partition or not. u2. The partition constraint (of the original partition) is tested. u3. If the partition constraint returns OK, we're done. ... since the partition constraint failed, we have to route the tuple: u4. a DELETE is executed in the original partition. Appropriate triggers run. u5. ExecFindPartition determines the target partition u6. an INSERT is executed in the new partition. Appropriate triggers run. The originally claimed reason not to allow the trigger from moving the row to another partition was that if we allowed that, then we would not run the correct triggers. But that's wrong: because the UPDATE at step u1 runs triggers in the original partition, not in the new one (which would be determined only at u5) then that holds true for the original update too, not just the changes in the before-row triggers. So if the triggers change the partkey columns ... it doesn't have any semantic difference from the user changing the partkey columns. We don't care. As for INSERT -- it does not know how to handle rerouting. So we're only producing a better-quality error message by having the same-partition check. If we did not have the check, the only difference is that ExecPartitionCheck would fail a bit later, with a mysterious error that the tuple doesn't meet the partition constraint. -- Álvaro Herrera 39°49'30"S 73°17'W Tom: There seems to be something broken here. Teodor: I'm in sackcloth and ashes... Fixed. http://archives.postgresql.org/message-id/482D1632.8010507@sigaev.ru --PEIAKu/WMn1b1Hv9 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="0001-Remove-bogus-restriction-from-BEFORE-UPDATE-triggers.patch"