[PATCH] doc: Fix description of relative extension "directory" setting
Hi,
Since PostgreSQL 18 (commit 81eaaa2c41d), the documentation of the
extension control file "directory" parameter says a relative path is
"relative to the directory where the control file was found".
However, that doesn't match the code: a relative path is resolved
against SHAREDIR,
or against the extension_control_path element in which the control
file was found, i.e. the parent of that "extension" directory.
Repro steps on master:
/tmp/repro/extension/dir_doc_probe.control:
default_version = '1.0'
directory = 'scripts'
relocatable = true
/tmp/repro/scripts/dir_doc_probe--1.0.sql:
CREATE TABLE dir_doc_probe_result (origin text);
INSERT INTO dir_doc_probe_result VALUES ('installation base');
/tmp/repro/extension/scripts/dir_doc_probe--1.0.sql:
CREATE TABLE dir_doc_probe_result (origin text);
INSERT INTO dir_doc_probe_result VALUES ('control-file directory');
BEGIN;
SET LOCAL extension_control_path = '/tmp/repro';
CREATE EXTENSION dir_doc_probe;
SELECT origin FROM dir_doc_probe_result;
origin
-------------------
installation base
(1 row)
ROLLBACK;
The attached patch restores the pre-18 wording, extended to cover
extension_control_path, and clarifies the extension_control_path
description accordingly.
On Oct 31, 2026, at 11:47, Mahendrakar Srinivasarao <mahendrakarforpg@gmail.com> wrote:
Hi,
Since PostgreSQL 18 (commit 81eaaa2c41d), the documentation of the
extension control file "directory" parameter says a relative path is
"relative to the directory where the control file was found".
However, that doesn't match the code: a relative path is resolved
against SHAREDIR,
or against the extension_control_path element in which the control
file was found, i.e. the parent of that "extension" directory.Repro steps on master:
/tmp/repro/extension/dir_doc_probe.control:
default_version = '1.0'
directory = 'scripts'
relocatable = true/tmp/repro/scripts/dir_doc_probe--1.0.sql:
CREATE TABLE dir_doc_probe_result (origin text);
INSERT INTO dir_doc_probe_result VALUES ('installation base');/tmp/repro/extension/scripts/dir_doc_probe--1.0.sql:
CREATE TABLE dir_doc_probe_result (origin text);
INSERT INTO dir_doc_probe_result VALUES ('control-file directory');BEGIN;
SET LOCAL extension_control_path = '/tmp/repro';
CREATE EXTENSION dir_doc_probe;
SELECT origin FROM dir_doc_probe_result;
origin
-------------------
installation base
(1 row)
ROLLBACK;The attached patch restores the pre-18 wording, extended to cover
extension_control_path, and clarifies the extension_control_path
description accordingly.
<0001-doc-Fix-description-of-relative-extension-directory.patch>
Thanks for the patch. I think the fix is going in the right direction.
The relevant code is:
```
static char *
get_extension_script_directory(ExtensionControlFile *control)
{
/*
* The directory parameter can be omitted, absolute, or relative to the
* installation's base directory, which can be the sharedir or a custom
* path that was set via extension_control_path. It depends on where the
* .control file was found.
*/
if (!control->directory)
return pstrdup(control->control_dir);
if (is_absolute_path(control->directory))
return pstrdup(control->directory);
Assert(control->basedir != NULL);
return psprintf("%s/%s", control->basedir, control->directory);
}
```
When control->directory is a relative path, it is resolved relative to control->basedir, which is either SHAREDIR or the corresponding path element in extension_control_path.
In the patch:
```
- 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 in which the
+ control file was found. The default behavior is equivalent to
+ specifying <literal>directory = 'extension'</literal>.
```
I think the phrase "the extension_control_path element in which the control file was found" is a little misleading.
For example, suppose we have:
```
extension_control_path = '/opt/myext/share’
```
The primary control file is found in /opt/myext/share/extension. If it specifies:
```
directory = ‘scripts’
```
the scripts will be loaded from /opt/myext/share/scripts, not /opt/myext/share/extension/scripts.
So, saying "in which the control file was found" might suggest /opt/myext/share/extension, rather than /opt/myext/share.
I would suggest wording it more explicitly, like:
```
or to the extension_control_path element used to locate the primary control file.
```
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
+PostgreSQL Hackers
Show quoted text
On Tue, 3 Nov 2026 at 10:53, Chao Li <li.evan.chao@gmail.com> wrote:
On Nov 3, 2026, at 00:34, Mahendrakar Srinivasarao <mahendrakarforpg@gmail.com> wrote:
Hi Chao,
Thanks for the review.
I would suggest wording it more explicitly, like:
or to the extension_control_path element used to locate the primary control file.Agreed, the sentence "in which the control file was found" could be read as the
"extension" subdirectory itself.v2 patch uses your suggested wording:
```
Unless an absolute path is given, the name is relative to the
installation's SHAREDIR directory, or to the extension_control_path
element used to locate the primary control file. The default
behavior is equivalent to specifying directory = 'extension'.
```
I have also updated the commit message to match the same.Best regards,
Mahendrakar.<v2-0001-doc-Fix-description-of-relative-extension-directo.patch>
V2 LGTM.
Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/
Import Notes
Reply to msg id not found: A40EAC4A-F75E-405F-8A15-92A203AE5B95@gmail.com