<!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.55 2003/01/19 00:13:30 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.56 2003/02/13 04:54:15 momjian Exp $
PostgreSQL documentation
-->
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>-n <replaceable class="parameter">namespace</replaceable></option></term>
+ <term><option>--schema=<replaceable class="parameter">schema</replaceable></option></term>
+ <listitem>
+ <para>
+ Dump the contents of <replaceable class="parameter">schema</>
+ only. If this option is not specified, all non-system schemas
+ in the target database will be dumped.
+ </para>
+
+ <note>
+ <para>
+ In this mode, <application>pg_dump</application> makes no
+ attempt to dump any other database objects that may depend
+ upon objects in the selected schema. Therefore, there is no
+ guarantee that the results of a single schema dump can be
+ successfully restored by themselves into a clean database.
+ </para>
+ </note>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>-o</></term>
<term><option>--oids</></term>
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem>
<para>
- Dump data for <replaceable class="parameter">table</replaceable> only.
- </para>
+ Dump data for <replaceable class="parameter">table</replaceable>
+ only. If <literal>*</literal> is specified, all tables in the
+ specified database will be dumped. It is possible for there to be
+ multiple tables with the same name in different schemas; if that
+ is the case, all matching tables will be dumped.
+ </para>
+
+ <note>
+ <para>
+ In this mode, <application>pg_dump</application> makes no
+ attempt to dump any other database objects that may depend
+ upon the selected table. Therefore, there is no guarantee
+ that the results of a single table dump can be successfully
+ restored by themselves into a clean database.
+ </para>
+ </note>
</listitem>
</varlistentry>
<term><option>--host=<replaceable class="parameter">host</replaceable></option></term>
<listitem>
<para>
- Specifies the host name of the machine on which the
- server
- is running. If host begins with a slash, it is used
- as the directory for the Unix domain socket.
+ Specifies the host name of the machine on which the server is
+ running. If the host name begins with a slash, it is used as the
+ directory for the Unix domain socket.
</para>
</listitem>
</varlistentry>
<listitem>
<para>
- Default connection parameters
+ Default connection parameters.
</para>
</listitem>
</varlistentry>
<msgexplan>
<para>
- <application>pg_dump</application> could not attach to the
- PostgreSQL server on the specified host and port. If you see this message,
- ensure that the server
- is running on the proper host and that you have specified the proper
- port.
+ <application>pg_dump</application> could not connect to the
+ PostgreSQL server on the specified host and port. If you see this
+ message, ensure that the server is running on the proper host and
+ that you have specified the proper port.
</para>
</msgexplan>
</msgentry>
<listitem>
<para>
- When doing a data only dump, <application>pg_dump</application> emits queries
+ When doing a data-only dump, <application>pg_dump</application> emits queries
to disable triggers on user tables before inserting the data and queries to
re-enable them after the data has been inserted. If the restore is stopped
in the middle, the system catalogs may be left in the wrong state.
* by PostgreSQL
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.316 2003/02/11 21:06:58 petere Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.317 2003/02/13 04:54:16 momjian Exp $
*
*-------------------------------------------------------------------------
*/
} DumpContext;
static void help(const char *progname);
+static void formatIdentifierArg(char *identifier);
static NamespaceInfo *findNamespace(const char *nsoid, const char *objoid);
static void dumpClasses(const TableInfo *tblinfo, const int numTables,
Archive *fout, const bool oids);
/* 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 char *selectTableName = NULL; /* name of a single table to dump */
+static char *selectSchemaName = NULL; /* name of a single schema to dump */
char g_opaque_type[10]; /* name for the opaque type */
{"oids", no_argument, NULL, 'o'},
{"no-owner", no_argument, NULL, 'O'},
{"port", required_argument, NULL, 'p'},
+ {"schema", required_argument, NULL, 'n'},
{"schema-only", no_argument, NULL, 's'},
{"superuser", required_argument, NULL, 'S'},
{"table", required_argument, NULL, 't'},
}
}
- while ((c = getopt_long(argc, argv, "abcCdDf:F:h:ioOp:RsS:t:uU:vWxX:Z:",
+ while ((c = getopt_long(argc, argv, "abcCdDf:F:h:in:oOp:RsS:t:uU:vWxX:Z:",
long_options, &optindex)) != -1)
{
switch (c)
ignore_version = true;
break;
+ case 'n': /* Dump data for this schema only */
+ selectSchemaName = strdup(optarg);
+ formatIdentifierArg(selectSchemaName);
+ break;
+
case 'o': /* Dump oids */
oids = true;
break;
break;
case 't': /* Dump data for this table only */
- {
- int i;
-
- selectTablename = strdup(optarg);
+ selectTableName = strdup(optarg);
- /*
- * quoted string? Then strip quotes and preserve
- * case...
- */
- if (selectTablename[0] == '"')
- {
- char *endptr;
+ /*
+ * '*' is a special case meaning ALL tables, but
+ * only if unquoted
+ */
+ if (selectTableName[0] != '"' &&
+ strcmp(selectTableName, "*") == 0)
+ selectTableName[0] = '\0';
+ else
+ formatIdentifierArg(selectTableName);
- endptr = selectTablename + strlen(selectTablename) - 1;
- if (*endptr == '"')
- *endptr = '\0';
- strcpy(selectTablename, &selectTablename[1]);
- }
- else
- {
- /* otherwise, convert table name to lowercase... */
- for (i = 0; selectTablename[i]; i++)
- if (isupper((unsigned char) selectTablename[i]))
- selectTablename[i] = tolower((unsigned char) selectTablename[i]);
-
- /*
- * '*' is a special case meaning ALL tables, but
- * only if unquoted
- */
- if (strcmp(selectTablename, "*") == 0)
- selectTablename[0] = '\0';
- }
- }
break;
case 'u':
exit(1);
}
- if (outputBlobs && selectTablename != NULL && strlen(selectTablename) > 0)
+ if (outputBlobs && selectTableName != NULL && strlen(selectTableName) > 0)
{
write_msg(NULL, "Large object output is not supported for a single table.\n");
write_msg(NULL, "Use all tables or a full dump instead.\n");
exit(1);
}
+ if (outputBlobs && selectSchemaName != NULL)
+ {
+ write_msg(NULL, "Large object output is not supported for a single schema.\n");
+ write_msg(NULL, "Use a full dump instead.\n");
+ exit(1);
+ }
+
+ if (selectTableName != NULL && selectSchemaName != NULL)
+ {
+ write_msg(NULL, "Single table and single schema dumps cannot be used simultaneously.\n");
+ write_msg(NULL, "Use one option or the other, not both.\n");
+ exit(1);
+ }
+
if (dumpData == true && oids == true)
{
write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together.\n");
/* open the output file */
switch (format[0])
{
-
case 'c':
case 'C':
g_fout = CreateArchive(filename, archCustom, compressLevel);
* Open the database using the Archiver, so it knows about it. Errors
* mean death.
*/
- g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport, username, force_password, ignore_version);
+ g_conn = ConnectDatabase(g_fout, dbname, pghost, pgport,
+ username, force_password, ignore_version);
/*
* Start serializable transaction to dump consistent data.
printf(_(" -C, --create include commands to create database in dump\n"));
printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n"));
printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n"));
+ printf(_(" -n, --schema=SCHEMA dump this schema only\n"));
printf(_(" -o, --oids include OIDs in dump\n"));
printf(_(" -O, --no-owner do not output \\connect commands in plain\n"
" text format\n"));
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
}
+/*
+ * Accepts an identifier as specified as a command-line argument, and
+ * converts it into a form acceptable to the PostgreSQL backend. The
+ * input string is modified in-place.
+ */
+static void
+formatIdentifierArg(char *identifier)
+{
+ /*
+ * quoted string? Then strip quotes and preserve
+ * case...
+ */
+ if (identifier[0] == '"')
+ {
+ char *endptr;
+
+ endptr = identifier + strlen(identifier) - 1;
+ if (*endptr == '"')
+ *endptr = '\0';
+ strcpy(identifier, &identifier[1]);
+ }
+ else
+ {
+ int i;
+
+ /* otherwise, convert identifier name to lowercase... */
+ for (i = 0; identifier[i]; i++)
+ if (isupper((unsigned char) identifier[i]))
+ identifier[i] = tolower((unsigned char) identifier[i]);
+ }
+}
+
void
exit_nicely(void)
{
{
/*
* If a specific table is being dumped, do not dump any complete
- * namespaces. Otherwise, dump all non-system namespaces.
+ * namespaces. If a specific namespace is being dumped, dump just
+ * that namespace. Otherwise, dump all non-system namespaces.
*/
- if (selectTablename != NULL)
+ if (selectTableName != NULL)
nsinfo->dump = false;
+ else if (selectSchemaName != NULL)
+ {
+ if (strcmp(nsinfo->nspname, selectSchemaName) == 0)
+ nsinfo->dump = true;
+ else
+ nsinfo->dump = false;
+ }
else if (strncmp(nsinfo->nspname, "pg_", 3) == 0 ||
strcmp(nsinfo->nspname, "information_schema") == 0)
nsinfo->dump = false;
*/
if (tbinfo->relnamespace->dump)
tbinfo->dump = true;
- else if (selectTablename != NULL)
- tbinfo->dump = (strcmp(tbinfo->relname, selectTablename) == 0);
+ else if (selectTableName != NULL)
+ tbinfo->dump = (strcmp(tbinfo->relname, selectTableName) == 0);
else
tbinfo->dump = false;
}
nsinfo[i].nspname);
}
+ /*
+ * If the user attempted to dump a specific namespace, check to
+ * ensure that the specified namespace actually exists.
+ */
+ if (selectSchemaName)
+ {
+ for (i = 0; i < ntups; i++)
+ if (strcmp(nsinfo[i].nspname, selectSchemaName) == 0)
+ break;
+
+ /* Didn't find a match */
+ if (i == ntups)
+ {
+ write_msg(NULL, "Specified schema \"%s\" does not exist.\n",
+ selectSchemaName);
+ exit_nicely();
+ }
+ }
+
PQclear(res);
destroyPQExpBuffer(query);
tblinfo[i].relname);
}
+ /*
+ * If the user is attempting to dump a specific table, check to
+ * ensure that the specified table actually exists (and is a table
+ * or a view, not a sequence).
+ */
+ if (selectTableName)
+ {
+ for (i = 0; i < ntups; i++)
+ if (strcmp(tblinfo[i].relname, selectTableName) == 0 &&
+ tblinfo[i].relkind != 'S')
+ break;
+
+ /* Didn't find a match */
+ if (i == ntups)
+ {
+ write_msg(NULL, "Specified table \"%s\" does not exist.\n",
+ selectTableName);
+ exit_nicely();
+ }
+ }
+
PQclear(res);
destroyPQExpBuffer(query);
destroyPQExpBuffer(delqry);
* setting, instead.
*/
- /*** Build query to find comment ***/
+ /* Build query to find comment */
query = createPQExpBuffer();
appendPQExpBuffer(query, "SELECT description FROM pg_description WHERE objoid = '%s'::oid", oid);
}
- /*** Execute query ***/
+ /* Execute query */
res = PQexec(g_conn, query->data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
exit_nicely();
}
- /*** If a comment exists, build COMMENT ON statement ***/
+ /* If a comment exists, build COMMENT ON statement */
if (PQntuples(res) == 1)
{
* setting, instead.
*/
- /*** Build query to find comments ***/
+ /* Build query to find comments */
query = createPQExpBuffer();
target = createPQExpBuffer();
appendPQExpBuffer(query, "SELECT description, 0 as objsubid FROM pg_description WHERE objoid = '%s'::oid", tbinfo->oid);
}
- /*** Execute query ***/
+ /* Execute query */
res = PQexec(g_conn, query->data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
i_description = PQfnumber(res, "description");
i_objsubid = PQfnumber(res, "objsubid");
- /*** If comments exist, build COMMENT ON statements ***/
+ /* If comments exist, build COMMENT ON statements */
ntups = PQntuples(res);
for (i = 0; i < ntups; i++)
/* Make sure we are in proper schema */
selectSourceSchema("pg_catalog");
- /*** Build query to find comment ***/
+ /* Build query to find comment */
query = createPQExpBuffer();
appendPQExpBuffer(query, "SELECT oid FROM pg_database WHERE datname = ");
appendStringLiteral(query, PQdb(g_conn), true);
- /*** Execute query ***/
+ /* Execute query */
res = PQexec(g_conn, query->data);
if (!res || PQresultStatus(res) != PGRES_TUPLES_OK)
exit_nicely();
}
- /*** If a comment exists, build COMMENT ON statement ***/
+ /* If a comment exists, build COMMENT ON statement */
if (PQntuples(res) != 0)
{
nspinfo->usename, "SCHEMA", NULL,
q->data, delq->data, NULL, NULL, NULL);
- /*** Dump Schema Comments ***/
+ /* Dump Schema Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "SCHEMA %s", qnspname);
dumpComment(fout, q->data,
tinfo->usename, "TYPE", deps,
q->data, delq->data, NULL, NULL, NULL);
- /*** Dump Type Comments ***/
+ /* Dump Type Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo->typname));
tinfo->usename, "DOMAIN", deps,
q->data, delq->data, NULL, NULL, NULL);
- /*** Dump Domain Comments ***/
+ /* Dump Domain Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "DOMAIN %s", fmtId(tinfo->typname));
tinfo->usename, "TYPE", NULL,
q->data, delq->data, NULL, NULL, NULL);
- /*** Dump Type Comments ***/
+ /* Dump Type Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "TYPE %s", fmtId(tinfo->typname));
q->data, delqry->data,
NULL, NULL, NULL);
- /*** Dump Function Comments ***/
+ /* Dump Function Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "FUNCTION %s", funcsig);
q->data, delq->data,
NULL, NULL, NULL);
- /*** Dump Operator Comments ***/
+ /* Dump Operator Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "OPERATOR %s", oprid->data);
q->data, delq->data,
NULL, NULL, NULL);
- /*** Dump Aggregate Comments ***/
+ /* Dump Aggregate Comments */
resetPQExpBuffer(q);
appendPQExpBuffer(q, "AGGREGATE %s", aggsig);