Commit 24e97528 authored by Tom Lane's avatar Tom Lane

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.
parent 77d2b1b6
<!-- <!--
$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 PostgreSQL documentation
--> -->
...@@ -14,7 +14,7 @@ PostgreSQL documentation ...@@ -14,7 +14,7 @@ PostgreSQL documentation
<refname>pg_dump</refname> <refname>pg_dump</refname>
<refpurpose> <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> </refpurpose>
</refnamediv> </refnamediv>
...@@ -126,6 +126,19 @@ PostgreSQL documentation ...@@ -126,6 +126,19 @@ PostgreSQL documentation
</listitem> </listitem>
</varlistentry> </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> <varlistentry>
<term><option>-c</option></term> <term><option>-c</option></term>
<term><option>--clean</option></term> <term><option>--clean</option></term>
...@@ -170,12 +183,14 @@ PostgreSQL documentation ...@@ -170,12 +183,14 @@ PostgreSQL documentation
Dump data as <command>INSERT</command> commands (rather Dump data as <command>INSERT</command> commands (rather
than <command>COPY</command>). This will make restoration very slow; than <command>COPY</command>). This will make restoration very slow;
it is mainly useful for making dumps that can be loaded into 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 restore may fail altogether if you have rearranged column order.
The <option>-D</option> option is safer, though even slower. The <option>-D</option> option is safe against column order changes,
Also, while this option generates errors for invalid data, though even slower.
it allows other <command>INSERT</command>s to continue loading
data into the table.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -193,9 +208,9 @@ PostgreSQL documentation ...@@ -193,9 +208,9 @@ PostgreSQL documentation
...</literal>). This will make restoration very slow; it is mainly ...</literal>). This will make restoration very slow; it is mainly
useful for making dumps that can be loaded into useful for making dumps that can be loaded into
non-<productname>PostgreSQL</productname> databases. non-<productname>PostgreSQL</productname> databases.
Also, while this option generates errors for invalid data, Also, since this option generates a separate command for each row,
it allows other <command>INSERT</command>s to continue loading an error in reloading a row causes only that row to be lost rather
data into the table. than the entire table contents.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -238,7 +253,7 @@ PostgreSQL documentation ...@@ -238,7 +253,7 @@ PostgreSQL documentation
<term><literal>plain</></term> <term><literal>plain</></term>
<listitem> <listitem>
<para> <para>
Output a plain-text <acronym>SQL</acronym> script file (default) Output a plain-text <acronym>SQL</acronym> script file (the default).
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -248,10 +263,10 @@ PostgreSQL documentation ...@@ -248,10 +263,10 @@ PostgreSQL documentation
<term><literal>custom</></term> <term><literal>custom</></term>
<listitem> <listitem>
<para> <para>
Output a custom archive suitable for input into Output a custom archive suitable for input into
<application>pg_restore</application>. This is the most flexible <application>pg_restore</application>. This is the most flexible
format in that it allows reordering of loading data as well format in that it allows reordering of loading data as well
as object definitions. This format is also compressed by default. as object definitions. This format is also compressed by default.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -261,11 +276,11 @@ PostgreSQL documentation ...@@ -261,11 +276,11 @@ PostgreSQL documentation
<term><literal>tar</></term> <term><literal>tar</></term>
<listitem> <listitem>
<para> <para>
Output a <command>tar</command> archive suitable for input into Output a <command>tar</command> archive suitable for input into
<application>pg_restore</application>. Using this archive format <application>pg_restore</application>. Using this archive format
allows reordering and/or exclusion of database objects allows reordering and/or exclusion of database objects
at the time the database is restored. It is also possible to limit at the time the database is restored. It is also possible to limit
which data is reloaded at restore time. which data is reloaded at restore time.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -286,9 +301,11 @@ PostgreSQL documentation ...@@ -286,9 +301,11 @@ PostgreSQL documentation
</para> </para>
<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 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 Use this option if you need to override the version check (and
if <application>pg_dump</application> then fails, don't say if <application>pg_dump</application> then fails, don't say
you weren't warned). you weren't warned).
...@@ -301,20 +318,61 @@ PostgreSQL documentation ...@@ -301,20 +318,61 @@ PostgreSQL documentation
<term><option>--schema=<replaceable class="parameter">schema</replaceable></option></term> <term><option>--schema=<replaceable class="parameter">schema</replaceable></option></term>
<listitem> <listitem>
<para> <para>
Dump the contents of <replaceable class="parameter">schema</> Dump only schemas matching <replaceable
only. If this option is not specified, all non-system schemas class="parameter">schema</replaceable>; this selects both the
in the target database will be dumped. 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> </para>
<note> <note>
<para> <para>
In this mode, <application>pg_dump</application> makes no When <option>-n</> is specified, <application>pg_dump</application>
attempt to dump any other database objects that objects in the makes no attempt to dump any other database objects that the selected
selected schema may depend upon. Therefore, there is no schema(s) may depend upon. Therefore, there is no guarantee
guarantee that the results of a single-schema dump can be that the results of a specific-schema dump can be successfully
successfully restored by themselves into a clean database. 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> </para>
</note> </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> </listitem>
</varlistentry> </varlistentry>
...@@ -340,7 +398,7 @@ PostgreSQL documentation ...@@ -340,7 +398,7 @@ PostgreSQL documentation
Do not output commands to set Do not output commands to set
ownership of objects to match the original database. ownership of objects to match the original database.
By default, <application>pg_dump</application> issues By default, <application>pg_dump</application> issues
<command>ALTER OWNER</> or <command>ALTER OWNER</> or
<command>SET SESSION AUTHORIZATION</command> <command>SET SESSION AUTHORIZATION</command>
statements to set ownership of created database objects. statements to set ownership of created database objects.
These statements These statements
...@@ -397,67 +455,47 @@ PostgreSQL documentation ...@@ -397,67 +455,47 @@ PostgreSQL documentation
<term><option>--table=<replaceable class="parameter">table</replaceable></option></term> <term><option>--table=<replaceable class="parameter">table</replaceable></option></term>
<listitem> <listitem>
<para> <para>
Dump data for <replaceable class="parameter">table</replaceable> Dump only tables (or views or sequences) matching <replaceable
only. It is possible for there to be multiple tables with the same class="parameter">table</replaceable>. Multiple tables can be
name in different schemas; if that is the case, all matching tables selected by writing multiple <option>-t</> switches. Also, the
will be dumped. Also, if any POSIX regular expression character appears <replaceable class="parameter">table</replaceable> parameter is
in the table name (<literal>([{\.?+</>, the string will be interpreted interpreted as a pattern according to the same rules used by
as a regular expression. Note that when in regular expression mode, the <application>psql</>'s <literal>\d</> commands (see <xref
string will not be anchored to the start/end unless <literal>^</> and linkend="APP-PSQL-patterns" endterm="APP-PSQL-patterns-title">),
<literal>$</> are used at the beginning/end of the string. 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>
<para> <para>
The options <option>-t</>, <option>-T</>, <option>-n</>, and <option>-N</> The <option>-n</> and <option>-N</> switches have no effect when
can be used together to achieve a high degree of control over what is <option>-t</> is used, because tables selected by <option>-t</> will
dumped. Multiple arguments can be used, and are parsed in the order be dumped regardless of those switches, and non-table objects will not
given to build a list of valid tables and schemas. The schema options are be dumped.
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.
</para> </para>
<para>For example, to dump a single table named <literal>pg_class</>:
<screen>
<prompt>$</prompt> <userinput>pg_dump -t pg_class mydb &gt; 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 &gt; 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 &gt; 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 &gt; db.out</userinput>
</screen>
</para>
<note> <note>
<para> <para>
In this mode, <application>pg_dump</application> makes no When <option>-t</> is specified, <application>pg_dump</application>
attempt to dump any other database objects that the selected tables makes no attempt to dump any other database objects that the selected
may depend upon. Therefore, there is no guarantee table(s) may depend upon. Therefore, there is no guarantee
that the results of a specific-table dump can be successfully that the results of a specific-table dump can be successfully
restored by themselves into a clean database. restored by themselves into a clean database.
</para> </para>
</note> </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> </listitem>
</varlistentry> </varlistentry>
...@@ -466,36 +504,20 @@ PostgreSQL documentation ...@@ -466,36 +504,20 @@ PostgreSQL documentation
<term><option>--exclude-table=<replaceable class="parameter">table</replaceable></option></term> <term><option>--exclude-table=<replaceable class="parameter">table</replaceable></option></term>
<listitem> <listitem>
<para> <para>
Do not dump any matching <replaceable class="parameter">tables</replaceable>. Do not dump any tables matching the <replaceable
More than one option can be used, and POSIX regular expressions are handled just class="parameter">table</replaceable> pattern. The pattern is
like <literal>-t</>. 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> </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</>.
</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> <para>
Do not dump the matching <replaceable class="parameter">schemas</replaceable>. When both <option>-t</> and <option>-T</> are given, the behavior
More than one option can be used, and POSIX regular expressions are handled just is to dump just the tables that match at least one <option>-t</>
like <literal>-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> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -506,7 +528,7 @@ PostgreSQL documentation ...@@ -506,7 +528,7 @@ PostgreSQL documentation
<para> <para>
Specifies verbose mode. This will cause Specifies verbose mode. This will cause
<application>pg_dump</application> to output detailed object <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. messages to standard error.
</para> </para>
</listitem> </listitem>
...@@ -742,33 +764,80 @@ CREATE DATABASE foo WITH TEMPLATE template0; ...@@ -742,33 +764,80 @@ CREATE DATABASE foo WITH TEMPLATE template0;
<title>Examples</title> <title>Examples</title>
<para> <para>
To dump a database: To dump a database called <literal>mydb</> into a SQL-script file:
<screen>
<prompt>$</prompt> <userinput>pg_dump mydb &gt; db.sql</userinput>
</screen>
</para>
<para>
To reload such a script into a (freshly created) database named
<literal>newdb</>:
<screen> <screen>
<prompt>$</prompt> <userinput>pg_dump mydb &gt; db.out</userinput> <prompt>$</prompt> <userinput>psql -d newdb -f db.sql</userinput>
</screen> </screen>
</para> </para>
<para> <para>
To reload this database: To dump a database into a custom-format archive file:
<screen>
<prompt>$</prompt> <userinput>pg_dump -Fc mydb &gt; db.dump</userinput>
</screen>
</para>
<para>
To reload an archive file into a (freshly created) database named
<literal>newdb</>:
<screen>
<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 &gt; 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 &gt; 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> <screen>
<prompt>$</prompt> <userinput>psql -d database -f db.out</userinput> <prompt>$</prompt> <userinput>pg_dump -n 'east*gsm' -n 'west*gsm' -N '*test*' mydb &gt; db.sql</userinput>
</screen> </screen>
</para> </para>
<para> <para>
To dump a database called <literal>mydb</> to a file in custom format: The same, using regular expression notation to consolidate the switches:
file:
<screen> <screen>
<prompt>$</prompt> <userinput>pg_dump -Fc mydb &gt; db.out</userinput> <prompt>$</prompt> <userinput>pg_dump -n '(east|west)*gsm' -N '*test*' mydb &gt; db.sql</userinput>
</screen> </screen>
</para> </para>
<para> <para>
To reload this dump into an existing database called <literal>newdb</>: To dump all database objects except for tables whose names begin with
<literal>ts_</literal>:
<screen> <screen>
<prompt>$</prompt> <userinput>pg_restore -d newdb db.out</userinput> <prompt>$</prompt> <userinput>pg_dump -T 'ts_*' mydb &gt; db.sql</userinput>
</screen> </screen>
</para> </para>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -402,16 +402,14 @@ AssignDumpId(DumpableObject *dobj)
{ {
newAlloc = 256; newAlloc = 256;
dumpIdMap = (DumpableObject **) dumpIdMap = (DumpableObject **)
malloc(newAlloc * sizeof(DumpableObject *)); pg_malloc(newAlloc * sizeof(DumpableObject *));
} }
else else
{ {
newAlloc = allocedDumpIds * 2; newAlloc = allocedDumpIds * 2;
dumpIdMap = (DumpableObject **) 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, memset(dumpIdMap + allocedDumpIds, 0,
(newAlloc - allocedDumpIds) * sizeof(DumpableObject *)); (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
allocedDumpIds = newAlloc; allocedDumpIds = newAlloc;
...@@ -541,9 +539,7 @@ getDumpableObjects(DumpableObject ***objs, int *numObjs) ...@@ -541,9 +539,7 @@ getDumpableObjects(DumpableObject ***objs, int *numObjs)
j; j;
*objs = (DumpableObject **) *objs = (DumpableObject **)
malloc(allocedDumpIds * sizeof(DumpableObject *)); pg_malloc(allocedDumpIds * sizeof(DumpableObject *));
if (*objs == NULL)
exit_horribly(NULL, NULL, "out of memory\n");
j = 0; j = 0;
for (i = 1; i < allocedDumpIds; i++) for (i = 1; i < allocedDumpIds; i++)
{ {
...@@ -567,17 +563,15 @@ addObjectDependency(DumpableObject *dobj, DumpId refId) ...@@ -567,17 +563,15 @@ addObjectDependency(DumpableObject *dobj, DumpId refId)
{ {
dobj->allocDeps = 16; dobj->allocDeps = 16;
dobj->dependencies = (DumpId *) dobj->dependencies = (DumpId *)
malloc(dobj->allocDeps * sizeof(DumpId)); pg_malloc(dobj->allocDeps * sizeof(DumpId));
} }
else else
{ {
dobj->allocDeps *= 2; dobj->allocDeps *= 2;
dobj->dependencies = (DumpId *) dobj->dependencies = (DumpId *)
realloc(dobj->dependencies, pg_realloc(dobj->dependencies,
dobj->allocDeps * sizeof(DumpId)); dobj->allocDeps * sizeof(DumpId));
} }
if (dobj->dependencies == NULL)
exit_horribly(NULL, NULL, "out of memory\n");
} }
dobj->dependencies[dobj->nDeps++] = refId; dobj->dependencies[dobj->nDeps++] = refId;
} }
...@@ -707,7 +701,8 @@ findParentsByOid(TableInfo *self, ...@@ -707,7 +701,8 @@ findParentsByOid(TableInfo *self,
if (numParents > 0) if (numParents > 0)
{ {
self->parents = (TableInfo **) malloc(sizeof(TableInfo *) * numParents); self->parents = (TableInfo **)
pg_malloc(sizeof(TableInfo *) * numParents);
j = 0; j = 0;
for (i = 0; i < numInherits; i++) for (i = 0; i < numInherits; i++)
{ {
...@@ -806,3 +801,124 @@ strInArray(const char *pattern, char **arr, int arr_size) ...@@ -806,3 +801,124 @@ strInArray(const char *pattern, char **arr, int arr_size)
} }
return -1; 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 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * 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 @@ ...@@ -40,8 +40,6 @@
int optreset; int optreset;
#endif #endif
#include "access/htup.h" #include "access/htup.h"
#include "catalog/pg_class.h" #include "catalog/pg_class.h"
#include "catalog/pg_proc.h" #include "catalog/pg_proc.h"
...@@ -87,20 +85,24 @@ static const char *username_subquery; ...@@ -87,20 +85,24 @@ static const char *username_subquery;
/* obsolete as of 7.3: */ /* obsolete as of 7.3: */
static Oid g_last_builtin_oid; /* value of the last builtin oid */ static Oid g_last_builtin_oid; /* value of the last builtin oid */
/* select and exclude tables and schemas */ /*
typedef struct objnameArg * Object inclusion/exclusion lists
{ *
struct objnameArg *next; * The string lists record the patterns given by command-line switches,
char *name; /* name of the relation */ * which we then convert to lists of OIDs of matching objects.
bool is_include; /* include/exclude? */ */
} objnameArg; 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 */ static SimpleStringList table_include_patterns = { NULL, NULL };
objnameArg *tableList = NULL; /* List of tables to include/exclude */ 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 /* default, if no "inclusion" switches appear, is to dump everything */
* oid */ static bool include_everything = true;
char *matchingTables = NULL; /* Final list of tables to dump by oid */
char g_opaque_type[10]; /* name for the opaque type */ char g_opaque_type[10]; /* name for the opaque type */
...@@ -119,6 +121,10 @@ static int disable_dollar_quoting = 0; ...@@ -119,6 +121,10 @@ static int disable_dollar_quoting = 0;
static void help(const char *progname); 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 NamespaceInfo *findNamespace(Oid nsoid, Oid objoid);
static void dumpTableData(Archive *fout, TableDataInfo *tdinfo); static void dumpTableData(Archive *fout, TableDataInfo *tdinfo);
static void dumpComment(Archive *fout, const char *target, static void dumpComment(Archive *fout, const char *target,
...@@ -188,11 +194,6 @@ static void check_sql_result(PGresult *res, PGconn *conn, const char *query, ...@@ -188,11 +194,6 @@ static void check_sql_result(PGresult *res, PGconn *conn, const char *query,
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
PQExpBuffer query = createPQExpBuffer();
PGresult *res;
objnameArg *this_obj_name,
*schemaList_tail = NULL,
*tableList_tail = NULL;
int c; int c;
const char *filename = NULL; const char *filename = NULL;
const char *format = "p"; const char *format = "p";
...@@ -208,14 +209,13 @@ main(int argc, char **argv) ...@@ -208,14 +209,13 @@ main(int argc, char **argv)
DumpableObject **dobjs; DumpableObject **dobjs;
int numObjs; int numObjs;
int i; int i;
bool switch_include_exclude;
bool force_password = false; bool force_password = false;
int compressLevel = -1; int compressLevel = -1;
bool ignore_version = false; bool ignore_version = false;
int plainText = 0; int plainText = 0;
int outputClean = 0; int outputClean = 0;
int outputCreate = 0; int outputCreate = 0;
bool outputBlobs = true; bool outputBlobs = false;
int outputNoOwner = 0; int outputNoOwner = 0;
static int use_setsessauth = 0; static int use_setsessauth = 0;
static int disable_triggers = 0; static int disable_triggers = 0;
...@@ -306,7 +306,7 @@ main(int argc, char **argv) ...@@ -306,7 +306,7 @@ main(int argc, char **argv)
break; break;
case 'b': /* Dump blobs */ case 'b': /* Dump blobs */
/* this is now default, so just ignore the switch */ outputBlobs = true;
break; break;
case 'c': /* clean (i.e., drop) schema prior to create */ case 'c': /* clean (i.e., drop) schema prior to create */
...@@ -347,42 +347,13 @@ main(int argc, char **argv) ...@@ -347,42 +347,13 @@ main(int argc, char **argv)
ignore_version = true; ignore_version = true;
break; break;
case 'n': /* Include schemas */ case 'n': /* include schema(s) */
case 'N': /* Exclude schemas */ simple_string_list_append(&schema_include_patterns, optarg);
case 't': /* Include tables */ include_everything = false;
case 'T': /* Exclude tables */ 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 */ case 'N': /* exclude schema(s) */
if (tolower((unsigned char) c) == 'n') simple_string_list_append(&schema_exclude_patterns, optarg);
{
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;
}
}
break; break;
case 'o': /* Dump oids */ case 'o': /* Dump oids */
...@@ -403,13 +374,21 @@ main(int argc, char **argv) ...@@ -403,13 +374,21 @@ main(int argc, char **argv)
case 's': /* dump schema only */ case 's': /* dump schema only */
schemaOnly = true; schemaOnly = true;
outputBlobs = false;
break; break;
case 'S': /* Username for superuser in plain text output */ case 'S': /* Username for superuser in plain text output */
outputSuperuser = strdup(optarg); outputSuperuser = strdup(optarg);
break; 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': case 'u':
force_password = true; force_password = true;
username = simple_prompt("User name: ", 100, true); username = simple_prompt("User name: ", 100, true);
...@@ -488,9 +467,6 @@ main(int argc, char **argv) ...@@ -488,9 +467,6 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
if (matchingTables != NULL || matchingSchemas != NULL)
outputBlobs = false;
if (dumpInserts == true && oids == true) if (dumpInserts == true && oids == true)
{ {
write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together\n"); write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together\n");
...@@ -607,162 +583,42 @@ main(int argc, char **argv) ...@@ -607,162 +583,42 @@ main(int argc, char **argv)
write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid); write_msg(NULL, "last built-in OID is %u\n", g_last_builtin_oid);
} }
/* Expand schema selection patterns into OID lists */
if (schemaList != NULL && g_fout->remoteVersion < 70300) if (schema_include_patterns.head != NULL)
{ {
write_msg(NULL, "server version must be at least 7.3 to use schema switches\n"); expand_schema_name_patterns(&schema_include_patterns,
exit_nicely(); &schema_include_oids);
} if (schema_include_oids.head == NULL)
/* 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)
{ {
write_msg(NULL, "No matching schemas were found\n"); write_msg(NULL, "No matching schemas were found\n");
exit_nicely(); 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 */ /* Expand table selection patterns into OID lists */
resetPQExpBuffer(query); if (table_include_patterns.head != NULL)
switch_include_exclude = true;
for (this_obj_name = tableList; this_obj_name; this_obj_name = this_obj_name->next)
{ {
if (switch_include_exclude) expand_table_name_patterns(&table_include_patterns,
{ &table_include_oids);
/* Special case for when -T is the first argument */ if (table_include_oids.head == NULL)
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)
{ {
write_msg(NULL, "No matching tables were found\n"); write_msg(NULL, "No matching tables were found\n");
exit_nicely(); 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 * Now scan the database and create DumpableObject structs for all the
...@@ -824,7 +680,7 @@ main(int argc, char **argv) ...@@ -824,7 +680,7 @@ main(int argc, char **argv)
dumpStdStrings(g_fout); dumpStdStrings(g_fout);
/* The database item is always next, unless we don't want it at all */ /* 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); dumpDatabase(g_fout);
/* Now the rearrangeable objects. */ /* Now the rearrangeable objects. */
...@@ -884,28 +740,28 @@ help(const char *progname) ...@@ -884,28 +740,28 @@ help(const char *progname)
printf(_("\nOptions controlling the output content:\n")); printf(_("\nOptions controlling the output content:\n"));
printf(_(" -a, --data-only dump only the data, not the schema\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, --clean clean (drop) schema prior to create\n"));
printf(_(" -C, --create include commands to create database in dump\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, --inserts dump data as INSERT commands, rather than COPY\n"));
printf(_(" -D, --column-inserts dump data as INSERT commands with column names\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(_(" -E, --encoding=ENCODING dump the data in encoding ENCODING\n"));
printf(_(" -n, --schema=SCHEMA dump the named schema only\n")); printf(_(" -n, --schema=SCHEMA dump the named schema(s) only\n"));
printf(_(" -N, --exclude-schema=SCHEMA\n" printf(_(" -N, --exclude-schema=SCHEMA do NOT dump the named schema(s)\n"));
" do NOT dump the named schema\n"));
printf(_(" -o, --oids include OIDs in dump\n")); printf(_(" -o, --oids include OIDs in dump\n"));
printf(_(" -O, --no-owner skip restoration of object ownership\n" printf(_(" -O, --no-owner skip restoration of object ownership\n"
" in plain text format\n")); " in plain text format\n"));
printf(_(" -s, --schema-only dump only the schema, no data\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" printf(_(" -S, --superuser=NAME specify the superuser user name to use in\n"
" plain text format\n")); " plain text format\n"));
printf(_(" -t, --table=TABLE dump the named table only\n")); printf(_(" -t, --table=TABLE dump the named table(s) only\n"));
printf(_(" -T, --exclude-table=TABLE do NOT dump the named table\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(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n")); printf(_(" --disable-dollar-quoting disable dollar quoting, use SQL standard quoting\n"));
printf(_(" --disable-triggers disable triggers during data-only restore\n")); printf(_(" --disable-triggers disable triggers during data-only restore\n"));
printf(_(" --use-set-session-authorization\n" printf(_(" --use-set-session-authorization\n"
" use SESSION AUTHORIZATION commands instead of\n" " use SESSION AUTHORIZATION commands instead of\n"
" OWNER TO commands\n")); " ALTER OWNER commands to set ownership\n"));
printf(_("\nConnection options:\n")); printf(_("\nConnection options:\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
...@@ -928,66 +784,159 @@ exit_nicely(void) ...@@ -928,66 +784,159 @@ exit_nicely(void)
} }
/* /*
* selectDumpableNamespace: policy-setting subroutine * Find the OIDs of all schemas matching the given list of patterns,
* Mark a namespace as to be dumped or not * and append them to the given OID list.
*/ */
static void 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 * We use UNION ALL rather than UNION; this might sometimes result in
* namespaces. If specific namespaces are being dumped, dump just those * duplicate entries in the OID list, but we don't care.
* namespaces. Otherwise, dump all non-system namespaces.
*/ */
nsinfo->dobj.dump = false;
if (matchingTables != NULL) for (cell = patterns->head; cell; cell = cell->next)
/* false */ ;
else if (matchingSchemas != NULL)
{ {
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); res = PQexec(g_conn, query->data);
if (strstr(matchingSchemas, search_oid) != NULL) check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
nsinfo->dobj.dump = true;
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 && PQclear(res);
strcmp(nsinfo->dobj.name, "information_schema") != 0) destroyPQExpBuffer(query);
nsinfo->dobj.dump = true;
} }
/* /*
* selectDumpableTable: policy-setting subroutine * Find the OIDs of all tables matching the given list of patterns,
* Mark a table as to be dumped or not * and append them to the given OID list.
*/ */
static void 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 * We use UNION ALL rather than UNION; this might sometimes result in
* tablename has been specified, dump matching table name; else, do not * duplicate entries in the OID list, but we don't care.
* dump.
*/ */
tbinfo->dobj.dump = false;
if (matchingTables == NULL) for (cell = patterns->head; cell; cell = cell->next)
{ {
if (tbinfo->dobj.namespace->dobj.dump) if (cell != patterns->head)
tbinfo->dobj.dump = true; 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); res = PQexec(g_conn, query->data);
if (strstr(matchingTables, search_oid) != NULL) check_sql_result(res, g_conn, query->data, PGRES_TUPLES_OK);
tbinfo->dobj.dump = true;
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) ...@@ -5596,7 +5545,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
static bool static bool
shouldDumpProcLangs(void) shouldDumpProcLangs(void)
{ {
if (matchingTables != NULL || matchingSchemas != NULL) if (!include_everything)
return false; return false;
/* And they're schema not data */ /* And they're schema not data */
if (dataOnly) if (dataOnly)
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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 ...@@ -41,6 +41,35 @@ typedef struct
typedef int DumpId; 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 * The data structures used to store system catalog information. Every
...@@ -364,6 +393,16 @@ extern TypeInfo *findTypeByOid(Oid oid); ...@@ -364,6 +393,16 @@ extern TypeInfo *findTypeByOid(Oid oid);
extern FuncInfo *findFuncByOid(Oid oid); extern FuncInfo *findFuncByOid(Oid oid);
extern OprInfo *findOprByOid(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 check_conn_and_db(void);
extern void exit_nicely(void); extern void exit_nicely(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment