>From 9bba783d6581bc445b8a24fc8e615969fc16ab90 Mon Sep 17 00:00:00 2001
From: Sandro Santilli <strk@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

