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 1uicN8-00Dlra-HU for pgsql-bugs@arkaria.postgresql.org; Sun, 03 Aug 2025 17:19:46 +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 1uicN6-00ED4O-Nz for pgsql-bugs@arkaria.postgresql.org; Sun, 03 Aug 2025 17:19:44 +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 1uicN6-00ED4F-Fd for pgsql-bugs@lists.postgresql.org; Sun, 03 Aug 2025 17:19:44 +0000 Received: from sss.pgh.pa.us ([68.162.161.243]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1uicN4-000YmS-0g for pgsql-bugs@lists.postgresql.org; Sun, 03 Aug 2025 17:19:44 +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 573HJeWL516625; Sun, 3 Aug 2025 13:19:40 -0400 From: Tom Lane To: bryfox@gmail.com cc: pgsql-bugs@lists.postgresql.org, Richard Guo Subject: Re: BUG #19007: Planner fails to choose partial index with spurious 'not null' In-reply-to: <19007-4cc6e252ed8aa54a@postgresql.org> References: <19007-4cc6e252ed8aa54a@postgresql.org> Comments: In-reply-to PG Bug reporting form message dated "Sun, 03 Aug 2025 16:15:10 -0000" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <516623.1754241580.1@sss.pgh.pa.us> Date: Sun, 03 Aug 2025 13:19:40 -0400 Message-ID: <516624.1754241580@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk PG Bug reporting form writes: > I'm not sure if this is a bug, but the behavior was unexpected to me and > changed since v16. Documentation doesn't mention this as far as I can see. > This example has a partial index over one column where another column is not > null. The latter column is in fact 'not null' in the schema. > Prior to v17, this index would be used; in v17, the planner will choose a > sequential scan instead. Yeah. What is happening is that the query's "flag is not null" condition is thrown away as redundant fairly early in planning, and then it's not available to match to the index's predicate, so the index doesn't appear to be applicable. I had thought that e2debb643 would fix this in HEAD, since it moved the throw-it-away behavior into eval_const_expressions which is also applied to index predicates. Testing shows not, which feels like a bug. It is not okay that eval_const_expressions' behavior varies depending on context; we need it to act the same on index expressions/predicates as on query expressions. Maybe we should give up on trying to pre-apply eval_const_expressions to the relcache's copies of the index expressions, and just do that part during plancat's collection of the info? (I'm also quite displeased that e2debb643 didn't nuke restriction_is_always_true/false. But that's a separate discussion.) regards, tom lane