Re: RFC: Additional Directory for Extensions

Peter Eisentraut <peter@eisentraut.org>

From: Peter Eisentraut <peter@eisentraut.org>
To: "David E. Wheeler" <david@justatheory.com>, Craig Ringer <craig.ringer@enterprisedb.com>
Cc: Gabriele Bartolini <gabriele.bartolini@enterprisedb.com>, Robert Haas <robertmhaas@gmail.com>, Alvaro Herrera <alvherre@alvh.no-ip.org>, PostgreSQL-development <pgsql-hackers@postgresql.org>
Date: 2024-11-11T07:16:05Z
Lists: pgsql-hackers

Attachments

I implemented a patch along the lines Craig had suggested.  It's a new 
GUC variable that is a path for extension control files.  It's called 
extension_control_path, and it works exactly the same way as 
dynamic_library_path.  Except that the magic token is called $system 
instead of $libdir.  In fact, most of the patch is refactoring the 
routines in dfmgr.c to not hardcode dynamic_library_path but allow 
searching for any file in any path.  Once a control file is found, the 
other extension support files (script files and auxiliary control files) 
are looked for in the same directory.

This works pretty much fine for the use cases that have been presented 
here, including installing extensions outside of the core installation 
tree (for CNPG and Postgres.app) and for testing uninstalled extensions 
(for Debian).

There are some TODOs in the patch.  Some of those are for documentation 
that needs to be completed.  Others are for functions like 
pg_available_extensions() that need to be rewritten to be aware of the 
path.  I think this would be pretty straightforward.

Some open problems or discussion points:

- You can install extensions into alternative directories using PGXS like

     make install datadir=/else/where/share pkglibdir=/else/where/lib

This works.  I was hoping it would work to use

     make install prefix=/else/where

but that doesn't because of some details in Makefile.global.  I think we 
can tweak that a little bit to make that work too.

- With the current patch, if you install into datadir=/else/where/share, 
then you need to set extension_control_path=/else/where/share/extension. 
  This is a bit confusing.  Maybe we want to make the "extension" part 
implicit.

- The biggest problem is that many extensions set in their control file

     module_pathname = '$libdir/foo'

This disables the use of dynamic_library_path, so this whole idea of 
installing an extension elsewhere won't work that way.  The obvious 
solution is that extensions change this to just 'foo'.  But this will 
require a lot updating work for many extensions, or a lot of patching by 
packagers.

Maybe we could devise some sort of rule that if the extension control 
file is found via the path outside of $system, then the leading $libdir 
is ignored.

Commits

  1. doc: Flesh out extension docs for the "prefix" make variable

  2. Fix extension control path tests

  3. extension_control_path