mirror of
https://github.com/postgres/postgres.git
synced 2025-10-04 00:02:26 -04:00
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
This commit is contained in:
parent
454c046094
commit
bf5da5d6ca
@ -11065,6 +11065,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system'
|
||||
string, the default <literal>'$system'</literal> is also assumed.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
If extensions with equal names are present in multiple directories in
|
||||
the configured path, only the instance found first in the path will be
|
||||
used.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
This parameter can be changed at run time by superusers and users
|
||||
with the appropriate <literal>SET</literal> privilege, but a
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
Loading…
x
Reference in New Issue
Block a user