]> granicus.if.org Git - postgresql/commitdiff
Be more wary about mixed-case database names and user names. Get
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 11 Feb 2002 00:18:20 +0000 (00:18 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 11 Feb 2002 00:18:20 +0000 (00:18 +0000)
the CREATE DATABASE command right in pg_dump -C case.

src/bin/pg_dump/common.c
src/bin/pg_dump/pg_backup.h
src/bin/pg_dump/pg_backup_archiver.c
src/bin/pg_dump/pg_dump.c
src/bin/pg_dump/pg_dump.h
src/bin/pg_dump/pg_dumpall.sh

index 1a32e22b22b3747a7c1bc8a90e7dbb4fcc5da147..907590518cf40834632e1e499a244ae65bd372de 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.61 2002/01/11 23:21:55 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/common.c,v 1.62 2002/02/11 00:18:20 tgl Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -590,65 +590,3 @@ findFuncByName(FuncInfo *finfo, int numFuncs, const char *name)
        }
        return -1;
 }
-
-/*
- * fmtId
- *
- *     checks input string for non-lowercase characters
- *     returns pointer to input string or string surrounded by double quotes
- *
- *     Note that the returned string should be used immediately since it
- *     uses a static buffer to hold the string. Non-reentrant but faster?
- */
-const char *
-fmtId(const char *rawid, bool force_quotes)
-{
-       static PQExpBuffer id_return = NULL;
-       const char *cp;
-
-       if (!force_quotes)
-       {
-               /* do a quick check on the first character... */
-               if (!islower((unsigned char) *rawid))
-                       force_quotes = true;
-               /* otherwise check the entire string */
-               else
-                       for (cp = rawid; *cp; cp++)
-                       {
-                               if (!(islower((unsigned char) *cp) ||
-                                         isdigit((unsigned char) *cp) ||
-                                         (*cp == '_')))
-                               {
-                                       force_quotes = true;
-                                       break;
-                               }
-                       }
-       }
-
-       if (!force_quotes)
-               return rawid;                   /* no quoting needed */
-
-       if (id_return)
-               resetPQExpBuffer(id_return);
-       else
-               id_return = createPQExpBuffer();
-
-       appendPQExpBufferChar(id_return, '\"');
-       for (cp = rawid; *cp; cp++)
-       {
-               /*
-                * Did we find a double-quote in the string? Then make this a
-                * double double-quote per SQL99. Before, we put in a
-                * backslash/double-quote pair. - thomas 2000-08-05
-                */
-               if (*cp == '\"')
-               {
-                       appendPQExpBufferChar(id_return, '\"');
-                       appendPQExpBufferChar(id_return, '\"');
-               }
-               appendPQExpBufferChar(id_return, *cp);
-       }
-       appendPQExpBufferChar(id_return, '\"');
-
-       return id_return->data;
-}      /* fmtId() */
index b81b029e293cbdcd7b06e21d8ec43b669a71cbed..32d4c1e88eb1720eb38eec942b128953cbe77645 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.17 2001/10/28 06:25:58 momjian Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup.h,v 1.18 2002/02/11 00:18:20 tgl Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -136,10 +136,11 @@ extern void
 exit_horribly(Archive *AH, const char *modulename, const char *fmt,...)
 __attribute__((format(printf, 3, 4)));
 
-extern char *
-                       simple_prompt(const char *prompt, int maxlen, bool echo);
+extern char *simple_prompt(const char *prompt, int maxlen, bool echo);
 
-/* Lets the archibe know we have a DB connection to shutdown if it dies */
+extern const char *fmtId(const char *identifier, bool force_quotes);
+
+/* Lets the archive know we have a DB connection to shutdown if it dies */
 
 PGconn *ConnectDatabase(Archive *AH,
                                const char *dbname,
index baebc56e4d4300c6d71c363c1e0d0cde9c1e3b11..2c8ea7d828f899992e07f98cc3008bd7d9eb1094 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.41 2002/02/06 17:27:50 tgl Exp $
+ *             $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.42 2002/02/11 00:18:20 tgl Exp $
  *
  * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
  *
@@ -74,6 +74,7 @@
 #include "pg_backup_archiver.h"
 #include "pg_backup_db.h"
 
+#include <ctype.h>
 #include <errno.h>
 #include <unistd.h>                            /* for dup */
 
@@ -1953,7 +1954,7 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
  * user, this won't do anything.
  *
  * If we're currently restoring right into a database, this will
- * actuall establish a connection.     Otherwise it puts a \connect into
+ * actually establish a connection.    Otherwise it puts a \connect into
  * the script output.
  */
 static void
@@ -1974,7 +1975,8 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
                        PQExpBuffer qry = createPQExpBuffer();
                        PGresult   *res;
 
-                       appendPQExpBuffer(qry, "SET SESSION AUTHORIZATION '%s';", user);
+                       appendPQExpBuffer(qry, "SET SESSION AUTHORIZATION %s;",
+                                                         fmtId(user, false));
                        res = PQexec(AH->connection, qry->data);
 
                        if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
@@ -1985,19 +1987,29 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
                        destroyPQExpBuffer(qry);
                }
                else
