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 1vGLfz-00D3s2-HT for pgsql-bugs@arkaria.postgresql.org; Tue, 04 Nov 2025 18:22:38 +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 1vGLfx-00FsrD-5P for pgsql-bugs@arkaria.postgresql.org; Tue, 04 Nov 2025 18:22:36 +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 1vGLfw-00Fsr3-Sp for pgsql-bugs@lists.postgresql.org; Tue, 04 Nov 2025 18:22:35 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vGLfu-005RiY-0g for pgsql-bugs@postgresql.org; Tue, 04 Nov 2025 18:22:35 +0000 Received: from sss1.sss.pgh.pa.us (localhost [127.0.0.1]) by sss.pgh.pa.us (8.15.2/8.15.2) with ESMTP id 5A4IMWRB650760; Tue, 4 Nov 2025 13:22:32 -0500 From: Tom Lane To: Jeff Davis cc: pgsql-bugs@postgresql.org Subject: Re: ALTER TABLE ... ADD COLUMN ... DEFAULT with volatile function loses DML In-reply-to: References: Comments: In-reply-to Jeff Davis message dated "Tue, 04 Nov 2025 10:14:08 -0800" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <650758.1762280552.1@sss.pgh.pa.us> Date: Tue, 04 Nov 2025 13:22:32 -0500 Message-ID: <650759.1762280552@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Jeff Davis writes: > The following SQL seems to lose the updates during the ALTER: > CREATE TABLE t(id INT); > INSERT INTO t VALUES (1), (2); > CREATE FUNCTION f() RETURNS INT VOLATILE AS $$ > BEGIN > UPDATE t SET id = id + 10; > RETURN (SELECT MAX(id) FROM t); > END > $$ LANGUAGE plpgsql; > ALTER TABLE t ADD COLUMN c INT DEFAULT f(); > SELECT * FROM t; > id | c > ----+---- > 1 | 12 > 2 | 22 > (2 rows) Hmm ... ideally we'd throw an error for that. CheckTableNotInUse() intends to prevent some similar cases, but it misses this one because ALTER TABLE is the outermost command and there's no check performed at the inner UPDATE. Not sure how hard we need to work at preventing people from shooting themselves in the foot, though. regards, tom lane