Glob Support in extension_control_path / dynamic_library_path
Core Problem
PostgreSQL 18 introduced the extension_control_path GUC (along with changes to dynamic_library_path) to allow extensions to be loaded from directories outside the default system installation path. This was a significant packaging improvement, but it has a practical limitation: each extension directory must be explicitly enumerated in the configuration.
For packagers like Postgres.app who install each extension into its own isolated directory tree (e.g., /Users/USER/Library/Application Support/Postgres/Extensions/18/pg_cron/), this creates two operational problems:
- Configuration bloat: The
extension_control_pathvalue becomes extremely long as more extensions are installed, with each extension's path explicitly listed. - Server restart required: Every time a new extension is installed, the configuration must be updated and the server restarted (since these are typically
postmaster-level GUCs requiring restart).
Why Per-Extension Directories Matter
The per-extension directory layout is architecturally motivated by clean lifecycle management. When each extension owns its own directory subtree, uninstallation is simply rm -rf <extension_dir> — there's no need to track which individual files (.control, .sql, .so) belong to which extension. This prevents orphaned files, a real concern when extensions are independently downloaded and updated outside the system package manager.
The directory structure looks like:
/Extensions/18/<extension_name>/share/postgresql/ (control + SQL files)
/Extensions/18/<extension_name>/lib/postgresql/ (shared libraries)
Proposed Solution: Glob Patterns
The proposal is to allow shell glob patterns (specifically * wildcards) in both extension_control_path and dynamic_library_path:
extension_control_path = "$system:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/share/postgresql"
dynamic_library_path = "$libdir:/Users/jakob/Library/Application Support/Postgres/Extensions/18/*/lib/postgresql"
Technical Implications
-
Implementation: Jakob reports a proof-of-concept was "pretty straightforward" — likely using POSIX
glob(3)to expand patterns at path resolution time rather than at GUC parse time. -
Lazy vs. Eager Expansion: A key design question (not yet discussed in the thread) is when the glob is expanded:
- Eager (at config load): Expand once at startup — simpler but still requires restart for new extensions.
- Lazy (at lookup time): Expand each time an extension is searched for — eliminates the restart requirement entirely, which is the stated goal.
Jakob explicitly notes the advantage of "not requiring a server restart after installing an extension," which implies lazy expansion is the intended semantic.
-
Performance Considerations: Lazy glob expansion means filesystem
readdir/statcalls on everyCREATE EXTENSIONor shared library load. For typical use cases (few extension directories), this is negligible. But it's a design point that would need discussion. -
Security Implications: Glob expansion in path settings expands the attack surface — if a user can create directories matching the pattern, they could inject malicious extensions. This is similar to existing risks with
dynamic_library_pathbut amplified by the wildcard semantics. The security model here depends on filesystem permissions on the parent directory. -
Platform Portability: POSIX
glob(3)is available on all Unix-like systems. Windows has different glob semantics (FindFirstFile/FindNextFile), so a portable implementation would need platform-specific code or a compatibility layer.
Relationship to Original extension_control_path Work
The original extension_control_path feature (proposed by David Wheeler / David Christensen) was motivated by Docker and packaging scenarios where extensions come from multiple sources. The glob proposal is a natural evolution — David Wheeler's response ("I had been planning to propose a new directory layout, but a glob is a much simpler solution") confirms this solves the multi-extension packaging problem more elegantly than a prescribed directory convention.
Status and Open Questions
This is an early-stage proposal (just initial email + positive reception). Key questions for the community:
- Should glob expansion happen at config load time or at lookup time?
- What ordering guarantees exist when globs expand to multiple directories?
- Should this work for both GUCs symmetrically?
- Are there security concerns with wildcard path expansion for shared library loading?
- How does this interact with
$systemand$libdirsentinel values? - Would this be a PG18 late addition or PG19 material? (Given the May 2026 date, this is likely targeting PG19 development.)