Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iPTpY-0007sY-Ep for pgsql-docs@arkaria.postgresql.org; Tue, 29 Oct 2019 15:54:49 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1iPTpX-0000Qv-0X for pgsql-docs@arkaria.postgresql.org; Tue, 29 Oct 2019 15:54:47 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1iPTpW-0000Qi-Hd for pgsql-docs@lists.postgresql.org; Tue, 29 Oct 2019 15:54:46 +0000 Received: from forward100p.mail.yandex.net ([2a02:6b8:0:1472:2741:0:8b7:100]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1iPTpR-00071K-VI for pgsql-docs@lists.postgresql.org; Tue, 29 Oct 2019 15:54:45 +0000 Received: from forward100q.mail.yandex.net (forward100q.mail.yandex.net [IPv6:2a02:6b8:c0e:4b:0:640:4012:bb97]) by forward100p.mail.yandex.net (Yandex) with ESMTP id 575095980E87; Tue, 29 Oct 2019 18:54:38 +0300 (MSK) Received: from mxback8q.mail.yandex.net (mxback8q.mail.yandex.net [IPv6:2a02:6b8:c0e:42:0:640:b38f:32ec]) by forward100q.mail.yandex.net (Yandex) with ESMTP id 5299A708000E; Tue, 29 Oct 2019 18:54:38 +0300 (MSK) Received: from vla3-11710f0f0dbd.qloud-c.yandex.net (vla3-11710f0f0dbd.qloud-c.yandex.net [2a02:6b8:c15:2584:0:640:1171:f0f]) by mxback8q.mail.yandex.net (nwsmtp/Yandex) with ESMTP id iuoHTSENeS-scs009Rf; Tue, 29 Oct 2019 18:54:38 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yandex.ru; s=mail; t=1572364478; bh=hNC65Pd3kwVXV4YBNKHxSNxAX/aFINizfOnV3IoNxQA=; h=Subject:CC:To:From:Date:Message-ID; b=JESQg399fgjVHv+hngrRqemow3RhlbpVMJUFXsO3zrmFR5rKGVrPHdCoIUgueOnv8 VwZ/QcPh5h5nHiAHfasjsu7bm+7SFcqXHZEg7b1m8N/hb5E648GBA6/x2bwGkL5L8s t3sFzvH0xdx3XdtsMdq68zB90QAqZUFnPs1Gc/Dw= Authentication-Results: mxback8q.mail.yandex.net; dkim=pass header.i=@yandex.ru Received: by vla3-11710f0f0dbd.qloud-c.yandex.net (nwsmtp/Yandex) with ESMTPSA id EAm1avdhFG-sbX8d0GL; Tue, 29 Oct 2019 18:54:37 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (Client certificate not present) Date: Tue, 29 Oct 2019 17:54:36 +0200 From: Eugen Konkov Message-ID: <919823407.20191029175436@yandex.ru> Return-Receipt-To: kes-kes@yandex.ru To: PostgreSQL-development CC: pgsql-docs@lists.postgresql.org Subject: Does 'instead of delete' trigger support modification of OLD MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Hi. This is not clear from doc, so I have asked on IRC too. from the DOC: https://www.postgresql.org/docs/current/trigger-definition.html In the case of INSTEAD OF triggers, the possibly-modified row returned by each trigger becomes the input to the next trigger I modify OLD row, thus I expect to get modified version when run next query: WITH t1 AS( delete from abc returning *) select * from t1; fiddle: https://dbfiddle.uk/?rdbms=postgres_12&fiddle=637730305f66bf531794edb09a462c95 > https://www.postgresql.org/docs/current/trigger-definition.html A row-level INSTEAD OF trigger should either return NULL to indicate that it did not modify any data from the view's underlying base tables, or it should return the view row that was passed in (the NEW row for INSERT and UPDATE operations, or the OLD row for DELETE operations). A nonnull return value is used to signal that the trigger performed the necessary data modifications in the view. This will cause the count of the number of rows affected by the command to be incremented. For INSERT and UPDATE operations, the trigger may modify the NEW row before returning it. This will change the data returned by INSERT RETURNING or UPDATE RETURNING, and is useful when the view will not show exactly the same data that was provided. But I still does not understand. Doc explicitly do not prohibit modification of OLD and has no examples for DELETE RETURNING case So I want to ask clarify doc a bit. If this prohibited, why this is prohibited? have any discussion on this? If not prohibited, does this is not implemented for DELETE RETURNING queries? if so, is it left for later? I have next use case. I am implementing Bi-Temporal tables. The table have columns: id, app_period, value for example I have next data: 7, '[2019-01-01, 2020-01-01)', 130 You can imagine this as having value 7 for each day of the year. Now I want to delete this value for May month. I setup special variable to period: '[2019-05-01,2019-06-01)' and then delete: select app_period( '[2019-05-01,2019-06-01)' ); WITH t1 AS( delete from abc returning *) select * from t1; Algorithm of deletion is next: 1. Deactivate target row 7, '[2019-01-01, 2020-01-01)', 130 2. If target row has wider app_period then we insert record that data back: NOT '[2019-05-01,2019-06-01)' @> '[2019-01-01, 2020-01-01)' INSERT INTO abc ( id, app_period, value ) values ( 7, '[2019-01-01,2019-05-01)', 130 ), ( 7, '[2019-06-01,2020-01-01)', 130 ), 3. OLD.app_period = OLD.app_period * app_period(); '[2019-01-01, 2020-01-01)' * '[2019-05-01,2019-06-01)' --> '[2019-05-01,2019-06-01)' Because only 130 value is deleted from specified period I expect next result for the query above: ( 7, '[2019-05-01,2019-06-01)', 130 ) But despite on OLD was modified, actual result is: ( 7, '[2019-01-01,2020-01-01)', 130 ) You can see that this is original data. So, does INSTEAD OF DELETE support modification of row? -- Best regards, Eugen Konkov