Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit60e3bd1

Browse files
committed
pg_upgrade: report database names with missing extension libs
Previously only the missing library name was reported, forcing users tolook in all databases to find the library entries.Discussion:https://postgr.es/m/20180713162815.GA3835@momjian.usAuthor: Daniel Gustafsson, me
1 parent96313bf commit60e3bd1

File tree

2 files changed

+85
-80
lines changed

2 files changed

+85
-80
lines changed

‎src/bin/pg_upgrade/function.c

Lines changed: 79 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,30 @@
1818
/*
1919
* qsort comparator for pointers to library names
2020
*
21-
* We sort first by name length, then alphabetically for names of the same
22-
* length. This is to ensure that, eg, "hstore_plpython" sorts after both
23-
* "hstore" and "plpython"; otherwise transform modules will probably fail
24-
* their LOAD tests. (The backend ought to cope with that consideration,
25-
* but it doesn't yet, and even when it does it'll still be a good idea
26-
* to have a predictable order of probing here.)
21+
* We sort first by name length, then alphabetically for names of the
22+
* same length, then database array index. This is to ensure that, eg,
23+
* "hstore_plpython" sorts after both "hstore" and "plpython"; otherwise
24+
* transform modules will probably fail their LOAD tests. (The backend
25+
* ought to cope with that consideration, but it doesn't yet, and even
26+
* when it does it'll still be a good idea to have a predictable order of
27+
* probing here.)
2728
*/
2829
staticint
2930
library_name_compare(constvoid*p1,constvoid*p2)
3031
{
31-
constchar*str1=*(constchar*const*)p1;
32-
constchar*str2=*(constchar*const*)p2;
32+
constchar*str1=((constLibraryInfo*)p1)->name;
33+
constchar*str2=((constLibraryInfo*)p2)->name;
3334
intslen1=strlen(str1);
3435
intslen2=strlen(str2);
35-
36+
intcmp=strcmp(str1,str2);
37+
3638
if (slen1!=slen2)
3739
returnslen1-slen2;
38-
returnstrcmp(str1,str2);
40+
if (cmp!=0)
41+
returncmp;
42+
else
43+
return ((constLibraryInfo*)p1)->dbnum-
44+
((constLibraryInfo*)p2)->dbnum;
3945
}
4046

4147

@@ -137,18 +143,7 @@ get_loadable_libraries(void)
137143
if (found_public_plpython_handler)
138144
pg_fatal("Remove the problem functions from the old cluster to continue.\n");
139145

140-
/*
141-
* Now we want to remove duplicates across DBs and sort the library names
142-
* into order. This avoids multiple probes of the same library, and
143-
* ensures that libraries are probed in a consistent order, which is
144-
* important for reproducible behavior if one library depends on another.
145-
*
146-
* First transfer all the names into one array, then sort, then remove
147-
* duplicates. Note: we strdup each name in the first loop so that we can
148-
* safely clear the PGresults in the same loop. This is a bit wasteful
149-
* but it's unlikely there are enough names to matter.
150-
*/
151-
os_info.libraries= (char**)pg_malloc(totaltups*sizeof(char*));
146+
os_info.libraries= (LibraryInfo*)pg_malloc(totaltups*sizeof(LibraryInfo));
152147
totaltups=0;
153148

154149
for (dbnum=0;dbnum<old_cluster.dbarr.ndbs;dbnum++)
@@ -162,32 +157,16 @@ get_loadable_libraries(void)
162157
{
163158
char*lib=PQgetvalue(res,rowno,0);
164159

165-
os_info.libraries[totaltups++]=pg_strdup(lib);
160+
os_info.libraries[totaltups].name=pg_strdup(lib);
161+
os_info.libraries[totaltups].dbnum=dbnum;
162+
163+
totaltups++;
166164
}
167165
PQclear(res);
168166
}
169167

170168
pg_free(ress);
171169

172-
if (totaltups>1)
173-
{
174-
inti,
175-
lastnondup;
176-
177-
qsort((void*)os_info.libraries,totaltups,sizeof(char*),
178-
library_name_compare);
179-
180-
for (i=1,lastnondup=0;i<totaltups;i++)
181-
{
182-
if (strcmp(os_info.libraries[i],
183-
os_info.libraries[lastnondup])!=0)
184-
os_info.libraries[++lastnondup]=os_info.libraries[i];
185-
else
186-
pg_free(os_info.libraries[i]);
187-
}
188-
totaltups=lastnondup+1;
189-
}
190-
191170
os_info.num_libraries=totaltups;
192171
}
193172

