Multiple --table options for other commands
Hi all,
I see there's already a TODO for allowing pg_restore to accept
multiple --table arguments[1]http://archives.postgresql.org/pgsql-hackers/2010-08/msg00689.php, but would folks support adding this
capability to various other commands which currently accept only a
single --table argument, such as clusterdb, vacuumdb, and reindexdb?
Looking at pg_dump, it seems like these other commands would want to
use the SimpleStringList / SimpleStringCell machinery which currently
lives only in pg_dump. I'm guessing that ./src/bin/pg_dump/dumputils.c
would be the right place for such common code?
Josh
[1]: http://archives.postgresql.org/pgsql-hackers/2010-08/msg00689.php
On Sun, Oct 28, 2012 at 4:30 PM, Josh Kupershmidt <schmiddy@gmail.com> wrote:
I see there's already a TODO for allowing pg_restore to accept
multiple --table arguments[1], but would folks support adding this
capability to various other commands which currently accept only a
single --table argument, such as clusterdb, vacuumdb, and reindexdb?
I went ahead and cooked up a patch to allow pg_restore, clusterdb,
vacuumdb, and reindexdb to accept multiple --table switches. Hope I
didn't overlook a similar tool, but these were the only other commands
I found taking a --table argument.
If you run, say:
pg_dump -Fc --table=tab1 --table=tab2 ... |
pg_restore --table=tab1 --table=tab2 ...
without the patch, only "tab2" will be restored and pg_restore will
make no mention of this omission to the user. With the patch, both
tables should be restored.
I also added support for multiple --index options for reindexdb, since
that use-case seemed symmetrical to --table. As suggested previously,
I moved the SimpleStringList types and functions out of pg_dump.h and
common.c into dumputils.{h,c}, so that the code in ./src/bin/scripts/
could use it.
If there are no objections, I can add the patch to the next CF.
Josh
Attachments:
multiple_tables.v1.diffapplication/octet-stream; name=multiple_tables.v1.diffDownload
diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
new file mode 100644
index 097ea91..83dfd0f
*** a/doc/src/sgml/ref/clusterdb.sgml
--- b/doc/src/sgml/ref/clusterdb.sgml
*************** PostgreSQL documentation
*** 117,122 ****
--- 117,124 ----
<listitem>
<para>
Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
new file mode 100644
index d4f6166..4cb40ea
*** a/doc/src/sgml/ref/pg_restore.sgml
--- b/doc/src/sgml/ref/pg_restore.sgml
***************
*** 400,406 ****
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
--- 400,407 ----
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. Multiple tables
! may be specified with multiple <option>-t</> switches. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
new file mode 100644
index 781012f..4edde9a
*** a/doc/src/sgml/ref/reindexdb.sgml
--- b/doc/src/sgml/ref/reindexdb.sgml
*************** PostgreSQL documentation
*** 128,133 ****
--- 128,135 ----
<listitem>
<para>
Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</> switches.
</para>
</listitem>
</varlistentry>
*************** PostgreSQL documentation
*** 158,163 ****
--- 160,167 ----
<listitem>
<para>
Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
new file mode 100644
index c60ba44..c540c5d
*** a/doc/src/sgml/ref/vacuumdb.sgml
--- b/doc/src/sgml/ref/vacuumdb.sgml
*************** PostgreSQL documentation
*** 147,152 ****
--- 147,154 ----
Clean or analyze <replaceable class="parameter">table</replaceable> only.
Column names can be specified only in conjunction with
the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</> switches.
</para>
<tip>
<para>
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
new file mode 100644
index 611c8e3..88c07be
*** a/src/bin/pg_dump/common.c
--- b/src/bin/pg_dump/common.c
*************** simple_oid_list_append(SimpleOidList *li
*** 898,921 ****
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)
{
--- 898,903 ----
*************** simple_oid_list_member(SimpleOidList *li
*** 928,943 ****
}
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;
- }
--- 910,912 ----
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
new file mode 100644
index 91f2774..c0b10f0
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 17,23 ****
#include <ctype.h>
#include "dumputils.h"
!
#include "parser/keywords.h"
--- 17,23 ----
#include <ctype.h>
#include "dumputils.h"
! #include "dumpmem.h"
#include "parser/keywords.h"
*************** exit_nicely(int code)
*** 1349,1351 ****
--- 1349,1383 ----
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;
+ }
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
new file mode 100644
index 4ef8cb3..a300e7e
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
*************** typedef enum /* bits returned by set
*** 27,32 ****
--- 27,45 ----
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;
*************** __attribute__((format(PG_PRINTF_ATTRIBUT
*** 75,78 ****
--- 88,95 ----
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 */
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
new file mode 100644
index 3b49395..9972e68
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
***************
*** 26,32 ****
#include "postgres_fe.h"
#include "pg_dump.h"
!
#include "libpq-fe.h"
--- 26,32 ----
#include "postgres_fe.h"
#include "pg_dump.h"
! #include "dumputils.h"
#include "libpq-fe.h"
*************** typedef struct _restoreOptions
*** 125,133 ****
int selTable;
char *indexNames;
char *functionNames;
- char *tableNames;
char *schemaNames;
char *triggerNames;
int useDB;
char *dbname;
--- 125,133 ----
int selTable;
char *indexNames;
char *functionNames;
char *schemaNames;
char *triggerNames;
+ SimpleStringList tableNames;
int useDB;
char *dbname;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
new file mode 100644
index 1fead28..a810efd
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** _tocEntryRequired(TocEntry *te, teSectio
*** 2493,2499 ****
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
--- 2493,2499 ----
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
new file mode 100644
index 2100d43..0ab451a
*** a/src/bin/pg_dump/pg_dump.h
--- b/src/bin/pg_dump/pg_dump.h
*************** typedef struct SimpleOidList
*** 58,74 ****
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
--- 58,63 ----
*************** extern CollInfo *findCollationByOid(Oid
*** 532,540 ****
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);
--- 521,527 ----
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
new file mode 100644
index 49d799b..54b58f2
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
*************** main(int argc, char **argv)
*** 234,240 ****
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! opts->tableNames = pg_strdup(optarg);
break;
case 'U':
--- 234,240 ----
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! simple_string_list_append(&opts->tableNames, optarg);
break;
case 'U':
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
new file mode 100644
index 0980b4c..d9ba29d
*** a/src/bin/scripts/Makefile
--- b/src/bin/scripts/Makefile
*************** dropdb: dropdb.o common.o dumputils.o kw
*** 32,38 ****
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
reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
--- 32,38 ----
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 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/%
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
new file mode 100644
index 261b438..4f163ee
*** a/src/bin/scripts/clusterdb.c
--- b/src/bin/scripts/clusterdb.c
*************** main(int argc, char *argv[])
*** 58,65 ****
bool echo = false;
bool quiet = false;
bool alldb = false;
- char *table = NULL;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 58,65 ----
bool echo = false;
bool quiet = false;
bool alldb = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 98,104 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'v':
verbose = true;
--- 98,104 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'v':
verbose = true;
*************** main(int argc, char *argv[])
*** 140,148 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
progname);
exit(1);
}
--- 140,149 ----
progname);
exit(1);
}
!
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 162,170 ****
dbname = get_user_name(progname);
}
! cluster_one_database(dbname, verbose, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 163,182 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 253,259 ****
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(_(" -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"));
--- 265,271 ----
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(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"));
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
new file mode 100644
index f61dada..da06395
*** a/src/bin/scripts/reindexdb.c
--- b/src/bin/scripts/reindexdb.c
*************** main(int argc, char *argv[])
*** 64,71 ****
bool alldb = false;
bool echo = false;
bool quiet = false;
! const char *table = NULL;
! const char *index = NULL;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 64,71 ----
bool alldb = false;
bool echo = false;
bool quiet = false;
! SimpleStringList indexes = {NULL, NULL};
! SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 108,117 ****
syscatalog = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'i':
! index = pg_strdup(optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
--- 108,117 ----
syscatalog = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'i':
! simple_string_list_append(&indexes, optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
*************** main(int argc, char *argv[])
*** 154,167 ****
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
exit(1);
}
--- 154,167 ----
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 170,183 ****
}
else if (syscatalog)
{
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs at the same time\n"), progname);
exit(1);
}
--- 170,183 ----
}
else if (syscatalog)
{
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 206,219 ****
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)
reindex_one_database(dbname, dbname, "DATABASE", host, port,
username, prompt_password, progname, echo);
}
--- 206,231 ----
dbname = get_user_name(progname);
}
! 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);
}
*************** help(const char *progname)
*** 334,340 ****
printf(_(" -i, --index=INDEX recreate specific index 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(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
--- 346,352 ----
printf(_(" -i, --index=INDEX recreate specific index 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(s) only\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
new file mode 100644
index eb28ad4..dc5fcaf
*** a/src/bin/scripts/vacuumdb.c
--- b/src/bin/scripts/vacuumdb.c
***************
*** 12,17 ****
--- 12,18 ----
#include "postgres_fe.h"
#include "common.h"
+ #include "dumputils.h"
static void vacuum_one_database(const char *dbname, bool full, bool verbose,
*************** main(int argc, char *argv[])
*** 68,76 ****
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
- char *table = NULL;
bool full = false;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 69,77 ----
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
bool full = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 118,124 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'f':
full = true;
--- 119,125 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'f':
full = true;
*************** main(int argc, char *argv[])
*** 181,189 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
progname);
exit(1);
}
--- 182,190 ----
progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 204,213 ****
dbname = get_user_name(progname);
}
! vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
! freeze, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 205,228 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 348,354 ****
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(_(" -v, --verbose write a lot of output\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -z, --analyze update optimizer statistics\n"));
--- 363,369 ----
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(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"));
On 10/30/2012 10:14:19 PM, Josh Kupershmidt wrote:
I went ahead and cooked up a patch to allow pg_restore, clusterdb,
vacuumdb, and reindexdb to accept multiple --table switches. Hope I
didn't overlook a similar tool, but these were the only other
commands
I found taking a --table argument.
I believe you need ellipses behind --table in the syntax summaries
of the command reference docs.
(This was all I noticed while reading the patch.)
Regards,
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Hi Josh,
I've signed up to review this patch.
I configured with assertions, built, and tested using
the attached script. It seems to do what it's supposed
to and the code looks ok to me.
The docs build. The text is reasonable.
I also diffed the output of the attached script with
the output of an unpatched head and got what I expected.
Yes, the current pg_restore silently
ignores multiple --table arguments, and seems to use the last
one. You are introducing a backwards incompatible
change here. I don't know what to do about it, other
than perhaps to have the patch go into 10.0 (!?) and
introduce a patch now that complains about multiple
--table arguments. On the other hand, perhaps it's
simply undocumented what pg_restore does when
given repeated, conflicting, arguments and we're
free to change this. Any thoughts?
On 12/10/2012 09:23:03 PM, Karl O. Pinc wrote:
On 10/30/2012 10:14:19 PM, Josh Kupershmidt wrote:
I went ahead and cooked up a patch to allow pg_restore, clusterdb,
vacuumdb, and reindexdb to accept multiple --table switches. Hope I
didn't overlook a similar tool, but these were the only other
commands
I found taking a --table argument.I believe you need ellipses behind --table in the syntax summaries
of the command reference docs.
I also note that the pg_dump --help output says "table(s)" so
you probably want to have pg_restore say the same now that it
takes multiple tables.
These two minor points seem to be all that needs fixing.
Regards,
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
Attachments:
On Tue, Dec 11, 2012 at 1:46 PM, Karl O. Pinc <kop@meme.com> wrote:
Yes, the current pg_restore silently
ignores multiple --table arguments, and seems to use the last
one. You are introducing a backwards incompatible
change here. I don't know what to do about it, other
than perhaps to have the patch go into 10.0 (!?) and
introduce a patch now that complains about multiple
--table arguments. On the other hand, perhaps it's
simply undocumented what pg_restore does when
given repeated, conflicting, arguments and we're
free to change this. Any thoughts?
I wouldn't worry about this. I don't think we're obliged to be
bug-compatible with our own prior releases. We've made far bigger
changes for far less meritorious reasons.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com> wrote:
Hi Josh,
I've signed up to review this patch.
Thanks!
I configured with assertions, built, and tested using
the attached script. It seems to do what it's supposed
to and the code looks ok to me.The docs build. The text is reasonable.
I also diffed the output of the attached script with
the output of an unpatched head and got what I expected.
Cool test script.
Yes, the current pg_restore silently
ignores multiple --table arguments, and seems to use the last
one. You are introducing a backwards incompatible
change here. I don't know what to do about it, other
than perhaps to have the patch go into 10.0 (!?) and
introduce a patch now that complains about multiple
--table arguments. On the other hand, perhaps it's
simply undocumented what pg_restore does when
given repeated, conflicting, arguments and we're
free to change this. Any thoughts?
Agreed with Robert that this change should be reasonable in a major
version (i.e. 9.3).
On 12/10/2012 09:23:03 PM, Karl O. Pinc wrote:
On 10/30/2012 10:14:19 PM, Josh Kupershmidt wrote:
I went ahead and cooked up a patch to allow pg_restore, clusterdb,
vacuumdb, and reindexdb to accept multiple --table switches. Hope I
didn't overlook a similar tool, but these were the only other
commands
I found taking a --table argument.I believe you need ellipses behind --table in the syntax summaries
of the command reference docs.
Hrm, I was following pg_dump's lead here for the .sgml docs, and
didn't see anywhere that pg_dump makes the multiple --table syntax
explicit other than in the explanatory text underneath the option.
I also note that the pg_dump --help output says "table(s)" so
you probably want to have pg_restore say the same now that it
takes multiple tables.
Good catch, will fix, and ditto reindexdb's --index help output. (It
is possible that the --help output for pg_dump was worded to say
"table(s)" because one can use a "pattern" --table specification with
pg_dump, though IMO it's helpful to mention "table(s)" in the --help
output for the rest of these programs as well, as a little reminder to
the user.)
Josh
Attachments:
multiple_tables.v2.diffapplication/octet-stream; name=multiple_tables.v2.diffDownload
diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
new file mode 100644
index 097ea91..83dfd0f
*** a/doc/src/sgml/ref/clusterdb.sgml
--- b/doc/src/sgml/ref/clusterdb.sgml
*************** PostgreSQL documentation
*** 117,122 ****
--- 117,124 ----
<listitem>
<para>
Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
new file mode 100644
index f4668e7..0d73294
*** a/doc/src/sgml/ref/pg_restore.sgml
--- b/doc/src/sgml/ref/pg_restore.sgml
***************
*** 400,406 ****
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
--- 400,407 ----
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. Multiple tables
! may be specified with multiple <option>-t</> switches. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
new file mode 100644
index 781012f..4edde9a
*** a/doc/src/sgml/ref/reindexdb.sgml
--- b/doc/src/sgml/ref/reindexdb.sgml
*************** PostgreSQL documentation
*** 128,133 ****
--- 128,135 ----
<listitem>
<para>
Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</> switches.
</para>
</listitem>
</varlistentry>
*************** PostgreSQL documentation
*** 158,163 ****
--- 160,167 ----
<listitem>
<para>
Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
new file mode 100644
index c60ba44..c540c5d
*** a/doc/src/sgml/ref/vacuumdb.sgml
--- b/doc/src/sgml/ref/vacuumdb.sgml
*************** PostgreSQL documentation
*** 147,152 ****
--- 147,154 ----
Clean or analyze <replaceable class="parameter">table</replaceable> only.
Column names can be specified only in conjunction with
the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</> switches.
</para>
<tip>
<para>
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
new file mode 100644
index 611c8e3..88c07be
*** a/src/bin/pg_dump/common.c
--- b/src/bin/pg_dump/common.c
*************** simple_oid_list_append(SimpleOidList *li
*** 898,921 ****
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)
{
--- 898,903 ----
*************** simple_oid_list_member(SimpleOidList *li
*** 928,943 ****
}
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;
- }
--- 910,912 ----
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
new file mode 100644
index 639ee9e..621c510
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 17,23 ****
#include <ctype.h>
#include "dumputils.h"
!
#include "parser/keywords.h"
--- 17,23 ----
#include <ctype.h>
#include "dumputils.h"
! #include "dumpmem.h"
#include "parser/keywords.h"
*************** exit_nicely(int code)
*** 1352,1354 ****
--- 1352,1386 ----
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;
+ }
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
new file mode 100644
index 4ef8cb3..a300e7e
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
*************** typedef enum /* bits returned by set
*** 27,32 ****
--- 27,45 ----
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;
*************** __attribute__((format(PG_PRINTF_ATTRIBUT
*** 75,78 ****
--- 88,95 ----
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 */
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
new file mode 100644
index 3b49395..9972e68
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
***************
*** 26,32 ****
#include "postgres_fe.h"
#include "pg_dump.h"
!
#include "libpq-fe.h"
--- 26,32 ----
#include "postgres_fe.h"
#include "pg_dump.h"
! #include "dumputils.h"
#include "libpq-fe.h"
*************** typedef struct _restoreOptions
*** 125,133 ****
int selTable;
char *indexNames;
char *functionNames;
- char *tableNames;
char *schemaNames;
char *triggerNames;
int useDB;
char *dbname;
--- 125,133 ----
int selTable;
char *indexNames;
char *functionNames;
char *schemaNames;
char *triggerNames;
+ SimpleStringList tableNames;
int useDB;
char *dbname;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
new file mode 100644
index 1fead28..a810efd
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** _tocEntryRequired(TocEntry *te, teSectio
*** 2493,2499 ****
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
--- 2493,2499 ----
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
new file mode 100644
index aa1546a..344f705
*** a/src/bin/pg_dump/pg_dump.h
--- b/src/bin/pg_dump/pg_dump.h
*************** typedef struct SimpleOidList
*** 58,74 ****
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
--- 58,63 ----
*************** extern CollInfo *findCollationByOid(Oid
*** 533,541 ****
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);
--- 522,528 ----
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
new file mode 100644
index 49d799b..45b8b58
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
*************** main(int argc, char **argv)
*** 234,240 ****
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! opts->tableNames = pg_strdup(optarg);
break;
case 'U':
--- 234,240 ----
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! simple_string_list_append(&opts->tableNames, optarg);
break;
case 'U':
*************** usage(const char *progname)
*** 424,430 ****
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, --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"));
--- 424,430 ----
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(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"));
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
new file mode 100644
index 0980b4c..d9ba29d
*** a/src/bin/scripts/Makefile
--- b/src/bin/scripts/Makefile
*************** dropdb: dropdb.o common.o dumputils.o kw
*** 32,38 ****
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
reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
--- 32,38 ----
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 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/%
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
new file mode 100644
index 261b438..4f163ee
*** a/src/bin/scripts/clusterdb.c
--- b/src/bin/scripts/clusterdb.c
*************** main(int argc, char *argv[])
*** 58,65 ****
bool echo = false;
bool quiet = false;
bool alldb = false;
- char *table = NULL;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 58,65 ----
bool echo = false;
bool quiet = false;
bool alldb = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 98,104 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'v':
verbose = true;
--- 98,104 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'v':
verbose = true;
*************** main(int argc, char *argv[])
*** 140,148 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
progname);
exit(1);
}
--- 140,149 ----
progname);
exit(1);
}
!
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 162,170 ****
dbname = get_user_name(progname);
}
! cluster_one_database(dbname, verbose, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 163,182 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 253,259 ****
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(_(" -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"));
--- 265,271 ----
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(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"));
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
new file mode 100644
index f61dada..6b1ca49
*** a/src/bin/scripts/reindexdb.c
--- b/src/bin/scripts/reindexdb.c
*************** main(int argc, char *argv[])
*** 64,71 ****
bool alldb = false;
bool echo = false;
bool quiet = false;
! const char *table = NULL;
! const char *index = NULL;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 64,71 ----
bool alldb = false;
bool echo = false;
bool quiet = false;
! SimpleStringList indexes = {NULL, NULL};
! SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 108,117 ****
syscatalog = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'i':
! index = pg_strdup(optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
--- 108,117 ----
syscatalog = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'i':
! simple_string_list_append(&indexes, optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
*************** main(int argc, char *argv[])
*** 154,167 ****
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
exit(1);
}
--- 154,167 ----
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 170,183 ****
}
else if (syscatalog)
{
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs at the same time\n"), progname);
exit(1);
}
--- 170,183 ----
}
else if (syscatalog)
{
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 206,219 ****
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)
reindex_one_database(dbname, dbname, "DATABASE", host, port,
username, prompt_password, progname, echo);
}
--- 206,231 ----
dbname = get_user_name(progname);
}
! 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);
}
*************** help(const char *progname)
*** 331,340 ****
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(_(" -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(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
--- 343,352 ----
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(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(s) only\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
new file mode 100644
index eb28ad4..dc5fcaf
*** a/src/bin/scripts/vacuumdb.c
--- b/src/bin/scripts/vacuumdb.c
***************
*** 12,17 ****
--- 12,18 ----
#include "postgres_fe.h"
#include "common.h"
+ #include "dumputils.h"
static void vacuum_one_database(const char *dbname, bool full, bool verbose,
*************** main(int argc, char *argv[])
*** 68,76 ****
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
- char *table = NULL;
bool full = false;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 69,77 ----
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
bool full = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 118,124 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'f':
full = true;
--- 119,125 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'f':
full = true;
*************** main(int argc, char *argv[])
*** 181,189 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
progname);
exit(1);
}
--- 182,190 ----
progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 204,213 ****
dbname = get_user_name(progname);
}
! vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
! freeze, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 205,228 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 348,354 ****
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(_(" -v, --verbose write a lot of output\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -z, --analyze update optimizer statistics\n"));
--- 363,369 ----
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(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"));
On 12/11/2012 10:25:43 PM, Josh Kupershmidt wrote:
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com> wrote:
Yes, the current pg_restore silently
ignores multiple --table arguments, and seems to use the last
one. You are introducing a backwards incompatible
change here.
Agreed with Robert that this change should be reasonable in a major
version (i.e. 9.3).
Good by me. Seemed worth a mention.
I believe you need ellipses behind --table in the syntax summaries
of the command reference docs.Hrm, I was following pg_dump's lead here for the .sgml docs, and
didn't see anywhere that pg_dump makes the multiple --table syntax
explicit other than in the explanatory text underneath the option.
Yes. I see. I didn't look at all the command's reference pages
but did happen to look at clusterdb, which does have --table
in the syntax summary. I just checked and you need to fix
clusterdb, reindexdb, and vacuumdb.
I also note that the pg_dump --help output says "table(s)" so
you probably want to have pg_restore say the same now that it
takes multiple tables.Good catch, will fix, and ditto reindexdb's --index help output. (It
is possible that the --help output for pg_dump was worded to say
"table(s)" because one can use a "pattern" --table specification with
pg_dump, though IMO it's helpful to mention "table(s)" in the --help
output for the rest of these programs as well, as a little reminder
to
the user.)
Agreed.
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Dec 12, 2012 at 8:14 AM, Karl O. Pinc <kop@meme.com> wrote:
On 12/11/2012 10:25:43 PM, Josh Kupershmidt wrote:
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com> wrote:
I believe you need ellipses behind --table in the syntax summaries
of the command reference docs.Hrm, I was following pg_dump's lead here for the .sgml docs, and
didn't see anywhere that pg_dump makes the multiple --table syntax
explicit other than in the explanatory text underneath the option.Yes. I see. I didn't look at all the command's reference pages
but did happen to look at clusterdb, which does have --table
in the syntax summary. I just checked and you need to fix
clusterdb, reindexdb, and vacuumdb.
OK, I made some changes to the command synopses for these three
commands. For some reason, reindexdb.sgml was slightly different from
the other two, in that the --table and --index bits were underneath a
<group> node instead of <arg>. I've changed that one to be like the
other two, and made them all have:
<arg choice="opt" rep="repeat">
to include the ellipses after the table -- I hope that matches what
you had in mind.
Josh
Attachments:
multiple_tables.v3.diffapplication/octet-stream; name=multiple_tables.v3.diffDownload
diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
new file mode 100644
index 097ea91..f1cbdc8
*** a/doc/src/sgml/ref/clusterdb.sgml
--- b/doc/src/sgml/ref/clusterdb.sgml
*************** PostgreSQL documentation
*** 24,30 ****
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
! <arg choice="opt"><group choice="plain"><arg choice="plain"><option>--table</option></arg><arg choice="plain"><option>-t</option></arg></group> <replaceable>table</replaceable> </arg>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 24,35 ----
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
! <arg choice="opt" rep="repeat">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable> </arg>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
*************** PostgreSQL documentation
*** 117,122 ****
--- 122,129 ----
<listitem>
<para>
Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
new file mode 100644
index f4668e7..0d73294
*** a/doc/src/sgml/ref/pg_restore.sgml
--- b/doc/src/sgml/ref/pg_restore.sgml
***************
*** 400,406 ****
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
--- 400,407 ----
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. Multiple tables
! may be specified with multiple <option>-t</> switches. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
new file mode 100644
index 781012f..47907c7
*** a/doc/src/sgml/ref/reindexdb.sgml
--- b/doc/src/sgml/ref/reindexdb.sgml
*************** PostgreSQL documentation
*** 23,42 ****
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
! <group choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
</group>
<replaceable>table</replaceable>
! </group>
! <group choice="opt">
<group choice="plain">
<arg choice="plain"><option>--index</option></arg>
<arg choice="plain"><option>-i</option></arg>
</group>
<replaceable>index</replaceable>
! </group>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 23,43 ----
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
! <arg choice="opt" rep="repeat">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
</group>
<replaceable>table</replaceable>
! </arg>
! <arg choice="opt" rep="repeat">
<group choice="plain">
<arg choice="plain"><option>--index</option></arg>
<arg choice="plain"><option>-i</option></arg>
</group>
<replaceable>index</replaceable>
! </arg>
!
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
*************** PostgreSQL documentation
*** 128,133 ****
--- 129,136 ----
<listitem>
<para>
Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</> switches.
</para>
</listitem>
</varlistentry>
*************** PostgreSQL documentation
*** 158,163 ****
--- 161,168 ----
<listitem>
<para>
Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
new file mode 100644
index c60ba44..13dfe57
*** a/doc/src/sgml/ref/vacuumdb.sgml
--- b/doc/src/sgml/ref/vacuumdb.sgml
*************** PostgreSQL documentation
*** 24,30 ****
<command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<arg rep="repeat"><replaceable>option</replaceable></arg>
! <arg choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
--- 24,30 ----
<command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<arg rep="repeat"><replaceable>option</replaceable></arg>
! <arg choice="opt" rep="repeat">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
*************** PostgreSQL documentation
*** 147,152 ****
--- 147,154 ----
Clean or analyze <replaceable class="parameter">table</replaceable> only.
Column names can be specified only in conjunction with
the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</> switches.
</para>
<tip>
<para>
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
new file mode 100644
index 611c8e3..88c07be
*** a/src/bin/pg_dump/common.c
--- b/src/bin/pg_dump/common.c
*************** simple_oid_list_append(SimpleOidList *li
*** 898,921 ****
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)
{
--- 898,903 ----
*************** simple_oid_list_member(SimpleOidList *li
*** 928,943 ****
}
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;
- }
--- 910,912 ----
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
new file mode 100644
index 639ee9e..621c510
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 17,23 ****
#include <ctype.h>
#include "dumputils.h"
!
#include "parser/keywords.h"
--- 17,23 ----
#include <ctype.h>
#include "dumputils.h"
! #include "dumpmem.h"
#include "parser/keywords.h"
*************** exit_nicely(int code)
*** 1352,1354 ****
--- 1352,1386 ----
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;
+ }
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
new file mode 100644
index 4ef8cb3..a300e7e
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
*************** typedef enum /* bits returned by set
*** 27,32 ****
--- 27,45 ----
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;
*************** __attribute__((format(PG_PRINTF_ATTRIBUT
*** 75,78 ****
--- 88,95 ----
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 */
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
new file mode 100644
index 3b49395..9972e68
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
***************
*** 26,32 ****
#include "postgres_fe.h"
#include "pg_dump.h"
!
#include "libpq-fe.h"
--- 26,32 ----
#include "postgres_fe.h"
#include "pg_dump.h"
! #include "dumputils.h"
#include "libpq-fe.h"
*************** typedef struct _restoreOptions
*** 125,133 ****
int selTable;
char *indexNames;
char *functionNames;
- char *tableNames;
char *schemaNames;
char *triggerNames;
int useDB;
char *dbname;
--- 125,133 ----
int selTable;
char *indexNames;
char *functionNames;
char *schemaNames;
char *triggerNames;
+ SimpleStringList tableNames;
int useDB;
char *dbname;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
new file mode 100644
index 1fead28..a810efd
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** _tocEntryRequired(TocEntry *te, teSectio
*** 2493,2499 ****
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
--- 2493,2499 ----
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
new file mode 100644
index aa1546a..344f705
*** a/src/bin/pg_dump/pg_dump.h
--- b/src/bin/pg_dump/pg_dump.h
*************** typedef struct SimpleOidList
*** 58,74 ****
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
--- 58,63 ----
*************** extern CollInfo *findCollationByOid(Oid
*** 533,541 ****
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);
--- 522,528 ----
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
new file mode 100644
index 49d799b..45b8b58
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
*************** main(int argc, char **argv)
*** 234,240 ****
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! opts->tableNames = pg_strdup(optarg);
break;
case 'U':
--- 234,240 ----
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! simple_string_list_append(&opts->tableNames, optarg);
break;
case 'U':
*************** usage(const char *progname)
*** 424,430 ****
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, --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"));
--- 424,430 ----
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(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"));
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
new file mode 100644
index 0980b4c..d9ba29d
*** a/src/bin/scripts/Makefile
--- b/src/bin/scripts/Makefile
*************** dropdb: dropdb.o common.o dumputils.o kw
*** 32,38 ****
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
reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
--- 32,38 ----
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 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/%
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
new file mode 100644
index 261b438..4f163ee
*** a/src/bin/scripts/clusterdb.c
--- b/src/bin/scripts/clusterdb.c
*************** main(int argc, char *argv[])
*** 58,65 ****
bool echo = false;
bool quiet = false;
bool alldb = false;
- char *table = NULL;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 58,65 ----
bool echo = false;
bool quiet = false;
bool alldb = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 98,104 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'v':
verbose = true;
--- 98,104 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'v':
verbose = true;
*************** main(int argc, char *argv[])
*** 140,148 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
progname);
exit(1);
}
--- 140,149 ----
progname);
exit(1);
}
!
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 162,170 ****
dbname = get_user_name(progname);
}
! cluster_one_database(dbname, verbose, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 163,182 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 253,259 ****
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(_(" -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"));
--- 265,271 ----
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(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"));
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
new file mode 100644
index f61dada..6b1ca49
*** a/src/bin/scripts/reindexdb.c
--- b/src/bin/scripts/reindexdb.c
*************** main(int argc, char *argv[])
*** 64,71 ****
bool alldb = false;
bool echo = false;
bool quiet = false;
! const char *table = NULL;
! const char *index = NULL;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 64,71 ----
bool alldb = false;
bool echo = false;
bool quiet = false;
! SimpleStringList indexes = {NULL, NULL};
! SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 108,117 ****
syscatalog = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'i':
! index = pg_strdup(optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
--- 108,117 ----
syscatalog = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'i':
! simple_string_list_append(&indexes, optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
*************** main(int argc, char *argv[])
*** 154,167 ****
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
exit(1);
}
--- 154,167 ----
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 170,183 ****
}
else if (syscatalog)
{
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs at the same time\n"), progname);
exit(1);
}
--- 170,183 ----
}
else if (syscatalog)
{
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 206,219 ****
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)
reindex_one_database(dbname, dbname, "DATABASE", host, port,
username, prompt_password, progname, echo);
}
--- 206,231 ----
dbname = get_user_name(progname);
}
! 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);
}
*************** help(const char *progname)
*** 331,340 ****
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(_(" -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(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
--- 343,352 ----
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(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(s) only\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
new file mode 100644
index eb28ad4..dc5fcaf
*** a/src/bin/scripts/vacuumdb.c
--- b/src/bin/scripts/vacuumdb.c
***************
*** 12,17 ****
--- 12,18 ----
#include "postgres_fe.h"
#include "common.h"
+ #include "dumputils.h"
static void vacuum_one_database(const char *dbname, bool full, bool verbose,
*************** main(int argc, char *argv[])
*** 68,76 ****
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
- char *table = NULL;
bool full = false;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 69,77 ----
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
bool full = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 118,124 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'f':
full = true;
--- 119,125 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'f':
full = true;
*************** main(int argc, char *argv[])
*** 181,189 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
progname);
exit(1);
}
--- 182,190 ----
progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 204,213 ****
dbname = get_user_name(progname);
}
! vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
! freeze, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 205,228 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 348,354 ****
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(_(" -v, --verbose write a lot of output\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -z, --analyze update optimizer statistics\n"));
--- 363,369 ----
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(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"));
Hi Josh,
The good news is that there's only this little bit of
documentation formatting to fix....
On 12/12/2012 11:04:53 PM, Josh Kupershmidt wrote:
On Wed, Dec 12, 2012 at 8:14 AM, Karl O. Pinc <kop@meme.com> wrote:
On 12/11/2012 10:25:43 PM, Josh Kupershmidt wrote:
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com>
wrote:
I believe you need ellipses behind --table in the syntax
summaries
of the command reference docs.
Yes. I see. I didn't look at all the command's reference pages
but did happen to look at clusterdb, which does have --table
in the syntax summary. I just checked and you need to fix
clusterdb, reindexdb, and vacuumdb.OK, I made some changes to the command synopses for these three
commands. For some reason, reindexdb.sgml was slightly different from
the other two, in that the --table and --index bits were underneath a
<group> node instead of <arg>. I've changed that one to be like the
other two, and made them all have:
<arg choice="opt" rep="repeat">to include the ellipses after the table -- I hope that matches what
you had in mind.
Sadly, the ... is in the wrong place in all 3. Yours looks like (for
2 examples):
vacuumdb [connection-option...] [option...] [ --table | -t table
[( column [,...] )] ...] [dbname]
reindexdb [connection-option...] [ --table | -t table ...] [ --index |
-i index ...] [dbname]
I want the ... outside the square braces, because the --table (or -t)
must repeat for each table specified. Like:
vacuumdb [connection-option...] [option...] [ --table | -t table
[( column [,...] )] ]... [dbname]
reindexdb [connection-option...] [ --table | -t table ]... [ --index |
-i index ]... [dbname]
Sorry, I don't see any examples in the existing docs of how this is
done.
It seems like what you have should work, although perhaps
somehow that's the difference between the <arg> and <group>
and you need to switch them back to how reindex used to
be. Otherwise, there's the docs at docbook.org, and
the docbook mailing lists. Or maybe the stylesheets
are broken. (Always blame the tool! It's never _our_
fault! ;-)
Have you had trouble getting this to work?
Maybe someone who knows what they're doing will step
in and give us the answer.
Regards,
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 12/13/2012 12:35:14 AM, Karl O. Pinc wrote:
On 12/12/2012 11:04:53 PM, Josh Kupershmidt wrote:
On Wed, Dec 12, 2012 at 8:14 AM, Karl O. Pinc <kop@meme.com> wrote:
On 12/11/2012 10:25:43 PM, Josh Kupershmidt wrote:
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com>
wrote:
I believe you need ellipses behind --table in the syntax
summaries
of the command reference docs.
Yes. I see. I didn't look at all the command's reference pages
but did happen to look at clusterdb, which does have --table
in the syntax summary. I just checked and you need to fix
clusterdb, reindexdb, and vacuumdb.OK, I made some changes to the command synopses for these three
commands.
I want the ... outside the square braces, because the --table (or -t)
must repeat for each table specified. Like:vacuumdb [connection-option...] [option...] [ --table | -t table
[( column [,...] )] ]... [dbname]reindexdb [connection-option...] [ --table | -t table ]... [ --index
|-i index ]... [dbname]
Have you had trouble getting this to work?
Perhaps <arg choice="opt"><arg rep="repeat"> ... would work?
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Dec 13, 2012 at 6:05 AM, Karl O. Pinc <kop@meme.com> wrote:
On 12/13/2012 12:35:14 AM, Karl O. Pinc wrote:
On 12/12/2012 11:04:53 PM, Josh Kupershmidt wrote:
On Wed, Dec 12, 2012 at 8:14 AM, Karl O. Pinc <kop@meme.com> wrote:
On 12/11/2012 10:25:43 PM, Josh Kupershmidt wrote:
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com>
wrote:
I believe you need ellipses behind --table in the syntax
summaries
of the command reference docs.
Yes. I see. I didn't look at all the command's reference pages
but did happen to look at clusterdb, which does have --table
in the syntax summary. I just checked and you need to fix
clusterdb, reindexdb, and vacuumdb.OK, I made some changes to the command synopses for these three
commands.I want the ... outside the square braces, because the --table (or -t)
must repeat for each table specified. Like:vacuumdb [connection-option...] [option...] [ --table | -t table
[( column [,...] )] ]... [dbname]reindexdb [connection-option...] [ --table | -t table ]... [ --index
|-i index ]... [dbname]
Have you had trouble getting this to work?
Perhaps <arg choice="opt"><arg rep="repeat"> ... would work?
Well, I fooled around with the SGML for a bit and came up with
something which has the ellipses in brackets:
[ --table | -t table ] [...]
which I like a little better than not having the second set of
brackets. New version attached.
Josh
Attachments:
multiple_tables.v04.diffapplication/octet-stream; name=multiple_tables.v04.diffDownload
diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
new file mode 100644
index 097ea91..a7cf1d1
*** a/doc/src/sgml/ref/clusterdb.sgml
--- b/doc/src/sgml/ref/clusterdb.sgml
*************** PostgreSQL documentation
*** 24,30 ****
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
! <arg choice="opt"><group choice="plain"><arg choice="plain"><option>--table</option></arg><arg choice="plain"><option>-t</option></arg></group> <replaceable>table</replaceable> </arg>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 24,39 ----
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
!
! <arg choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable>
! </arg>
! <arg rep="repeat"></arg>
!
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
*************** PostgreSQL documentation
*** 117,122 ****
--- 126,133 ----
<listitem>
<para>
Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
new file mode 100644
index f4668e7..0d73294
*** a/doc/src/sgml/ref/pg_restore.sgml
--- b/doc/src/sgml/ref/pg_restore.sgml
***************
*** 400,406 ****
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
--- 400,407 ----
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. Multiple tables
! may be specified with multiple <option>-t</> switches. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
new file mode 100644
index 781012f..329a8c3
*** a/doc/src/sgml/ref/reindexdb.sgml
--- b/doc/src/sgml/ref/reindexdb.sgml
*************** PostgreSQL documentation
*** 23,42 ****
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
! <group choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
</group>
<replaceable>table</replaceable>
! </group>
! <group choice="opt">
<group choice="plain">
<arg choice="plain"><option>--index</option></arg>
<arg choice="plain"><option>-i</option></arg>
</group>
<replaceable>index</replaceable>
! </group>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 23,47 ----
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
!
! <arg choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
</group>
<replaceable>table</replaceable>
! </arg>
! <arg rep="repeat"></arg>
!
! <arg choice="opt">
<group choice="plain">
<arg choice="plain"><option>--index</option></arg>
<arg choice="plain"><option>-i</option></arg>
</group>
<replaceable>index</replaceable>
! </arg>
! <arg rep="repeat"></arg>
!
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
*************** PostgreSQL documentation
*** 128,133 ****
--- 133,140 ----
<listitem>
<para>
Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</> switches.
</para>
</listitem>
</varlistentry>
*************** PostgreSQL documentation
*** 158,163 ****
--- 165,172 ----
<listitem>
<para>
Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
new file mode 100644
index c60ba44..d1053ea
*** a/doc/src/sgml/ref/vacuumdb.sgml
--- b/doc/src/sgml/ref/vacuumdb.sgml
*************** PostgreSQL documentation
*** 24,29 ****
--- 24,30 ----
<command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<arg rep="repeat"><replaceable>option</replaceable></arg>
+
<arg choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
*************** PostgreSQL documentation
*** 32,37 ****
--- 33,40 ----
<replaceable>table</replaceable>
<arg choice="opt">( <replaceable class="parameter">column</replaceable> [,...] )</arg>
</arg>
+ <arg rep="repeat"></arg>
+
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
*************** PostgreSQL documentation
*** 147,152 ****
--- 150,157 ----
Clean or analyze <replaceable class="parameter">table</replaceable> only.
Column names can be specified only in conjunction with
the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</> switches.
</para>
<tip>
<para>
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
new file mode 100644
index 611c8e3..88c07be
*** a/src/bin/pg_dump/common.c
--- b/src/bin/pg_dump/common.c
*************** simple_oid_list_append(SimpleOidList *li
*** 898,921 ****
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)
{
--- 898,903 ----
*************** simple_oid_list_member(SimpleOidList *li
*** 928,943 ****
}
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;
- }
--- 910,912 ----
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
new file mode 100644
index 639ee9e..621c510
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 17,23 ****
#include <ctype.h>
#include "dumputils.h"
!
#include "parser/keywords.h"
--- 17,23 ----
#include <ctype.h>
#include "dumputils.h"
! #include "dumpmem.h"
#include "parser/keywords.h"
*************** exit_nicely(int code)
*** 1352,1354 ****
--- 1352,1386 ----
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;
+ }
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
new file mode 100644
index 4ef8cb3..a300e7e
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
*************** typedef enum /* bits returned by set
*** 27,32 ****
--- 27,45 ----
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;
*************** __attribute__((format(PG_PRINTF_ATTRIBUT
*** 75,78 ****
--- 88,95 ----
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 */
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
new file mode 100644
index 3b49395..9972e68
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
***************
*** 26,32 ****
#include "postgres_fe.h"
#include "pg_dump.h"
!
#include "libpq-fe.h"
--- 26,32 ----
#include "postgres_fe.h"
#include "pg_dump.h"
! #include "dumputils.h"
#include "libpq-fe.h"
*************** typedef struct _restoreOptions
*** 125,133 ****
int selTable;
char *indexNames;
char *functionNames;
- char *tableNames;
char *schemaNames;
char *triggerNames;
int useDB;
char *dbname;
--- 125,133 ----
int selTable;
char *indexNames;
char *functionNames;
char *schemaNames;
char *triggerNames;
+ SimpleStringList tableNames;
int useDB;
char *dbname;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
new file mode 100644
index 1fead28..a810efd
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
*************** _tocEntryRequired(TocEntry *te, teSectio
*** 2493,2499 ****
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
--- 2493,2499 ----
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
new file mode 100644
index aa1546a..344f705
*** a/src/bin/pg_dump/pg_dump.h
--- b/src/bin/pg_dump/pg_dump.h
*************** typedef struct SimpleOidList
*** 58,74 ****
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
--- 58,63 ----
*************** extern CollInfo *findCollationByOid(Oid
*** 533,541 ****
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);
--- 522,528 ----
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
new file mode 100644
index 49d799b..45b8b58
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
*************** main(int argc, char **argv)
*** 234,240 ****
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! opts->tableNames = pg_strdup(optarg);
break;
case 'U':
--- 234,240 ----
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! simple_string_list_append(&opts->tableNames, optarg);
break;
case 'U':
*************** usage(const char *progname)
*** 424,430 ****
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, --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"));
--- 424,430 ----
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(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"));
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
new file mode 100644
index 0980b4c..d9ba29d
*** a/src/bin/scripts/Makefile
--- b/src/bin/scripts/Makefile
*************** dropdb: dropdb.o common.o dumputils.o kw
*** 32,38 ****
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
reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
--- 32,38 ----
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 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/%
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
new file mode 100644
index 261b438..4f163ee
*** a/src/bin/scripts/clusterdb.c
--- b/src/bin/scripts/clusterdb.c
*************** main(int argc, char *argv[])
*** 58,65 ****
bool echo = false;
bool quiet = false;
bool alldb = false;
- char *table = NULL;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 58,65 ----
bool echo = false;
bool quiet = false;
bool alldb = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 98,104 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'v':
verbose = true;
--- 98,104 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'v':
verbose = true;
*************** main(int argc, char *argv[])
*** 140,148 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
progname);
exit(1);
}
--- 140,149 ----
progname);
exit(1);
}
!
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 162,170 ****
dbname = get_user_name(progname);
}
! cluster_one_database(dbname, verbose, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 163,182 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 253,259 ****
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(_(" -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"));
--- 265,271 ----
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(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"));
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
new file mode 100644
index f61dada..6b1ca49
*** a/src/bin/scripts/reindexdb.c
--- b/src/bin/scripts/reindexdb.c
*************** main(int argc, char *argv[])
*** 64,71 ****
bool alldb = false;
bool echo = false;
bool quiet = false;
! const char *table = NULL;
! const char *index = NULL;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 64,71 ----
bool alldb = false;
bool echo = false;
bool quiet = false;
! SimpleStringList indexes = {NULL, NULL};
! SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 108,117 ****
syscatalog = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'i':
! index = pg_strdup(optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
--- 108,117 ----
syscatalog = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'i':
! simple_string_list_append(&indexes, optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
*************** main(int argc, char *argv[])
*** 154,167 ****
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
exit(1);
}
--- 154,167 ----
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 170,183 ****
}
else if (syscatalog)
{
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs at the same time\n"), progname);
exit(1);
}
--- 170,183 ----
}
else if (syscatalog)
{
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 206,219 ****
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)
reindex_one_database(dbname, dbname, "DATABASE", host, port,
username, prompt_password, progname, echo);
}
--- 206,231 ----
dbname = get_user_name(progname);
}
! 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);
}
*************** help(const char *progname)
*** 331,340 ****
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(_(" -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(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
--- 343,352 ----
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(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(s) only\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
new file mode 100644
index eb28ad4..dc5fcaf
*** a/src/bin/scripts/vacuumdb.c
--- b/src/bin/scripts/vacuumdb.c
***************
*** 12,17 ****
--- 12,18 ----
#include "postgres_fe.h"
#include "common.h"
+ #include "dumputils.h"
static void vacuum_one_database(const char *dbname, bool full, bool verbose,
*************** main(int argc, char *argv[])
*** 68,76 ****
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
- char *table = NULL;
bool full = false;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 69,77 ----
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
bool full = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
*************** main(int argc, char *argv[])
*** 118,124 ****
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'f':
full = true;
--- 119,125 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'f':
full = true;
*************** main(int argc, char *argv[])
*** 181,189 ****
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
progname);
exit(1);
}
--- 182,190 ----
progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"),
progname);
exit(1);
}
*************** main(int argc, char *argv[])
*** 204,213 ****
dbname = get_user_name(progname);
}
! vacuum_one_database(dbname, full, verbose, and_analyze, analyze_only,
! freeze, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 205,228 ----
dbname = get_user_name(progname);
}
! 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);
*************** help(const char *progname)
*** 348,354 ****
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(_(" -v, --verbose write a lot of output\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -z, --analyze update optimizer statistics\n"));
--- 363,369 ----
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(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"));
On 12/13/2012 07:37:27 PM, Josh Kupershmidt wrote:
On Thu, Dec 13, 2012 at 6:05 AM, Karl O. Pinc <kop@meme.com> wrote:
On 12/13/2012 12:35:14 AM, Karl O. Pinc wrote:
On 12/12/2012 11:04:53 PM, Josh Kupershmidt wrote:
On Wed, Dec 12, 2012 at 8:14 AM, Karl O. Pinc <kop@meme.com>
wrote:
On 12/11/2012 10:25:43 PM, Josh Kupershmidt wrote:
On Tue, Dec 11, 2012 at 11:46 AM, Karl O. Pinc <kop@meme.com>
wrote:
I believe you need ellipses behind --table in the syntax
summaries
of the command reference docs.
Yes. I see. I didn't look at all the command's reference
pages
but did happen to look at clusterdb, which does have --table
in the syntax summary. I just checked and you need to fix
clusterdb, reindexdb, and vacuumdb.OK, I made some changes to the command synopses for these three
commands.I want the ... outside the square braces, because the --table (or
-t)
must repeat for each table specified. Like:
vacuumdb [connection-option...] [option...] [ --table | -t table
[( column [,...] )] ]... [dbname]reindexdb [connection-option...] [ --table | -t table ]... [
--index
|
-i index ]... [dbname]
Have you had trouble getting this to work?
Perhaps <arg choice="opt"><arg rep="repeat"> ... would work?
Well, I fooled around with the SGML for a bit and came up with
something which has the ellipses in brackets:[ --table | -t table ] [...]
which I like a little better than not having the second set of
brackets. New version attached.
The problem is that the pg man pages would then have a
syntax different from all the other man pages in the system,
which all have ... outside of square braces.
See "man cat", e.g.
(I wonder if the problem is because the style sheets
have been tweaked to work well with sql?)
Because I don't see the traditional man page ellipsis syntax
anywhere in the pg docs, and because all the pg
client command line programs that use repeating arguments
all have a simplified syntax summary with just [options ...]
or some such, I suspect that there may be a problem
putting the ellipsis outside of the square braces.
It would be nice if we could get some guidance from someone
more familiar with the pg docbook stylesheets.
As a fallback I'd do to the clusterdb, reindexdb, and vacuumdb
syntax summaries what was done to the pg_dump and pg_restore
syntax summaries. Remove all the detail. This is sucky,
and _still_ leaves the reference pages with a syntax summary syntax
that differs from regular man pages, but because the text
is relatively information free nobody notices.
My inclination, since you can't make it work
and we don't seem to be getting any help here,
is to remove all the detail in the syntax summaries,
push it through to a committer, and get some feedback that way.
Regards,
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Dec 13, 2012 at 7:24 PM, Karl O. Pinc <kop@meme.com> wrote:
The problem is that the pg man pages would then have a
syntax different from all the other man pages in the system,
which all have ... outside of square braces.
See "man cat", e.g.
FWIW, `man cat` on my OS X machine has synopsis:
cat [-benstuv] [file ...]
though I see:
cat [OPTION] [FILE]...
on Debian.
(I wonder if the problem is because the style sheets
have been tweaked to work well with sql?)Because I don't see the traditional man page ellipsis syntax
anywhere in the pg docs, and because all the pg
client command line programs that use repeating arguments
all have a simplified syntax summary with just [options ...]
or some such, I suspect that there may be a problem
putting the ellipsis outside of the square braces.
Yeah, I tried a few different ways and didn't manage to get:
[ --table | -t table ] ...
It would be nice if we could get some guidance from someone
more familiar with the pg docbook stylesheets.As a fallback I'd do to the clusterdb, reindexdb, and vacuumdb
syntax summaries what was done to the pg_dump and pg_restore
syntax summaries. Remove all the detail. This is sucky,
and _still_ leaves the reference pages with a syntax summary syntax
that differs from regular man pages, but because the text
is relatively information free nobody notices.
That should be how the v2 patch has it.
My inclination, since you can't make it work
and we don't seem to be getting any help here,
is to remove all the detail in the syntax summaries,
push it through to a committer, and get some feedback that way.
If someone out there feels that the formatting of these commands'
synopses should look like:
[ --table | -t table ] ...
and knows how to massage the SGML to get that, I'm happy to
accommodate the change. Otherwise, I think either the v4 or v2 patch
should be acceptable.
Josh
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 12/13/2012 09:24:24 PM, Josh Kupershmidt wrote:
On Thu, Dec 13, 2012 at 7:24 PM, Karl O. Pinc <kop@meme.com> wrote:
As a fallback I'd do to the clusterdb, reindexdb, and vacuumdb
syntax summaries what was done to the pg_dump and pg_restore
syntax summaries. Remove all the detail. This is sucky,
and _still_ leaves the reference pages with a syntax summary syntax
that differs from regular man pages, but because the text
is relatively information free nobody notices.That should be how the v2 patch has it.
No. The v2 patch does not touch the syntax synopsis.
My inclination, since you can't make it work
and we don't seem to be getting any help here,
is to remove all the detail in the syntax summaries,
push it through to a committer, and get some feedback that way.If someone out there feels that the formatting of these commands'
synopses should look like:
[ --table | -t table ] ...and knows how to massage the SGML to get that, I'm happy to
accommodate the change. Otherwise, I think either the v4 or v2 patch
should be acceptable.
My brain seems to have turned itself on. I went and (re)read
the docbook manual and was able to come up with this,
which works:
<arg choice="plain" rep="repeat"><arg choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
</group>
<replaceable>table</replaceable> </arg></arg>
Yay! (indentation et-al aside)
Sorry to be so persnickety, and unhelpful until now.
It seemed like it should be doable, but something
was going wrong between keyboard and chair. I guess
I should be doing this when better rested.
Regards,
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Dec 13, 2012 at 9:03 PM, Karl O. Pinc <kop@meme.com> wrote:
My brain seems to have turned itself on. I went and (re)read
the docbook manual and was able to come up with this,
which works:<arg choice="plain" rep="repeat"><arg choice="opt">
<group choice="plain">
<arg choice="plain"><option>--table</option></arg>
<arg choice="plain"><option>-t</option></arg>
</group>
<replaceable>table</replaceable> </arg></arg>Yay! (indentation et-al aside)
That does seem to work, thanks for figuring out the syntax.
Sorry to be so persnickety, and unhelpful until now.
It seemed like it should be doable, but something
was going wrong between keyboard and chair. I guess
I should be doing this when better rested.
No problem, here is v5 with changed synopses.
Josh
Attachments:
multiple_tables.v5.diffapplication/octet-stream; name=multiple_tables.v5.diffDownload
*** a/doc/src/sgml/ref/clusterdb.sgml
--- b/doc/src/sgml/ref/clusterdb.sgml
***************
*** 24,30 **** PostgreSQL documentation
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
! <arg choice="opt"><group choice="plain"><arg choice="plain"><option>--table</option></arg><arg choice="plain"><option>-t</option></arg></group> <replaceable>table</replaceable> </arg>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 24,40 ----
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
!
! <arg choice="plain" rep="repeat">
! <arg choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable>
! </arg>
! </arg>
!
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
***************
*** 117,122 **** PostgreSQL documentation
--- 127,134 ----
<listitem>
<para>
Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
*** a/doc/src/sgml/ref/pg_restore.sgml
--- b/doc/src/sgml/ref/pg_restore.sgml
***************
*** 400,406 ****
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
--- 400,407 ----
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
! Restore definition and/or data of named table only. Multiple tables
! may be specified with multiple <option>-t</> switches. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
*** a/doc/src/sgml/ref/reindexdb.sgml
--- b/doc/src/sgml/ref/reindexdb.sgml
***************
*** 23,42 **** PostgreSQL documentation
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
! <group choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable>
! </group>
! <group choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--index</option></arg>
! <arg choice="plain"><option>-i</option></arg>
! </group>
! <replaceable>index</replaceable>
! </group>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 23,49 ----
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
!
! <arg choice="plain" rep="repeat">
! <arg choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable>
! </arg>
! </arg>
!
! <arg choice="plain" rep="repeat">
! <arg choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--index</option></arg>
! <arg choice="plain"><option>-i</option></arg>
! </group>
! <replaceable>index</replaceable>
! </arg>
! </arg>
!
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
***************
*** 128,133 **** PostgreSQL documentation
--- 135,142 ----
<listitem>
<para>
Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</> switches.
</para>
</listitem>
</varlistentry>
***************
*** 158,163 **** PostgreSQL documentation
--- 167,174 ----
<listitem>
<para>
Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
*** a/doc/src/sgml/ref/vacuumdb.sgml
--- b/doc/src/sgml/ref/vacuumdb.sgml
***************
*** 24,37 **** PostgreSQL documentation
<command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<arg rep="repeat"><replaceable>option</replaceable></arg>
! <arg choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable>
! <arg choice="opt">( <replaceable class="parameter">column</replaceable> [,...] )</arg>
</arg>
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
--- 24,41 ----
<command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<arg rep="repeat"><replaceable>option</replaceable></arg>
!
! <arg choice="plain" rep="repeat">
! <arg choice="opt">
! <group choice="plain">
! <arg choice="plain"><option>--table</option></arg>
! <arg choice="plain"><option>-t</option></arg>
! </group>
! <replaceable>table</replaceable>
! <arg choice="opt">( <replaceable class="parameter">column</replaceable> [,...] )</arg>
! </arg>
</arg>
+
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
***************
*** 147,152 **** PostgreSQL documentation
--- 151,158 ----
Clean or analyze <replaceable class="parameter">table</replaceable> only.
Column names can be specified only in conjunction with
the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</> switches.
</para>
<tip>
<para>
*** a/src/bin/pg_dump/common.c
--- b/src/bin/pg_dump/common.c
***************
*** 898,921 **** 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)
{
--- 898,903 ----
***************
*** 928,943 **** 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;
- }
--- 910,912 ----
*** a/src/bin/pg_dump/dumputils.c
--- b/src/bin/pg_dump/dumputils.c
***************
*** 17,23 ****
#include <ctype.h>
#include "dumputils.h"
!
#include "parser/keywords.h"
--- 17,23 ----
#include <ctype.h>
#include "dumputils.h"
! #include "dumpmem.h"
#include "parser/keywords.h"
***************
*** 1352,1354 **** exit_nicely(int code)
--- 1352,1386 ----
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;
+ }
*** a/src/bin/pg_dump/dumputils.h
--- b/src/bin/pg_dump/dumputils.h
***************
*** 27,32 **** typedef enum /* bits returned by set_dump_section */
--- 27,45 ----
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,78 **** __attribute__((format(PG_PRINTF_ATTRIBUTE, 2, 3), noreturn));
--- 88,95 ----
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 */
*** a/src/bin/pg_dump/pg_backup.h
--- b/src/bin/pg_dump/pg_backup.h
***************
*** 26,32 ****
#include "postgres_fe.h"
#include "pg_dump.h"
!
#include "libpq-fe.h"
--- 26,32 ----
#include "postgres_fe.h"
#include "pg_dump.h"
! #include "dumputils.h"
#include "libpq-fe.h"
***************
*** 125,133 **** typedef struct _restoreOptions
int selTable;
char *indexNames;
char *functionNames;
- char *tableNames;
char *schemaNames;
char *triggerNames;
int useDB;
char *dbname;
--- 125,133 ----
int selTable;
char *indexNames;
char *functionNames;
char *schemaNames;
char *triggerNames;
+ SimpleStringList tableNames;
int useDB;
char *dbname;
*** a/src/bin/pg_dump/pg_backup_archiver.c
--- b/src/bin/pg_dump/pg_backup_archiver.c
***************
*** 2493,2499 **** _tocEntryRequired(TocEntry *te, teSection curSection, RestoreOptions *ropt)
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames && strcmp(ropt->tableNames, te->tag) != 0)
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
--- 2493,2499 ----
{
if (!ropt->selTable)
return 0;
! if (ropt->tableNames.head != NULL && (!(simple_string_list_member(&ropt->tableNames, te->tag))))
return 0;
}
else if (strcmp(te->desc, "INDEX") == 0)
*** a/src/bin/pg_dump/pg_dump.h
--- b/src/bin/pg_dump/pg_dump.h
***************
*** 58,74 **** 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
--- 58,63 ----
***************
*** 533,541 **** 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);
--- 522,528 ----
*** a/src/bin/pg_dump/pg_restore.c
--- b/src/bin/pg_dump/pg_restore.c
***************
*** 234,240 **** main(int argc, char **argv)
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! opts->tableNames = pg_strdup(optarg);
break;
case 'U':
--- 234,240 ----
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
! simple_string_list_append(&opts->tableNames, optarg);
break;
case 'U':
***************
*** 424,430 **** 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, --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"));
--- 424,430 ----
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(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"));
*** a/src/bin/scripts/Makefile
--- b/src/bin/scripts/Makefile
***************
*** 32,38 **** 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
reindexdb: reindexdb.o common.o dumputils.o kwlookup.o keywords.o | submake-libpq
dumputils.c keywords.c: % : $(top_srcdir)/src/bin/pg_dump/%
--- 32,38 ----
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 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/%
*** a/src/bin/scripts/clusterdb.c
--- b/src/bin/scripts/clusterdb.c
***************
*** 58,65 **** main(int argc, char *argv[])
bool echo = false;
bool quiet = false;
bool alldb = false;
- char *table = NULL;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 58,65 ----
bool echo = false;
bool quiet = false;
bool alldb = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
***************
*** 98,104 **** main(int argc, char *argv[])
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'v':
verbose = true;
--- 98,104 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'v':
verbose = true;
***************
*** 140,148 **** main(int argc, char *argv[])
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot cluster a specific table in all databases\n"),
progname);
exit(1);
}
--- 140,149 ----
progname);
exit(1);
}
!
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot cluster specific table(s) in all databases\n"),
progname);
exit(1);
}
***************
*** 162,170 **** main(int argc, char *argv[])
dbname = get_user_name(progname);
}
! cluster_one_database(dbname, verbose, table,
! host, port, username, prompt_password,
! progname, echo);
}
exit(0);
--- 163,182 ----
dbname = get_user_name(progname);
}
! 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,259 **** 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(_(" -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"));
--- 265,271 ----
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(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"));
*** a/src/bin/scripts/reindexdb.c
--- b/src/bin/scripts/reindexdb.c
***************
*** 64,71 **** main(int argc, char *argv[])
bool alldb = false;
bool echo = false;
bool quiet = false;
! const char *table = NULL;
! const char *index = NULL;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 64,71 ----
bool alldb = false;
bool echo = false;
bool quiet = false;
! SimpleStringList indexes = {NULL, NULL};
! SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
***************
*** 108,117 **** main(int argc, char *argv[])
syscatalog = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'i':
! index = pg_strdup(optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
--- 108,117 ----
syscatalog = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'i':
! simple_string_list_append(&indexes, optarg);
break;
case 2:
maintenance_db = pg_strdup(optarg);
***************
*** 154,167 **** 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)
{
! fprintf(stderr, _("%s: cannot reindex a specific table in all databases\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index in all databases\n"), progname);
exit(1);
}
--- 154,167 ----
fprintf(stderr, _("%s: cannot reindex all databases and system catalogs at the same time\n"), progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) in all databases\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) in all databases\n"), progname);
exit(1);
}
***************
*** 170,183 **** main(int argc, char *argv[])
}
else if (syscatalog)
{
! if (table)
{
! fprintf(stderr, _("%s: cannot reindex a specific table and system catalogs at the same time\n"), progname);
exit(1);
}
! if (index)
{
! fprintf(stderr, _("%s: cannot reindex a specific index and system catalogs at the same time\n"), progname);
exit(1);
}
--- 170,183 ----
}
else if (syscatalog)
{
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific table(s) and system catalogs at the same time\n"), progname);
exit(1);
}
! if (indexes.head != NULL)
{
! fprintf(stderr, _("%s: cannot reindex specific index(es) and system catalogs at the same time\n"), progname);
exit(1);
}
***************
*** 206,219 **** 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)
reindex_one_database(dbname, dbname, "DATABASE", host, port,
username, prompt_password, progname, echo);
}
--- 206,231 ----
dbname = get_user_name(progname);
}
! 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,340 **** 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(_(" -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(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
--- 343,352 ----
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(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(s) only\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
*** a/src/bin/scripts/vacuumdb.c
--- b/src/bin/scripts/vacuumdb.c
***************
*** 12,17 ****
--- 12,18 ----
#include "postgres_fe.h"
#include "common.h"
+ #include "dumputils.h"
static void vacuum_one_database(const char *dbname, bool full, bool verbose,
***************
*** 68,76 **** main(int argc, char *argv[])
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
- char *table = NULL;
bool full = false;
bool verbose = false;
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
--- 69,77 ----
bool analyze_only = false;
bool freeze = false;
bool alldb = false;
bool full = false;
bool verbose = false;
+ SimpleStringList tables = {NULL, NULL};
progname = get_progname(argv[0]);
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pgscripts"));
***************
*** 118,124 **** main(int argc, char *argv[])
alldb = true;
break;
case 't':
! table = pg_strdup(optarg);
break;
case 'f':
full = true;
--- 119,125 ----
alldb = true;
break;
case 't':
! simple_string_list_append(&tables, optarg);
break;
case 'f':
full = true;
***************
*** 181,189 **** main(int argc, char *argv[])
progname);
exit(1);
}
! if (table)
{
! fprintf(stderr, _("%s: cannot vacuum a specific table in all databases\n"),
progname);
exit(1);
}
--- 182,190 ----
progname);
exit(1);
}
! if (tables.head != NULL)
{
! fprintf(stderr, _("%s: cannot vacuum specific table(s) in all databases\n"),
progname);
exit(1);
}
***************
*** 204,213 **** 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);
}
exit(0);
--- 205,228 ----
dbname = get_user_name(progname);
}
! 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,354 **** 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(_(" -v, --verbose write a lot of output\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -z, --analyze update optimizer statistics\n"));
--- 363,369 ----
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(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"));
On 12/13/2012 11:02:56 PM, Josh Kupershmidt wrote:
On Thu, Dec 13, 2012 at 9:03 PM, Karl O. Pinc <kop@meme.com> wrote:
Sorry to be so persnickety, and unhelpful until now.
It seemed like it should be doable, but something
was going wrong between keyboard and chair. I guess
I should be doing this when better rested.No problem, here is v5 with changed synopses.
The clusterdb synopsis had tabs in it, which I understand
is frowned upon in the docs. I've fixed this.
It looks good to me, passes check and so forth.
Attached is a v6 patch, with no tabs in docs and based
off the latest head.
I'm marking it ready for committer.
Regards,
Karl <kop@meme.com>
Free Software: "You don't pay back, you pay forward."
-- Robert A. Heinlein
Attachments:
multiple_tables.v6.difftext/x-patch; charset=us-ascii; name=multiple_tables.v6.diffDownload
diff --git a/doc/src/sgml/ref/clusterdb.sgml b/doc/src/sgml/ref/clusterdb.sgml
index 097ea91..1316932 100644
--- a/doc/src/sgml/ref/clusterdb.sgml
+++ b/doc/src/sgml/ref/clusterdb.sgml
@@ -24,7 +24,17 @@ PostgreSQL documentation
<command>clusterdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<group choice="opt"><arg choice="plain"><option>--verbose</option></arg><arg choice="plain"><option>-v</option></arg></group>
- <arg choice="opt"><group choice="plain"><arg choice="plain"><option>--table</option></arg><arg choice="plain"><option>-t</option></arg></group> <replaceable>table</replaceable> </arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>--table</option></arg>
+ <arg choice="plain"><option>-t</option></arg>
+ </group>
+ <replaceable>table</replaceable>
+ </arg>
+ </arg>
+
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
@@ -117,6 +127,8 @@ PostgreSQL documentation
<listitem>
<para>
Cluster <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be clustered by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml
index f4668e7..0d73294 100644
--- a/doc/src/sgml/ref/pg_restore.sgml
+++ b/doc/src/sgml/ref/pg_restore.sgml
@@ -400,7 +400,8 @@
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
- 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 <option>-t</> switches. This can be
combined with the <option>-n</option> option to specify a schema.
</para>
</listitem>
diff --git a/doc/src/sgml/ref/reindexdb.sgml b/doc/src/sgml/ref/reindexdb.sgml
index 781012f..3ba9951 100644
--- a/doc/src/sgml/ref/reindexdb.sgml
+++ b/doc/src/sgml/ref/reindexdb.sgml
@@ -23,20 +23,27 @@ PostgreSQL documentation
<cmdsynopsis>
<command>reindexdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
- <group choice="opt">
- <group choice="plain">
- <arg choice="plain"><option>--table</option></arg>
- <arg choice="plain"><option>-t</option></arg>
- </group>
- <replaceable>table</replaceable>
- </group>
- <group choice="opt">
- <group choice="plain">
- <arg choice="plain"><option>--index</option></arg>
- <arg choice="plain"><option>-i</option></arg>
- </group>
- <replaceable>index</replaceable>
- </group>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>--table</option></arg>
+ <arg choice="plain"><option>-t</option></arg>
+ </group>
+ <replaceable>table</replaceable>
+ </arg>
+ </arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>--index</option></arg>
+ <arg choice="plain"><option>-i</option></arg>
+ </group>
+ <replaceable>index</replaceable>
+ </arg>
+ </arg>
+
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
@@ -128,6 +135,8 @@ PostgreSQL documentation
<listitem>
<para>
Recreate <replaceable class="parameter">index</replaceable> only.
+ Multiple indexes can be recreated by writing multiple
+ <option>-i</> switches.
</para>
</listitem>
</varlistentry>
@@ -158,6 +167,8 @@ PostgreSQL documentation
<listitem>
<para>
Reindex <replaceable class="parameter">table</replaceable> only.
+ Multiple tables can be reindexed by writing multiple
+ <option>-t</> switches.
</para>
</listitem>
</varlistentry>
diff --git a/doc/src/sgml/ref/vacuumdb.sgml b/doc/src/sgml/ref/vacuumdb.sgml
index c60ba44..a5216ec 100644
--- a/doc/src/sgml/ref/vacuumdb.sgml
+++ b/doc/src/sgml/ref/vacuumdb.sgml
@@ -24,14 +24,18 @@ PostgreSQL documentation
<command>vacuumdb</command>
<arg rep="repeat"><replaceable>connection-option</replaceable></arg>
<arg rep="repeat"><replaceable>option</replaceable></arg>
- <arg choice="opt">
- <group choice="plain">
- <arg choice="plain"><option>--table</option></arg>
- <arg choice="plain"><option>-t</option></arg>
- </group>
- <replaceable>table</replaceable>
- <arg choice="opt">( <replaceable class="parameter">column</replaceable> [,...] )</arg>
+
+ <arg choice="plain" rep="repeat">
+ <arg choice="opt">
+ <group choice="plain">
+ <arg choice="plain"><option>--table</option></arg>
+ <arg choice="plain"><option>-t</option></arg>
+ </group>
+ <replaceable>table</replaceable>
+ <arg choice="opt">( <replaceable class="parameter">column</replaceable> [,...] )</arg>
+ </arg>
</arg>
+
<arg choice="opt"><replaceable>dbname</replaceable></arg>
</cmdsynopsis>
@@ -147,6 +151,8 @@ PostgreSQL documentation
Clean or analyze <replaceable class="parameter">table</replaceable> only.
Column names can be specified only in conjunction with
the <option>--analyze</option> or <option>--analyze-only</option> options.
+ Multiple tables can be vacuumed by writing multiple
+ <option>-t</> switches.
</para>
<tip>
<para>
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 611c8e3..88c07be 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -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;
-}
diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 91f2774..c0b10f0 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -17,7 +17,7 @@
#include <ctype.h>
#include "dumputils.h"
-
+#include "dumpmem.h"
#include "parser/keywords.h"
@@ -1349,3 +1349,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;
+}
diff --git a/src/bin/pg_dump/dumputils.h b/src/bin/pg_dump/dumputils.h
index 4ef8cb3..a300e7e 100644
--- a/src/bin/pg_dump/dumputils.h
+++ b/src/bin/pg_dump/dumputils.h
@@ -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 */
diff --git a/src/bin/pg_dump/pg_backup.h b/src/bin/pg_dump/pg_backup.h
index 3b49395..9972e68 100644
--- a/src/bin/pg_dump/pg_backup.h
+++ b/src/bin/pg_dump/pg_backup.h
@@ -26,7 +26,7 @@
#include "postgres_fe.h"
#include "pg_dump.h"
-
+#include "dumputils.h"
#include "libpq-fe.h"
@@ -125,9 +125,9 @@ typedef struct _restoreOptions
int selTable;
char *indexNames;
char *functionNames;
- char *tableNames;
char *schemaNames;
char *triggerNames;
+ SimpleStringList tableNames;
int useDB;
char *dbname;
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index 1fead28..a810efd 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -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)
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index 2100d43..0ab451a 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -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
@@ -532,9 +521,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);
diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c
index 49d799b..45b8b58 100644
--- a/src/bin/pg_dump/pg_restore.c
+++ b/src/bin/pg_dump/pg_restore.c
@@ -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"));
diff --git a/src/bin/scripts/Makefile b/src/bin/scripts/Makefile
index 0980b4c..d9ba29d 100644
--- a/src/bin/scripts/Makefile
+++ b/src/bin/scripts/Makefile
@@ -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/%
diff --git a/src/bin/scripts/clusterdb.c b/src/bin/scripts/clusterdb.c
index 261b438..4f163ee 100644
--- a/src/bin/scripts/clusterdb.c
+++ b/src/bin/scripts/clusterdb.c
@@ -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,20 @@ 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 +265,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"));
diff --git a/src/bin/scripts/reindexdb.c b/src/bin/scripts/reindexdb.c
index f61dada..6b1ca49 100644
--- a/src/bin/scripts/reindexdb.c
+++ b/src/bin/scripts/reindexdb.c
@@ -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,26 @@ 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 +343,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"));
diff --git a/src/bin/scripts/vacuumdb.c b/src/bin/scripts/vacuumdb.c
index eb28ad4..dc5fcaf 100644
--- a/src/bin/scripts/vacuumdb.c
+++ b/src/bin/scripts/vacuumdb.c
@@ -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,24 @@ 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 +363,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"));
On Fri, Dec 14, 2012 at 4:14 PM, Karl O. Pinc <kop@meme.com> wrote:
On 12/13/2012 11:02:56 PM, Josh Kupershmidt wrote:
On Thu, Dec 13, 2012 at 9:03 PM, Karl O. Pinc <kop@meme.com> wrote:
Sorry to be so persnickety, and unhelpful until now.
It seemed like it should be doable, but something
was going wrong between keyboard and chair. I guess
I should be doing this when better rested.No problem, here is v5 with changed synopses.
The clusterdb synopsis had tabs in it, which I understand
is frowned upon in the docs. I've fixed this.
It looks good to me, passes check and so forth.Attached is a v6 patch, with no tabs in docs and based
off the latest head.I'm marking it ready for committer.
Thanks. Applied, with only some small whitespace changes.
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers