diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/pg_dump/common.c | 144 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.c | 445 | ||||
-rw-r--r-- | src/bin/pg_dump/pg_dump.h | 41 |
3 files changed, 367 insertions, 263 deletions
diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c index f4b4a1e5bbb..44ccb2eab1f 100644 --- a/src/bin/pg_dump/common.c +++ b/src/bin/pg_dump/common.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.93 2006/09/27 15:41:23 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/common.c,v 1.94 2006/10/09 23:36:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -402,16 +402,14 @@ AssignDumpId(DumpableObject *dobj) { newAlloc = 256; dumpIdMap = (DumpableObject **) - malloc(newAlloc * sizeof(DumpableObject *)); + pg_malloc(newAlloc * sizeof(DumpableObject *)); } else { newAlloc = allocedDumpIds * 2; dumpIdMap = (DumpableObject **) - realloc(dumpIdMap, newAlloc * sizeof(DumpableObject *)); + pg_realloc(dumpIdMap, newAlloc * sizeof(DumpableObject *)); } - if (dumpIdMap == NULL) - exit_horribly(NULL, NULL, "out of memory\n"); memset(dumpIdMap + allocedDumpIds, 0, (newAlloc - allocedDumpIds) * sizeof(DumpableObject *)); allocedDumpIds = newAlloc; @@ -541,9 +539,7 @@ getDumpableObjects(DumpableObject ***objs, int *numObjs) j; *objs = (DumpableObject **) - malloc(allocedDumpIds * sizeof(DumpableObject *)); - if (*objs == NULL) - exit_horribly(NULL, NULL, "out of memory\n"); + pg_malloc(allocedDumpIds * sizeof(DumpableObject *)); j = 0; for (i = 1; i < allocedDumpIds; i++) { @@ -567,17 +563,15 @@ addObjectDependency(DumpableObject *dobj, DumpId refId) { dobj->allocDeps = 16; dobj->dependencies = (DumpId *) - malloc(dobj->allocDeps * sizeof(DumpId)); + pg_malloc(dobj->allocDeps * sizeof(DumpId)); } else { dobj->allocDeps *= 2; dobj->dependencies = (DumpId *) - realloc(dobj->dependencies, - dobj->allocDeps * sizeof(DumpId)); + pg_realloc(dobj->dependencies, + dobj->allocDeps * sizeof(DumpId)); } - if (dobj->dependencies == NULL) - exit_horribly(NULL, NULL, "out of memory\n"); } dobj->dependencies[dobj->nDeps++] = refId; } @@ -707,7 +701,8 @@ findParentsByOid(TableInfo *self, if (numParents > 0) { - self->parents = (TableInfo **) malloc(sizeof(TableInfo *) * numParents); + self->parents = (TableInfo **) + pg_malloc(sizeof(TableInfo *) * numParents); j = 0; for (i = 0; i < numInherits; i++) { @@ -806,3 +801,124 @@ strInArray(const char *pattern, char **arr, int arr_size) } return -1; } + + +/* + * Support for simple list operations + */ + +void +simple_oid_list_append(SimpleOidList *list, Oid val) +{ + SimpleOidListCell *cell; + + cell = (SimpleOidListCell *) pg_malloc(sizeof(SimpleOidListCell)); + cell->next = NULL; + cell->val = val; + + if (list->tail) + list->tail->next = cell; + else + list->head = cell; + 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) +{ + SimpleOidListCell *cell; + + for (cell = list->head; cell; cell = cell->next) + { + if (cell->val == val) + return true; + } + 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; +} + + +/* + * Safer versions of some standard C library functions. If an + * out-of-memory condition occurs, these functions will bail out + * safely; therefore, their return value is guaranteed to be non-NULL. + * + * XXX need to refactor things so that these can be in a file that can be + * shared by pg_dumpall and pg_restore as well as pg_dump. + */ + +char * +pg_strdup(const char *string) +{ + char *tmp; + + if (!string) + exit_horribly(NULL, NULL, "cannot duplicate null pointer\n"); + tmp = strdup(string); + if (!tmp) + exit_horribly(NULL, NULL, "out of memory\n"); + return tmp; +} + +void * +pg_malloc(size_t size) +{ + void *tmp; + + tmp = malloc(size); + if (!tmp) + exit_horribly(NULL, NULL, "out of memory\n"); + return tmp; +} + +void * +pg_calloc(size_t nmemb, size_t size) +{ + void *tmp; + + tmp = calloc(nmemb, size); + if (!tmp) + exit_horribly(NULL, NULL, "out of memory\n"); + return tmp; +} + +void * +pg_realloc(void *ptr, size_t size) +{ + void *tmp; + + tmp = realloc(ptr, size); + if (!tmp) + exit_horribly(NULL, NULL, "out of memory\n"); + return tmp; +} diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 5cf0b76b50f..c4df03083e1 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -12,7 +12,7 @@ * by PostgreSQL * * IDENTIFICATION - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.452 2006/10/07 20:59:04 petere Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.453 2006/10/09 23:36:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -40,8 +40,6 @@ int optreset; #endif - - #include "access/htup.h" #include "catalog/pg_class.h" #include "catalog/pg_proc.h" @@ -87,20 +85,24 @@ static const char *username_subquery; /* obsolete as of 7.3: */ static Oid g_last_builtin_oid; /* value of the last builtin oid */ -/* select and exclude tables and schemas */ -typedef struct objnameArg -{ - struct objnameArg *next; - char *name; /* name of the relation */ - bool is_include; /* include/exclude? */ -} objnameArg; +/* + * Object inclusion/exclusion lists + * + * The string lists record the patterns given by command-line switches, + * which we then convert to lists of OIDs of matching objects. + */ +static SimpleStringList schema_include_patterns = { NULL, NULL }; +static SimpleOidList schema_include_oids = { NULL, NULL }; +static SimpleStringList schema_exclude_patterns = { NULL, NULL }; +static SimpleOidList schema_exclude_oids = { NULL, NULL }; -objnameArg *schemaList = NULL; /* List of schemas to include/exclude */ -objnameArg *tableList = NULL; /* List of tables to include/exclude */ +static SimpleStringList table_include_patterns = { NULL, NULL }; +static SimpleOidList table_include_oids = { NULL, NULL }; +static SimpleStringList table_exclude_patterns = { NULL, NULL }; +static SimpleOidList table_exclude_oids = { NULL, NULL }; -char *matchingSchemas = NULL; /* Final list of schemas to dump by - * oid */ -char *matchingTables = NULL; /* Final list of tables to dump by oid */ +/* default, if no "inclusion" switches appear, is to dump everything */ +static bool include_everything = true; char g_opaque_type[10]; /* name for the opaque type */ @@ -119,6 +121,10 @@ static int disable_dollar_quoting = 0; static void help(const char *progname); +static void expand_schema_name_patterns(SimpleStringList *patterns, + SimpleOidList *oids); +static void expand_table_name_patterns(SimpleStringList *patterns, + SimpleOidList *oids); static NamespaceInfo *findNamespace(Oid nsoid, Oid objoid); static void dumpTableData(Archive *fout, TableDataInfo *tdinfo); static void dumpComment(Archive *fout, const char *target, @@ -188,11 +194,6 @@ static void check_sql_result(PGresult *res, PGconn *conn, const char *query, int main(int argc, char **argv) { - PQExpBuffer query = createPQExpBuffer(); - PGresult *res; - objnameArg *this_obj_name, - *schemaList_tail = NULL, - *tableList_tail = NULL; int c; const char *filename = NULL; const char *format = "p"; @@ -208,14 +209,13 @@ main(int argc, char **argv) DumpableObject **dobjs; int numObjs; int i; - bool switch_include_exclude; bool force_password = false; int compressLevel = -1; bool ignore_version = false; int plainText = 0; int outputClean = 0; int outputCreate = 0; - bool outputBlobs = true; + bool outputBlobs = false; int outputNoOwner = 0; static int use_setsessauth = 0; static int disable_triggers = 0; @@ -306,7 +306,7 @@ main(int argc, char **argv) break; case 'b': /* Dump blobs */ - /* this is now default, so just ignore the switch */ + outputBlobs = true; break; case 'c': /* clean (i.e., drop) schema prior to create */ @@ -347,42 +347,13 @@ main(int argc, char **argv) ignore_version = true; break; - case 'n': /* Include schemas */ - case 'N': /* Exclude schemas */ - case 't': /* Include tables */ - case 'T': /* Exclude tables */ - - if (strlen(optarg) < 1) - { - fprintf(stderr, _("%s: invalid -%c option\n"), progname, c); - exit(1); - } - - { - /* Create a struct for this name */ - objnameArg *new_obj_name = (objnameArg *) - malloc(sizeof(objnameArg)); - - new_obj_name->next = NULL; - new_obj_name->name = strdup(optarg); - new_obj_name->is_include = islower((unsigned char) c) ? true : false; + case 'n': /* include schema(s) */ + simple_string_list_append(&schema_include_patterns, optarg); + include_everything = false; + break; - /* add new entry to the proper list */ - if (tolower((unsigned char) c) == 'n') - { - if (!schemaList_tail) - schemaList_tail = schemaList = new_obj_name; - else - schemaList_tail = schemaList_tail->next = new_obj_name; - } - else - { - if (!tableList_tail) - tableList_tail = tableList = new_obj_name; - else - tableList_tail = tableList_tail->next = new_obj_name; - } - } + case 'N': /* exclude schema(s) */ + simple_string_list_append(&schema_exclude_patterns, optarg); break; case 'o': /* Dump oids */ @@ -403,13 +374,21 @@ main(int argc, char **argv) case 's': /* dump schema only */ schemaOnly = true; - outputBlobs = false; break; case 'S': /* Username for superuser in plain text output */ outputSuperuser = strdup(optarg); break; + case 't': /* include table(s) */ + simple_string_list_append(&table_include_patterns, optarg); + include_everything = false; + break; + + case 'T': /* exclude table(s) */ + simple_string_list_append(&table_exclude_patterns, optarg); + break; + case 'u': force_password = true; username = simple_prompt("User name: ", 100, true); @@ -488,9 +467,6 @@ main(int argc, char **argv) exit(1); } - if (matchingTables != NULL || matchingSchemas != NULL) - outputBlobs = false; - if (dumpInserts == true && oids == true) { write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together\n"); @@ -607,162 +583,42 @@ main(int argc, char **argv) write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid); } - - if (schemaList != NULL && g_fout->remoteVersion < 70300) + /* Expand schema selection patterns into OID lists */ + if (schema_include_patterns.head != NULL) { - write_msg(NULL, "server version must be at least 7.3 to use schema switches\n"); - exit_nicely(); - } - - /* Check schema selection flags */ - resetPQExpBuffer(query); - switch_include_exclude = true; - - for (this_obj_name = schemaList; this_obj_name; this_obj_name = this_obj_name->next) - { - if (switch_include_exclude) - { - /* Special case for when -N is the first argument */ - if (this_obj_name == schemaList && !this_obj_name->is_include) - appendPQExpBuffer(query, - "SELECT oid FROM pg_catalog.pg_namespace " - "WHERE nspname NOT LIKE 'pg_%%' AND " - " nspname != 'information_schema' EXCEPT\n"); - - appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_namespace WHERE"); - } - - appendPQExpBuffer(query, "%s nspname %c ", switch_include_exclude ? "" : " OR", - /* any meta-characters? */ - strpbrk(this_obj_name->name, "([{\\.?+") == NULL ? '=' : '~'); - appendStringLiteralAH(query, this_obj_name->name, g_fout); - - if (this_obj_name->next && this_obj_name->next->is_include == this_obj_name->is_include) - switch_include_exclude = false; - else - { - switch_include_exclude = true; - - /* Add the joiner if needed */ - if (this_obj_name->next) - appendPQExpBuffer(query, "\n%s\n", - this_obj_name->next->is_include ? "UNION" : "EXCEPT"); - } - } - - /* Construct OID list of matching schemas */ - if (schemaList) - { - int len; - - res = PQexec(g_conn, query->data); - check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); - if (PQntuples(res) == 0) + expand_schema_name_patterns(&schema_include_patterns, + &schema_include_oids); + if (schema_include_oids.head == NULL) { write_msg(NULL, "No matching schemas were found\n"); exit_nicely(); } - - for (i = 0, len = strlen(" "); i < PQntuples(res); i++) - len += strlen(PQgetvalue(res, i, 0)) + 1; - - /* - * Need to use comma separators so it can be used by IN. zero is a - * dummy placeholder. Format is " oid oid oid ". - */ - matchingSchemas = malloc(len + 1); - strcpy(matchingSchemas, " "); - for (i = 0; i < PQntuples(res); i++) - { - strcat(matchingSchemas, PQgetvalue(res, i, 0)); - strcat(matchingSchemas, " "); - } } + expand_schema_name_patterns(&schema_exclude_patterns, + &schema_exclude_oids); + /* non-matching exclusion patterns aren't an error */ - /* Check table selection flags */ - resetPQExpBuffer(query); - switch_include_exclude = true; - - for (this_obj_name = tableList; this_obj_name; this_obj_name = this_obj_name->next) + /* Expand table selection patterns into OID lists */ + if (table_include_patterns.head != NULL) { - if (switch_include_exclude) - { - /* Special case for when -T is the first argument */ - if (this_obj_name == tableList && !this_obj_name->is_include && !strlen(query->data)) - appendPQExpBuffer(query, - "SELECT pg_class.oid FROM pg_catalog.pg_class, pg_catalog.pg_namespace " - "WHERE relkind='r' AND " - " relnamespace = pg_namespace.oid AND " - " nspname NOT LIKE 'pg_%%' AND " - " nspname != 'information_schema' EXCEPT\n"); - - appendPQExpBuffer(query, "SELECT oid FROM pg_catalog.pg_class WHERE relkind='r' AND ("); - } - - appendPQExpBuffer(query, "%srelname %c ", switch_include_exclude ? "" : " OR ", - /* any meta-characters? */ - strpbrk(this_obj_name->name, "([{\\.?+") == NULL ? '=' : '~'); - appendStringLiteralAH(query, this_obj_name->name, g_fout); - - if (this_obj_name->next && this_obj_name->next->is_include == this_obj_name->is_include) - switch_include_exclude = false; - else - { - switch_include_exclude = true; - appendPQExpBuffer(query, ")"); - - /* Add the joiner if needed */ - if (this_obj_name->next) - appendPQExpBuffer(query, "\n%s\n", this_obj_name->next->is_include ? - "UNION" : "EXCEPT"); - } - } - - /* Construct OID list of matching tables */ - if (tableList) - { - int len; - - /* Restrict by schema? */ - if (matchingSchemas != NULL) - { - char *matchingSchemas_commas = strdup(matchingSchemas), - *p; - - /* Construct "IN" SQL string by adding commas, " oid, oid, oid " */ - for (p = matchingSchemas_commas; *p; p++) - { - /* No commas for first/last characters */ - if (*p == ' ' && p != matchingSchemas_commas && *(p + 1)) - *p = ','; - } - - appendPQExpBuffer(query, - "\nINTERSECT\nSELECT oid FROM pg_catalog.pg_class WHERE relkind='r' AND relnamespace IN (%s)\n", - matchingSchemas_commas); - } - - res = PQexec(g_conn, query->data); - check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); - if (PQntuples(res) == 0) + expand_table_name_patterns(&table_include_patterns, + &table_include_oids); + if (table_include_oids.head == NULL) { write_msg(NULL, "No matching tables were found\n"); exit_nicely(); } - - for (i = 0, len = strlen(" "); i < PQntuples(res); i++) - len += strlen(PQgetvalue(res, i, 0)) + 1; - - matchingTables = malloc(len + 1); - strcpy(matchingTables, " "); - for (i = 0; i < PQntuples(res); i++) - { - strcat(matchingTables, PQgetvalue(res, i, 0)); - strcat(matchingTables, " "); - } } + expand_table_name_patterns(&table_exclude_patterns, + &table_exclude_oids); + /* non-matching exclusion patterns aren't an error */ - destroyPQExpBuffer(query); + /* + * Dumping blobs is now default unless we saw an inclusion switch or -s + * ... but even if we did see one of these, -b turns it back on. + */ + if (include_everything && !schemaOnly) + outputBlobs = true; /* * Now scan the database and create DumpableObject structs for all the @@ -824,7 +680,7 @@ main(int argc, char **argv) dumpStdStrings(g_fout); /* The database item is always next, unless we don't want it at all */ - if (!dataOnly && matchingTables == NULL && matchingSchemas == NULL) + if (include_everything && !dataOnly) dumpDatabase(g_fout); /* Now the rearrangeable objects. */ @@ -884,28 +740,28 @@ help(const char *progname) printf(_("\nOptions controlling the output content:\n")); printf(_(" -a, --data-only dump only the data, not the schema\n")); + printf(_(" -b, --blobs include large objects in dump\n")); printf(_(" -c, --clean clean (drop) schema prior to create\n")); printf(_(" -C, --create include commands to create database in dump\n")); printf(_(" -d, --inserts dump data as INSERT commands, rather than COPY\n")); printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n")); printf(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n")); - printf(_(" -n, --schema=SCHEMA dump the named schema only\n")); - printf(_(" -N, --exclude-schema=SCHEMA\n" - " do NOT dump the named schema\n")); + printf(_(" -n, --schema=SCHEMA dump the named schema(s) only\n")); + printf(_(" -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n")); printf(_(" -o, --oids include OIDs in dump\n")); printf(_(" -O, --no-owner skip restoration of object ownership\n" " in plain text format\n")); 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, --exclude-table=TABLE do NOT dump the named table\n")); + printf(_(" -t, --table=TABLE dump the named table(s) only\n")); + printf(_(" -T, --exclude-table=TABLE do NOT dump the named table(s)\n")); printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n")); printf(_(" --disable-triggers disable triggers during data-only restore\n")); printf(_(" --use-set-session-authorization\n" " use SESSION AUTHORIZATION commands instead of\n" - " OWNER TO commands\n")); + " ALTER OWNER commands to set ownership\n")); printf(_("\nConnection options:\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); @@ -928,66 +784,159 @@ exit_nicely(void) } /* - * selectDumpableNamespace: policy-setting subroutine - * Mark a namespace as to be dumped or not + * Find the OIDs of all schemas matching the given list of patterns, + * and append them to the given OID list. */ static void -selectDumpableNamespace(NamespaceInfo *nsinfo) +expand_schema_name_patterns(SimpleStringList *patterns, SimpleOidList *oids) { + PQExpBuffer query; + PGresult *res; + SimpleStringListCell *cell; + int i; + + if (patterns->head == NULL) + return; /* nothing to do */ + + if (g_fout->remoteVersion < 70300) + { + write_msg(NULL, "server version must be at least 7.3 to use schema selection switches\n"); + exit_nicely(); + } + + query = createPQExpBuffer(); + /* - * If specific tables are being dumped, do not dump any complete - * namespaces. If specific namespaces are being dumped, dump just those - * namespaces. Otherwise, dump all non-system namespaces. + * We use UNION ALL rather than UNION; this might sometimes result in + * duplicate entries in the OID list, but we don't care. */ - nsinfo->dobj.dump = false; - if (matchingTables != NULL) - /* false */ ; - else if (matchingSchemas != NULL) + for (cell = patterns->head; cell; cell = cell->next) { - char *search_oid = malloc(20); + if (cell != patterns->head) + appendPQExpBuffer(query, "UNION ALL\n"); + appendPQExpBuffer(query, + "SELECT oid FROM pg_catalog.pg_namespace n\n"); + processSQLNamePattern(g_conn, query, cell->val, false, false, + NULL, "n.nspname", NULL, + NULL); + } - sprintf(search_oid, " %d ", nsinfo->dobj.catId.oid); - if (strstr(matchingSchemas, search_oid) != NULL) - nsinfo->dobj.dump = true; + res = PQexec(g_conn, query->data); + check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); - free(search_oid); + for (i = 0; i < PQntuples(res); i++) + { + simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); } - /* The server prevents users from creating pg_ schemas */ - else if (strncmp(nsinfo->dobj.name, "pg_", 3) != 0 && - strcmp(nsinfo->dobj.name, "information_schema") != 0) - nsinfo->dobj.dump = true; + + PQclear(res); + destroyPQExpBuffer(query); } /* - * selectDumpableTable: policy-setting subroutine - * Mark a table as to be dumped or not + * Find the OIDs of all tables matching the given list of patterns, + * and append them to the given OID list. */ static void -selectDumpableTable(TableInfo *tbinfo) +expand_table_name_patterns(SimpleStringList *patterns, SimpleOidList *oids) { + PQExpBuffer query; + PGresult *res; + SimpleStringListCell *cell; + int i; + + if (patterns->head == NULL) + return; /* nothing to do */ + + query = createPQExpBuffer(); + /* - * Always dump if dumping parent namespace; else, if a particular - * tablename has been specified, dump matching table name; else, do not - * dump. + * We use UNION ALL rather than UNION; this might sometimes result in + * duplicate entries in the OID list, but we don't care. */ - tbinfo->dobj.dump = false; - if (matchingTables == NULL) + for (cell = patterns->head; cell; cell = cell->next) { - if (tbinfo->dobj.namespace->dobj.dump) - tbinfo->dobj.dump = true; + if (cell != patterns->head) + appendPQExpBuffer(query, "UNION ALL\n"); + appendPQExpBuffer(query, + "SELECT c.oid" + "\nFROM pg_catalog.pg_class c" + "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace" + "\nWHERE c.relkind in ('%c', '%c', '%c')\n", + RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW); + processSQLNamePattern(g_conn, query, cell->val, true, false, + "n.nspname", "c.relname", NULL, + "pg_catalog.pg_table_is_visible(c.oid)"); } - else - { - char *search_oid = malloc(20); - sprintf(search_oid, " %d ", tbinfo->dobj.catId.oid); - if (strstr(matchingTables, search_oid) != NULL) - tbinfo->dobj.dump = true; + res = PQexec(g_conn, query->data); + check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK); - free(search_oid); + for (i = 0; i < PQntuples(res); i++) + { + simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0))); } + + PQclear(res); + destroyPQExpBuffer(query); +} + +/* + * selectDumpableNamespace: policy-setting subroutine + * Mark a namespace as to be dumped or not + */ +static void +selectDumpableNamespace(NamespaceInfo *nsinfo) +{ + /* + * If specific tables are being dumped, do not dump any complete + * namespaces. If specific namespaces are being dumped, dump just those + * namespaces. Otherwise, dump all non-system namespaces. + */ + if (table_include_oids.head != NULL) + nsinfo->dobj.dump = false; + else if (schema_include_oids.head != NULL) + nsinfo->dobj.dump = simple_oid_list_member(&schema_include_oids, + nsinfo->dobj.catId.oid); + else if (strncmp(nsinfo->dobj.name, "pg_", 3) == 0 || + strcmp(nsinfo->dobj.name, "information_schema") == 0) + nsinfo->dobj.dump = false; + else + nsinfo->dobj.dump = true; + /* + * In any case, a namespace can be excluded by an exclusion switch + */ + if (nsinfo->dobj.dump && + simple_oid_list_member(&schema_exclude_oids, + nsinfo->dobj.catId.oid)) + nsinfo->dobj.dump = false; +} + +/* + * selectDumpableTable: policy-setting subroutine + * Mark a table as to be dumped or not + */ +static void +selectDumpableTable(TableInfo *tbinfo) +{ + /* + * If specific tables are being dumped, dump just those tables; + * else, dump according to the parent namespace's dump flag. + */ + if (table_include_oids.head != NULL) + tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids, + tbinfo->dobj.catId.oid); + else + tbinfo->dobj.dump = tbinfo->dobj.namespace->dobj.dump; + /* + * In any case, a table can be excluded by an exclusion switch + */ + if (tbinfo->dobj.dump && + simple_oid_list_member(&table_exclude_oids, + tbinfo->dobj.catId.oid)) + tbinfo->dobj.dump = false; } /* @@ -5596,7 +5545,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo) static bool shouldDumpProcLangs(void) { - if (matchingTables != NULL || matchingSchemas != NULL) + if (!include_everything) return false; /* And they're schema not data */ if (dataOnly) diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h index 65f5e84c416..dad62f96065 100644 --- a/src/bin/pg_dump/pg_dump.h +++ b/src/bin/pg_dump/pg_dump.h @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.129 2006/08/21 00:57:25 tgl Exp $ + * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.h,v 1.130 2006/10/09 23:36:59 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -41,6 +41,35 @@ typedef struct typedef int DumpId; +/* + * Data structures for simple lists of OIDs and strings. The support for + * these is very primitive compared to the backend's List facilities, but + * it's all we need in pg_dump. + */ + +typedef struct SimpleOidListCell +{ + struct SimpleOidListCell *next; + Oid val; +} SimpleOidListCell; + +typedef struct SimpleOidList +{ + SimpleOidListCell *head; + 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 @@ -364,6 +393,16 @@ extern TypeInfo *findTypeByOid(Oid oid); extern FuncInfo *findFuncByOid(Oid oid); extern OprInfo *findOprByOid(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 char *pg_strdup(const char *string); +extern void *pg_malloc(size_t size); +extern void *pg_calloc(size_t nmemb, size_t size); +extern void *pg_realloc(void *ptr, size_t size); + extern void check_conn_and_db(void); extern void exit_nicely(void); |