@@ -204,6 +183,7 @@ check_loadable_libraries(void)
204183
{
205184
PGconn*conn=connectToServer(&new_cluster,"template1");
206185
intlibnum;
186+
intwas_load_failure= false;
207187
FILE*script=NULL;
208188
boolfound= false;
209189
charoutput_path[MAXPGPATH];
@@ -212,52 +192,72 @@ check_loadable_libraries(void)
212192

213193
snprintf(output_path,sizeof(output_path),"loadable_libraries.txt");
214194

195+
/*
196+
* Now we want to sort the library names into order. This avoids multiple
197+
* probes of the same library, and ensures that libraries are probed in a
198+
* consistent order, which is important for reproducible behavior if one
199+
* library depends on another.
200+
*/
201+
qsort((void*)os_info.libraries,os_info.num_libraries,
202+
sizeof(LibraryInfo),library_name_compare);
203+
215204
for (libnum=0;libnum<os_info.num_libraries;libnum++)
216205
{
217-
char*lib=os_info.libraries[libnum];
206+
char*lib=os_info.libraries[libnum].name;
218207
intllen=strlen(lib);
219208
charcmd[7+2*MAXPGPATH+1];
220209
PGresult*res;
221210

222-
/*
223-
* In Postgres 9.0, Python 3 support was added, and to do that, a
224-
* plpython2u language was created with library name plpython2.so as a
225-
* symbolic link to plpython.so. In Postgres 9.1, only the
226-
* plpython2.so library was created, and both plpythonu and plpython2u
227-
* pointing to it. For this reason, any reference to library name
228-
* "plpython" in an old PG <= 9.1 cluster must look for "plpython2" in
229-
* the new cluster.
230-
*
231-
* For this case, we could check pg_pltemplate, but that only works
232-
* for languages, and does not help with function shared objects, so
233-
* we just do a general fix.
234-
*/
235-
if (GET_MAJOR_VERSION(old_cluster.major_version)<901&&
236-
strcmp(lib,"$libdir/plpython")==0)
237-
{
238-
lib="$libdir/plpython2";
239-
llen=strlen(lib);
240-
}
241-
242-
strcpy(cmd,"LOAD '");
243-
PQescapeStringConn(conn,cmd+strlen(cmd),lib,llen,NULL);
244-
strcat(cmd,"'");
245-
246-
res=PQexec(conn,cmd);
247-
248-
if (PQresultStatus(res)!=PGRES_COMMAND_OK)
211+
/* Did the library name change? Probe it. */
212+
if (libnum==0||strcmp(lib,os_info.libraries[libnum-1].name)!=0)
249213
{
250-
found= true;
251-
252-
if (script==NULL&& (script=fopen_priv(output_path,"w"))==NULL)
253-
pg_fatal("could not open file \"%s\": %s\n",
254-
output_path,strerror(errno));
255-
fprintf(script,_("could not load library \"%s\": %s"),
256-
lib,
257-
PQerrorMessage(conn));
214+
/*
215+
* In Postgres 9.0, Python 3 support was added, and to do that, a
216+
* plpython2u language was created with library name plpython2.so as a
217+
* symbolic link to plpython.so. In Postgres 9.1, only the
218+
* plpython2.so library was created, and both plpythonu and plpython2u
219+
* pointing to it. For this reason, any reference to library name
220+
* "plpython" in an old PG <= 9.1 cluster must look for "plpython2" in
221+
* the new cluster.
222+
*
223+
* For this case, we could check pg_pltemplate, but that only works
224+
* for languages, and does not help with function shared objects, so
225+
* we just do a general fix.
226+
*/
227+
if (GET_MAJOR_VERSION(old_cluster.major_version)<901&&
228+
strcmp(lib,"$libdir/plpython")==0)
229+
{
230+
lib="$libdir/plpython2";
231+
llen=strlen(lib);
232+
}
233+
234+
strcpy(cmd,"LOAD '");
235+
PQescapeStringConn(conn,cmd+strlen(cmd),lib,llen,NULL);
236+
strcat(cmd,"'");
237+
238+
res=PQexec(conn,cmd);
239+
240+
if (PQresultStatus(res)!=PGRES_COMMAND_OK)
241+
{
242+
found= true;
243+
was_load_failure= true;
244+
245+
if (script==NULL&& (script=fopen_priv(output_path,"w"))==NULL)
246+
pg_fatal("could not open file \"%s\": %s\n",
247+
output_path,strerror(errno));
248+
fprintf(script,_("could not load library \"%s\": %s"),
249+
lib,
250+
PQerrorMessage(conn));
251+
}
252+
else
253+
was_load_failure= false;
254+
255+
PQclear(res);
258256
}
259257

260-
PQclear(res);
258+
if (was_load_failure)
259+
fprintf(script,_("Database: %s\n"),
260+
old_cluster.dbarr.dbs[os_info.libraries[libnum].dbnum].db_name);
261261
}
262262

263263
PQfinish(conn);

‎src/bin/pg_upgrade/pg_upgrade.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,11 @@ typedef struct
300300
intjobs;
301301
}UserOpts;
302302

303+
typedefstruct
304+
{
305+
char*name;
306+
intdbnum;
307+
}LibraryInfo;
303308

304309
/*
305310
* OSInfo
@@ -312,7 +317,7 @@ typedef struct
312317
booluser_specified;/* user specified on command-line */
313318
char**old_tablespaces;/* tablespaces */
314319
intnum_old_tablespaces;
315-
char**libraries;/* loadable libraries */
320+
LibraryInfo*libraries;/* loadable libraries */
316321
intnum_libraries;
317322
ClusterInfo*running_cluster;
318323
}OSInfo;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp