Hackers, Back at the end of August, I promised[1]:
> Iβll try to put some thought into a more formal proposal in a new thread next > week. Unless your Gabriele beats me to it π. I guess I should get off my butt and do it. So letβs do this. Hereβs what I propose. * When an extension is installed, all of its files should live in a single directory. These include: * The Control file in directory describes extension * Subdirectories for SQL, shared libraries, docs, binaries (also locales and tsearch dictionaries?) * Next, there should be an extension lookup path. The first item in the path is the compile-time default, and ideally would include only core extensions. Subsequent paths would be set by a GUC, similar to dynamic_library_path, but only for extensions (including their shared libraries). * Modify PGXS (or create a new installer CLI used by PGXS?) to install an extension according to this pattern. Allow the specification of a prefix. This should differ from the current `PREFIX`, in that the values of `sharedir`, `pkglibdir`, etc. would not be fully-duplicated under the prefix, but point to a directory used in the extension path. For example, when installing an extension need βpair", something like make install BASE_DIR=/opt/pg/extension Would create `/opt/pg/extension/pair`, rather than `/opt/pg/extension/$(pg_config --sharedir)/extension/pair`. * Perhaps there could also be an option to symlink binary files or man pages to keep paths simple. * For CREATE EXTENSION, Postgres would look for an extension on the file system by directory name in each of the extension paths instead of control file name. It would then find the control file in that directory and the necessary SQL and shared library files in the `sql` and `lib` subdirectories of that directory. * Binary-only extensions might also be installed here; the difference is they have no control file. The LOAD command and shared_preload_libraries would need to know to look here, too. The basic idea, then, is three-fold: 1. This pattern is more like a packaging pattern than CREATE EXTENSION-specific, since it includes other types of extensions 2. All the files for a given extension live within a single directory, making it easier to reason about whatβs installed and whatβs not. 3. These extension packages can live in multiple paths. Some examples. Core extensions, like citext, would live in, say, $(pg_config --extensiondir)/citext), and have a structure such as: ``` citext βββ citext.control βββ lib β βββ citext.dylib β βββ bitcode β βββ citext β β βββ citext.bc β βββ citext.index.bc βββ sql βββ citext--1.0--1.1.sql βββ citext--1.1--1.2.sql βββ citext--1.2--1.3.sql βββ citext--1.3--1.4.sql βββ citext--1.4--1.5.sql βββ citext--1.4.sql βββ citext--1.5--1.6.sql ``` Third-party extensions would live in one or more other directories on the file system, unknown at compile time, but set in the extension path GUC and accessible to/owned by the Postgres system user. Letβs say we set `/opt/pgxn` as one of the paths. Within that directory, we might have a directory for a pure SQL extension in a a directory named βpairβ that looks like this: ``` pair βββ LICENSE.md βββ README.md βββ pair.control βββ doc β βββ html β β βββ pair.html β βββ pair.md βββ sql βββ pair--1.0--1.1.sql βββ pair--1.1.sql ``` A binary application like pg_top would live in the pg_top directory, structured something like: ``` pg_top βββ HISTORY.rst βββ INSTALL.rst βββ LICENSE βββ README.rst βββ bin | βββ pg_top βββ doc βββ man βββ man3 βββ pg_top.3 ``` And a C extension like semver would live in the semver directory and be structured something like: ``` semver βββ LICENSE βββ README.md βββ semver.control βββ doc β βββ semver.md βββ lib β βββ semver.dylib β βββ bitcode β βββ semver β β βββ semver.bc β βββ semver.index.bc βββ sql βββ semver--1.0--1.1.sql βββ semver--1.1.sql ``` Thoughts? Best, David [1]: https://www.postgresql.org/message-id/D30A91FA-A6D4-4737-941F-0BBB2984B730%40justatheory.com