Support multiple -t/--table arguments for more commands
authorMagnus Hagander
Thu, 17 Jan 2013 10:24:47 +0000 (11:24 +0100)
committerMagnus Hagander
Thu, 17 Jan 2013 10:24:47 +0000 (11:24 +0100)
On top of the previous support in pg_dump, add support to specify
multiple tables (by using the -t option multiple times) to
pg_restore, clsuterdb, reindexdb and vacuumdb.

Josh Kupershmidt, reviewed by Karl O. Pinc

15 files changed:
doc/src/sgml/ref/clusterdb.sgml
doc/src/sgml/ref/pg_restore.sgml
doc/src/sgml/ref/reindexdb.sgml
doc/src/sgml/ref/vacuumdb.sgml
src/bin/pg_dump/common.c
src/bin/pg_dump/dumputils.c
src/bin/pg_dump/dumputils.h
src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_restore.c
src/bin/scripts/Makefile
src/bin/scripts/clusterdb.c
src/bin/scripts/reindexdb.c
src/bin/scripts/vacuumdb.c

index 097ea912f1c7f6a0578fb7bbb3e43a9987d2cfe7..1316932450082aa34bd49a90a1d1cd3760ecdf7e 100644 (file)
@@ -24,7 +24,17 @@ PostgreSQL documentation
    clusterdb
    connection-option
    
-    table 
+
+   
+     
+       
+         
+         
+       
+       table
+     
+   
+
    dbname
   
 
@@ -117,6 +127,8 @@ PostgreSQL documentation
       
        
         Cluster table only.
+        Multiple tables can be clustered by writing multiple
+        
        
       
      
index f4668e73f6d86f9d00b9a4f679de5c0c2f26427b..0d73294930fd64d4d7b2c0bd5179ddd95cdc186a 100644 (file)
       
       
        
-        Restore definition and/or data of named table only.  This can be
+        Restore definition and/or data of named table only. Multiple tables
+        may be specified with multiple 
         combined with the  option to specify a schema.
        
       
index 781012f3c58ed58cf33fe5f89502aa810f12adfd..3ba9951df8e5ed01ff0dfef2333ea2bac23ad31e 100644 (file)
@@ -23,20 +23,27 @@ PostgreSQL documentation
   
    reindexdb
    connection-option
-   
-    
-     
-     
-    
-    table
-   
-   
-    
-     
-     
-    
-    index
-   
+
+   
+    
+     
+      
+      
+     
+     table
+    
+   
+
+   
+    
+     
+      
+      
+     
+     index
+    
+   
+
    dbname
   
 
@@ -128,6 +135,8 @@ PostgreSQL documentation
       
        
         Recreate index only.
+        Multiple indexes can be recreated by writing multiple
+        
        
       
      
@@ -158,6 +167,8 @@ PostgreSQL documentation
       
        
         Reindex table only.
+        Multiple tables can be reindexed by writing multiple
+        
        
       
      
index c60ba4424fe75b3f79042aa762cc996ee65ebf01..a5216ec038946f6ff2a0ae2ba0d50e01ac4a5fc7 100644 (file)
@@ -24,14 +24,18 @@ PostgreSQL documentation
    vacuumdb
    connection-option
    option
-   
-    
-     
-     
-    
-    table
-    column [,...] )
+
+   
+    
+     
+      
+      
+     
+     table
+     column [,...] )
+    
    
+
    dbname
   
 
@@ -147,6 +151,8 @@ PostgreSQL documentation
         Clean or analyze table only.
         Column names can be specified only in conjunction with
         the  or  options.
+        Multiple tables can be vacuumed by writing multiple
+        
        
        
         
index 99a3fe31f859d623df80477a29b0164c9dfc5c7a..706b9a75e3b00caf4f9fa6f216a0195c124ab17a 100644 (file)
@@ -898,24 +898,6 @@ simple_oid_list_append(SimpleOidList *list, Oid val)
    list->tail = cell;
 }
 
-void
-simple_string_list_append(SimpleStringList *list, const char *val)
-{
-   SimpleStringListCell *cell;
-
-   /* this calculation correctly accounts for the null trailing byte */
-   cell = (SimpleStringListCell *)
-       pg_malloc(sizeof(SimpleStringListCell) + strlen(val));
-   cell->next = NULL;
-   strcpy(cell->val, val);
-
-   if (list->tail)
-       list->tail->next = cell;
-   else
-       list->head = cell;
-   list->tail = cell;
-}
-
 bool
 simple_oid_list_member(SimpleOidList *list, Oid val)
 {
@@ -928,16 +910,3 @@ simple_oid_list_member(SimpleOidList *list, Oid val)
    }
    return false;
 }
-
-bool
-simple_string_list_member(SimpleStringList *list, const char *val)
-{
-   SimpleStringListCell *cell;
-
-   for (cell = list->head; cell; cell = cell->next)
-   {
-       if (strcmp(cell->val, val) == 0)
-           return true;
-   }
-   return false;
-}
index 80bc0c81782f3039eaf358fc7ff316266eb783fa..7ca0c60f3e50332ffdfbe3410de5bb0326f62633 100644 (file)
@@ -17,6 +17,7 @@
 #include 
 
 #include "dumputils.h"
+#include "dumpmem.h"
 
 #include "parser/keywords.h"
 
@@ -1352,3 +1353,35 @@ exit_nicely(int code)
 
    exit(code);
 }
+
+void
+simple_string_list_append(SimpleStringList *list, const char *val)
+{
+   SimpleStringListCell *cell;
+
+   /* this calculation correctly accounts for the null trailing byte */
+   cell = (SimpleStringListCell *)
+       pg_malloc(sizeof(SimpleStringListCell) + strlen(val));
+
+   cell->next = NULL;
+   strcpy(cell->val, val);
+
+   if (list->tail)
+       list->tail->next = cell;
+   else
+       list->head = cell;
+   list->tail = cell;
+}
+
+bool
+simple_string_list_member(SimpleStringList *list, const char *val)
+{
+   SimpleStringListCell *cell;
+
+   for (cell = list->head; cell; cell = cell->next)
+   {
+       if (strcmp(cell->val, val) == 0)
+           return true;
+   }
+   return false;
+}
index ac7480c1e5351863711c1ced036ed3567d00bd13..a4b351d03cae74c6792795114034684e6afc136b 100644 (file)
@@ -27,6 +27,19 @@ typedef enum                 /* bits returned by set_dump_section */
    DUMP_UNSECTIONED = 0xff
 } DumpSections;
 
+typedef struct SimpleStringListCell
+{
+    struct SimpleStringListCell *next;
+    char        val[1];         /* VARIABLE LENGTH FIELD */
+} SimpleStringListCell;
+
+typedef struct SimpleStringList
+{
+    SimpleStringListCell *head;
+    SimpleStringListCell *tail;
+} SimpleStringList;
+
+
 typedef void (*on_exit_nicely_callback) (int code, void *arg);
 
 extern int quote_all_identifiers;
@@ -75,4 +88,8 @@ __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
 extern void on_exit_nicely(on_exit_nicely_callback function, void *arg);
 extern void exit_nicely(int code) __attribute__((noreturn));
 
+extern void simple_string_list_append(SimpleStringList *list, const char *val);
+extern bool simple_string_list_member(SimpleStringList *list, const char *val);
+
+
 #endif   /* DUMPUTILS_H */
index 3b49395ecbc2b2adc2f9f459dbd00263f229824d..473670ddd3748a5e99f354143dc4eb2d568a55c2 100644 (file)
@@ -26,6 +26,7 @@
 #include "postgres_fe.h"
 
 #include "pg_dump.h"
+#include "dumputils.h"
 
 #include "libpq-fe.h"
 
@@ -125,9 +126,9 @@ typedef struct _restoreOptions
    int         selTable;
    char       *indexNames;
    char       *functionNames;
-   char       *tableNames;
    char       *schemaNames;
    char       *triggerNames;
+   SimpleStringList tableNames;
 
    int         useDB;
    char       *dbname;
