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.
This commit is contained in:
Tom Lane 2003-06-11 16:29:42 +00:00
parent 7481b7d1e4
commit 8bfe93c5c8
4 changed files with 37 additions and 158 deletions

View File

@ -1,5 +1,5 @@
<!--
$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
-->
@ -287,9 +287,9 @@ PostgreSQL documentation
<note>
<para>
In this mode, <application>pg_dump</application> makes no
attempt to dump any other database objects that may depend
upon objects in the selected schema. Therefore, there is no
guarantee that the results of a single schema dump can be
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.
</para>
</note>
@ -394,18 +394,18 @@ PostgreSQL documentation
<listitem>
<para>
Dump data for <replaceable class="parameter">table</replaceable>
only. If <literal>*</literal> is specified, all tables in the
specified database will be dumped. It is possible for there to be
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.
is the case, all matching tables will be dumped. Specify both
<option>--schema</> and <option>--table</> to select just one table.
</para>
<note>
<para>
In this mode, <application>pg_dump</application> makes no
attempt to dump any other database objects that may depend
upon the selected table. Therefore, there is no guarantee
that the results of a single table dump can be successfully
attempt to dump any other database objects that the selected table
may depend upon. Therefore, there is no guarantee
that the results of a single-table dump can be successfully
restored by themselves into a clean database.
</para>
</note>
@ -652,7 +652,7 @@ CREATE DATABASE foo WITH TEMPLATE template0;
<para>
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>
</refsect1>

View File

@ -1,4 +1,4 @@
<!-- $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">
<refmeta>
@ -269,7 +269,9 @@
<term><option>--function=<replaceable class="parameter">function-name(argtype [, ...])</replaceable></option></term>
<listitem>
<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>
</listitem>
</varlistentry>
@ -318,7 +320,7 @@
<term><option>--schema-only</option></term>
<listitem>
<para>
Restore only the schema (data defintions), not the data.
Restore only the schema (data definitions), not the data.
Sequence values will be reset.
</para>
</listitem>
@ -557,7 +559,7 @@ CREATE DATABASE foo WITH TEMPLATE template0;
<para>
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>
</refsect1>

View File

@ -12,7 +12,7 @@
* by PostgreSQL
*
* 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
} DumpContext;
static void help(const char *progname);
static void formatIdentifierArg(char *identifier);
static NamespaceInfo *findNamespace(const char *nsoid, const char *objoid);
static void dumpClasses(const TableInfo *tblinfo, const int numTables,
Archive *fout, const bool oids);
@ -311,7 +310,6 @@ main(int argc, char **argv)
case 'n': /* Dump data for this schema only */
selectSchemaName = strdup(optarg);
formatIdentifierArg(selectSchemaName);
break;
case 'o': /* Dump oids */
@ -341,17 +339,6 @@ main(int argc, char **argv)
case 't': /* Dump data for this table only */
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;
case 'u':
@ -436,10 +423,10 @@ main(int argc, char **argv)
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, "Use all tables or a full dump instead.\n");
write_msg(NULL, "Use a full dump instead.\n");
exit(1);
}
@ -450,13 +437,6 @@ main(int argc, char **argv)
exit(1);
}
if (selectTableName != NULL && selectSchemaName != NULL)
{
write_msg(NULL, "Single table and single schema dumps cannot be used simultaneously.\n");
write_msg(NULL, "Use one option or the other, not both.\n");
exit(1);
}
if (dumpData == true && oids == true)
{
write_msg(NULL, "INSERT (-d, -D) and OID (-o) options cannot be used together.\n");
@ -676,7 +656,7 @@ help(const char *progname)
printf(_(" -C, --create include commands to create database in dump\n"));
printf(_(" -d, --inserts dump data as INSERT, rather than COPY, commands\n"));
printf(_(" -D, --column-inserts dump data as INSERT commands with column names\n"));
printf(_(" -n, --schema=SCHEMA dump this schema only\n"));
printf(_(" -n, --schema=SCHEMA dump the named schema only\n"));
printf(_(" -o, --oids include OIDs in dump\n"));
printf(_(" -O, --no-owner do not output \\connect commands in plain\n"
" text format\n"));
@ -685,7 +665,7 @@ help(const char *progname)
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 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 use-set-session-authorization, --use-set-session-authorization\n"
" output SET SESSION AUTHORIZATION commands rather\n"
@ -704,38 +684,6 @@ help(const char *progname)
printf(_("Report bugs to <pgsql-bugs@postgresql.org>.\n"));
}
/*
* Accepts an identifier as specified as a command-line argument, and
* converts it into a form acceptable to the PostgreSQL backend. The
* input string is modified in-place.
*/
static void
formatIdentifierArg(char *identifier)
{
/*
* quoted string? Then strip quotes and preserve
* case...
*/
if (identifier[0] == '"')
{
char *endptr;
endptr = identifier + strlen(identifier) - 1;
if (*endptr == '"')
*endptr = '\0';
strcpy(identifier, &identifier[1]);
}
else
{
int i;
/* otherwise, convert identifier name to lowercase... */
for (i = 0; identifier[i]; i++)
if (isupper((unsigned char) identifier[i]))
identifier[i] = tolower((unsigned char) identifier[i]);
}
}
void
exit_nicely(void)
{
@ -785,12 +733,18 @@ selectDumpableTable(TableInfo *tbinfo)
* tablename has been specified, dump matching table name; else, do
* not dump.
*/
tbinfo->dump = false;
if (tbinfo->relnamespace->dump)
tbinfo->dump = true;
else if (selectTableName != NULL)
tbinfo->dump = (strcmp(tbinfo->relname, selectTableName) == 0);
else
tbinfo->dump = false;
else if (selectTableName != NULL &&
strcmp(tbinfo->relname, selectTableName) == 0)
{
/* 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;
}
}
/*

View File

@ -34,7 +34,7 @@
*
*
* 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;
/* Forward decls */
static void usage(const char *progname);
static char *_cleanupName(char *name);
static char *_cleanupFuncName(char *name);
typedef struct option optType;
int
main(int argc, char **argv)
{
@ -220,17 +217,17 @@ main(int argc, char **argv)
case 'P': /* Function */
opts->selTypes = 1;
opts->selFunction = 1;
opts->functionNames = _cleanupFuncName(optarg);
opts->functionNames = strdup(optarg);
break;
case 'I': /* Index */
opts->selTypes = 1;
opts->selIndex = 1;
opts->indexNames = _cleanupName(optarg);
opts->indexNames = strdup(optarg);
break;
case 'T': /* Trigger */
opts->selTypes = 1;
opts->selTrigger = 1;
opts->triggerNames = _cleanupName(optarg);
opts->triggerNames = strdup(optarg);
break;
case 's': /* dump schema only */
opts->schemaOnly = 1;
@ -242,7 +239,7 @@ main(int argc, char **argv)
case 't': /* Dump data for this table only */
opts->selTypes = 1;
opts->selTable = 1;
opts->tableNames = _cleanupName(optarg);
opts->tableNames = strdup(optarg);
break;
case 'u':
@ -417,77 +414,3 @@ usage(const char *progname)
printf(_("\nIf no input file name is supplied, then standard input is used.\n\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;
}