1515 *
1616 *
1717 * IDENTIFICATION
18- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.41 2002/02/06 17:27:50 tgl Exp $
18+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_backup_archiver.c,v 1.42 2002/02/11 00:18:20 tgl Exp $
1919 *
2020 * Modifications - 28-Jun-2000 - pjw@rhyme.com.au
2121 *
7474#include "pg_backup_archiver.h"
7575#include "pg_backup_db.h"
7676
77+ #include <ctype.h>
7778#include <errno.h>
7879#include <unistd.h> /* for dup */
7980
@@ -1953,7 +1954,7 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
19531954 * user, this won't do anything.
19541955 *
19551956 * If we're currently restoring right into a database, this will
1956- * actuall establish a connection. Otherwise it puts a \connect into
1957+ * actually establish a connection. Otherwise it puts a \connect into
19571958 * the script output.
19581959 */
19591960static void
@@ -1974,7 +1975,8 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
19741975 PQExpBuffer qry = createPQExpBuffer ();
19751976 PGresult * res ;
19761977
1977- appendPQExpBuffer (qry , "SET SESSION AUTHORIZATION '%s';" , user );
1978+ appendPQExpBuffer (qry , "SET SESSION AUTHORIZATION %s;" ,
1979+ fmtId (user , false));
19781980 res = PQexec (AH -> connection , qry -> data );
19791981
19801982 if (!res || PQresultStatus (res ) != PGRES_COMMAND_OK )
@@ -1985,19 +1987,29 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
19851987 destroyPQExpBuffer (qry );
19861988 }
19871989 else
1988- ahprintf (AH , "SET SESSION AUTHORIZATION '%s';\n\n" , user );
1990+ ahprintf (AH , "SET SESSION AUTHORIZATION %s;\n\n" ,
1991+ fmtId (user , false));
19891992 }
1990- /* When -R was given, don't do anything. */
19911993 else if (AH -> ropt && AH -> ropt -> noReconnect )
1994+ {
1995+ /* When -R was given, don't do anything. */
19921996 return ;
1993-
1997+ }
19941998 else if (RestoringToDB (AH ))
19951999 ReconnectToServer (AH , dbname , user );
19962000 else
1997- /* FIXME: does not handle mixed case user names */
1998- ahprintf (AH , "\\connect %s %s\n\n" ,
1999- dbname ? dbname : "-" ,
2000- user ? user : "-" );
2001+ {
2002+ PQExpBuffer qry = createPQExpBuffer ();
2003+
2004+ appendPQExpBuffer (qry , "\\connect %s" ,
2005+ dbname ? fmtId (dbname , false) : "-" );
2006+ appendPQExpBuffer (qry , " %s\n\n" ,
2007+ fmtId (user , false));
2008+
2009+ ahprintf (AH , qry -> data );
2010+
2011+ destroyPQExpBuffer (qry );
2012+ }
20012013
20022014 /*
20032015 * NOTE: currUser keeps track of what the imaginary session user in
@@ -2025,6 +2037,69 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
20252037}
20262038
20272039
2040+ /*
2041+ * fmtId
2042+ *
2043+ * checks input string for non-lowercase characters
2044+ * returns pointer to input string or string surrounded by double quotes
2045+ *
2046+ * Note that the returned string should be used immediately since it
2047+ * uses a static buffer to hold the string. Non-reentrant but faster?
2048+ */
2049+ const char *
2050+ fmtId (const char * rawid , bool force_quotes )
2051+ {
2052+ static PQExpBuffer id_return = NULL ;
2053+ const char * cp ;
2054+
2055+ if (!force_quotes )
2056+ {
2057+ /* do a quick check on the first character... */
2058+ if (!islower ((unsigned char ) * rawid ))
2059+ force_quotes = true;
2060+ /* otherwise check the entire string */
2061+ else
2062+ for (cp = rawid ; * cp ; cp ++ )
2063+ {
2064+ if (!(islower ((unsigned char ) * cp ) ||
2065+ isdigit ((unsigned char ) * cp ) ||
2066+ (* cp == '_' )))
2067+ {
2068+ force_quotes = true;
2069+ break ;
2070+ }
2071+ }
2072+ }
2073+
2074+ if (!force_quotes )
2075+ return rawid ; /* no quoting needed */
2076+
2077+ if (id_return )
2078+ resetPQExpBuffer (id_return );
2079+ else
2080+ id_return = createPQExpBuffer ();
2081+
2082+ appendPQExpBufferChar (id_return , '\"' );
2083+ for (cp = rawid ; * cp ; cp ++ )
2084+ {
2085+ /*
2086+ * Did we find a double-quote in the string? Then make this a
2087+ * double double-quote per SQL99. Before, we put in a
2088+ * backslash/double-quote pair. - thomas 2000-08-05
2089+ */
2090+ if (* cp == '\"' )
2091+ {
2092+ appendPQExpBufferChar (id_return , '\"' );
2093+ appendPQExpBufferChar (id_return , '\"' );
2094+ }
2095+ appendPQExpBufferChar (id_return , * cp );
2096+ }
2097+ appendPQExpBufferChar (id_return , '\"' );
2098+
2099+ return id_return -> data ;
2100+ }
2101+
2102+
20282103static int
20292104_printTocEntry (ArchiveHandle * AH , TocEntry * te , RestoreOptions * ropt , bool isData )
20302105{
0 commit comments