index 1fead285e962db8b4677b633a2b591433bac4b6c..a810efd3bb9c192aba7c98a9e9ca490859b498e5 100644 (file)
@@ -2493,7 +2493,7 @@ _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
        {
            if (!ropt->selTable)
                return 0;
-           if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
+           if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
                return 0;
        }
        else if (strcmp(te->desc, "INDEX") == 0)
index 3b2cde783076b509edf901f3991b01ddd54e21a1..b6dc856600f5d7aac62d6235a8b703a8588bae2e 100644 (file)
@@ -58,17 +58,6 @@ typedef struct SimpleOidList
    SimpleOidListCell *tail;
 } SimpleOidList;
 
-typedef struct SimpleStringListCell
-{
-   struct SimpleStringListCell *next;
-   char        val[1];         /* VARIABLE LENGTH FIELD */
-} SimpleStringListCell;
-
-typedef struct SimpleStringList
-{
-   SimpleStringListCell *head;
-   SimpleStringListCell *tail;
-} SimpleStringList;
 
 /*
  * The data structures used to store system catalog information.  Every
@@ -533,9 +522,7 @@ extern CollInfo *findCollationByOid(Oid oid);
 extern NamespaceInfo *findNamespaceByOid(Oid oid);
 
 extern void simple_oid_list_append(SimpleOidList *list, Oid val);
-extern void simple_string_list_append(SimpleStringList *list, const char *val);
 extern bool simple_oid_list_member(SimpleOidList *list, Oid val);
-extern bool simple_string_list_member(SimpleStringList *list, const char *val);
 
 extern void parseOidArray(const char *str, Oid *array, int arraysize);
 
index 49d799b95300792bddf6f9ec25f338e2877b3738..45b8b587e410a0e1deca9bee96144f0229c92c15 100644 (file)
@@ -234,7 +234,7 @@ main(int argc, char **argv)
            case 't':           /* Dump data for this table only */
                opts->selTypes = 1;
                opts->selTable = 1;
-               opts->tableNames = pg_strdup(optarg);
+               simple_string_list_append(&opts->tableNames, optarg);
                break;
 
            case 'U':
@@ -424,7 +424,7 @@ usage(const char *progname)
    printf(_("  -P, --function=NAME(args)    restore named function\n"));
    printf(_("  -s, --schema-only            restore only the schema, no data\n"));
    printf(_("  -S, --superuser=NAME         superuser user name to use for disabling triggers\n"));
-   printf(_("  -t, --table=NAME             restore named table\n"));
+   printf(_("  -t, --table=NAME             restore named table(s)\n"));
    printf(_("  -T, --trigger=NAME           restore named trigger\n"));
    printf(_("  -x, --no-privileges          skip restoration of access privileges (grant/revoke)\n"));
    printf(_("  -1, --single-transaction     restore as a single transaction\n"));
index 602c2623c39becabc484cbcd1e389af3b122583a..ea4841159d7a6f2c3389a10e14bff3aebaef9806 100644 (file)
@@ -32,7 +32,7 @@ dropdb: dropdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
 droplang: droplang.o common.o print.o mbprint.o | submake-libpq
 dropuser: dropuser.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
 clusterdb: clusterdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
-vacuumdb: vacuumdb.o common.o | submake-libpq
+vacuumdb: vacuumdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
 reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
 
 dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
index 414c8c974d0d3e201551144998dd1e2e0815c8da..0ac213d3c3137b8fda88878c8fa83f97c09a87a8 100644 (file)
@@ -58,8 +58,8 @@ main(int argc, char *argv[])
    bool        echo = false;
    bool        quiet = false;
    bool        alldb = false;
-   char       *table = NULL;
    bool        verbose = false;
+   SimpleStringList tables = {NULL, NULL};
 
    progname = get_progname(argv[0]);
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
@@ -98,7 +98,7 @@ main(int argc, char *argv[])
                alldb = true;
                break;
            case 't':
-               table = pg_strdup(optarg);
+               simple_string_list_append(&tables, optarg);
                break;
            case 'v':
                verbose = true;
@@ -140,9 +140,10 @@ main(int argc, char *argv[])
                    progname);
            exit(1);
        }
