diff -u -r -N postgresql-7.4.3.ORIG/src/bin/pg_dump/Makefile postgresql-7.4.3/src/bin/pg_dump/Makefile --- postgresql-7.4.3.ORIG/src/bin/pg_dump/Makefile 2003-08-08 00:52:21.000000000 -0400 +++ postgresql-7.4.3/src/bin/pg_dump/Makefile 2004-07-06 21:58:02.000000000 -0400 @@ -15,7 +15,7 @@ OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \ pg_backup_files.o pg_backup_null.o pg_backup_tar.o \ - dumputils.o + dumputils.o should_dump.o EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o diff -u -r -N postgresql-7.4.3.ORIG/src/bin/pg_dump/pg_dump.c postgresql-7.4.3/src/bin/pg_dump/pg_dump.c --- postgresql-7.4.3.ORIG/src/bin/pg_dump/pg_dump.c 2004-05-26 14:27:23.000000000 -0400 +++ postgresql-7.4.3/src/bin/pg_dump/pg_dump.c 2004-07-06 21:58:02.000000000 -0400 @@ -139,7 +139,7 @@ /* obsolete as of 7.3: */ static Oid g_last_builtin_oid; /* value of the last builtin oid */ -static char *selectTableName = NULL; /* name of a single table to dump */ +static int partial_dump = 0; /* True if -t or -T is used */ static char *selectSchemaName = NULL; /* name of a single schema to dump */ char g_opaque_type[10]; /* name for the opaque type */ @@ -201,6 +201,7 @@ {"schema-only", no_argument, NULL, 's'}, {"superuser", required_argument, NULL, 'S'}, {"table", required_argument, NULL, 't'}, + {"exclude-table", required_argument, NULL, 'T'}, {"password", no_argument, NULL, 'W'}, {"username", required_argument, NULL, 'U'}, {"verbose", no_argument, NULL, 'v'}, @@ -258,7 +259,7 @@ } } - while ((c = getopt_long(argc, argv, "abcCdDf:F:h:in:oOp:RsS:t:uU:vWxX:Z:", + while ((c = getopt_long(argc, argv, "abcCdDf:F:h:in:oOp:RsS:t:T:uU:vWxX:Z:", long_options, &optindex)) != -1) { switch (c) @@ -335,8 +336,14 @@ outputSuperuser = strdup(optarg); break; - case 't': /* Dump data for this table only */ - selectTableName = strdup(optarg); + case 't': /* Dump data for this table */ + add_table_to_include_list(optarg); + partial_dump = 1; + break; + + case 'T': /* Do NOT dump data for this table */ + add_table_to_exclude_list(optarg); + partial_dump = 1; break; case 'u': @@ -421,9 +428,9 @@ exit(1); } - if (outputBlobs && selectTableName != NULL) + if (outputBlobs && partial_dump) { - write_msg(NULL, "large-object output not supported for a single table\n"); + write_msg(NULL, "large-object output not supported for a partial dump\n"); write_msg(NULL, "use a full dump instead\n"); exit(1); } @@ -639,7 +646,8 @@ printf(_(" -s, --schema-only dump only the schema, no data\n")); printf(_(" -S, --superuser=NAME specify the superuser user name to use in\n" " plain text format\n")); - printf(_(" -t, --table=TABLE dump the named table only\n")); + printf(_(" -t, --table=TABLE dump the named table only (multiple -t allowed)\n")); + printf(_(" -T, --exclude-table=TABLE do not dump the named table (multiple -T allowed)\n")); printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); printf(_(" -X disable-triggers, --disable-triggers\n" " disable triggers during data-only restore\n")); @@ -672,11 +680,11 @@ selectDumpableNamespace(NamespaceInfo *nsinfo) { /* - * If a specific table is being dumped, do not dump any complete + * If a specific table or tables are being dumped, do not dump any complete * namespaces. If a specific namespace is being dumped, dump just * that namespace. Otherwise, dump all non-system namespaces. */ - if (selectTableName != NULL) + if (partial_dump) nsinfo->dump = false; else if (selectSchemaName != NULL) { @@ -707,8 +715,7 @@ tbinfo->dump = false; if (tbinfo->relnamespace->dump) tbinfo->dump = true; - else if (selectTableName != NULL && - strcmp(tbinfo->relname, selectTableName) == 0) + else if (should_dump_table(tbinfo->relname)) { /* If both -s and -t specified, must match both to dump */ if (selectSchemaName == NULL) @@ -2317,7 +2324,10 @@ * If the user is attempting to dump a specific table, check to ensure * that the specified table actually exists. (This is a bit simplistic * since we don't fully check the combination of -n and -t switches.) + * + * This check is DISABLED with support for multiple -t swictches --dfs */ +#if 0 if (selectTableName) { for (i = 0; i < ntups; i++) @@ -2332,6 +2342,7 @@ exit_nicely(); } } +#endif PQclear(res); destroyPQExpBuffer(query); diff -u -r -N postgresql-7.4.3.ORIG/src/bin/pg_dump/pg_dump.h postgresql-7.4.3/src/bin/pg_dump/pg_dump.h --- postgresql-7.4.3.ORIG/src/bin/pg_dump/pg_dump.h 2003-08-08 00:52:21.000000000 -0400 +++ postgresql-7.4.3/src/bin/pg_dump/pg_dump.h 2004-07-06 21:58:02.000000000 -0400 @@ -235,4 +235,9 @@ const bool schemaOnly, const bool dataOnly); extern void dumpIndexes(Archive *fout, TableInfo *tbinfo, int numTables); +/* Defined in should_dump.c */ +extern int add_table_to_exclude_list(char const *name); +extern int add_table_to_include_list(char const *name); +extern int should_dump_table(char const *name); + #endif /* PG_DUMP_H */ diff -u -r -N postgresql-7.4.3.ORIG/src/bin/pg_dump/should_dump.c postgresql-7.4.3/src/bin/pg_dump/should_dump.c --- postgresql-7.4.3.ORIG/src/bin/pg_dump/should_dump.c 1969-12-31 19:00:00.000000000 -0500 +++ postgresql-7.4.3/src/bin/pg_dump/should_dump.c 2004-07-06 21:58:02.000000000 -0400 @@ -0,0 +1,73 @@ +#include "pg_dump.h" +#include +#include + +/* Routines for keeping track of which tables should be dumped, so + pg_dump can take multiple "-t" options + + Copyright 2004 Roaring Penguin Software Inc. + + This file may be distributed under the same terms as the PostgreSQL + database system */ + +typedef struct name_list_t { + struct name_list_t *next; + char const *name; +} name_list; + +static name_list *tables_to_include = NULL; +static name_list *tables_to_exclude = NULL; + +/* Add a name to one of the lists */ +static int +add_name_to_list(name_list **list, char const *name) +{ + name_list *node = malloc(sizeof(name_list)); + if (!node) return -1; + node->name = strdup(name); + if (!node->name) { + free(node); + return -1; + } + node->next = *list; + *list = node; + return 0; +} + +/* Return true if a node is on a list, false otherwise */ +static int +name_is_on_list(name_list *list, char const *name) +{ + while(list) { + if (!strcmp(name, list->name)) { + return 1; + } + list = list->next; + } + return 0; +} + +/* Add a table to the exclude list */ +int +add_table_to_exclude_list(char const *name) { + return add_name_to_list(&tables_to_exclude, name); +} + +/* Add a table to the include list */ +int +add_table_to_include_list(char const *name) { + return add_name_to_list(&tables_to_include, name); +} + +/* Should we dump a table? */ +int +should_dump_table(char const *name) +{ + if (tables_to_exclude && name_is_on_list(tables_to_exclude, name)) { + return 0; + } + if (tables_to_include && !name_is_on_list(tables_to_include, name)) { + return 0; + } + return 1; +}