One problem we have with PostGIS is you cannot test an extension
unless you have access to the system extension dir.

The following patch tries to address that by allowing to specify
a per-cluster extension path via an "extensions_path" GUC.

It is more a request-for-comments rather than a ready patch, as
I hadn't considered all use cases like upgrades of already-loaded
extensions and the possibility ot have a list of directories to
seek for extensions.

Anyway, patch is attached.

--strk;

  ()   Free GIS & Flash consultant/developer
  /\   http://strk.keybit.net/services.html
>From 9bba783d6581bc445b8a24fc8e615969fc16ab90 Mon Sep 17 00:00:00 2001
From: Sandro Santilli <s...@keybit.net>
Date: Fri, 23 Oct 2015 12:00:51 +0200
Subject: [PATCH] Add extensions_path GUC

---
 src/backend/commands/extension.c | 37 ++++++++++++++++++++++++++-----------
 src/backend/utils/misc/guc.c     | 14 ++++++++++++++
 src/include/commands/extension.h |  3 +++
 3 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 67b16a7..df4e5df 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -64,6 +64,7 @@
 /* Globally visible state variables */
 bool		creating_extension = false;
 Oid			CurrentExtensionObject = InvalidOid;
+char		*Extension_path = NULL; /* set by guc.c */
 
 /*
  * Internal data structure to hold the results of parsing a control file
@@ -348,15 +349,29 @@ is_extension_script_filename(const char *filename)
 	return (extension != NULL) && (strcmp(extension, ".sql") == 0);
 }
 
+static void
+get_extension_path(char *ret_path)
+{
+	char		sharepath[MAXPGPATH];
+	if ( Extension_path )
+	{
+		snprintf(ret_path, MAXPGPATH, "%s", Extension_path);
+	}
+	else
+	{
+		get_share_path(my_exec_path, sharepath);
+		snprintf(ret_path, MAXPGPATH, "%s/extension", sharepath);
+	}
+}
+
 static char *
 get_extension_control_directory(void)
 {
-	char		sharepath[MAXPGPATH];
 	char	   *result;
 
-	get_share_path(my_exec_path, sharepath);
 	result = (char *) palloc(MAXPGPATH);
-	snprintf(result, MAXPGPATH, "%s/extension", sharepath);
+
+	get_extension_path(result);
 
 	return result;
 }
@@ -364,13 +379,13 @@ get_extension_control_directory(void)
 static char *
 get_extension_control_filename(const char *extname)
 {
-	char		sharepath[MAXPGPATH];
-	char	   *result;
+	char		extpath[MAXPGPATH];
+	char	  *result;
 
-	get_share_path(my_exec_path, sharepath);
+	get_extension_path(extpath);
 	result = (char *) palloc(MAXPGPATH);
-	snprintf(result, MAXPGPATH, "%s/extension/%s.control",
-			 sharepath, extname);
+	snprintf(result, MAXPGPATH, "%s/%s.control",
+			 extpath, extname);
 
 	return result;
 }
@@ -378,7 +393,7 @@ get_extension_control_filename(const char *extname)
 static char *
 get_extension_script_directory(ExtensionControlFile *control)
 {
-	char		sharepath[MAXPGPATH];
+	char		extpath[MAXPGPATH];
 	char	   *result;
 
 	/*
@@ -391,9 +406,9 @@ get_extension_script_directory(ExtensionControlFile *control)
 	if (is_absolute_path(control->directory))
 		return pstrdup(control->directory);
 
-	get_share_path(my_exec_path, sharepath);
+	get_extension_path(extpath);
 	result = (char *) palloc(MAXPGPATH);
-	snprintf(result, MAXPGPATH, "%s/%s", sharepath, control->directory);
+	snprintf(result, MAXPGPATH, "%s/%s", extpath, control->directory);
 
 	return result;
 }
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index fda0fb9..f76d07b 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -33,6 +33,7 @@
 #include "access/xact.h"
 #include "catalog/namespace.h"
 #include "commands/async.h"
+#include "commands/extension.h"
 #include "commands/prepare.h"
 #include "commands/vacuum.h"
 #include "commands/variable.h"
@@ -2943,6 +2944,19 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		{"extensions_path", PGC_SUSET, CLIENT_CONN_OTHER,
+			gettext_noop("Sets the path for extensions."),
+			gettext_noop("If an extension control file needs to be opened "
+						 "the system will search this path for "
+						 "the specified file."),
+			GUC_SUPERUSER_ONLY
+		},
+		&Extension_path,
+		NULL, /* will be handled by get_extension_control_directory */
+		NULL, NULL, NULL
+	},
+
+	{
 		{"krb_server_keyfile", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Sets the location of the Kerberos server key file."),
 			NULL,
diff --git a/src/include/commands/extension.h b/src/include/commands/extension.h
index 0423350..bf6f44b 100644
--- a/src/include/commands/extension.h
+++ b/src/include/commands/extension.h
@@ -27,6 +27,9 @@
 extern PGDLLIMPORT bool creating_extension;
 extern Oid	CurrentExtensionObject;
 
+/* Path to find extension control files in,
+ * defaults to sharedir/extension */
+extern char *Extension_path;
 
 extern ObjectAddress CreateExtension(CreateExtensionStmt *stmt);
 
-- 
1.9.1

-- 
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