8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.21 2003/08/04 02:39:56 momjian Exp $
11
+ * $Header: /cvsroot/pgsql/contrib/vacuumlo/vacuumlo.c,v 1.22 2003/08/04 22:03:39 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -256,8 +256,9 @@ vacuumlo(char *database, struct _param * param)
256
256
/*
257
257
* Now find any candidate tables who have columns of type oid.
258
258
*
259
- * NOTE: the temp table formed above is ignored, because its real table
260
- * name will be pg_something. Also, pg_largeobject will be ignored.
259
+ * NOTE: we ignore system tables and temp tables by the expedient of
260
+ * rejecting tables in schemas named 'pg_*'. In particular, the temp
261
+ * table formed above is ignored, and pg_largeobject will be too.
261
262
* If either of these were scanned, obviously we'd end up with nothing
262
263
* to delete...
263
264
*
@@ -266,14 +267,14 @@ vacuumlo(char *database, struct _param * param)
266
267
*/
267
268
buf [0 ] = '\0' ;
268
269
strcat (buf , "SELECT c.relname, a.attname " );
269
- strcat (buf , "FROM pg_class c, pg_attribute a, pg_type t " );
270
+ strcat (buf , "FROM pg_class c, pg_attribute a, pg_namespace s, pg_type t " );
270
271
strcat (buf , "WHERE a.attnum > 0 " );
271
272
strcat (buf , " AND a.attrelid = c.oid " );
272
273
strcat (buf , " AND a.atttypid = t.oid " );
274
+ strcat (buf , " AND c.relnamespace = s.oid " );
273
275
strcat (buf , " AND t.typname in ('oid', 'lo') " );
274
276
strcat (buf , " AND c.relkind = 'r'" );
275
- strcat (buf , " AND c.relname NOT LIKE 'pg_%'" );
276
- strcat (buf , " AND c.relname != 'vacuum_l'" );
277
+ strcat (buf , " AND s.nspname NOT LIKE 'pg\\\\_%'" );
277
278
res = PQexec (conn , buf );
278
279
if (PQresultStatus (res ) != PGRES_TUPLES_OK )
279
280
{
@@ -296,12 +297,14 @@ vacuumlo(char *database, struct _param * param)
296
297
fprintf (stdout , "Checking %s in %s\n" , field , table );
297
298
298
299
/*
299
- * We use a DELETE with implicit join for efficiency. This is a
300
- * Postgres-ism and not portable to other DBMSs, but then this
301
- * whole program is a Postgres-ism .
300
+ * The "IN" construct used here was horribly inefficient before
301
+ * Postgres 7.4, but should be now competitive if not better than
302
+ * the bogus join we used before .
302
303
*/
303
- snprintf (buf , BUFSIZE , "DELETE FROM vacuum_l WHERE lo = \"%s\".\"%s\" " ,
304
- table , field );
304
+ snprintf (buf , BUFSIZE ,
305
+ "DELETE FROM vacuum_l "
306
+ "WHERE lo IN (SELECT \"%s\" FROM \"%s\")" ,
307
+ field , table );
305
308
res2 = PQexec (conn , buf );
306
309
if (PQresultStatus (res2 ) != PGRES_COMMAND_OK )
307
310
{
@@ -388,10 +391,10 @@ void
388
391
usage (void )
389
392
{
390
393
fprintf (stdout , "vacuumlo removes unreferenced large objects from databases\n\n" );
391
- fprintf (stdout , "Usage:\n vacuumlo [options] dbname [dbnames ...]\n\n" );
394
+ fprintf (stdout , "Usage:\n vacuumlo [options] dbname [dbname ...]\n\n" );
392
395
fprintf (stdout , "Options:\n" );
393
- fprintf (stdout , " -v\t\tWrite a lot of output \n" );
394
- fprintf (stdout , " -n\t\tDon't remove any large object , just show what would be done\n" );
396
+ fprintf (stdout , " -v\t\tWrite a lot of progress messages \n" );
397
+ fprintf (stdout , " -n\t\tDon't remove large objects , just show what would be done\n" );
395
398
fprintf (stdout , " -U username\tUsername to connect as\n" );
396
399
fprintf (stdout , " -W\t\tPrompt for password\n" );
397
400
fprintf (stdout , " -h hostname\tDatabase server host\n" );
0 commit comments