Skip to content

Commit 03858c0

Browse files
committed
Add positive defense against dropped columns, per suggestion from
Christopher Kings-Lynne. Also fix a couple more schema-awareness issues.
1 parent a9e9abe commit 03858c0

File tree

1 file changed

+22
-18
lines changed

1 file changed

+22
-18
lines changed

contrib/vacuumlo/vacuumlo.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.24 2003/08/08 21:41:25 momjian Exp $
11+
* $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.25 2003/09/24 05:38:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -98,10 +98,13 @@ vacuumlo(char *database, struct _param * param)
9898
fprintf(stdout, "Test run: no large objects will be removed!\n");
9999
}
100100

101-
res = PQexec(conn, "SET search_path = public");
101+
/*
102+
* Don't get fooled by any non-system catalogs
103+
*/
104+
res = PQexec(conn, "SET search_path = pg_catalog");
102105
if (PQresultStatus(res) != PGRES_COMMAND_OK)
103106
{
104-
fprintf(stderr, "Failed to set search_path on:\n");
107+
fprintf(stderr, "Failed to set search_path:\n");
105108
fprintf(stderr, "%s", PQerrorMessage(conn));
106109
PQclear(res);
107110
PQfinish(conn);
@@ -113,9 +116,8 @@ vacuumlo(char *database, struct _param * param)
113116
* First we create and populate the LO temp table
114117
*/
115118
buf[0] = '\0';
116-
strcat(buf, "SELECT DISTINCT loid AS lo ");
117-
strcat(buf, "INTO TEMP TABLE vacuum_l ");
118-
strcat(buf, "FROM pg_largeobject ");
119+
strcat(buf, "CREATE TEMP TABLE vacuum_l AS ");
120+
strcat(buf, "SELECT DISTINCT loid AS lo FROM pg_largeobject ");
119121
res = PQexec(conn, buf);
120122
if (PQresultStatus(res) != PGRES_COMMAND_OK)
121123
{
@@ -132,7 +134,7 @@ vacuumlo(char *database, struct _param * param)
132134
* for the DELETEs below.
133135
*/
134136
buf[0] = '\0';
135-
strcat(buf, "VACUUM ANALYZE vacuum_l ");
137+
strcat(buf, "VACUUM ANALYZE vacuum_l");
136138
res = PQexec(conn, buf);
137139
if (PQresultStatus(res) != PGRES_COMMAND_OK)
138140
{
@@ -145,7 +147,7 @@ vacuumlo(char *database, struct _param * param)
145147
PQclear(res);
146148

147149
/*
148-
* Now find any candidate tables who have columns of type oid.
150+
* Now find any candidate tables that have columns of type oid.
149151
*
150152
* NOTE: we ignore system tables and temp tables by the expedient of
151153
* rejecting tables in schemas named 'pg_*'. In particular, the temp
@@ -157,9 +159,9 @@ vacuumlo(char *database, struct _param * param)
157159
* shouldn't matter for correctness, but it saves time.
158160
*/
159161
buf[0] = '\0';
160-
strcat(buf, "SELECT c.relname, a.attname ");
162+
strcat(buf, "SELECT s.nspname, c.relname, a.attname ");
161163
strcat(buf, "FROM pg_class c, pg_attribute a, pg_namespace s, pg_type t ");
162-
strcat(buf, "WHERE a.attnum > 0 ");
164+
strcat(buf, "WHERE a.attnum > 0 AND NOT a.attisdropped ");
163165
strcat(buf, " AND a.attrelid = c.oid ");
164166
strcat(buf, " AND a.atttypid = t.oid ");
165167
strcat(buf, " AND c.relnamespace = s.oid ");
@@ -178,14 +180,16 @@ vacuumlo(char *database, struct _param * param)
178180

179181
for (i = 0; i < PQntuples(res); i++)
180182
{
181-
char *table,
183+
char *schema,
184+
*table,
182185
*field;
183186

184-
table = PQgetvalue(res, i, 0);
185-
field = PQgetvalue(res, i, 1);
187+
schema = PQgetvalue(res, i, 0);
188+
table = PQgetvalue(res, i, 1);
189+
field = PQgetvalue(res, i, 2);
186190

187191
if (param->verbose)
188-
fprintf(stdout, "Checking %s in %s\n", field, table);
192+
fprintf(stdout, "Checking %s in %s.%s\n", field, schema, table);
189193

190194
/*
191195
* The "IN" construct used here was horribly inefficient before
@@ -194,13 +198,13 @@ vacuumlo(char *database, struct _param * param)
194198
*/
195199
snprintf(buf, BUFSIZE,
196200
"DELETE FROM vacuum_l "
197-
"WHERE lo IN (SELECT \"%s\" FROM \"%s\")",
198-
field, table);
201+
"WHERE lo IN (SELECT \"%s\" FROM \"%s\".\"%s\")",
202+
field, schema, table);
199203
res2 = PQexec(conn, buf);
200204
if (PQresultStatus(res2) != PGRES_COMMAND_OK)
201205
{
202-
fprintf(stderr, "Failed to check %s in table %s:\n",
203-
field, table);
206+
fprintf(stderr, "Failed to check %s in table %s.%s:\n",
207+
field, schema, table);
204208
fprintf(stderr, "%s", PQerrorMessage(conn));
205209
PQclear(res2);
206210
PQclear(res);

0 commit comments

Comments
 (0)