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 1tmasP-007uyU-Jt for pgsql-general@arkaria.postgresql.org; Mon, 24 Feb 2025 16:00:14 +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 1tmasO-004Mdd-CI for pgsql-general@arkaria.postgresql.org; Mon, 24 Feb 2025 16:00:12 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tmasN-004MdV-2X for pgsql-general@lists.postgresql.org; Mon, 24 Feb 2025 16:00:12 +0000 Received: from fout-a5-smtp.messagingengine.com ([103.168.172.148]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tmasI-000Ylv-1X for pgsql-general@lists.postgresql.org; Mon, 24 Feb 2025 16:00:10 +0000 Received: from phl-compute-09.internal (phl-compute-09.phl.internal [10.202.2.49]) by mailfout.phl.internal (Postfix) with ESMTP id 40F3F1380F0E; Mon, 24 Feb 2025 11:00:04 -0500 (EST) Received: from phl-mailfrontend-01 ([10.202.2.162]) by phl-compute-09.internal (MEProxy); Mon, 24 Feb 2025 11:00:04 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aklaver.com; h= cc:content-transfer-encoding:content-type:content-type:date:date :from:from:in-reply-to:in-reply-to:message-id:mime-version :references:reply-to:subject:subject:to:to; s=fm3; t=1740412804; x=1740499204; bh=6r7bSHuw0H0laB0yIUtg+Q5jcylD7gjw8KpuChuY2JQ=; b= HBgRf82cgwbIkxqBMJGUUAuSwRmYIQ1AxjYTd02+BkAVA3YrkOt4sp/d+gi6hJ5l A09rEzUhjsiUnLP9z0DuKMfLTvEK3mMtxe4HyCG4WO9cREWt5+IXB/aIhhf2Zfbp mnAceXUywO6iF4c+vV6fNvj2av3FoshmexZmI4e1rgR0N6BfizgkNjtEqPVMLhyg EmRpw1F6Kl4iuJE2FEjr9k66RZE8BwQd+x7ISH7LJIsZ5qzGJ8NIOR/+ma3NdWc3 gbsoaZAlIT76bYU0+r+I0TThV/KR+G8i9+/B+Tko/jnZe5cb0KBKigWMzkPsXzcf 11GMicTfafFsnmv3ErQIyg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :content-type:date:date:feedback-id:feedback-id:from:from :in-reply-to:in-reply-to:message-id:mime-version:references :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm1; t=1740412804; x=1740499204; bh=6 r7bSHuw0H0laB0yIUtg+Q5jcylD7gjw8KpuChuY2JQ=; b=husuBR9R16GXDb9YS tkl3kGKLc8DqBmAz/EySqxTwQKkRykPPp8ypb02t0mnSlW5JjFyTGyJAPKK7gO0u Be8vGj7TEtm0z7l52hPL2z3UI6PVlRROzreyf2XWyoWCiH6aAkyvhvrXXeb+MG7o ySQfEgM9GpYVnYPTQN5RnTh8SIaxk8fF9utAXoq5rbOvrYiYArQ+g4cLpEbbTdLR C4b+XhP9TCFpGmGsmGRtoeX0XLXdYrkrNWfsHo+D0k0rrCPQ8QyW20hKlaDjqeTB 4SatVal18CdwVhyb9iF9xGxL9mGndlfkD4LUTKJEtTf8aZrY6b6Rrr4QjXby3qVS r5mDQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefvddrtddtgdejledvudcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpggftfghnshhusghstghrihgsvgdp uffrtefokffrpgfnqfghnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivg hnthhsucdlqddutddtmdenucfjughrpefkffggfgfuvfhfhfgjtgfgsehtjeertddtvdej necuhfhrohhmpeetughrihgrnhcumfhlrghvvghruceorggurhhirghnrdhklhgrvhgvrh esrghklhgrvhgvrhdrtghomheqnecuggftrfgrthhtvghrnhepkeefheduvdejiefgieef jedtudduffelvdefleehfedtieffuefgvdekleegtddvnecuffhomhgrihhnpehpohhsth hgrhgvshhqlhdrohhrghenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgr ihhlfhhrohhmpegrughrihgrnhdrkhhlrghvvghrsegrkhhlrghvvghrrdgtohhmpdhnsg gprhgtphhtthhopedvpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopehmrghrtggv fhgvrhhnjeesghhmrghilhdrtghomhdprhgtphhtthhopehpghhsqhhlqdhgvghnvghrrg hlsehlihhsthhsrdhpohhsthhgrhgvshhqlhdrohhrgh X-ME-Proxy: Feedback-ID: i76984098:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 24 Feb 2025 11:00:03 -0500 (EST) Message-ID: <165cb7ec-8214-4c47-98e1-e764330ef711@aklaver.com> Date: Mon, 24 Feb 2025 08:00:02 -0800 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Default Value Retention After Dropping Default To: Marcelo Fernandes , pgsql-general@lists.postgresql.org References: Content-Language: en-US From: Adrian Klaver In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk 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.klaver@aklaver.com