diff options
author | Peter Eisentraut <peter@eisentraut.org> | 2025-09-15 07:25:22 +0200 |
---|---|---|
committer | Peter Eisentraut <peter@eisentraut.org> | 2025-09-15 07:30:31 +0200 |
commit | bf5da5d6cae959d8119b4b137ddd9912292b8014 (patch) | |
tree | 521bfed6f54cacf94cac656414fc200e9c39ce5a /src | |
parent | 454c046094ab3431c2ce0c540c46e623bc05bd1a (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.c | 24 | ||||
-rw-r--r-- | src/test/modules/test_extensions/t/001_extension_control_path.pl | 9 |
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"); |