-                       ahprintf(AH, "SET SESSION AUTHORIZATION '%s';\n\n", user);
+                       ahprintf(AH, "SET SESSION AUTHORIZATION %s;\n\n",
+                                        fmtId(user, false));
        }
-       /* When -R was given, don't do anything. */
        else if (AH->ropt && AH->ropt->noReconnect)
+       {
+               /* When -R was given, don't do anything. */
                return;
-
+       }
        else if (RestoringToDB(AH))
                ReconnectToServer(AH, dbname, user);
        else
-               /* FIXME: does not handle mixed case user names */
-               ahprintf(AH, "\\connect %s %s\n\n",
-                                dbname ? dbname : "-",
-                                user ? user : "-");
+       {
+               PQExpBuffer qry = createPQExpBuffer();
+
+               appendPQExpBuffer(qry, "\\connect %s",
+                                                 dbname ? fmtId(dbname, false) : "-");
+               appendPQExpBuffer(qry, " %s\n\n",
+                                                 fmtId(user, false));
+
+               ahprintf(AH, qry->data);
+
+               destroyPQExpBuffer(qry);
+       }
 
        /*
         * NOTE: currUser keeps track of what the imaginary session user in
@@ -2025,6 +2037,69 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
 }
 
 
+/*
+ * fmtId
+ *
+ *     checks input string for non-lowercase characters
+ *     returns pointer to input string or string surrounded by double quotes
+ *
+ *     Note that the returned string should be used immediately since it
+ *     uses a static buffer to hold the string. Non-reentrant but faster?
+ */
+const char *
+fmtId(const char *rawid, bool force_quotes)
+{
+       static PQExpBuffer id_return = NULL;
+       const char *cp;
+
+       if (!force_quotes)
+       {
+               /* do a quick check on the first character... */
+               if (!islower((unsigned char) *rawid))
+                       force_quotes = true;
+               /* otherwise check the entire string */
+               else
+                       for (cp = rawid; *cp; cp++)
+                       {
+                               if (!(islower((unsigned char) *cp) ||
+                                         isdigit((unsigned char) *cp) ||
+                                         (*cp == '_')))
+                               {
+                                       force_quotes = true;
+                                       break;
+                               }
+                       }
+       }
+
+       if (!force_quotes)
+               return rawid;                   /* no quoting needed */
+
+       if (id_return)
+               resetPQExpBuffer(id_return);
+       else
+               id_return = createPQExpBuffer();
+
+       appendPQExpBufferChar(id_return, '\"');
+       for (cp = rawid; *cp; cp++)
+       {
+               /*
+                * Did we find a double-quote in the string? Then make this a
+                * double double-quote per SQL99. Before, we put in a
+                * backslash/double-quote pair. - thomas 2000-08-05
+                */
+               if (*cp == '\"')
+               {
+                       appendPQExpBufferChar(id_return, '\"');
+                       appendPQExpBufferChar(id_return, '\"');
+               }
+               appendPQExpBufferChar(id_return, *cp);
+       }
+       appendPQExpBufferChar(id_return, '\"');
+
+       return id_return->data;
+}
+
+
 static int
 _printTocEntry(ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt, bool isData)
 {
index 0eb30b58d16f72ac53e0381bb411f8ad0df1db0b..64b4887e29c48e3dbaf06f1c7d7c57d37c6e223d 100644 (file)
@@ -22,7 +22,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.240 2002/02/06 17:27:50 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.241 2002/02/11 00:18:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1141,15 +1141,24 @@ dumpDatabase(Archive *AH)
        PQExpBuffer creaQry = createPQExpBuffer();
        PGresult   *res;
        int                     ntups;
-       int                     i_dba;
+       int                     i_dba,
+                               i_encoding,
+                               i_datpath;
+       const char *datname,
+                          *dba,
+                          *encoding,
+                          *datpath;
+
+       datname = PQdb(g_conn);
 
        if (g_verbose)
                write_msg(NULL, "saving database definition\n");
 
-       /* Get the dba */
-       appendPQExpBuffer(dbQry, "select (select usename from pg_user where datdba = usesysid) as dba from pg_database"
+       /* Get the database owner and parameters from pg_database */
+       appendPQExpBuffer(dbQry, "select (select usename from pg_user where usesysid = datdba) as dba,"
+                                         " encoding, datpath from pg_database"
                                          " where datname = ");
-       formatStringLiteral(dbQry, PQdb(g_conn), CONV_ALL);
+       formatStringLiteral(dbQry, datname, CONV_ALL);
 
        res = PQexec(g_conn, dbQry->data);
        if (!res ||
@@ -1165,24 +1174,39 @@ dumpDatabase(Archive *AH)
 
        if (ntups <= 0)
        {
-               write_msg(NULL, "missing pg_database entry for database \"%s\"\n", PQdb(g_conn));
+               write_msg(NULL, "missing pg_database entry for database \"%s\"\n",
+                                 datname);
                exit_nicely();
        }
 
        if (ntups != 1)
        {
                write_msg(NULL, "query returned more than one (%d) pg_database entry for database \"%s\"\n",
-                                 ntups, PQdb(g_conn));
+                                 ntups, datname);
                exit_nicely();
        }
 
-       appendPQExpBuffer(creaQry, "Create Database \"%s\";\n", PQdb(g_conn));
-       appendPQExpBuffer(delQry, "Drop Database \"%s\";\n", PQdb(g_conn));
        i_dba = PQfnumber(res, "dba");
-
-       ArchiveEntry(AH, "0" /* OID */ , PQdb(g_conn) /* Name */ , "DATABASE", NULL,
+       i_encoding = PQfnumber(res, "encoding");
+       i_datpath = PQfnumber(res, "datpath");
+       dba = PQgetvalue(res, 0, i_dba);
+       encoding = PQgetvalue(res, 0, i_encoding);
+       datpath = PQgetvalue(res, 0, i_datpath);
+
+       appendPQExpBuffer(creaQry, "CREATE DATABASE %s WITH TEMPLATE = template0",
+                                         fmtId(datname, force_quotes));
+       if (strlen(encoding) > 0)
+               appendPQExpBuffer(creaQry, " ENCODING = %s", encoding);
+       if (strlen(datpath) > 0)
+               appendPQExpBuffer(creaQry, " LOCATION = '%s'", datpath);
+       appendPQExpBuffer(creaQry, ";\n");
+
+       appendPQExpBuffer(delQry, "DROP DATABASE %s;\n",
+                                         fmtId(datname, force_quotes));
+
+       ArchiveEntry(AH, "0" /* OID */ , datname /* Name */ , "DATABASE", NULL,
                                 creaQry->data /* Create */ , delQry->data /* Del */ ,
-                                "" /* Copy */ , PQgetvalue(res, 0, i_dba) /* Owner */ ,
+                                "" /* Copy */ , dba /* Owner */ ,
                                 NULL /* Dumper */ , NULL /* Dumper Arg */ );
 
        PQclear(res);
index 3af39b8d2e59979132a84995d19f4a313dfc7764..0d69fda200b78945b175c50ddc45461987a662a1 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_dump.h,v 1.77 2002/01/11 23:21:55 tgl Exp $
+ * $Id: pg_dump.h,v 1.78 2002/02/11 00:18:20 tgl Exp $
  *
  * Modifications - 6/12/96 - dave@bensoft.com - version 1.13.dhb.2
  *
@@ -280,7 +280,6 @@ extern void dumpTables(Archive *fout, TableInfo *tbinfo, int numTables,
                   const bool schemaOnly, const bool dataOnly);
 extern void dumpIndexes(Archive *fout, IndInfo *indinfo, int numIndexes,
                        TableInfo *tbinfo, int numTables, const char *tablename);
-extern const char *fmtId(const char *identifier, bool force_quotes);
 extern void exit_nicely(void);
 
 #endif   /* PG_DUMP_H */
index 122cf75b2dc33ced1768101c7cbb080270cdf220..7aab5e2d7664e654bc225b79a069d28022ffd489 100644 (file)
@@ -6,7 +6,7 @@
 # and "pg_group" tables, which belong to the whole installation rather
 # than any one individual database.
 #
-# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.14 2002/01/09 04:56:44 momjian Exp $
+# $Header: /cvsroot/pgsql/src/bin/pg_dump/Attic/pg_dumpall.sh,v 1.15 2002/02/11 00:18:20 tgl Exp $
 
 CMDNAME=`basename $0`
 
@@ -217,7 +217,7 @@ while read DATABASE DBOWNER ENCODING ISTEMPLATE DBPATH; do
     echo "--"
     echo "-- Database $DATABASE"
     echo "--"
-    echo "${BS}connect template1 $DBOWNER"
+    echo "${BS}connect template1 \"$DBOWNER\""
 
     if [ "$cleanschema" = yes -a "$DATABASE" != template1 ] ; then
         echo "DROP DATABASE \"$DATABASE\";"
@@ -234,7 +234,7 @@ while read DATABASE DBOWNER ENCODING ISTEMPLATE DBPATH; do
        echo "$createdbcmd;"
     fi
 
-    echo "${BS}connect $DATABASE $DBOWNER"
+    echo "${BS}connect \"$DATABASE\" \"$DBOWNER\""
     echo "dumping database \"$DATABASE\"..." 1>&2
     $PGDUMP "$DATABASE" <&4
     if [ "$?" -ne 0 ] ; then