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 1u1Tds-00352E-Sc for pgsql-hackers@arkaria.postgresql.org; Sun, 06 Apr 2025 17:18:45 +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 1u1Tdr-00GyrP-1P for pgsql-hackers@arkaria.postgresql.org; Sun, 06 Apr 2025 17:18:43 +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 1u1Tdq-00GyrE-Ec for pgsql-hackers@lists.postgresql.org; Sun, 06 Apr 2025 17:18:43 +0000 Received: from 004.mia.mailroute.net ([199.89.3.7]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1u1Tdk-003ktC-1W for pgsql-hackers@postgresql.org; Sun, 06 Apr 2025 17:18:39 +0000 Received: from localhost (localhost [127.0.0.1]) by 004.mia.mailroute.net (Postfix) with ESMTP id 4ZVzZf0HRYzm0jvN for ; Sun, 6 Apr 2025 17:18:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=acm.org; h= content-transfer-encoding:content-type:content-type:mime-version :user-agent:date:date:message-id:subject:subject:from:from :received:received; s=mr01; t=1743959913; x=1746551914; bh=SYG5l hclsVrCH+AU1LfNo7x5ZyQqrr0I96VTUKiwEDg=; b=WdeAEkUH6XoWnsrTQh7DA bPLWnhZm7mVquysuOnQNTQ+LINnr/1gJdxB33n4rvW28wAVRHO2wfYy4yca8t2kp jwlDBcNfe9BB7+KOQNtXBmm7fWw0QDQs2iGJXgMbaRSwUV4ps64V9IxWz9SBTepc 32VdfDSRSnIMhwRPlouXZXCfJbrlnE55TcoXzuk7cIlTCt2eUlHlczkpjPA7LBzV /cPa4wTHMnIa5cbkTEuc9/0bByNkexuFaSQY8QSDtE9fL1xsBP3Y4nfoz+oouu0k hQfUCGRbfUNUCjlQJ4+/+wCtsFSr2PkYDTByO4F00LrYvjgiTsj+AkIK5kYSii1k A== X-Virus-Scanned: by MailRoute Received: from 004.mia.mailroute.net ([127.0.0.1]) by localhost (004.mia [127.0.0.1]) (mroute_mailscanner, port 10029) with LMTP id C7GEueIbg492 for ; Sun, 6 Apr 2025 17:18:33 +0000 (UTC) Received: from [73.103.120.3] (c-73-103-120-3.hsd1.in.comcast.net [73.103.120.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: jcflack@acm.org) by 004.mia.mailroute.net (Postfix) with ESMTPSA id 4ZVzZd1TbMzm0jvG for ; Sun, 6 Apr 2025 17:18:32 +0000 (UTC) From: Chapman Flack X-Enigmail-Draft-Status: N1110 Subject: FmgrInfo allocation patterns (and PL handling as staged programming) To: PostgreSQL Hackers Message-ID: <67F2B767.9040507@acm.org> Date: Sun, 6 Apr 2025 13:18:31 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi hackers, The way the core code allocates FmgrInfo structures has a pleasing property (at least in the parts of the code I have read and the cases I've tested) that the docs don't seem to emphasize. To wit, given a query like SELECT hello(n), hello(x) FROM (VALUES (1::int4, 1.0::float4), (2, 2.0 ), (3, 3.0 )) AS t(n,x); the core code allocates one FmgrInfo for each of the two uses. If the PL handler has a useful way to specialize the polymorphic-typed function to int4 in the one case and float4 in the other, each can be stashed in its respective flinfo->fn_extra and the specialized versions used as expected for the duration of the query. Likewise, the trigger manager prepares for a query by allocating one FmgrInfo for each distinct trigger involved, so if there is a single trigger function referenced by multiple triggers, a version specialized to each trigger can be stashed on its respective flinfo and used for all firings of that trigger the query may generate. This lends itself to a nice staged-programming view of a PL handler's job: prepare: RegProcedure -> Template (cache by regproc) specialize: (Template, call site) -> Routine (cache on fn_extra) apply: (Routine, fcinfo) -> result (where I consider some members both of flinfo, such as fn_expr, and of fcinfo, such as nargs, context, resultinfo, to be logically properties of a notional "call site"). I wonder, though, if there might be code in the wild, or even in corners of the core I haven't looked in, where FmgrInfo structs aren't being used that way, and could get reused for successive calls of one routine but with, say, different nargs or argument types. That would seem odd but I don't see that the documentation ever came right out and said not to. If that seems like a non-imaginary risk, I wonder if FmgrInfo could sprout something like a safe-to-specialize bit, initialized to false for old code that doesn't know about it, but set true in places where FmgrInfo structs are definitely being managed as described above? I suspect that would result in the vast majority of FmgrInfo structs ever really encountered having the bit set. Regards, -Chap A work-in-progress PL dispatcher based on the above can be seen at: https://tada.github.io/pljava/preview1.7/pljava-api/apidocs/org.postgresql.pljava/org/postgresql/pljava/PLJavaBasedLanguage.html