Hi all

I was a puzzled by  src/backend/utils/fmgr/README and fmgr.h's descriptions
of fcinfo->flinfo->fn_extra (FmgrInfo.fn_extra) as they seem to conflict
with actual usage.

The docs suggest that fl_extra is for the use of function call handlers,
but in practice it's also used heavily by function implementations as a
cache space.

For example, SQL functions use fn_extra in init_sql_fcache, plpgsql uses it
in plpgsql_compile, but also most of the array functions use it for a type
cache.

I'm inclined to change the docs to say that functions called directly by
the fmgr may also use fn_extra (per existing practice). Handlers that wrap
functions usually called directly by the fmgr must save and restore
fn_extra or leave it untouched.

Trivial patch to do the above attached.

-- 
 Craig Ringer                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
From c58dec9d20911a91d7db63f313091d69f7999b17 Mon Sep 17 00:00:00 2001
From: Craig Ringer <cr...@2ndquadrant.com>
Date: Fri, 29 May 2015 10:13:41 +0800
Subject: [PATCH] Document that fn_extra is also usable as a cache by
 direct-call fns

---
 src/backend/utils/fmgr/README | 6 +++++-
 src/include/fmgr.h            | 2 +-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/backend/utils/fmgr/README b/src/backend/utils/fmgr/README
index e7e7ae9..0913d28 100644
--- a/src/backend/utils/fmgr/README
+++ b/src/backend/utils/fmgr/README
@@ -71,7 +71,7 @@ typedef struct
     bool        fn_strict;  /* function is "strict" (NULL in => NULL out) */
     bool        fn_retset;  /* function returns a set (over multiple calls) */
     unsigned char fn_stats; /* collect stats if track_functions > this */
-    void       *fn_extra;   /* extra space for use by handler */
+    void       *fn_extra;   /* extra space for use by function or handler */
     MemoryContext fn_mcxt;  /* memory context to store fn_extra in */
     Node       *fn_expr;    /* expression parse tree for call, or NULL */
 } FmgrInfo;
@@ -98,6 +98,10 @@ field really is information about the arguments rather than information
 about the function, but it's proven to be more convenient to keep it in
 FmgrInfo than in FunctionCallInfoData where it might more logically go.
 
+Functions with signature PGFunction (those that are callable directly from the
+fmgr without a handler) may also use fn_extra to cache expensive-to-generate
+information across calls. Handlers that wrap direct function calls must leave
+fn_extra untouched or save and restore it around calls to the wrapped function.
 
 During a call of a function, the following data structure is created
 and passed to the function:
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index a901770..1bbff1e 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -58,7 +58,7 @@ typedef struct FmgrInfo
 	bool		fn_strict;		/* function is "strict" (NULL in => NULL out) */
 	bool		fn_retset;		/* function returns a set */
 	unsigned char fn_stats;		/* collect stats if track_functions > this */
-	void	   *fn_extra;		/* extra space for use by handler */
+	void	   *fn_extra;		/* extra space for use by function or handler */
 	MemoryContext fn_mcxt;		/* memory context to store fn_extra in */
 	fmNodePtr	fn_expr;		/* expression parse tree for call, or NULL */
 } FmgrInfo;
-- 
2.1.0

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to