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 1uhVEp-000gdp-LJ for pgsql-docs@arkaria.postgresql.org; Thu, 31 Jul 2025 15:30:36 +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 1uhVEo-001w7A-Md for pgsql-docs@arkaria.postgresql.org; Thu, 31 Jul 2025 15:30:34 +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 1uhVEn-001w72-T5 for pgsql-docs@lists.postgresql.org; Thu, 31 Jul 2025 15:30:34 +0000 Received: from fhigh-b1-smtp.messagingengine.com ([202.12.124.152]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uhVEk-0002ka-2o for pgsql-docs@lists.postgresql.org; Thu, 31 Jul 2025 15:30:33 +0000 Received: from phl-compute-06.internal (phl-compute-06.phl.internal [10.202.2.46]) by mailfhigh.stl.internal (Postfix) with ESMTP id 9FD9D7A23C4; Thu, 31 Jul 2025 11:30:28 -0400 (EDT) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Thu, 31 Jul 2025 11:30:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kurilemu.de; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:in-reply-to:message-id:mime-version :reply-to:subject:subject:to:to; s=fm1; t=1753975828; x= 1754062228; bh=uFtfWuG1k/ZadxEAZEwy8yygQhaT2WoCrislvkZa48g=; b=n 0fCqtgPZduazglyu9JJQ4Y50hJwtpQkhq85DcHU7TDs6ArGgHJuBCD8ofTOFR2BW j6cvzOFM0ZeuMQAMr6Y4JovX/uLksos/DR7BYX7r54KpF/5iN33fLMdcfpNDx+t+ 9+JCF8JrMcQyIEH6tOqZCg9iiH8jNlhJG4sADbKa1NBIJV7Kma/3ZlUfRI3AKTrh gK2fcCB1jJjG8HA6zEP9rAYPSfCafBxFAUHnJ97auG28r+D11HTuLQ/a1h5u+7j+ 5hFkebJbZKm1Ngv5R1JjP5oH09aRayHALZ4jgKXeyt8SMLwmnPlvjcxECZDqk3Se eN4PYmNlO+rDQZUbKX8dQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc: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 :reply-to:subject:subject:to:to:x-me-proxy:x-me-sender :x-me-sender:x-sasl-enc; s=fm3; t=1753975828; x=1754062228; bh=u FtfWuG1k/ZadxEAZEwy8yygQhaT2WoCrislvkZa48g=; b=UgILAmtc9U5qzIhwH M6fzA4v40PNuja/ZH8CP/UDYfX6oxgJv2uFl6FM0jzn3WeGGn2YFdPhO8r0r4Lp/ jWBYDLyAV4xHRdU/j3sFheo/2N0eL2MjQ/i9oaMrjirje12pXJ0RsBUKxwMUI1kc ak9o1gUL+mpvPXvH49N1sMg7NGgL03yKbzWZwiG5KWFr4mB4vfnk5GYPoVQesold HbVxyiNs45lOT60jIMdyU5MBbm54APg0Lnb2/XhDTmNPqwJhCPGdvRmPACwhMgFM PpXWvL/KdrAvAFUIsHKQ83gs9l9dlGSO98WijZ9glj7BhDp4t/hBNpj4kxL8cLOB /vU/Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgddutdduudekucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfurfetoffkrfgpnffqhgenuceu rghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujf gurhepfffhvfevuffkgggtugfgjgesthekredttddtjeenucfhrhhomheplmhlvhgrrhho ucfjvghrrhgvrhgruceorghlvhhhvghrrhgvsehkuhhrihhlvghmuhdruggvqeenucggtf frrghtthgvrhhnpedtkeelleffudejfefhkeetteehtedutedtteffueffieelkeekhffh vdfhveejleenucffohhmrghinhepphhoshhtghhrvghsqhhlrdhorhhgpdgvnhhtvghrph hrihhsvggusgdrtghomhdpghhnuhdrohhrghenucevlhhushhtvghrufhiiigvpedtnecu rfgrrhgrmhepmhgrihhlfhhrohhmpegrlhhvhhgvrhhrvgeskhhurhhilhgvmhhurdguvg dpnhgspghrtghpthhtohepfedpmhhouggvpehsmhhtphhouhhtpdhrtghpthhtohepuggr vhhiugdrghdrjhhohhhnshhtohhnsehgmhgrihhlrdgtohhmpdhrtghpthhtohepphhgsh hqlhdqughotghssehlihhsthhsrdhpohhsthhgrhgvshhqlhdrohhrghdprhgtphhtthho pehpshihvddttddtuhhsrgeshigrhhhoohdrtghomh X-ME-Proxy: Feedback-ID: ie3de48e3:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Thu, 31 Jul 2025 11:30:27 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kurilemu.de; s=schmee; t=1753975824; bh=HCIx7BKdxzMH3x3Tzw9/sqeAaPJ2zQ87IWC80yqspKU=; h=Date:From:To:Cc:Subject:In-Reply-To:From; b=dw/HB9220ru5q2JLj0cD2v1EvfoFt87n8Bv3A3EL0wGIlpELhkSzbsCI4KJhEZ0r3 pIq4xaFWgNgZrXV8VdGVCNjTH+LXkn2J7ApDpkF/CBwgJ1l8CxaXUHpTFAts5h3elY Oci/vAE7EHhqlIzla12gZrXyIiaadNQ41fW4hkqgo8q9sLede4fyiDEEYZPxkLl77o 0f4A1ihBiiqdOFH/dBOsFraw3nbw4TKpSesvA5tRJL0D2thOn7+gFdghFiiiD9q8tk mld02kUn3rDJstG0Dp3X5tUV2zrFJ1pCwH6rRp71rNl7QAjD+dQlg24+WewrhZJ3zV Ax09lJnBhSdNg== Received: by schmee.kurilemu.internal (Postfix, from userid 1000) id C897190; Thu, 31 Jul 2025 17:30:24 +0200 (CEST) Date: Thu, 31 Jul 2025 17:30:24 +0200 From: =?utf-8?Q?=C3=81lvaro?= Herrera To: "David G. Johnston" Cc: psy2000usa@yahoo.com, PostgreSQL Documentation Subject: Re: further clarification: alter table alter column set not null - table scan is skipped Message-ID: <202507311530.ls53ug7urrgx@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 2025-Jul-30, David G. Johnston wrote: > On Wed, Jul 30, 2025, 13:55 PG Doc comments form > wrote: > > The "table scan is skipped" optimization can use some clarification > > > > https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-DESC-SET-DROP-NOT-NULL > > My proposal is "then the table scan is skipped if the alter statement > > doesn't drop the constraint." > I'm kinda hoping this is actually just a fixable bug... I don't think so -- it's just the way ALTER TABLE is designed to work. We don't promise that the subcommands are going to be executed in the order that they are given, and thus this sort of thing can happen. I suspect a mechanism that would throw an error at trying to drop the constraint would be too complicated / brittle / laborious to write. It's possible that there are other combinations that are similarly affected, but I suspect the majority of them would just give an error rather than silently wasting a lot of time; so I agree that this subcommand specifically could use a small note. While writing it I realized we failed to note that the addition of NOT VALID changes behavior. So, how about like this: SET NOT NULL may only be applied to a column provided none of the records in the table contain a NULL value for the column. Ordinarily this is checked during the ALTER TABLE by scanning the - entire table; however, if a valid CHECK constraint is - found which proves no NULL can exist, then the - table scan is skipped. + entire table, unless NOT VALID is specified; + however, if a valid CHECK constraint is + found which proves no NULL can exist (and is not + dropped in the same command), then the table scan is skipped. If a column has an invalid not-null constraint, SET NOT NULL validates it. (This is correct for 18; for 17 and earlier, the mention of NOT VALID needs to be removed.) Of course, in 18 you'd rely on ADD NOT NULL NOT VALID instead of using a separate CHECK constraint. Not sure if this reads better: if a valid CHECK constraint is found (and is not dropped in the same command) which proves no NULL can exist, then -- Álvaro Herrera 48°01'N 7°57'E — https://www.EnterpriseDB.com/ "Most hackers will be perfectly comfortable conceptualizing users as entropy sources, so let's move on." (Nathaniel Smith) https://mail.gnu.org/archive/html/monotone-devel/2007-01/msg00080.html