Skip to content

Commit

Permalink
vacuumdb: Fix excluding multiple schemas with -N
Browse files Browse the repository at this point in the history
When specifying multiple schemas to exclude with -N parameters, none
of the schemas are actually excluded (a single -N worked as expected).
This fixes the catalog query to handle multiple exclusions and adds a
test for this case.

Backpatch to v16 where this was introduced.

Author: Nathan Bossart <nathandbossart@gmail.com>
Author: Kuwamura Masaki <kuwamura@db.is.i.nagoya-u.ac.jp>
Reported-by: Kuwamura Masaki <kuwamura@db.is.i.nagoya-u.ac.jp>
Discussion: https://postgr.es/m/CAMyC8qp9mXPQd5D6s6CJxvmignsbTqGZwDDB6VYJOn1A8WG38w@mail.gmail.com
Backpatch-through: 16
  • Loading branch information
danielgustafsson committed Sep 25, 2023
1 parent fb9ddd0 commit 2143d96
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 11 deletions.
15 changes: 14 additions & 1 deletion src/bin/scripts/t/100_vacuumdb.pl
Expand Up @@ -112,6 +112,8 @@
CREATE INDEX i0 ON funcidx ((f1(x)));
CREATE SCHEMA "Foo";
CREATE TABLE "Foo".bar(id int);
CREATE SCHEMA "Bar";
CREATE TABLE "Bar".baz(id int);
|);
$node->command_ok([qw|vacuumdb -Z --table="need""q(uot"(")x") postgres|],
'column list');
Expand Down Expand Up @@ -159,10 +161,21 @@
[ 'vacuumdb', '--schema', '"Foo"', 'postgres' ],
qr/VACUUM \(SKIP_DATABASE_STATS\) "Foo".bar/,
'vacuumdb --schema');
$node->issues_sql_like(
[ 'vacuumdb', '--schema', '"Foo"', '--schema', '"Bar"', 'postgres' ],
qr/VACUUM\ \(SKIP_DATABASE_STATS\)\ "Foo".bar
.*VACUUM\ \(SKIP_DATABASE_STATS\)\ "Bar".baz
/sx,
'vacuumdb multiple --schema switches');
$node->issues_sql_like(
[ 'vacuumdb', '--exclude-schema', '"Foo"', 'postgres' ],
qr/(?:(?!VACUUM "Foo".bar).)*/,
qr/^(?!.*VACUUM \(SKIP_DATABASE_STATS\) "Foo".bar).*$/s,
'vacuumdb --exclude-schema');
$node->issues_sql_like(
[ 'vacuumdb', '--exclude-schema', '"Foo"', '--exclude-schema', '"Bar"', 'postgres' ],
qr/^(?!.*VACUUM\ \(SKIP_DATABASE_STATS\)\ "Foo".bar
| VACUUM\ \(SKIP_DATABASE_STATS\)\ "Bar".baz).*$/sx,
'vacuumdb multiple --exclude-schema switches');
$node->command_fails_like(
[ 'vacuumdb', '-N', 'pg_catalog', '-t', 'pg_class', 'postgres', ],
qr/cannot vacuum specific table\(s\) and exclude schema\(s\) at the same time/,
Expand Down
26 changes: 16 additions & 10 deletions src/bin/scripts/vacuumdb.c
Expand Up @@ -678,18 +678,22 @@ vacuum_one_database(ConnParams *cparams,
/* Used to match the tables or schemas listed by the user */
if (objects_listed)
{
appendPQExpBufferStr(&catalog_query, " JOIN listed_objects"
" ON listed_objects.object_oid ");

if (objfilter & OBJFILTER_SCHEMA_EXCLUDE)
appendPQExpBufferStr(&catalog_query, "OPERATOR(pg_catalog.!=) ");
else
appendPQExpBufferStr(&catalog_query, "OPERATOR(pg_catalog.=) ");
appendPQExpBufferStr(&catalog_query, " LEFT JOIN listed_objects"
" ON listed_objects.object_oid"
" OPERATOR(pg_catalog.=) ");

if (objfilter & OBJFILTER_TABLE)
appendPQExpBufferStr(&catalog_query, "c.oid\n");
else
appendPQExpBufferStr(&catalog_query, "ns.oid\n");

if (objfilter & OBJFILTER_SCHEMA_EXCLUDE)
appendPQExpBuffer(&catalog_query,
" WHERE listed_objects.object_oid IS NULL\n");
else
appendPQExpBuffer(&catalog_query,
" WHERE listed_objects.object_oid IS NOT NULL\n");
has_where = true;
}

/*
Expand All @@ -700,9 +704,11 @@ vacuum_one_database(ConnParams *cparams,
*/
if ((objfilter & OBJFILTER_TABLE) == 0)
{
appendPQExpBufferStr(&catalog_query, " WHERE c.relkind OPERATOR(pg_catalog.=) ANY (array["
CppAsString2(RELKIND_RELATION) ", "
CppAsString2(RELKIND_MATVIEW) "])\n");
appendPQExpBuffer(&catalog_query,
" %s c.relkind OPERATOR(pg_catalog.=) ANY (array["
CppAsString2(RELKIND_RELATION) ", "
CppAsString2(RELKIND_MATVIEW) "])\n",
has_where ? "AND" : "WHERE");
has_where = true;
}

Expand Down

0 comments on commit 2143d96

Please sign in to comment.