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 1qee23-007LzT-5Q for pgsql-bugs@arkaria.postgresql.org; Fri, 08 Sep 2023 16:08:31 +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 1qee20-00Bgrf-UZ for pgsql-bugs@arkaria.postgresql.org; Fri, 08 Sep 2023 16:08:28 +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 1qee20-00Bgr7-LL for pgsql-bugs@lists.postgresql.org; Fri, 08 Sep 2023 16:08:28 +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.94.2) (envelope-from ) id 1qee1u-003uxN-KU for pgsql-bugs@lists.postgresql.org; Fri, 08 Sep 2023 16:08:25 +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 388G8JWq1887198; Fri, 8 Sep 2023 12:08:19 -0400 From: Tom Lane To: James Keener cc: "David G. Johnston" , "pgsql-bugs@lists.postgresql.org" Subject: Re: BUG #18097: Immutable expression not allowed in generated at In-reply-to: <118FF128-C9CA-490C-8E67-65888EE8283F@jimkeener.com> References: <18097-ebb179674f22932f@postgresql.org> <118FF128-C9CA-490C-8E67-65888EE8283F@jimkeener.com> Comments: In-reply-to James Keener message dated "Fri, 08 Sep 2023 11:22:07 -0400" MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <1887196.1694189299.1@sss.pgh.pa.us> Content-Transfer-Encoding: quoted-printable Date: Fri, 08 Sep 2023 12:08:19 -0400 Message-ID: <1887197.1694189299@sss.pgh.pa.us> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk James Keener writes: > The issue here, though, is that it works as an expression for an index, = but doesn't work as a generated column unless I explicitly cast it to text= (which should have happened implicitly anyways). (The cast is turning a n= on-immutable expression to be immutable.) The reason that the generated expression fails is that (if you don't explicitly cast to text) then it relies on anytextcat(anynonarray,text), which is only stable, and can't be marked any more restrictively because depending on the type of the non-text argument the corresponding output function might not be immutable. But then why doesn't the equivalent index definition spit up? I found the answer in indexcmds.c's CheckMutability(): /* * First run the expression through the planner. This has a couple of * important consequences. First, function default arguments will get * inserted, which may affect volatility (consider "default now()"). * Second, inline-able functions will get inlined, which may allow us = to * conclude that the function is really less volatile than it's marked= . As * an example, polymorphic functions must be marked with the most vola= tile * behavior that they have for any input type, but once we inline the * function we may be able to conclude that it's not so volatile for t= he * particular input type we're dealing with. * * We assume here that expression_planner() won't scribble on its inpu= t. */ expr =3D expression_planner(expr); /* Now we can search for non-immutable functions */ return contain_mutable_functions((Node *) expr); Applying expression_planner() solves the problem because it inlines anytextcat(anynonarray,text), resolving that the required cast is numeric->text which is immutable. The code for generated expressions omits that step and arrives at the less desirable answer. I wonder where else we have the same issue. regards, tom lane