Re: ALTER TABLE ... ADD COLUMN ... DEFAULT with volatile function loses DML

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Jeff Davis <pgsql(at)j-davis(dot)com>
Cc: pgsql-bugs(at)postgresql(dot)org
Subject: Re: ALTER TABLE ... ADD COLUMN ... DEFAULT with volatile function loses DML
Date: 2025-11-04 18:22:32
Message-ID: 650759.1762280552@sss.pgh.pa.us
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Jeff Davis <pgsql(at)j-davis(dot)com> 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

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Jeff Davis 2025-11-04 19:20:38 Re: ALTER TABLE ... ADD COLUMN ... DEFAULT with volatile function loses DML
Previous Message Jeff Davis 2025-11-04 18:14:08 ALTER TABLE ... ADD COLUMN ... DEFAULT with volatile function loses DML