Re: Default Value Retention After Dropping Default

From: Adrian Klaver <adrian(dot)klaver(at)aklaver(dot)com>
To: Marcelo Fernandes <marcefern7(at)gmail(dot)com>, pgsql-general(at)lists(dot)postgresql(dot)org
Subject: Re: Default Value Retention After Dropping Default
Date: 2025-02-24 16:00:02
Message-ID: 165cb7ec-8214-4c47-98e1-e764330ef711@aklaver.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

On 2/23/25 23:56, Marcelo Fernandes wrote:
> Hi folks,
>
> I am experiencing an interesting behavior in PostgreSQL and would like to seek
> some clarification.
>
> In the following snippet, I first add a column with a default value, then drop
> that default. However, when I query the table, the column still retains the
> dropped default for existing rows:
>
> SET client_min_messages=debug1;
>
> DROP TABLE IF EXISTS foo CASCADE;
> CREATE TABLE foo (id SERIAL PRIMARY KEY);
>
> INSERT INTO foo (id) SELECT generate_series(1, 10000);
>
> ALTER TABLE foo ADD COLUMN bar varchar(255) NOT NULL DEFAULT 'default';
> ALTER TABLE foo ALTER COLUMN bar DROP DEFAULT;
>
> SELECT * from foo order by id desc limit 5;
> -- id | bar
> -- -------+---------
> -- 10000 | default
> -- 9999 | default
> -- 9998 | default
> -- 9997 | default
> -- 9996 | default
>
> In this example, even after dropping the default value from the bar column, the
> rows that were previously inserted (prior to dropping the default) still show
> 'default' as their value in the bar column.

From

https://www.postgresql.org/docs/current/sql-createtable.html

"
DEFAULT default_expr

The DEFAULT clause assigns a default data value for the column
whose column definition it appears within. The value is any
variable-free expression (in particular, cross-references to other
columns in the current table are not allowed). Subqueries are not
allowed either. The data type of the default expression must match the
data type of the column.

The default expression will be used in any insert operation that
does not specify a value for the column. If there is no default for a
column, then the default is null.
"

The DEFAULT is just a value that is entered when you do not explicitly
provide a value for a given field. That value is saved just like any
other value and will not disappear once it is no longer the DEFAULT.
>
> It does not see that the table has been rewritten or rescanned, otherwise the
> debug1 messages would be triggered.
>
> Can anyone explain how PostgreSQL "knows about" the default value that has just
> been dropped and what is happened under the scenes? I am keen on a deep
> understanding on how Postgres achieves this.
>
> Here is what I could find in the docs, but it does not satisfy my question:
>
>> From PostgreSQL 11, adding a column with a constant default value no longer
>> means that each row of the table needs to be updated when the ALTER TABLE
>> statement is executed. Instead, the default value will be returned the next
>> time the row is accessed, and applied when the table is rewritten, making the
>> ALTER TABLE very fast even on large tables.
>
> https://www.postgresql.org/docs/current/ddl-alter.html#DDL-ALTER-ADDING-A-COLUMN
>
>

--
Adrian Klaver
adrian(dot)klaver(at)aklaver(dot)com

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Adrian Klaver 2025-02-24 16:37:06 Re: Default Value Retention After Dropping Default
Previous Message Dominique Devienne 2025-02-24 15:27:12 Re: Keep specialized query pairs, or use single more general but more complex one