reindexdb: Allow specifying objects to process in all databases.
authorNathan Bossart <nathan@postgresql.org>
Mon, 11 Mar 2024 20:42:27 +0000 (15:42 -0500)
committerNathan Bossart <nathan@postgresql.org>
Mon, 11 Mar 2024 20:42:27 +0000 (15:42 -0500)
Presently, reindexdb's --table, --schema, --index, and --system
options cannot be used together with --all, i.e., you cannot
specify objects to process in all databases.  This commit removes
this unnecessary restriction.  Furthermore, it removes the
restriction that --system cannot be used with --table, --schema,
and --index.  There is no such restriction for the latter options,
and there is no technical reason to disallow these combinations.

Reviewed-by: Kyotaro Horiguchi, Dean Rasheed
Discussion: https://postgr.es/m/20230628232402.GA1954626%40nathanxps13

doc/src/sgml/ref/reindexdb.sgml
src/bin/scripts/reindexdb.c
src/bin/scripts/t/090_reindexdb.pl
src/bin/scripts/t/091_reindexdb_all.pl

index 8d9ced212f34f8a87820aa59beb6a324ebe95518..a877439dc5b7b548197f48524596a9f5140a8e05 100644 (file)
@@ -55,30 +55,22 @@ PostgreSQL documentation
     </arg>
    </arg>
 
-   <arg choice="opt"><replaceable>dbname</replaceable></arg>
-  </cmdsynopsis>
-
-  <cmdsynopsis>
-   <command>reindexdb</command>
-   <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
-   <arg rep="repeat"><replaceable>option</replaceable></arg>
-
-   <group choice="plain">
-    <arg choice="plain"><option>-a</option></arg>
-    <arg choice="plain"><option>--all</option></arg>
-   </group>
-  </cmdsynopsis>
-
-  <cmdsynopsis>
-   <command>reindexdb</command>
-   <arg rep="repeat"><replaceable>connection-option</replaceable></arg>
-   <arg rep="repeat"><replaceable>option</replaceable></arg>
+   <arg choice="plain">
+    <arg choice="opt">
+     <group choice="plain">
+      <arg choice="plain"><option>-s</option></arg>
+      <arg choice="plain"><option>--system</option></arg>
+     </group>
+    </arg>
+   </arg>
 
-   <group choice="plain">
-    <arg choice="plain"><option>-s</option></arg>
-    <arg choice="plain"><option>--system</option></arg>
-   </group>
-   <arg choice="opt"><replaceable>dbname</replaceable></arg>
+   <arg choice="opt">
+    <group choice="plain">
+     <arg choice="plain"><replaceable>dbname</replaceable></arg>
+     <arg choice="plain"><option>-a</option></arg>
+     <arg choice="plain"><option>--all</option></arg>
+    </group>
+   </arg>
   </cmdsynopsis>
  </refsynopsisdiv>
 