-       if (table)
+
+       if (tables.head != NULL)
        {
-           fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
+           fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
                    progname);
            exit(1);
        }
@@ -162,9 +163,21 @@ main(int argc, char *argv[])
                dbname = get_user_name(progname);
        }
 
-       cluster_one_database(dbname, verbose, table,
-                            host, port, username, prompt_password,
-                            progname, echo);
+       if (tables.head != NULL)
+       {
+           SimpleStringListCell *cell;
+
+           for (cell = tables.head; cell; cell = cell->next)
+           {
+               cluster_one_database(dbname, verbose, cell->val,
+                                    host, port, username, prompt_password,
+                                    progname, echo);
+           }
+       }
+       else
+           cluster_one_database(dbname, verbose, NULL,
+                                host, port, username, prompt_password,
+                                progname, echo);
    }
 
    exit(0);
@@ -253,7 +266,7 @@ help(const char *progname)
    printf(_("  -d, --dbname=DBNAME       database to cluster\n"));
    printf(_("  -e, --echo                show the commands being sent to the server\n"));
    printf(_("  -q, --quiet               don't write any messages\n"));
-   printf(_("  -t, --table=TABLE         cluster specific table only\n"));
+   printf(_("  -t, --table=TABLE         cluster specific table(s) only\n"));
    printf(_("  -v, --verbose             write a lot of output\n"));
    printf(_("  -V, --version             output version information, then exit\n"));
    printf(_("  -?, --help                show this help, then exit\n"));
index ffd8a4e3d3199392c4a85e1c04a9d7c862bd6f18..342e4c94d1a1cb8032062b0794805522f3bcbc0e 100644 (file)
@@ -64,8 +64,8 @@ main(int argc, char *argv[])
    bool        alldb = false;
    bool        echo = false;
    bool        quiet = false;
-   const char *table = NULL;
-   const char *index = NULL;
+   SimpleStringList indexes = {NULL, NULL};
+   SimpleStringList tables = {NULL, NULL};
 
    progname = get_progname(argv[0]);
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
@@ -108,10 +108,10 @@ main(int argc, char *argv[])
                syscatalog = true;
                break;
            case 't':
-               table = pg_strdup(optarg);
+               simple_string_list_append(&tables, optarg);
                break;
            case 'i':
-               index = pg_strdup(optarg);
+               simple_string_list_append(&indexes, optarg);
                break;
            case 2:
                maintenance_db = pg_strdup(optarg);
@@ -154,14 +154,14 @@ main(int argc, char *argv[])
            fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
            exit(1);
        }
-       if (table)
+       if (tables.head != NULL)
        {
-           fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
+           fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
            exit(1);
        }
-       if (index)
+       if (indexes.head != NULL)
        {
-           fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
+           fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
            exit(1);
        }
 
@@ -170,14 +170,14 @@ main(int argc, char *argv[])
    }
    else if (syscatalog)
    {
-       if (table)
+       if (tables.head != NULL)
        {
-           fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
+           fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
            exit(1);
        }
-       if (index)
+       if (indexes.head != NULL)
        {
-           fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs at the same time\n"), progname);
+           fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
            exit(1);
        }
 
@@ -206,14 +206,28 @@ main(int argc, char *argv[])
                dbname = get_user_name(progname);
        }
 
-       if (index)
-           reindex_one_database(index, dbname, "INDEX", host, port,
-                                username, prompt_password, progname, echo);
-       if (table)
-           reindex_one_database(table, dbname, "TABLE", host, port,
-                                username, prompt_password, progname, echo);
-       /* reindex database only if index or table is not specified */
-       if (index == NULL && table == NULL)
+       if (indexes.head != NULL)
+       {
+           SimpleStringListCell *cell;
+
+           for (cell = indexes.head; cell; cell = cell->next)
+           {
+               reindex_one_database(cell->val, dbname, "INDEX", host, port,
+                                 username, prompt_password, progname, echo);
+           }
+       }
+       if (tables.head != NULL)
+       {
+           SimpleStringListCell *cell;
+
+           for (cell = tables.head; cell; cell = cell->next)
+           {
+               reindex_one_database(cell->val, dbname, "TABLE", host, port,
+                                 username, prompt_password, progname, echo);
+           }
+       }
+       /* reindex database only if neither index nor table is specified */
+       if (indexes.head == NULL && tables.head == NULL)
            reindex_one_database(dbname, dbname, "DATABASE", host, port,
                                 username, prompt_password, progname, echo);
    }
