15
15
*
16
16
*
17
17
* 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 $
19
19
*
20
20
* Modifications - 28-Jun-2000 - pjw@rhyme.com.au
21
21
*
74
74
#include "pg_backup_archiver.h"
75
75
#include "pg_backup_db.h"
76
76
77
+ #include <ctype.h>
77
78
#include <errno.h>
78
79
#include <unistd.h> /* for dup */
79
80
@@ -1953,7 +1954,7 @@ _tocEntryRequired(TocEntry *te, RestoreOptions *ropt)
1953
1954
* user, this won't do anything.
1954
1955
*
1955
1956
* 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
1957
1958
* the script output.
1958
1959
*/
1959
1960
static void
@@ -1974,7 +1975,8 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
1974
1975
PQExpBuffer qry = createPQExpBuffer ();
1975
1976
PGresult * res ;
1976
1977
1977
- appendPQExpBuffer (qry ,"SET SESSION AUTHORIZATION '%s';" ,user );
1978
+ appendPQExpBuffer (qry ,"SET SESSION AUTHORIZATION %s;" ,
1979
+ fmtId (user , false));
1978
1980
res = PQexec (AH -> connection ,qry -> data );
1979
1981
1980
1982
if (!res || PQresultStatus (res )!= PGRES_COMMAND_OK )
@@ -1985,19 +1987,29 @@ _reconnectAsUser(ArchiveHandle *AH, const char *dbname, const char *user)
1985
1987
destroyPQExpBuffer (qry );
1986
1988
}
1987
1989
else
1988
- ahprintf (AH ,"SET SESSION AUTHORIZATION '%s';\n\n" ,user );
1990
+ ahprintf (AH ,"SET SESSION AUTHORIZATION %s;\n\n" ,
1991
+ fmtId (user , false));
1989
1992
}
1990
- /* When -R was given, don't do anything. */
1991
1993
else if (AH -> ropt && AH -> ropt -> noReconnect )
1994
+ {
1995
+ /* When -R was given, don't do anything. */
1992
1996
return ;
1993
-
1997
+ }
1994
1998
else if (RestoringToDB (AH ))
1995
1999
ReconnectToServer (AH ,dbname ,user );
1996
2000
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
+ }
2001
2013
2002
2014
/*
2003
2015
* NOTE: currUser keeps track of what the imaginary session user in
@@ -2025,6 +2037,69 @@ _reconnectAsOwner(ArchiveHandle *AH, const char *dbname, TocEntry *te)
2025
2037
}
2026
2038
2027
2039
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
+
2028
2103
static int
2029
2104
_printTocEntry (ArchiveHandle * AH ,TocEntry * te ,RestoreOptions * ropt ,bool isData )
2030
2105
{