index 6ae30dff31fd8a496b8522946b2e8efdb799ee06..231e5c8fd0268127e017b7f33cf3ae51c1e1dc93 100644 (file)
@@ -46,7 +46,10 @@ static void reindex_one_database(ConnParams *cparams, ReindexType type,
 static void reindex_all_databases(ConnParams *cparams,
                                  const char *progname, bool echo,
                                  bool quiet, bool verbose, bool concurrently,
-                                 int concurrentCons, const char *tablespace);
+                                 int concurrentCons, const char *tablespace,
+                                 bool syscatalog, SimpleStringList *schemas,
+                                 SimpleStringList *tables,
+                                 SimpleStringList *indexes);
 static void run_reindex_command(PGconn *conn, ReindexType type,
                                const char *name, bool echo, bool verbose,
                                bool concurrently, bool async,
@@ -203,62 +206,33 @@ main(int argc, char *argv[])
 
    setup_cancel_handler(NULL);
 
+   if (concurrentCons > 1)
+   {
+       /*
+        * Index-level REINDEX is not supported with multiple jobs as we
+        * cannot control the concurrent processing of multiple indexes
+        * depending on the same relation.
+        */
+       if (indexes.head != NULL)
+           pg_fatal("cannot use multiple jobs to reindex indexes");
+
+       if (syscatalog)
+           pg_fatal("cannot use multiple jobs to reindex system catalogs");
+   }
+
    if (alldb)
    {
        if (dbname)
            pg_fatal("cannot reindex all databases and a specific one at the same time");
-       if (syscatalog)
-           pg_fatal("cannot reindex all databases and system catalogs at the same time");
-       if (schemas.head != NULL)
-           pg_fatal("cannot reindex specific schema(s) in all databases");
-       if (tables.head != NULL)
-           pg_fatal("cannot reindex specific table(s) in all databases");
-       if (indexes.head != NULL)
-           pg_fatal("cannot reindex specific index(es) in all databases");
 
        cparams.dbname = maintenance_db;
 
        reindex_all_databases(&cparams, progname, echo, quiet, verbose,
-                             concurrently, concurrentCons, tablespace);
-   }
-   else if (syscatalog)
-   {
-       if (schemas.head != NULL)
-           pg_fatal("cannot reindex specific schema(s) and system catalogs at the same time");
-       if (tables.head != NULL)
-           pg_fatal("cannot reindex specific table(s) and system catalogs at the same time");
-       if (indexes.head != NULL)
-           pg_fatal("cannot reindex specific index(es) and system catalogs at the same time");
-
-       if (concurrentCons > 1)
-           pg_fatal("cannot use multiple jobs to reindex system catalogs");
-
-       if (dbname == NULL)
-       {
-           if (getenv("PGDATABASE"))
-               dbname = getenv("PGDATABASE");
-           else if (getenv("PGUSER"))
-               dbname = getenv("PGUSER");
-           else
-               dbname = get_user_name_or_exit(progname);
-       }
-
-       cparams.dbname = dbname;
-
-       reindex_one_database(&cparams, REINDEX_SYSTEM, NULL,
-                            progname, echo, verbose,
-                            concurrently, 1, tablespace);
+                             concurrently, concurrentCons, tablespace,
+                             syscatalog, &schemas, &tables, &indexes);
    }
    else
    {
-       /*
-        * Index-level REINDEX is not supported with multiple jobs as we
-        * cannot control the concurrent processing of multiple indexes
-        * depending on the same relation.
-        */
-       if (concurrentCons > 1 && indexes.head != NULL)
-           pg_fatal("cannot use multiple jobs to reindex indexes");
-
        if (dbname == NULL)
        {
            if (getenv("PGDATABASE"))
@@ -271,6 +245,11 @@ main(int argc, char *argv[])
 
        cparams.dbname = dbname;
 
+       if (syscatalog)
+           reindex_one_database(&cparams, REINDEX_SYSTEM, NULL,
+                                progname, echo, verbose,
+                                concurrently, 1, tablespace);
+
        if (schemas.head != NULL)
            reindex_one_database(&cparams, REINDEX_SCHEMA, &schemas,
                                 progname, echo, verbose,
@@ -287,10 +266,11 @@ main(int argc, char *argv[])
                                 concurrently, concurrentCons, tablespace);
 
        /*
-        * reindex database only if neither index nor table nor schema is
-        * specified
+        * reindex database only if neither index nor table nor schema nor
+        * system catalogs is specified
         */
-       if (indexes.head == NULL && tables.head == NULL && schemas.head == NULL)
+       if (!syscatalog && indexes.head == NULL &&
+           tables.head == NULL && schemas.head == NULL)
            reindex_one_database(&cparams, REINDEX_DATABASE, NULL,
                                 progname, echo, verbose,
                                 concurrently, concurrentCons, tablespace);
@@ -711,7 +691,9 @@ static void
 reindex_all_databases(ConnParams *cparams,
                      const char *progname, bool echo, bool quiet, bool verbose,
                      bool concurrently, int concurrentCons,
-                     const char *tablespace)
+                     const char *tablespace, bool syscatalog,
+                     SimpleStringList *schemas, SimpleStringList *tables,
+                     SimpleStringList *indexes)
 {
    PGconn     *conn;
    PGresult   *result;
@@ -735,9 +717,35 @@ reindex_all_databases(ConnParams *cparams,
 
        cparams->override_dbname = dbname;
 
-       reindex_one_database(cparams, REINDEX_DATABASE, NULL,
-                            progname, echo, verbose, concurrently,
-                            concurrentCons, tablespace);
+       if (syscatalog)
+           reindex_one_database(cparams, REINDEX_SYSTEM, NULL,
+                                progname, echo, verbose,
+                                concurrently, 1, tablespace);
+
+       if (schemas->head != NULL)
+           reindex_one_database(cparams, REINDEX_SCHEMA, schemas,
+                                progname, echo, verbose,
+                                concurrently, concurrentCons, tablespace);
+
+       if (indexes->head != NULL)
+           reindex_one_database(cparams, REINDEX_INDEX, indexes,
+                                progname, echo, verbose,
+                                concurrently, 1, tablespace);
+
+       if (tables->head != NULL)
+           reindex_one_database(cparams, REINDEX_TABLE, tables,
+                                progname, echo, verbose,
+                                concurrently, concurrentCons, tablespace);
+
+       /*
+        * reindex database only if neither index nor table nor schema nor
+        * system catalogs is specified
+        */
+       if (!syscatalog && indexes->head == NULL &&
+           tables->head == NULL && schemas->head == NULL)
+           reindex_one_database(cparams, REINDEX_DATABASE, NULL,
+                                progname, echo, verbose,
+                                concurrently, concurrentCons, tablespace);
    }
 
    PQclear(result);
index 4f1a141132061097c286472726956758d34155f8..429dd3acd68353ad39f1a158ebeba049d3f25faf 100644 (file)
@@ -262,4 +262,18 @@ $node->command_ok(
    [ 'reindexdb', '-j', '2', '--concurrently', '-d', 'postgres' ],
    'parallel reindexdb on database, concurrently');
 
+# combinations of objects
+$node->issues_sql_like(
+   [ 'reindexdb', '-s', '-t', 'test1', 'postgres' ],
+   qr/statement:\ REINDEX SYSTEM postgres;/,
+   'specify both --system and --table');
+$node->issues_sql_like(
+   [ 'reindexdb', '-s', '-i', 'test1x', 'postgres' ],
+   qr/statement:\ REINDEX INDEX public.test1x;/,
+   'specify both --system and --index');
+$node->issues_sql_like(
+   [ 'reindexdb', '-s', '-S', 'pg_catalog', 'postgres' ],
+   qr/statement:\ REINDEX SCHEMA pg_catalog;/,
+   'specify both --system and --schema');
+
 done_testing();
index a4540084fe158d3d78d0c2a93a2647b9edc4ff05..8061883f7f11af6e1140ca9995bcabcec3ac46cc 100644 (file)
@@ -13,10 +13,30 @@ $node->start;
 
 $ENV{PGOPTIONS} = '--client-min-messages=WARNING';
 
+$node->safe_psql('postgres',
+   'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a);');
+$node->safe_psql('template1',
+   'CREATE TABLE test1 (a int); CREATE INDEX test1x ON test1 (a);');
 $node->issues_sql_like(
    [ 'reindexdb', '-a' ],
    qr/statement: REINDEX.*statement: REINDEX/s,
    'reindex all databases');
+$node->issues_sql_like(
+   [ 'reindexdb', '-a', '-s' ],
+   qr/statement: REINDEX SYSTEM postgres/s,
+   'reindex system catalogs in all databases');
+$node->issues_sql_like(
+   [ 'reindexdb', '-a', '-S', 'public' ],
+   qr/statement: REINDEX SCHEMA public/s,
+   'reindex schema in all databases');
+$node->issues_sql_like(
+   [ 'reindexdb', '-a', '-i', 'test1x' ],
+   qr/statement: REINDEX INDEX public\.test1x/s,
+   'reindex index in all databases');
+$node->issues_sql_like(
+   [ 'reindexdb', '-a', '-t', 'test1' ],
+   qr/statement: REINDEX TABLE public\.test1/s,
+   'reindex table in all databases');
 
 $node->safe_psql(
    'postgres', q(