0003-Log-a-WARNING-if-_PG_init-accesses-syscache-v2.patch

application/octet-stream

Filename: 0003-Log-a-WARNING-if-_PG_init-accesses-syscache-v2.patch
Type: application/octet-stream
Part: 2
Message: Re: BUG #15350: Getting invalid cache ID: 11 Errors

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch v2-0003
Subject: Log a WARNING if _PG_init() accesses syscache.
File+
src/backend/utils/cache/catcache.c 10 0
src/backend/utils/fmgr/dfmgr.c 21 1
src/include/fmgr.h 1 0
From f617409943eb0c24051a4d480207805f0db31171 Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@enterprisedb.com>
Date: Thu, 13 Sep 2018 16:01:54 +1200
Subject: [PATCH 3/3] Log a WARNING if _PG_init() accesses syscache.

Libraries that access syscache from _PG_init() don't work when loaded
via shared_preload_libraries.  Log a warning to indicate that it will not
be allowed in a future release.

Discussion: https://postgr.es/m/153512195228.1489.8545997741965926448%40wrigleys.postgresql.org
---
 src/backend/utils/cache/catcache.c | 10 ++++++++++
 src/backend/utils/fmgr/dfmgr.c     | 22 +++++++++++++++++++++-
 src/include/fmgr.h                 |  1 +
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 5ddbf6eab1..59f2ddd48f 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -24,6 +24,7 @@
 #include "access/xact.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_type.h"
+#include "fmgr.h"
 #include "miscadmin.h"
 #ifdef CATCACHE_STATS
 #include "storage/ipc.h"		/* for on_proc_exit */
@@ -1227,6 +1228,15 @@ SearchCatCacheInternal(CatCache *cache,
 	dlist_head *bucket;
 	CatCTup    *ct;
 
+	/*
+	 * Libraries' _PG_init() functions should not access syscache.  While that
+	 * works in a regular backend, it results in extensions that cannot be
+	 * loaded via shared_preload_libraries.
+	 */
+	if (unlikely(InitializingLibrary))
+		ereport(WARNING,
+				(errmsg("syscache access from _PG_init() is deprecated and will not be allowed in a future release of PostgreSQL")));
+
 	/* Make sure we're in an xact, even if this ends up being a cache hit */
 	Assert(IsTransactionState());
 
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index 4a5cc7cfc7..e7e946f899 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -76,6 +76,8 @@ static DynamicFileList *file_tail = NULL;
 
 char	   *Dynamic_library_path;
 
+bool		InitializingLibrary;
+
 static void *internal_load_library(const char *libname);
 static void incompatible_module_error(const char *libname,
 						  const Pg_magic_struct *module_magic_data) pg_attribute_noreturn();
@@ -291,7 +293,25 @@ internal_load_library(const char *libname)
 		 */
 		PG_init = (PG_init_t) dlsym(file_scanner->handle, "_PG_init");
 		if (PG_init)
-			(*PG_init) ();
+		{
+			/*
+			 * To prevent _PG_init() functions from doing certain things,
+			 * we set a global flag while running the function.  For now this
+			 * just triggers a warning on syscache access.
+			 */
+			InitializingLibrary = true;
+			PG_TRY();
+			{
+				(*PG_init) ();
+			}
+			PG_CATCH();
+			{
+				InitializingLibrary = false;
+				PG_RE_THROW();
+			}
+			PG_END_TRY();
+			InitializingLibrary = false;
+		}
 
 		/* OK to link it into list */
 		if (file_list == NULL)
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 101f513ba6..888e31ef04 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -678,6 +678,7 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
  * Routines in dfmgr.c
  */
 extern char *Dynamic_library_path;
+extern bool InitializingLibrary;
 
 extern PGFunction load_external_function(const char *filename, const char *funcname,
 					   bool signalNotFound, void **filehandle);
-- 
2.17.0