From: Tom Lane Date: Wed, 11 Jun 2003 16:29:42 +0000 (+0000) Subject: pg_dump and pg_restore were stripping quotes and downcasing some but X-Git-Tag: REL9_0_0~15169 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=8bfe93c5c8b10c9a824fd07138c55d3a857f4e98;p=pg-rex%2Fsyncrep.git 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. --- diff --git a/doc/src/sgml/ref/pg_dump.sgml b/doc/src/sgml/ref/pg_dump.sgml index 79f30c771f..5b9e2d4c40 100644 --- a/doc/src/sgml/ref/pg_dump.sgml +++ b/doc/src/sgml/ref/pg_dump.sgml @@ -1,5 +1,5 @@ @@ -287,9 +287,9 @@ PostgreSQL documentation In this mode, pg_dump 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. @@ -394,18 +394,18 @@ PostgreSQL documentation Dump data for table - only. If * 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 + In this mode, pg_dump 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. @@ -652,7 +652,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; Once restored, it is wise to run ANALYZE on each - restored object so the optimizer has useful statistics. + restored table so the optimizer has useful statistics. diff --git a/doc/src/sgml/ref/pg_restore.sgml b/doc/src/sgml/ref/pg_restore.sgml index ffc019b3e5..cf028b93e5 100644 --- a/doc/src/sgml/ref/pg_restore.sgml +++ b/doc/src/sgml/ref/pg_restore.sgml @@ -1,4 +1,4 @@ - + @@ -269,7 +269,9 @@ - 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. @@ -318,7 +320,7 @@ - Restore only the schema (data defintions), not the data. + Restore only the schema (data definitions), not the data. Sequence values will be reset. @@ -557,7 +559,7 @@ CREATE DATABASE foo WITH TEMPLATE template0; Once restored, it is wise to run ANALYZE on each - restored object so the optimizer has useful statistics. + restored table so the optimizer has useful statistics. diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c index 9ea5ac2786..e241c8e15b 100644 --- a/src/bin/pg_dump/pg_dump.c +++ b/src/bin/pg_dump/pg_dump.c @@ -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 .\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; + } } /* diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 60fff5ff70..be4fac3571 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -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 .\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; -}