Commit 8bfe93c5 authored by Tom Lane's avatar Tom Lane

pg_dump and pg_restore were stripping quotes and downcasing some but

not all SQL identifiers taken from command line arguments.  We decided
years ago that that was a bad idea: identifiers taken from the command
line should be treated as literally correct.  Remove the inconsistent
code that has crept in recently.  Also fix pg_dump so that the combination
of --schema and --table does what you'd expect, namely dump exactly one
table from exactly one schema.  Per gripe from Deepak Bhole of Red Hat.
parent 7481b7d1
<!-- <!--
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.61 2003/04/17 15:34:37 momjian Exp $ $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.62 2003/06/11 16:29:42 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
...@@ -287,9 +287,9 @@ PostgreSQL documentation ...@@ -287,9 +287,9 @@ PostgreSQL documentation
<note> <note>
<para> <para>
In this mode, <application>pg_dump</application> makes no In this mode, <application>pg_dump</application> makes no
attempt to dump any other database objects that may depend attempt to dump any other database objects that objects in the
upon objects in the selected schema. Therefore, there is no selected schema may depend upon. Therefore, there is no
guarantee that the results of a single schema dump can be guarantee that the results of a single-schema dump can be
successfully restored by themselves into a clean database. successfully restored by themselves into a clean database.
</para> </para>
</note> </note>
...@@ -394,18 +394,18 @@ PostgreSQL documentation ...@@ -394,18 +394,18 @@ PostgreSQL documentation
<listitem> <listitem>
<para> <para>
Dump data for <replaceable class="parameter">table</replaceable> Dump data for <replaceable class="parameter">table</replaceable>
only. If <literal>*</literal> is specified, all tables in the only. It is possible for there to be
specified database will be dumped. It is possible for there to be
multiple tables with the same name in different schemas; if that multiple tables with the same name in different schemas; if that
is the case, all matching tables will be dumped. is the case, all matching tables will be dumped. Specify both
<option>--schema</> and <option>--table</> to select just one table.
</para> </para>
<note> <note>
<para> <para>
In this mode, <application>pg_dump</application> makes no In this mode, <application>pg_dump</application> makes no
attempt to dump any other database objects that may depend attempt to dump any other database objects that the selected table
upon the selected table. Therefore, there is no guarantee may depend upon. Therefore, there is no guarantee
that the results of a single table dump can be successfully that the results of a single-table dump can be successfully
restored by themselves into a clean database. restored by themselves into a clean database.
</para> </para>
</note> </note>
...@@ -652,7 +652,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; ...@@ -652,7 +652,7 @@ CREATE DATABASE foo WITH TEMPLATE template0;
<para> <para>
Once restored, it is wise to run <command>ANALYZE</> on each Once restored, it is wise to run <command>ANALYZE</> on each
restored object so the optimizer has useful statistics. restored table so the optimizer has useful statistics.
</para> </para>
</refsect1> </refsect1>
......
<!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v 1.38 2003/03/25 16:15:43 petere Exp $ --> <!-- $Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_restore.sgml,v 1.39 2003/06/11 16:29:42 tgl Exp $ -->
<refentry id="APP-PGRESTORE"> <refentry id="APP-PGRESTORE">
<refmeta> <refmeta>
...@@ -269,7 +269,9 @@ ...@@ -269,7 +269,9 @@
<term><option>--function=<replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term> <term><option>--function=<replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term>
<listitem> <listitem>
<para> <para>
Restore the named function only. Restore the named function only. Be careful to spell the function
name and arguments exactly as they appear in the dump file's table
of contents.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
...@@ -318,7 +320,7 @@ ...@@ -318,7 +320,7 @@
<term><option>--schema-only</option></term> <term><option>--schema-only</option></term>
<listitem> <listitem>
<para> <para>
Restore only the schema (data defintions), not the data. Restore only the schema (data definitions), not the data.
Sequence values will be reset. Sequence values will be reset.
</para> </para>
</listitem> </listitem>
...@@ -557,7 +559,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; ...@@ -557,7 +559,7 @@ CREATE DATABASE foo WITH TEMPLATE template0;
<para> <para>
Once restored, it is wise to run <command>ANALYZE</> on each Once restored, it is wise to run <command>ANALYZE</> on each
restored object so the optimizer has useful statistics. restored table so the optimizer has useful statistics.
</para> </para>
</refsect1> </refsect1>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.332 2003/06/11 05:13:08 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.333 2003/06/11 16:29:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -72,7 +72,6 @@ typedef struct _dumpContext ...@@ -72,7 +72,6 @@ typedef struct _dumpContext
} DumpContext; } DumpContext;
static void help(const char *progname); static void help(const char *progname);
static void formatIdentifierArg(char *identifier);
static NamespaceInfo *findNamespace(const char *nsoid, const char *objoid); static NamespaceInfo *findNamespace(const char *nsoid, const char *objoid);
static void dumpClasses(const TableInfo *tblinfo, const int numTables, static void dumpClasses(const TableInfo *tblinfo, const int numTables,
Archive *fout, const bool oids); Archive *fout, const bool oids);
...@@ -311,7 +310,6 @@ main(int argc, char **argv) ...@@ -311,7 +310,6 @@ main(int argc, char **argv)
case 'n': /* Dump data for this schema only */ case 'n': /* Dump data for this schema only */
selectSchemaName = strdup(optarg); selectSchemaName = strdup(optarg);
formatIdentifierArg(selectSchemaName);
break; break;
case 'o': /* Dump oids */ case 'o': /* Dump oids */
...@@ -341,17 +339,6 @@ main(int argc, char **argv) ...@@ -341,17 +339,6 @@ main(int argc, char **argv)
case 't': /* Dump data for this table only */ case 't': /* Dump data for this table only */
selectTableName = strdup(optarg); selectTableName = strdup(optarg);
/*
* '*' is a special case meaning ALL tables, but
* only if unquoted
*/
if (selectTableName[0] != '"' &&
strcmp(selectTableName, "*") == 0)
selectTableName[0] = '\0';
else
formatIdentifierArg(selectTableName);
break; break;
case 'u': case 'u':
...@@ -436,10 +423,10 @@ main(int argc, char **argv) ...@@ -436,10 +423,10 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
if (outputBlobs && selectTableName != NULL && strlen(selectTableName) > 0) if (outputBlobs && selectTableName != NULL)
{ {
write_msg(NULL, "Large object output is not supported for a single table.\n"); write_msg(NULL, "Large object output is not supported for a single table.\n");
write_msg(NULL, "Use all tables or a full dump instead.\n"); write_msg(NULL, "Use a full dump instead.\n");
exit(1); exit(1);
} }
...@@ -450,13 +437,6 @@ main(int argc, char **argv) ...@@ -450,13 +437,6 @@ main(int argc, char **argv)
exit(1); exit(1);
} }
if (selectTableName != NULL && selectSchemaName != NULL)
{
write_msg(NULL, "Single table and single schema dumps cannot be used simultaneously.\n");
write_msg(NULL, "Use one option or the other, not both.\n");
exit(1);
}
if (dumpData == true && oids == true) if (dumpData == 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");
...@@ -676,7 +656,7 @@ help(const char *progname) ...@@ -676,7 +656,7 @@ help(const char *progname)
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, rather than COPY, commands\n")); printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n"));
printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n")); printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n"));
printf(_(" -n, --schema=SCHEMA dump this schema only\n")); printf(_(" -n, --schema=SCHEMA dump the named schema only\n"));
printf(_(" -o, --oids include OIDs in dump\n")); printf(_(" -o, --oids include OIDs in dump\n"));
printf(_(" -O, --no-owner do not output \\connect commands in plain\n" printf(_(" -O, --no-owner do not output \\connect commands in plain\n"
" text format\n")); " text format\n"));
...@@ -685,7 +665,7 @@ help(const char *progname) ...@@ -685,7 +665,7 @@ help(const char *progname)
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 this table only (* for all)\n")); printf(_(" -t, --table=TABLE dump the named table only\n"));
printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n")); printf(_(" -x, --no-privileges do not dump privileges (grant/revoke)\n"));
printf(_(" -X use-set-session-authorization, --use-set-session-authorization\n" printf(_(" -X use-set-session-authorization, --use-set-session-authorization\n"
" output SET SESSION AUTHORIZATION commands rather\n" " output SET SESSION AUTHORIZATION commands rather\n"
...@@ -704,38 +684,6 @@ help(const char *progname) ...@@ -704,38 +684,6 @@ help(const char *progname)
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n")); printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
} }
/*
* Accepts an identifier as specified as a command-line argument, and
* converts it into a form acceptable to the PostgreSQL backend. The
* input string is modified in-place.
*/
static void
formatIdentifierArg(char *identifier)
{
/*
* quoted string? Then strip quotes and preserve
* case...
*/
if (identifier[0] == '"')
{
char *endptr;
endptr = identifier + strlen(identifier) - 1;
if (*endptr == '"')
*endptr = '\0';
strcpy(identifier, &identifier[1]);
}
else
{
int i;
/* otherwise, convert identifier name to lowercase... */
for (i = 0; identifier[i]; i++)
if (isupper((unsigned char) identifier[i]))
identifier[i] = tolower((unsigned char) identifier[i]);
}
}
void void
exit_nicely(void) exit_nicely(void)
{ {
...@@ -785,12 +733,18 @@ selectDumpableTable(TableInfo *tbinfo) ...@@ -785,12 +733,18 @@ selectDumpableTable(TableInfo *tbinfo)
* tablename has been specified, dump matching table name; else, do * tablename has been specified, dump matching table name; else, do
* not dump. * not dump.
*/ */
tbinfo->dump = false;
if (tbinfo->relnamespace->dump) if (tbinfo->relnamespace->dump)
tbinfo->dump = true; tbinfo->dump = true;
else if (selectTableName != NULL) else if (selectTableName != NULL &&
tbinfo->dump = (strcmp(tbinfo->relname, selectTableName) == 0); strcmp(tbinfo->relname, selectTableName) == 0)
else {
tbinfo->dump = false; /* If both -s and -t specified, must match both to dump */
if (selectSchemaName == NULL)
tbinfo->dump = true;
else if (strcmp(tbinfo->relnamespace->nspname, selectSchemaName) == 0)
tbinfo->dump = true;
}
} }
/* /*
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.46 2003/06/11 05:13:11 momjian Exp $ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_restore.c,v 1.47 2003/06/11 16:29:42 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -72,12 +72,9 @@ int optreset; ...@@ -72,12 +72,9 @@ int optreset;
/* Forward decls */ /* Forward decls */
static void usage(const char *progname); static void usage(const char *progname);
static char *_cleanupName(char *name);
static char *_cleanupFuncName(char *name);
typedef struct option optType; typedef struct option optType;
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
...@@ -220,17 +217,17 @@ main(int argc, char **argv) ...@@ -220,17 +217,17 @@ main(int argc, char **argv)
case 'P': /* Function */ case 'P': /* Function */
opts->selTypes = 1; opts->selTypes = 1;
opts->selFunction = 1; opts->selFunction = 1;
opts->functionNames = _cleanupFuncName(optarg); opts->functionNames = strdup(optarg);
break; break;
case 'I': /* Index */ case 'I': /* Index */
opts->selTypes = 1; opts->selTypes = 1;
opts->selIndex = 1; opts->selIndex = 1;
opts->indexNames = _cleanupName(optarg); opts->indexNames = strdup(optarg);
break; break;
case 'T': /* Trigger */ case 'T': /* Trigger */
opts->selTypes = 1; opts->selTypes = 1;
opts->selTrigger = 1; opts->selTrigger = 1;
opts->triggerNames = _cleanupName(optarg); opts->triggerNames = strdup(optarg);
break; break;
case 's': /* dump schema only */ case 's': /* dump schema only */
opts->schemaOnly = 1; opts->schemaOnly = 1;
...@@ -242,7 +239,7 @@ main(int argc, char **argv) ...@@ -242,7 +239,7 @@ main(int argc, char **argv)
case 't': /* Dump data for this table only */ case 't': /* Dump data for this table only */
opts->selTypes = 1; opts->selTypes = 1;
opts->selTable = 1; opts->selTable = 1;
opts->tableNames = _cleanupName(optarg); opts->tableNames = strdup(optarg);
break; break;
case 'u': case 'u':
...@@ -417,77 +414,3 @@ usage(const char *progname) ...@@ -417,77 +414,3 @@ usage(const char *progname)
printf(_("\nIf no input file name is supplied, then standard input is used.\n\n")); printf(_("\nIf no input file name is supplied, then standard input is used.\n\n"));
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n")); printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
} }
static char *
_cleanupName(char *name)
{
int i;
if (!name || !name[0])
return NULL;
name = strdup(name);
if (name[0] == '"')
{
strcpy(name, &name[1]);
if (name[0] && *(name + strlen(name) - 1) == '"')
*(name + strlen(name) - 1) = '\0';
}
/* otherwise, convert table name to lowercase... */
else
{
for (i = 0; name[i]; i++)
if (isupper((unsigned char) name[i]))
name[i] = tolower((unsigned char) name[i]);
}
return name;
}
static char *
_cleanupFuncName(char *name)
{
int i;
char *ch;
if (!name || !name[0])
return NULL;
name = strdup(name);
if (name[0] == '"')
{
strcpy(name, &name[1]);
if (strchr(name, '"') != NULL)
strcpy(strchr(name, '"'), strchr(name, '"') + 1);
}
/* otherwise, convert function name to lowercase... */
else
{
for (i = 0; name[i]; i++)
if (isupper((unsigned char) name[i]))
name[i] = tolower((unsigned char) name[i]);
}
/* strip out any space before paren */
ch = strchr(name, '(');
while (ch && ch > name && *(ch - 1) == ' ')
{
strcpy(ch - 1, ch);
ch--;
}
/*
* Strip out spaces after commas in parameter list. We can't remove
* all spaces because some types, like 'double precision' have spaces.
*/
if ((ch = strchr(name, '(')) != NULL)
{
while ((ch = strstr(ch, ", ")) != NULL)
strcpy(ch + 1, ch + 2);
}
return name;
}
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