summaryrefslogtreecommitdiffstats
path: root/debian/patches/extension_destdir
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--debian/patches/extension_destdir270
1 files changed, 270 insertions, 0 deletions
diff --git a/debian/patches/extension_destdir b/debian/patches/extension_destdir
new file mode 100644
index 0000000..dc94b5a
--- /dev/null
+++ b/debian/patches/extension_destdir
@@ -0,0 +1,270 @@
+--- a/src/backend/utils/misc/guc.c
++++ b/src/backend/utils/misc/guc.c
+@@ -655,6 +655,7 @@ char *ConfigFileName;
+ char *HbaFileName;
+ char *IdentFileName;
+ char *external_pid_file;
++char *extension_destdir;
+
+ char *pgstat_temp_directory;
+
+@@ -4529,6 +4530,17 @@ static struct config_string ConfigureNam
+ },
+
+ {
++ {"extension_destdir", PGC_SUSET, FILE_LOCATIONS,
++ gettext_noop("Path to prepend for extension loading."),
++ gettext_noop("This directory is prepended to paths when loading extensions (control and SQL files), and to the '$libdir' directive when loading modules that back functions. The location is made configurable to allow build-time testing of extensions that do not have been installed to their proper location yet."),
++ GUC_SUPERUSER_ONLY
++ },
++ &extension_destdir,
++ "",
++ NULL, NULL, NULL
++ },
++
++ {
+ {"ssl_library", PGC_INTERNAL, PRESET_OPTIONS,
+ gettext_noop("Shows the name of the SSL library."),
+ NULL,
+--- a/src/backend/commands/extension.c
++++ b/src/backend/commands/extension.c
+@@ -128,6 +128,8 @@ static void ApplyExtensionUpdates(Oid ex
+ bool cascade,
+ bool is_create);
+ static char *read_whole_file(const char *filename, int *length);
++static bool file_exists(const char *name);
++static bool directory_exists(const char *dir);
+
+
+ /*
+@@ -388,6 +390,16 @@ get_extension_control_filename(const cha
+
+ get_share_path(my_exec_path, sharepath);
+ result = (char *) palloc(MAXPGPATH);
++ /*
++ * If extension_destdir is set, try to find the file there first
++ */
++ if (*extension_destdir != '\0')
++ {
++ snprintf(result, MAXPGPATH, "%s%s/extension/%s.control",
++ extension_destdir, sharepath, extname);
++ if (file_exists(result))
++ return result;
++ }
+ snprintf(result, MAXPGPATH, "%s/extension/%s.control",
+ sharepath, extname);
+
+@@ -427,6 +439,16 @@ get_extension_aux_control_filename(Exten
+ scriptdir = get_extension_script_directory(control);
+
+ result = (char *) palloc(MAXPGPATH);
++ /*
++ * If extension_destdir is set, try to find the file there first
++ */
++ if (*extension_destdir != '\0')
++ {
++ snprintf(result, MAXPGPATH, "%s%s/%s--%s.control",
++ extension_destdir, scriptdir, control->name, version);
++ if (file_exists(result))
++ return result;
++ }
+ snprintf(result, MAXPGPATH, "%s/%s--%s.control",
+ scriptdir, control->name, version);
+
+@@ -445,6 +467,23 @@ get_extension_script_filename(ExtensionC
+ scriptdir = get_extension_script_directory(control);
+
+ result = (char *) palloc(MAXPGPATH);
++ /*
++ * If extension_destdir is set, try to find the file there first
++ */
++ if (*extension_destdir != '\0')
++ {
++ if (from_version)
++ snprintf(result, MAXPGPATH, "%s%s/%s--%s--%s.sql",
++ extension_destdir, scriptdir, control->name, from_version, version);
++ else
++ snprintf(result, MAXPGPATH, "%s%s/%s--%s.sql",
++ extension_destdir, scriptdir, control->name, version);
++ if (file_exists(result))
++ {
++ pfree(scriptdir);
++ return result;
++ }
++ }
+ if (from_version)
+ snprintf(result, MAXPGPATH, "%s/%s--%s--%s.sql",
+ scriptdir, control->name, from_version, version);
+@@ -1133,6 +1172,59 @@ get_ext_ver_list(ExtensionControlFile *c
+ DIR *dir;
+ struct dirent *de;
+
++ /*
++ * If extension_destdir is set, try to find the files there first
++ */
++ if (*extension_destdir != '\0')
++ {
++ char location[MAXPGPATH];
++
++ snprintf(location, MAXPGPATH, "%s%s", extension_destdir,
++ get_extension_script_directory(control));
++ dir = AllocateDir(location);
++ while ((de = ReadDir(dir, location)) != NULL)
++ {
++ char *vername;
++ char *vername2;
++ ExtensionVersionInfo *evi;
++ ExtensionVersionInfo *evi2;
++
++ /* must be a .sql file ... */
++ if (!is_extension_script_filename(de->d_name))
++ continue;
++
++ /* ... matching extension name followed by separator */
++ if (strncmp(de->d_name, control->name, extnamelen) != 0 ||
++ de->d_name[extnamelen] != '-' ||
++ de->d_name[extnamelen + 1] != '-')
++ continue;
++
++ /* extract version name(s) from 'extname--something.sql' filename */
++ vername = pstrdup(de->d_name + extnamelen + 2);
++ *strrchr(vername, '.') = '\0';
++ vername2 = strstr(vername, "--");
++ if (!vername2)
++ {
++ /* It's an install, not update, script; record its version name */
++ evi = get_ext_ver_info(vername, &evi_list);
++ evi->installable = true;
++ continue;
++ }
++ *vername2 = '\0'; /* terminate first version */
++ vername2 += 2; /* and point to second */
++
++ /* if there's a third --, it's bogus, ignore it */
++ if (strstr(vername2, "--"))
++ continue;
++
++ /* Create ExtensionVersionInfos and link them together */
++ evi = get_ext_ver_info(vername, &evi_list);
++ evi2 = get_ext_ver_info(vername2, &evi_list);
++ evi->reachable = lappend(evi->reachable, evi2);
++ }
++ FreeDir(dir);
++ }
++
+ location = get_extension_script_directory(control);
+ dir = AllocateDir(location);
+ while ((de = ReadDir(dir, location)) != NULL)
+@@ -3393,3 +3485,32 @@ read_whole_file(const char *filename, in
+ buf[*length] = '\0';
+ return buf;
+ }
++
++static bool
++file_exists(const char *name)
++{
++ struct stat st;
++
++ AssertArg(name != NULL);
++
++ if (stat(name, &st) == 0)
++ return S_ISDIR(st.st_mode) ? false : true;
++ else if (!(errno == ENOENT || errno == ENOTDIR || errno == EACCES))
++ ereport(ERROR,
++ (errcode_for_file_access(),
++ errmsg("could not access file \"%s\": %m", name)));
++
++ return false;
++}
++
++static bool
++directory_exists(const char *dir)
++{
++ struct stat st;
++
++ if (stat(dir, &st) != 0)
++ return false;
++ if (S_ISDIR(st.st_mode))
++ return true;
++ return false;
++}
+--- a/src/include/utils/guc.h
++++ b/src/include/utils/guc.h
+@@ -276,6 +276,7 @@ extern PGDLLIMPORT char *ConfigFileName;
+ extern PGDLLIMPORT char *HbaFileName;
+ extern PGDLLIMPORT char *IdentFileName;
+ extern PGDLLIMPORT char *external_pid_file;
++extern PGDLLIMPORT char *extension_destdir;
+
+ extern PGDLLIMPORT char *application_name;
+
+--- a/src/backend/utils/fmgr/dfmgr.c
++++ b/src/backend/utils/fmgr/dfmgr.c
+@@ -34,6 +34,7 @@
+ #include "lib/stringinfo.h"
+ #include "miscadmin.h"
+ #include "storage/shmem.h"
++#include "utils/guc.h"
+ #include "utils/hsearch.h"
+
+
+@@ -497,7 +498,7 @@ expand_dynamic_library_name(const char *
+ {
+ bool have_slash;
+ char *new;
+- char *full;
++ char *full, *full2;
+
+ AssertArg(name);
+
+@@ -512,6 +513,19 @@ expand_dynamic_library_name(const char *
+ else
+ {
+ full = substitute_libpath_macro(name);
++ /*
++ * If extension_destdir is set, try to find the file there first
++ */
++ if (*extension_destdir != '\0')
++ {
++ full2 = psprintf("%s%s", extension_destdir, full);
++ if (file_exists(full2))
++ {
++ pfree(full);
++ return full2;
++ }
++ pfree(full2);
++ }
+ if (file_exists(full))
+ return full;
+ pfree(full);
+@@ -530,6 +544,19 @@ expand_dynamic_library_name(const char *
+ {
+ full = substitute_libpath_macro(new);
+ pfree(new);
++ /*
++ * If extension_destdir is set, try to find the file there first
++ */
++ if (*extension_destdir != '\0')
++ {
++ full2 = psprintf("%s%s", extension_destdir, full);
++ if (file_exists(full2))
++ {
++ pfree(full);
++ return full2;
++ }
++ pfree(full2);
++ }
+ if (file_exists(full))
+ return full;
+ pfree(full);
+--- a/src/backend/utils/misc/postgresql.conf.sample
++++ b/src/backend/utils/misc/postgresql.conf.sample
+@@ -744,6 +744,8 @@
+ # - Other Defaults -
+
+ #dynamic_library_path = '$libdir'
++#extension_destdir = '' # prepend path when loading extensions
++ # and shared objects (added by Debian)
+ #gin_fuzzy_search_limit = 0
+
+