Hi,
Thanks for the patch!
I tested extension_control_path with a few different "directory" values:
a relative 'scripts', the MODULEDIR style 'extension/foo', an absolute
path, 'extension' and no directory at all. In all cases the scripts were
loaded from where the new wording says they should be, and 'extension'
behaves the same as not setting it. The patch also applies cleanly on
REL_18_STABLE, which has the same wrong text, and the docs build fine.
I have some small comments:
1: The SHAREDIR vs extension_control_path wording
- the directory where the control file was found. By default,
- the script files are looked for in the same directory where the
- control file was found.
+ the installation's <literal>SHAREDIR</literal> directory, or to the
+ <xref linkend="guc-extension-control-path"/> element used to locate
+ the primary control file. The default behavior is equivalent to
+ specifying <literal>directory = 'extension'</literal>.
The "or" in the new sentence doesn't say when each case applies. If the
control file is found via $system, the extension_control_path element
is $system itself, which expands to SHAREDIR/extension, not SHAREDIR,
so the "element used to locate the primary control file" can still be
read as the extension subdirectory. Maybe something like this?
Unless an absolute path is given, the name is relative to the parent
of the extension directory where the primary control file was
found, that is, the installation's SHAREDIR directory, or the
corresponding extension_control_path element.
It's just a nit though, v2 is already much better than the current text.
2: Commit message
"relative to the installation's base directory, i.e., SHAREDIR or the
extension_control_path element" is a bit loose, since a custom path
element is not really the installation's directory. Just "the base
directory" would be enough IMO.
Unrelated to the "directory" fix, but while reading the
extension_control_path docs I noticed that it says "If a list element
starts with the special string $system, the compiled-in PostgreSQL
extension directory is substituted for $system", but
get_extension_control_directories() only accepts an exact match, so
something like '$system/foo' is not expanded. CREATE EXTENSION then
fails with "component in parameter "extension_control_path" is not an
absolute path", while pg_available_extensions silently skips it.
The attached v3 includes a 0002 that fixes the docs for this. 0001 is
the same as v2-0001, so the comments above still apply to it.
--
Matheus Alcantara
EDB: https://www.enterprisedb.com
From 92e25f8633fb68a2fb8b872064369b242f9ec0bb Mon Sep 17 00:00:00 2001
From: Mahendrakar Srinivasarao <[email protected]>
Date: Sat, 31 Oct 2026 03:11:36 +0000
Subject: [PATCH v3 1/2] doc: Fix description of relative extension "directory"
setting
Commit 81eaaa2c41d changed the documentation of the "directory"
control file parameter to say that a relative path is resolved against
the directory where the control file was found. That is not what the
code does: a relative path is resolved against the installation's base
directory, i.e., SHAREDIR or the extension_control_path element used to
locate the primary control file, not the "extension" subdirectory of it
in which the control file actually resides. This is also what the TAP
test in src/test/modules/test_extensions expects, and it keeps the
long-standing convention of "directory = 'extension/foo'" (with
MODULEDIR) working.
Restore the pre-18 wording, extended to cover extension_control_path,
and mention in the description of extension_control_path that the
"directory" setting can cause script files to be loaded from somewhere
other than the control file's directory.
Backpatch to 18, where the incorrect wording was introduced.
---
doc/src/sgml/config.sgml | 4 +++-
doc/src/sgml/extend.sgml | 7 ++++---
2 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index a6a2df177f2..0a94a7cac36 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -11750,7 +11750,9 @@ dynamic_library_path =
'C:\tools\postgresql;H:\my_project\lib;$libdir'
A path to search for extensions, specifically extension control files
(<filename><replaceable>name</replaceable>.control</filename>). The
remaining extension script and secondary control files are then loaded
- from the same directory where the primary control file was found.
+ from the same directory where the primary control file was found,
+ unless the primary control file specifies a different
+ <literal>directory</literal>.
See <xref linkend="extend-extensions-files"/> for details.
</para>
diff --git a/doc/src/sgml/extend.sgml b/doc/src/sgml/extend.sgml
index 63c5ec6d1eb..a283cc259a0 100644
--- a/doc/src/sgml/extend.sgml
+++ b/doc/src/sgml/extend.sgml
@@ -674,9 +674,10 @@ RETURNS anycompatible AS ...
<para>
The directory containing the extension's <acronym>SQL</acronym> script
file(s). Unless an absolute path is given, the name is relative to
- the directory where the control file was found. By default,
- the script files are looked for in the same directory where the
- control file was found.
+ the installation's <literal>SHAREDIR</literal> directory, or to the
+ <xref linkend="guc-extension-control-path"/> element used to locate
+ the primary control file. The default behavior is equivalent to
+ specifying <literal>directory = 'extension'</literal>.
</para>
</listitem>
</varlistentry>
--
2.50.1 (Apple Git-155)
From 49cccd90f206605698accae18541d656f6342c9b Mon Sep 17 00:00:00 2001
From: Matheus Alcantara <[email protected]>
Date: Mon, 9 Nov 2026 13:04:54 -0300
Subject: [PATCH v3 2/2] doc: Fix description of $system in
extension_control_path
The documentation says that a list element of extension_control_path
that starts with $system gets the system extension directory
substituted for it. However, since commit 81eaaa2c41d,
get_extension_control_directories() only recognizes an element that is
exactly "$system". Any other element, like "$system/foo", is taken as
a literal path with the "extension" suffix appended, so CREATE
EXTENSION fails with a "not an absolute path" error, while
pg_available_extensions silently returns no rows for it.
Expanding $system as a prefix doesn't fit well with the path elements
being base directories to which "extension" is appended, since $system
already points to the extension directory itself. So, rather than
changing the behavior, fix the documentation to say that the element
must be exactly $system. While at it, clarify that $system is the
"extension" subdirectory of pg_config --sharedir and that the
"extension" suffix is not appended to it.
Backpatch to 18, where the current behavior was introduced.
---
doc/src/sgml/config.sgml | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 0a94a7cac36..1f89be6eb04 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -11759,14 +11759,15 @@ dynamic_library_path =
'C:\tools\postgresql;H:\my_project\lib;$libdir'
<para>
The value for <varname>extension_control_path</varname> must be a
list of absolute directory paths separated by colons (or semi-colons
- on Windows). If a list element starts
- with the special string <literal>$system</literal>, the
+ on Windows). If a list element is
+ the special string <literal>$system</literal>, the
compiled-in <productname>PostgreSQL</productname> extension
directory is substituted for <literal>$system</literal>; this
is where the extensions provided by the standard
<productname>PostgreSQL</productname> distribution are installed.
- (Use <literal>pg_config --sharedir</literal> to find out the name of
- this directory.) For example:
+ (This is the <filename>extension</filename> subdirectory of the
+ directory shown by <literal>pg_config --sharedir</literal>.)
+ For example:
<programlisting>
extension_control_path =
'/usr/local/share/postgresql:/home/my_project/share:$system'
</programlisting>
@@ -11778,7 +11779,9 @@ extension_control_path =
'C:\tools\postgresql;H:\my_project\share;$system'
subdirectory <filename>extension</filename> which will contain the
<filename>.control</filename> and <filename>.sql</filename> files; the
<filename>extension</filename> suffix is automatically appended to
- each path element.
+ each path element other than <literal>$system</literal>.
+ <literal>$system</literal> cannot be combined with other path
+ components, as in <literal>$system/foo</literal>.
</para>
<para>
--
2.50.1 (Apple Git-155)