@@ -331,10 +345,10 @@ help(const char *progname)
    printf(_("  -a, --all                 reindex all databases\n"));
    printf(_("  -d, --dbname=DBNAME       database to reindex\n"));
    printf(_("  -e, --echo                show the commands being sent to the server\n"));
-   printf(_("  -i, --index=INDEX         recreate specific index only\n"));
+   printf(_("  -i, --index=INDEX         recreate specific index(es) only\n"));
    printf(_("  -q, --quiet               don't write any messages\n"));
    printf(_("  -s, --system              reindex system catalogs\n"));
-   printf(_("  -t, --table=TABLE         reindex specific table only\n"));
+   printf(_("  -t, --table=TABLE         reindex specific table(s) only\n"));
    printf(_("  -V, --version             output version information, then exit\n"));
    printf(_("  -?, --help                show this help, then exit\n"));
    printf(_("\nConnection options:\n"));
index 9bfb462e8612b6fc2df05ff313ab91521ed7636f..e4dde1fc9bf34481f226de1874ad16c31de153aa 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "postgres_fe.h"
 #include "common.h"
+#include "dumputils.h"
 
 
 static void vacuum_one_database(const char *dbname, bool full, bool verbose,
@@ -68,9 +69,9 @@ main(int argc, char *argv[])
    bool        analyze_only = false;
    bool        freeze = false;
    bool        alldb = false;
-   char       *table = NULL;
    bool        full = false;
    bool        verbose = false;
+   SimpleStringList tables = {NULL, NULL};
 
    progname = get_progname(argv[0]);
    set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
@@ -118,7 +119,7 @@ main(int argc, char *argv[])
                alldb = true;
                break;
            case 't':
-               table = pg_strdup(optarg);
+               simple_string_list_append(&tables, optarg);
                break;
            case 'f':
                full = true;
@@ -181,9 +182,9 @@ main(int argc, char *argv[])
                    progname);
            exit(1);
        }
-       if (table)
+       if (tables.head != NULL)
        {
-           fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
+           fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"),
                    progname);
            exit(1);
        }
@@ -204,10 +205,25 @@ main(int argc, char *argv[])
                dbname = get_user_name(progname);
        }
 
-       vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
-                           freeze, table,
-                           host, port, username, prompt_password,
-                           progname, echo);
+       if (tables.head != NULL)
+       {
+           SimpleStringListCell *cell;
+
+           for (cell = tables.head; cell; cell = cell->next)
+           {
+               vacuum_one_database(dbname, full, verbose, and_analyze,
+                                   analyze_only,
+                                   freeze, cell->val,
+                                   host, port, username, prompt_password,
+                                   progname, echo);
+           }
+       }
+       else
+           vacuum_one_database(dbname, full, verbose, and_analyze,
+                               analyze_only,
+                               freeze, NULL,
+                               host, port, username, prompt_password,
+                               progname, echo);
    }
 
    exit(0);
@@ -348,7 +364,7 @@ help(const char *progname)
    printf(_("  -f, --full                      do full vacuuming\n"));
    printf(_("  -F, --freeze                    freeze row transaction information\n"));
    printf(_("  -q, --quiet                     don't write any messages\n"));
-   printf(_("  -t, --table='TABLE[(COLUMNS)]'  vacuum specific table only\n"));
+   printf(_("  -t, --table='TABLE[(COLUMNS)]'  vacuum specific table(s) only\n"));
    printf(_("  -v, --verbose                   write a lot of output\n"));
    printf(_("  -V, --version                   output version information, then exit\n"));
    printf(_("  -z, --analyze                   update optimizer statistics\n"));