From 4ecaa7c65dcd1f2f843158fa554e14944096ba81 Mon Sep 17 00:00:00 2001 From: Jakob Egger Date: Mon, 1 Jun 2026 15:00:34 +0200 Subject: [PATCH] glob support in extension_search_path and dynamic_library_path --- src/backend/commands/extension.c | 40 ++++++++++++++++++++++++++++---- src/backend/utils/fmgr/dfmgr.c | 37 +++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index d073585c421..24348e4dcdc 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -28,6 +28,9 @@ #include #include #include +#ifndef WIN32 +#include +#endif #include "access/genam.h" #include "access/htup_details.h" @@ -541,7 +544,13 @@ get_extension_control_directories(void) int len; char *mangled; char *piece = first_path_var_separator(ecp); - ExtensionLocation *location = palloc_object(ExtensionLocation); + char *macro; +#ifndef WIN32 + glob_t globres; + int glob_status; + int i; +#endif + ExtensionLocation *location; /* Get the length of the next path on ecp */ if (piece == NULL) @@ -559,20 +568,43 @@ get_extension_control_directories(void) */ if (strcmp(piece, EXTENSION_SYSTEM_MACRO) == 0) { - location->macro = pstrdup(piece); + macro = pstrdup(piece); mangled = substitute_path_macro(piece, EXTENSION_SYSTEM_MACRO, system_dir); } else { - location->macro = NULL; + macro = NULL; mangled = psprintf("%s/extension", piece); } pfree(piece); - /* Canonicalize the path based on the OS and add to the list */ + /* Canonicalize the path based on the OS */ canonicalize_path(mangled); + +#ifndef WIN32 + glob_status = glob(mangled, GLOB_BRACE | GLOB_ERR, NULL, &globres); + if (glob_status != 0) + { + if (glob_status == GLOB_NOMATCH) + elog(DEBUG3, "extension_search_path: glob(%s) returned no match", mangled); + else + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("extension_search_path: glob(%s) returned %d", mangled, glob_status))); + } + for (i=0;i < globres.gl_pathc; i++) { + location = palloc_object(ExtensionLocation); + location->macro = macro; + location->loc = pstrdup(globres.gl_pathv[i]); + paths = lappend(paths, location); + } + globfree(&globres); +#else + location = palloc_object(ExtensionLocation); + location->macro = macro; location->loc = mangled; paths = lappend(paths, location); +#endif /* Break if ecp is empty or move to the next path on ecp */ if (ecp[len] == '\0') diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c index e636cc81cf8..6d5d072a8aa 100644 --- a/src/backend/utils/fmgr/dfmgr.c +++ b/src/backend/utils/fmgr/dfmgr.c @@ -18,6 +18,7 @@ #ifndef WIN32 #include +#include #endif /* !WIN32 */ #include "fmgr.h" @@ -598,6 +599,11 @@ find_in_path(const char *basename, const char *path, const char *path_param, char *piece; char *mangled; char *full; +#ifndef WIN32 + glob_t globres; + int glob_status; + int i; +#endif piece = first_path_var_separator(p); if (piece == p) @@ -624,6 +630,36 @@ find_in_path(const char *basename, const char *path, const char *path_param, (errcode(ERRCODE_INVALID_NAME), errmsg("component in parameter \"%s\" is not an absolute path", path_param))); +#ifndef WIN32 + glob_status = glob(mangled, GLOB_BRACE | GLOB_ERR, NULL, &globres); + if (glob_status != 0) + { + if (glob_status == GLOB_NOMATCH) + elog(DEBUG3, "%s: glob(%s) returned no match", path_param, mangled); + else + ereport(ERROR, + (errcode(ERRCODE_CONFIG_FILE_ERROR), + errmsg("%s: glob(%s) returned %d", path_param, mangled, glob_status))); + } + pfree(mangled); + for (i=0;i < globres.gl_pathc; i++) + { + mangled = globres.gl_pathv[i]; + full = palloc(strlen(mangled) + 1 + baselen + 1); + sprintf(full, "%s/%s", mangled, basename); + + elog(DEBUG3, "%s: trying \"%s\"", __func__, full); + + if (pg_file_exists(full)) + { + globfree(&globres); + return full; + } + + pfree(full); + } + globfree(&globres); +#else full = palloc(strlen(mangled) + 1 + baselen + 1); sprintf(full, "%s/%s", mangled, basename); pfree(mangled); @@ -634,6 +670,7 @@ find_in_path(const char *basename, const char *path, const char *path_param, return full; pfree(full); +#endif if (p[len] == '\0') break; -- 2.50.1 (Apple Git-155)