Revise psql pattern-matching switches as per discussion. The rule is now
to process all inclusion switches then all exclusion switches, so that the behavior is independent of switch ordering. Use of -T does not cause non-table objects to be suppressed. And the patterns are now interpreted the same way psql's \d commands do it, rather than as pure regex commands; this allows for example -t schema.tab to do what it should have been doing all along. Re-enable the --blobs switch to do something useful, ie, add back blobs into a dump they were otherwise suppressed from.
This commit is contained in:
parent
77d2b1b625
commit
24e9752863
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.89 2006/10/07 20:59:04 petere Exp $
|
||||
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.90 2006/10/09 23:36:58 tgl Exp $
|
||||
PostgreSQL documentation
|
||||
-->
|
||||
|
||||
|
@ -14,7 +14,7 @@ PostgreSQL documentation
|
|||
<refname>pg_dump</refname>
|
||||
|
||||
<refpurpose>
|
||||
extract a <productname>PostgreSQL</productname> database into a script file or other archive file
|
||||
extract a <productname>PostgreSQL</productname> database into a script file or other archive file
|
||||
</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
|
@ -126,6 +126,19 @@ PostgreSQL documentation
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-b</></term>
|
||||
<term><option>--blobs</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Include large objects in the dump. This is the default behavior
|
||||
except when <option>--schema</>, <option>--table</>, or
|
||||
<option>--schema-only</> is specified, so the <option>-b</>
|
||||
switch is only useful to add large objects to selective dumps.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-c</option></term>
|
||||
<term><option>--clean</option></term>
|
||||
|
@ -170,12 +183,14 @@ PostgreSQL documentation
|
|||
Dump data as <command>INSERT</command> commands (rather
|
||||
than <command>COPY</command>). This will make restoration very slow;
|
||||
it is mainly useful for making dumps that can be loaded into
|
||||
non-<productname>PostgreSQL</productname> databases. Note that
|
||||
non-<productname>PostgreSQL</productname> databases.
|
||||
Also, since this option generates a separate command for each row,
|
||||
an error in reloading a row causes only that row to be lost rather
|
||||
than the entire table contents.
|
||||
Note that
|
||||
the restore may fail altogether if you have rearranged column order.
|
||||
The <option>-D</option> option is safer, though even slower.
|
||||
Also, while this option generates errors for invalid data,
|
||||
it allows other <command>INSERT</command>s to continue loading
|
||||
data into the table.
|
||||
The <option>-D</option> option is safe against column order changes,
|
||||
though even slower.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -193,9 +208,9 @@ PostgreSQL documentation
|
|||
...</literal>). This will make restoration very slow; it is mainly
|
||||
useful for making dumps that can be loaded into
|
||||
non-<productname>PostgreSQL</productname> databases.
|
||||
Also, while this option generates errors for invalid data,
|
||||
it allows other <command>INSERT</command>s to continue loading
|
||||
data into the table.
|
||||
Also, since this option generates a separate command for each row,
|
||||
an error in reloading a row causes only that row to be lost rather
|
||||
than the entire table contents.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -238,7 +253,7 @@ PostgreSQL documentation
|
|||
<term><literal>plain</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Output a plain-text <acronym>SQL</acronym> script file (default)
|
||||
Output a plain-text <acronym>SQL</acronym> script file (the default).
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -248,10 +263,10 @@ PostgreSQL documentation
|
|||
<term><literal>custom</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Output a custom archive suitable for input into
|
||||
<application>pg_restore</application>. This is the most flexible
|
||||
format in that it allows reordering of loading data as well
|
||||
as object definitions. This format is also compressed by default.
|
||||
Output a custom archive suitable for input into
|
||||
<application>pg_restore</application>. This is the most flexible
|
||||
format in that it allows reordering of loading data as well
|
||||
as object definitions. This format is also compressed by default.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -261,11 +276,11 @@ PostgreSQL documentation
|
|||
<term><literal>tar</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Output a <command>tar</command> archive suitable for input into
|
||||
<application>pg_restore</application>. Using this archive format
|
||||
allows reordering and/or exclusion of database objects
|
||||
at the time the database is restored. It is also possible to limit
|
||||
which data is reloaded at restore time.
|
||||
Output a <command>tar</command> archive suitable for input into
|
||||
<application>pg_restore</application>. Using this archive format
|
||||
allows reordering and/or exclusion of database objects
|
||||
at the time the database is restored. It is also possible to limit
|
||||
which data is reloaded at restore time.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -286,9 +301,11 @@ PostgreSQL documentation
|
|||
</para>
|
||||
|
||||
<para>
|
||||
<application>pg_dump</application> can handle databases from
|
||||
<application>pg_dump</application> can dump from servers running
|
||||
previous releases of <productname>PostgreSQL</>, but very old
|
||||
versions are not supported anymore (currently prior to 7.0).
|
||||
versions are not supported anymore (currently, those prior to 7.0).
|
||||
Dumping from a server newer than <application>pg_dump</application>
|
||||
is likely not to work at all.
|
||||
Use this option if you need to override the version check (and
|
||||
if <application>pg_dump</application> then fails, don't say
|
||||
you weren't warned).
|
||||
|
@ -301,20 +318,61 @@ PostgreSQL documentation
|
|||
<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.
|
||||
Dump only schemas matching <replaceable
|
||||
class="parameter">schema</replaceable>; this selects both the
|
||||
schema itself, and all its contained objects. When this option is
|
||||
not specified, all non-system schemas in the target database will be
|
||||
dumped. Multiple schemas can be
|
||||
selected by writing multiple <option>-n</> switches. Also, the
|
||||
<replaceable class="parameter">schema</replaceable> parameter is
|
||||
interpreted as a pattern according to the same rules used by
|
||||
<application>psql</>'s <literal>\d</> commands (see <xref
|
||||
linkend="APP-PSQL-patterns" endterm="APP-PSQL-patterns-title">),
|
||||
so multiple schemas can also be selected by writing wildcard characters
|
||||
in the pattern. When using wildcards, be careful to quote the pattern
|
||||
if needed to prevent the shell from expanding the wildcards.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
In this mode, <application>pg_dump</application> makes no
|
||||
attempt to dump any other database objects that objects in the
|
||||
selected schema may depend upon. Therefore, there is no
|
||||
guarantee that the results of a single-schema dump can be
|
||||
successfully restored by themselves into a clean database.
|
||||
When <option>-n</> is specified, <application>pg_dump</application>
|
||||
makes no attempt to dump any other database objects that the selected
|
||||
schema(s) may depend upon. Therefore, there is no guarantee
|
||||
that the results of a specific-schema dump can be successfully
|
||||
restored by themselves into a clean database.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
Non-schema objects such as blobs are not dumped when <option>-n</> is
|
||||
specified. You can add blobs back to the dump with the
|
||||
<option>--blobs</> switch.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-N <replaceable class="parameter">schema</replaceable></option></term>
|
||||
<term><option>--exclude-schema=<replaceable class="parameter">schema</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not dump any schemas matching the <replaceable
|
||||
class="parameter">schema</replaceable> pattern. The pattern is
|
||||
interpreted according to the same rules as for <option>-n</>.
|
||||
<option>-N</> can be given more than once to exclude schemas
|
||||
matching any of several patterns.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When both <option>-n</> and <option>-N</> are given, the behavior
|
||||
is to dump just the schemas that match at least one <option>-n</>
|
||||
switch but no <option>-N</> switches. If <option>-N</> appears
|
||||
without <option>-n</>, then schemas matching <option>-N</> are
|
||||
excluded from what is otherwise a normal dump.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -340,7 +398,7 @@ PostgreSQL documentation
|
|||
Do not output commands to set
|
||||
ownership of objects to match the original database.
|
||||
By default, <application>pg_dump</application> issues
|
||||
<command>ALTER OWNER</> or
|
||||
<command>ALTER OWNER</> or
|
||||
<command>SET SESSION AUTHORIZATION</command>
|
||||
statements to set ownership of created database objects.
|
||||
These statements
|
||||
|
@ -397,67 +455,47 @@ PostgreSQL documentation
|
|||
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Dump data for <replaceable class="parameter">table</replaceable>
|
||||
only. 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. Also, if any POSIX regular expression character appears
|
||||
in the table name (<literal>([{\.?+</>, the string will be interpreted
|
||||
as a regular expression. Note that when in regular expression mode, the
|
||||
string will not be anchored to the start/end unless <literal>^</> and
|
||||
<literal>$</> are used at the beginning/end of the string.
|
||||
Dump only tables (or views or sequences) matching <replaceable
|
||||
class="parameter">table</replaceable>. Multiple tables can be
|
||||
selected by writing multiple <option>-t</> switches. Also, the
|
||||
<replaceable class="parameter">table</replaceable> parameter is
|
||||
interpreted as a pattern according to the same rules used by
|
||||
<application>psql</>'s <literal>\d</> commands (see <xref
|
||||
linkend="APP-PSQL-patterns" endterm="APP-PSQL-patterns-title">),
|
||||
so multiple tables can also be selected by writing wildcard characters
|
||||
in the pattern. When using wildcards, be careful to quote the pattern
|
||||
if needed to prevent the shell from expanding the wildcards.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The options <option>-t</>, <option>-T</>, <option>-n</>, and <option>-N</>
|
||||
can be used together to achieve a high degree of control over what is
|
||||
dumped. Multiple arguments can be used, and are parsed in the order
|
||||
given to build a list of valid tables and schemas. The schema options are
|
||||
parsed first to create a list of schemas to dump, and then the table options
|
||||
are parsed to only find tables in the matching schemas.
|
||||
The <option>-n</> and <option>-N</> switches have no effect when
|
||||
<option>-t</> is used, because tables selected by <option>-t</> will
|
||||
be dumped regardless of those switches, and non-table objects will not
|
||||
be dumped.
|
||||
</para>
|
||||
|
||||
<para>For example, to dump a single table named <literal>pg_class</>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -t pg_class mydb > db.out</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>To dump all tables starting with <literal>employee</> in the
|
||||
<literal>detroit</> schema, except for the table named <literal>employee_log</literal>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -n detroit -t ^employee -T employee_log mydb > db.out</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>To dump all schemas starting with <literal>east</> or <literal>west</> and ending in
|
||||
<literal>gsm</>, but not schemas that contain the letters <literal>test</>, except for
|
||||
one named <literal>east_alpha_test_five</>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -n "^(east|west).*gsm$" -N test -n east_alpha_test_five mydb > db.out</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
|
||||
<para>To dump all tables except for those beginning with <literal>ts_</literal>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -T "^ts_" mydb > db.out</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
|
||||
<note>
|
||||
<para>
|
||||
In this mode, <application>pg_dump</application> makes no
|
||||
attempt to dump any other database objects that the selected tables
|
||||
may depend upon. Therefore, there is no guarantee
|
||||
When <option>-t</> is specified, <application>pg_dump</application>
|
||||
makes no attempt to dump any other database objects that the selected
|
||||
table(s) may depend upon. Therefore, there is no guarantee
|
||||
that the results of a specific-table dump can be successfully
|
||||
restored by themselves into a clean database.
|
||||
</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The behavior of the <option>-t</> switch is not entirely upward
|
||||
compatible with pre-8.2 <productname>PostgreSQL</productname>
|
||||
versions. Formerly, writing <literal>-t tab</> would dump all
|
||||
tables named <literal>tab</>, but now it just dumps whichever one
|
||||
is visible in your default search path. To get the old behavior
|
||||
you can write <literal>-t '*.tab'</>. Also, you must write something
|
||||
like <literal>-t sch.tab</> to select a table in a particular schema,
|
||||
rather than the old locution of <literal>-n sch -t tab</>.
|
||||
</para>
|
||||
</note>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -466,36 +504,20 @@ PostgreSQL documentation
|
|||
<term><option>--exclude-table=<replaceable class="parameter">table</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not dump any matching <replaceable class="parameter">tables</replaceable>.
|
||||
More than one option can be used, and POSIX regular expressions are handled just
|
||||
like <literal>-t</>.
|
||||
Do not dump any tables matching the <replaceable
|
||||
class="parameter">table</replaceable> pattern. The pattern is
|
||||
interpreted according to the same rules as for <option>-t</>.
|
||||
<option>-T</> can be given more than once to exclude tables
|
||||
matching any of several patterns.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-n <replaceable class="parameter">schema</replaceable></option></term>
|
||||
<term><option>--schema=<replaceable class="parameter">schema</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Dump only the matching <replaceable class="parameter">schemas</replaceable>.
|
||||
More than one option can be used, and POSIX regular expressions are handled just
|
||||
like <literal>-t</>.
|
||||
When both <option>-t</> and <option>-T</> are given, the behavior
|
||||
is to dump just the tables that match at least one <option>-t</>
|
||||
switch but no <option>-T</> switches. If <option>-T</> appears
|
||||
without <option>-t</>, then tables matching <option>-T</> are
|
||||
excluded from what is otherwise a normal dump.
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-N <replaceable class="parameter">schema</replaceable></option></term>
|
||||
<term><option>--exclude-schema=<replaceable class="parameter">schema</replaceable></option></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Do not dump the matching <replaceable class="parameter">schemas</replaceable>.
|
||||
More than one option can be used, and POSIX regular expressions are handled just
|
||||
like <literal>-t</>.
|
||||
</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
@ -506,7 +528,7 @@ PostgreSQL documentation
|
|||
<para>
|
||||
Specifies verbose mode. This will cause
|
||||
<application>pg_dump</application> to output detailed object
|
||||
comments and start/stop times to the dump file, and progress
|
||||
comments and start/stop times to the dump file, and progress
|
||||
messages to standard error.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -742,33 +764,80 @@ CREATE DATABASE foo WITH TEMPLATE template0;
|
|||
<title>Examples</title>
|
||||
|
||||
<para>
|
||||
To dump a database:
|
||||
To dump a database called <literal>mydb</> into a SQL-script file:
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump mydb > db.out</userinput>
|
||||
<prompt>$</prompt> <userinput>pg_dump mydb > db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To reload this database:
|
||||
To reload such a script into a (freshly created) database named
|
||||
<literal>newdb</>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>psql -d database -f db.out</userinput>
|
||||
<prompt>$</prompt> <userinput>psql -d newdb -f db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To dump a database called <literal>mydb</> to a file in custom format:
|
||||
file:
|
||||
To dump a database into a custom-format archive file:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -Fc mydb > db.out</userinput>
|
||||
<prompt>$</prompt> <userinput>pg_dump -Fc mydb > db.dump</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To reload this dump into an existing database called <literal>newdb</>:
|
||||
To reload an archive file into a (freshly created) database named
|
||||
<literal>newdb</>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_restore -d newdb db.out</userinput>
|
||||
<prompt>$</prompt> <userinput>pg_restore -d newdb db.dump</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To dump a single table named <literal>mytab</>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -t mytab mydb > db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To dump all tables whose names start with <literal>emp</> in the
|
||||
<literal>detroit</> schema, except for the table named
|
||||
<literal>employee_log</literal>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -t 'detroit.emp*' -T detroit.employee_log mydb > db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To dump all schemas whose names start with <literal>east</> or
|
||||
<literal>west</> and end in <literal>gsm</>, excluding any schemas whose
|
||||
names contain the word <literal>test</>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -n 'east*gsm' -n 'west*gsm' -N '*test*' mydb > db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The same, using regular expression notation to consolidate the switches:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -n '(east|west)*gsm' -N '*test*' mydb > db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
To dump all database objects except for tables whose names begin with
|
||||
<literal>ts_</literal>:
|
||||
|
||||
<screen>
|
||||
<prompt>$</prompt> <userinput>pg_dump -T 'ts_*' mydb > db.sql</userinput>
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
case 'n': /* include schema(s) */
|
||||
simple_string_list_append(&schema_include_patterns, optarg);
|
||||
include_everything = false;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
/* 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"));
|
||||
|
@ -927,6 +783,106 @@ exit_nicely(void)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the OIDs of all schemas matching the given list of patterns,
|
||||
* and append them to the given OID list.
|
||||
*/
|
||||
static void
|
||||
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();
|
||||
|
||||
/*
|
||||
* We use UNION ALL rather than UNION; this might sometimes result in
|
||||
* duplicate entries in the OID list, but we don't care.
|
||||
*/
|
||||
|
||||
for (cell = patterns->head; cell; cell = cell->next)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
res = PQexec(g_conn, query->data);
|
||||
check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
|
||||
|
||||
for (i = 0; i < PQntuples(res); i++)
|
||||
{
|
||||
simple_oid_list_append(oids, atooid(PQgetvalue(res, i, 0)));
|
||||
}
|
||||
|
||||
PQclear(res);
|
||||
destroyPQExpBuffer(query);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the OIDs of all tables matching the given list of patterns,
|
||||
* and append them to the given OID list.
|
||||
*/
|
||||
static void
|
||||
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();
|
||||
|
||||
/*
|
||||
* We use UNION ALL rather than UNION; this might sometimes result in
|
||||
* duplicate entries in the OID list, but we don't care.
|
||||
*/
|
||||
|
||||
for (cell = patterns->head; cell; cell = cell->next)
|
||||
{
|
||||
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)");
|
||||
}
|
||||
|
||||
res = PQexec(g_conn, query->data);
|
||||
check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
|
||||
|
||||
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
|
||||
|
@ -936,27 +892,26 @@ 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. If specific namespaces are being dumped, dump just those
|
||||
* namespaces. Otherwise, dump all non-system namespaces.
|
||||
*/
|
||||
nsinfo->dobj.dump = false;
|
||||
|
||||
if (matchingTables != NULL)
|
||||
/* false */ ;
|
||||
else if (matchingSchemas != NULL)
|
||||
{
|
||||
char *search_oid = malloc(20);
|
||||
|
||||
sprintf(search_oid, " %d ", nsinfo->dobj.catId.oid);
|
||||
if (strstr(matchingSchemas, search_oid) != NULL)
|
||||
nsinfo->dobj.dump = true;
|
||||
|
||||
free(search_oid);
|
||||
}
|
||||
/* The server prevents users from creating pg_ schemas */
|
||||
else if (strncmp(nsinfo->dobj.name, "pg_", 3) != 0 &&
|
||||
strcmp(nsinfo->dobj.name, "information_schema") != 0)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -967,27 +922,21 @@ static void
|
|||
selectDumpableTable(TableInfo *tbinfo)
|
||||
{
|
||||
/*
|
||||
* Always dump if dumping parent namespace; else, if a particular
|
||||
* tablename has been specified, dump matching table name; else, do not
|
||||
* dump.
|
||||
* If specific tables are being dumped, dump just those tables;
|
||||
* else, dump according to the parent namespace's dump flag.
|
||||
*/
|
||||
tbinfo->dobj.dump = false;
|
||||
|
||||
if (matchingTables == NULL)
|
||||
{
|
||||
if (tbinfo->dobj.namespace->dobj.dump)
|
||||
tbinfo->dobj.dump = true;
|
||||
}
|
||||
if (table_include_oids.head != NULL)
|
||||
tbinfo->dobj.dump = simple_oid_list_member(&table_include_oids,
|
||||
tbinfo->dobj.catId.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;
|
||||
|
||||
free(search_oid);
|
||||
}
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue