summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Eisentraut <peter@eisentraut.org>2025-09-15 07:25:22 +0200
committerPeter Eisentraut <peter@eisentraut.org>2025-09-15 07:30:31 +0200
commitbf5da5d6cae959d8119b4b137ddd9912292b8014 (patch)
tree521bfed6f54cacf94cac656414fc200e9c39ce5a /src
parent454c046094ab3431c2ce0c540c46e623bc05bd1a (diff)
Hide duplicate names from extension views
If extensions of equal names were installed in different directories in the path, the views pg_available_extensions and pg_available_extension_versions would show all of them, even though only the first one was actually reachable by CREATE EXTENSION. To fix, have those views skip extensions found later in the path if they have names already found earlier. Also add a bit of documentation that only the first extension in the path can be used. Reported-by: Pierrick <pierrick.chovelon@dalibo.com> Discussion: https://www.postgresql.org/message-id/flat/8f5a0517-1cb8-4085-ae89-77e7454e27ba%40dalibo.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/commands/extension.c24
-rw-r--r--src/test/modules/test_extensions/t/001_extension_control_path.pl9
2 files changed, 30 insertions, 3 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index e6f9ab6dfd6..93ef1ad106f 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -2208,6 +2208,7 @@ pg_available_extensions(PG_FUNCTION_ARGS)
List *locations;
DIR *dir;
struct dirent *de;
+ List *found_ext = NIL;
/* Build tuplestore to hold the result rows */
InitMaterializedSRF(fcinfo, 0);
@@ -2232,6 +2233,7 @@ pg_available_extensions(PG_FUNCTION_ARGS)
{
ExtensionControlFile *control;
char *extname;
+ String *extname_str;
Datum values[3];
bool nulls[3];
@@ -2246,6 +2248,16 @@ pg_available_extensions(PG_FUNCTION_ARGS)
if (strstr(extname, "--"))
continue;
+ /*
+ * Ignore already-found names. They are not reachable by the
+ * path search, so don't shown them.
+ */
+ extname_str = makeString(extname);
+ if (list_member(found_ext, extname_str))
+ continue;
+ else
+ found_ext = lappend(found_ext, extname_str);
+
control = new_ExtensionControlFile(extname);
control->control_dir = pstrdup(location);
parse_extension_control_file(control, NULL);
@@ -2294,6 +2306,7 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
List *locations;
DIR *dir;
struct dirent *de;
+ List *found_ext = NIL;
/* Build tuplestore to hold the result rows */
InitMaterializedSRF(fcinfo, 0);
@@ -2318,6 +2331,7 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
{
ExtensionControlFile *control;
char *extname;
+ String *extname_str;
if (!is_extension_control_filename(de->d_name))
continue;
@@ -2330,6 +2344,16 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
if (strstr(extname, "--"))
continue;
+ /*
+ * Ignore already-found names. They are not reachable by the
+ * path search, so don't shown them.
+ */
+ extname_str = makeString(extname);
+ if (list_member(found_ext, extname_str))
+ continue;
+ else
+ found_ext = lappend(found_ext, extname_str);
+
/* read the control file */
control = new_ExtensionControlFile(extname);
control->control_dir = pstrdup(location);
diff --git a/src/test/modules/test_extensions/t/001_extension_control_path.pl b/src/test/modules/test_extensions/t/001_extension_control_path.pl
index 1a9c97bbf4d..7fbe5bde332 100644
--- a/src/test/modules/test_extensions/t/001_extension_control_path.pl
+++ b/src/test/modules/test_extensions/t/001_extension_control_path.pl
@@ -11,12 +11,15 @@ my $node = PostgreSQL::Test::Cluster->new('node');
$node->init;
-# Create a temporary directory for the extension control file
+# Create temporary directories for the extension control files
my $ext_dir = PostgreSQL::Test::Utils::tempdir();
mkpath("$ext_dir/extension");
+my $ext_dir2 = PostgreSQL::Test::Utils::tempdir();
+mkpath("$ext_dir2/extension");
my $ext_name = "test_custom_ext_paths";
create_extension($ext_name, $ext_dir);
+create_extension($ext_name, $ext_dir2);
my $ext_name2 = "test_custom_ext_paths_using_directory";
mkpath("$ext_dir/$ext_name2");
@@ -26,7 +29,7 @@ create_extension($ext_name2, $ext_dir, $ext_name2);
my $sep = $windows_os ? ";" : ":";
$node->append_conf(
'postgresql.conf', qq{
-extension_control_path = '\$system$sep@{[ $windows_os ? ($ext_dir =~ s/\\/\\\\/gr) : $ext_dir ]}'
+extension_control_path = '\$system$sep@{[ $windows_os ? ($ext_dir =~ s/\\/\\\\/gr) : $ext_dir ]}$sep@{[ $windows_os ? ($ext_dir2 =~ s/\\/\\\\/gr) : $ext_dir2 ]}'
});
# Start node
@@ -34,7 +37,7 @@ $node->start;
my $ecp = $node->safe_psql('postgres', 'show extension_control_path;');
-is($ecp, "\$system$sep$ext_dir",
+is($ecp, "\$system$sep$ext_dir$sep$ext_dir2",
"custom extension control directory path configured");
$node->safe_psql('postgres', "CREATE EXTENSION $ext_name");