🌐 AI搜索 & 代理 主页
Skip to content

Commit 8309f3f

Browse files
committed
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
1 parent bee763a commit 8309f3f

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

doc/src/sgml/config.sgml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11057,6 +11057,12 @@ extension_control_path = 'C:\tools\postgresql;H:\my_project\share;$system'
1105711057
string, the default <literal>'$system'</literal> is also assumed.
1105811058
</para>
1105911059

11060+
<para>
11061+
If extensions with equal names are present in multiple directories in
11062+
the configured path, only the instance found first in the path will be
11063+
used.
11064+
</para>
11065+
1106011066
<para>
1106111067
This parameter can be changed at run time by superusers and users
1106211068
with the appropriate <literal>SET</literal> privilege, but a

src/backend/commands/extension.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2208,6 +2208,7 @@ pg_available_extensions(PG_FUNCTION_ARGS)
22082208
List *locations;
22092209
DIR *dir;
22102210
struct dirent *de;
2211+
List *found_ext = NIL;
22112212

22122213
/* Build tuplestore to hold the result rows */
22132214
InitMaterializedSRF(fcinfo, 0);
@@ -2232,6 +2233,7 @@ pg_available_extensions(PG_FUNCTION_ARGS)
22322233
{
22332234
ExtensionControlFile *control;
22342235
char *extname;
2236+
String *extname_str;
22352237
Datum values[3];
22362238
bool nulls[3];
22372239

@@ -2246,6 +2248,16 @@ pg_available_extensions(PG_FUNCTION_ARGS)
22462248
if (strstr(extname, "--"))
22472249
continue;
22482250

2251+
/*
2252+
* Ignore already-found names. They are not reachable by the
2253+
* path search, so don't shown them.
2254+
*/
2255+
extname_str = makeString(extname);
2256+
if (list_member(found_ext, extname_str))
2257+
continue;
2258+
else
2259+
found_ext = lappend(found_ext, extname_str);
2260+
22492261
control = new_ExtensionControlFile(extname);
22502262
control->control_dir = pstrdup(location);
22512263
parse_extension_control_file(control, NULL);
@@ -2294,6 +2306,7 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
22942306
List *locations;
22952307
DIR *dir;
22962308
struct dirent *de;
2309+
List *found_ext = NIL;
22972310

22982311
/* Build tuplestore to hold the result rows */
22992312
InitMaterializedSRF(fcinfo, 0);
@@ -2318,6 +2331,7 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
23182331
{
23192332
ExtensionControlFile *control;
23202333
char *extname;
2334+
String *extname_str;
23212335

23222336
if (!is_extension_control_filename(de->d_name))
23232337
continue;
@@ -2330,6 +2344,16 @@ pg_available_extension_versions(PG_FUNCTION_ARGS)
23302344
if (strstr(extname, "--"))
23312345
continue;
23322346

2347+
/*
2348+
* Ignore already-found names. They are not reachable by the
2349+
* path search, so don't shown them.
2350+
*/
2351+
extname_str = makeString(extname);
2352+
if (list_member(found_ext, extname_str))
2353+
continue;
2354+
else
2355+
found_ext = lappend(found_ext, extname_str);
2356+
23332357
/* read the control file */
23342358
control = new_ExtensionControlFile(extname);
23352359
control->control_dir = pstrdup(location);

src/test/modules/test_extensions/t/001_extension_control_path.pl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,15 @@
1111

1212
$node->init;
1313

14-
# Create a temporary directory for the extension control file
14+
# Create temporary directories for the extension control files
1515
my $ext_dir = PostgreSQL::Test::Utils::tempdir();
1616
mkpath("$ext_dir/extension");
17+
my $ext_dir2 = PostgreSQL::Test::Utils::tempdir();
18+
mkpath("$ext_dir2/extension");
1719

1820
my $ext_name = "test_custom_ext_paths";
1921
create_extension($ext_name, $ext_dir);
22+
create_extension($ext_name, $ext_dir2);
2023

2124
my $ext_name2 = "test_custom_ext_paths_using_directory";
2225
mkpath("$ext_dir/$ext_name2");
@@ -26,15 +29,15 @@
2629
my $sep = $windows_os ? ";" : ":";
2730
$node->append_conf(
2831
'postgresql.conf', qq{
29-
extension_control_path = '\$system$sep@{[ $windows_os ? ($ext_dir =~ s/\\/\\\\/gr) : $ext_dir ]}'
32+
extension_control_path = '\$system$sep@{[ $windows_os ? ($ext_dir =~ s/\\/\\\\/gr) : $ext_dir ]}$sep@{[ $windows_os ? ($ext_dir2 =~ s/\\/\\\\/gr) : $ext_dir2 ]}'
3033
});
3134

3235
# Start node
3336
$node->start;
3437

3538
my $ecp = $node->safe_psql('postgres', 'show extension_control_path;');
3639

37-
is($ecp, "\$system$sep$ext_dir",
40+
is($ecp, "\$system$sep$ext_dir$sep$ext_dir2",
3841
"custom extension control directory path configured");
3942

4043
$node->safe_psql('postgres', "CREATE EXTENSION $ext_name");

0 commit comments

Comments
 (0)