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)
19741975PQExpBuffer qry = createPQExpBuffer ();
19751976PGresult * res ;
19761977
1977- appendPQExpBuffer (qry ,"SET SESSION AUTHORIZATION '%s';" ,user );
1978+ appendPQExpBuffer (qry ,"SET SESSION AUTHORIZATION %s;" ,
1979+ fmtId (user , false));
19781980res = PQexec (AH -> connection ,qry -> data );
19791981
19801982if (!res || PQresultStatus (res )!= PGRES_COMMAND_OK )
@@ -1985,19 +1987,29 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
19851987destroyPQExpBuffer (qry );
19861988}
19871989else
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. */
19911993else if (AH -> ropt && AH -> ropt -> noReconnect )
1994+ {
1995+ /* When -R was given, don't do anything. */
19921996return ;
1993-
1997+ }
19941998else if (RestoringToDB (AH ))
19951999ReconnectToServer (AH ,dbname ,user );
19962000else
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 ((unsignedchar )* rawid ))
2059+ force_quotes = true;
2060+ /* otherwise check the entire string */
2061+ else
2062+ for (cp = rawid ;* cp ;cp ++ )
2063+ {
2064+ if (!(islower ((unsignedchar )* cp )||
2065+ isdigit ((unsignedchar )* 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{