2525 *http://archives.postgresql.org/pgsql-bugs/2010-02/msg00187.php
2626 *
2727 * IDENTIFICATION
28- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.581 2010/07/06 19:18:59 momjian Exp $
28+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.582 2010/07/14 21:21:08 tgl Exp $
2929 *
3030 *-------------------------------------------------------------------------
3131 */
@@ -173,7 +173,7 @@ static void dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo);
173173static void dumpTSConfig (Archive * fout ,TSConfigInfo * cfginfo );
174174static void dumpForeignDataWrapper (Archive * fout ,FdwInfo * fdwinfo );
175175static void dumpForeignServer (Archive * fout ,ForeignServerInfo * srvinfo );
176- static void dumpUserMappings (Archive * fout ,const char * target ,
176+ static void dumpUserMappings (Archive * fout ,
177177const char * servername ,const char * namespace ,
178178const char * owner ,CatalogId catalogId ,DumpId dumpId );
179179static void dumpDefaultACL (Archive * fout ,DefaultACLInfo * daclinfo );
@@ -10138,6 +10138,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1013810138query = createPQExpBuffer ();
1013910139
1014010140/* look up the foreign-data wrapper */
10141+ selectSourceSchema ("pg_catalog" );
1014110142appendPQExpBuffer (query ,"SELECT fdwname "
1014210143"FROM pg_foreign_data_wrapper w "
1014310144"WHERE w.oid = '%u'" ,
@@ -10198,9 +10199,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1019810199free (namecopy );
1019910200
1020010201/* Dump user mappings */
10201- resetPQExpBuffer (q );
10202- appendPQExpBuffer (q ,"SERVER %s" ,fmtId (srvinfo -> dobj .name ));
10203- dumpUserMappings (fout ,q -> data ,
10202+ dumpUserMappings (fout ,
1020410203srvinfo -> dobj .name ,NULL ,
1020510204srvinfo -> rolname ,
1020610205srvinfo -> dobj .catId ,srvinfo -> dobj .dumpId );
@@ -10217,7 +10216,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
1021710216 * for the server.
1021810217 */
1021910218static void
10220- dumpUserMappings (Archive * fout ,const char * target ,
10219+ dumpUserMappings (Archive * fout ,
1022110220const char * servername ,const char * namespace ,
1022210221const char * owner ,
1022310222CatalogId catalogId ,DumpId dumpId )
@@ -10228,7 +10227,7 @@ dumpUserMappings(Archive *fout, const char *target,
1022810227PQExpBuffer tag ;
1022910228PGresult * res ;
1023010229int ntups ;
10231- int i_umuser ;
10230+ int i_usename ;
1023210231int i_umoptions ;
1023310232int i ;
1023410233
@@ -10237,31 +10236,40 @@ dumpUserMappings(Archive *fout, const char *target,
1023710236delq = createPQExpBuffer ();
1023810237query = createPQExpBuffer ();
1023910238
10239+ /*
10240+ * We read from the publicly accessible view pg_user_mappings, so as not
10241+ * to fail if run by a non-superuser. Note that the view will show
10242+ * umoptions as null if the user hasn't got privileges for the associated
10243+ * server; this means that pg_dump will dump such a mapping, but with no
10244+ * OPTIONS clause. A possible alternative is to skip such mappings
10245+ * altogether, but it's not clear that that's an improvement.
10246+ */
10247+ selectSourceSchema ("pg_catalog" );
10248+
1024010249appendPQExpBuffer (query ,
10241- "SELECT(%s umuser) AS umuser , "
10250+ "SELECTusename , "
1024210251"array_to_string(ARRAY(SELECT option_name || ' ' || quote_literal(option_value) FROM pg_options_to_table(umoptions)), ', ') AS umoptions\n"
10243- "FROM pg_user_mapping "
10244- "WHERE umserver=%u" ,
10245- username_subquery ,
10252+ "FROM pg_user_mappings "
10253+ "WHERE srvid = %u" ,
1024610254catalogId .oid );
1024710255
1024810256res = PQexec (g_conn ,query -> data );
1024910257check_sql_result (res ,g_conn ,query -> data ,PGRES_TUPLES_OK );
1025010258
1025110259ntups = PQntuples (res );
10252- i_umuser = PQfnumber (res ,"umuser " );
10260+ i_usename = PQfnumber (res ,"usename " );
1025310261i_umoptions = PQfnumber (res ,"umoptions" );
1025410262
1025510263for (i = 0 ;i < ntups ;i ++ )
1025610264{
10257- char * umuser ;
10265+ char * usename ;
1025810266char * umoptions ;
1025910267
10260- umuser = PQgetvalue (res ,i ,i_umuser );
10268+ usename = PQgetvalue (res ,i ,i_usename );
1026110269umoptions = PQgetvalue (res ,i ,i_umoptions );
1026210270
1026310271resetPQExpBuffer (q );
10264- appendPQExpBuffer (q ,"CREATE USER MAPPING FOR %s" ,fmtId (umuser ));
10272+ appendPQExpBuffer (q ,"CREATE USER MAPPING FOR %s" ,fmtId (usename ));
1026510273appendPQExpBuffer (q ," SERVER %s" ,fmtId (servername ));
1026610274
1026710275if (umoptions && strlen (umoptions )> 0 )
@@ -10270,10 +10278,12 @@ dumpUserMappings(Archive *fout, const char *target,
1027010278appendPQExpBuffer (q ,";\n" );
1027110279
1027210280resetPQExpBuffer (delq );
10273- appendPQExpBuffer (delq ,"DROP USER MAPPING FOR %s SERVER %s;\n" ,fmtId (umuser ),fmtId (servername ));
10281+ appendPQExpBuffer (delq ,"DROP USER MAPPING FOR %s" ,fmtId (usename ));
10282+ appendPQExpBuffer (delq ," SERVER %s;\n" ,fmtId (servername ));
1027410283
1027510284resetPQExpBuffer (tag );
10276- appendPQExpBuffer (tag ,"USER MAPPING %s %s" ,fmtId (umuser ),target );
10285+ appendPQExpBuffer (tag ,"USER MAPPING %s SERVER %s" ,
10286+ usename ,servername );
1027710287
1027810288ArchiveEntry (fout ,nilCatalogId ,createDumpId (),
1027910289tag -> data ,