2222 *
2323 *
2424 * IDENTIFICATION
25- * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.236 2001/10/28 06:25:58 momjian Exp $
25+ * $Header: /cvsroot/pgsql/src/bin/pg_dump/pg_dump.c,v 1.237 2002/01/11 23:21:55 tgl Exp $
2626 *
2727 *-------------------------------------------------------------------------
2828 */
@@ -2035,13 +2035,14 @@ getFuncs(int *numFuncs)
20352035 * numTables is set to the number of tables read in
20362036 */
20372037TableInfo *
2038- getTables (int * numTables ,FuncInfo * finfo ,int numFuncs )
2038+ getTables (int * numTables ,FuncInfo * finfo ,int numFuncs , const char * tablename )
20392039{
20402040PGresult * res ;
20412041int ntups ;
20422042int i ;
20432043PQExpBuffer query = createPQExpBuffer ();
20442044PQExpBuffer delqry = createPQExpBuffer ();
2045+ PQExpBuffer lockquery = createPQExpBuffer ();
20452046TableInfo * tblinfo ;
20462047
20472048int i_reloid ;
@@ -2054,11 +2055,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
20542055int i_relhasindex ;
20552056int i_relhasoids ;
20562057
2057- char relkindview [2 ];
2058-
2059- relkindview [0 ]= RELKIND_VIEW ;
2060- relkindview [1 ]= '\0' ;
2061-
20622058/*
20632059 * find all the user-defined tables (no indexes and no catalogs),
20642060 * ordering by oid is important so that we always process the parent
@@ -2129,6 +2125,17 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
21292125
21302126* numTables = ntups ;
21312127
2128+ /*
2129+ * First pass: extract data from result and lock tables. We do the
2130+ * locking before anything else, to minimize the window wherein a table
2131+ * could disappear under us.
2132+ *
2133+ * Note that we have to collect info about all tables here, even when
2134+ * dumping only one, because we don't know which tables might be
2135+ * inheritance ancestors of the target table. Possible future
2136+ * improvement: suppress later collection of schema info about tables
2137+ * that are determined not to be either targets or ancestors of targets.
2138+ */
21322139tblinfo = (TableInfo * )malloc (ntups * sizeof (TableInfo ));
21332140
21342141i_reloid = PQfnumber (res ,"oid" );
@@ -2146,17 +2153,63 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
21462153tblinfo [i ].oid = strdup (PQgetvalue (res ,i ,i_reloid ));
21472154tblinfo [i ].relname = strdup (PQgetvalue (res ,i ,i_relname ));
21482155tblinfo [i ].relacl = strdup (PQgetvalue (res ,i ,i_relacl ));
2149- tblinfo [i ].sequence = (strcmp (PQgetvalue (res ,i ,i_relkind ),"S" )== 0 );
2156+ tblinfo [i ].relkind = * (PQgetvalue (res ,i ,i_relkind ));
2157+ tblinfo [i ].sequence = (tblinfo [i ].relkind == RELKIND_SEQUENCE );
2158+ tblinfo [i ].hasindex = (strcmp (PQgetvalue (res ,i ,i_relhasindex ),"t" )== 0 );
2159+ tblinfo [i ].hasoids = (strcmp (PQgetvalue (res ,i ,i_relhasoids ),"t" )== 0 );
21502160tblinfo [i ].usename = strdup (PQgetvalue (res ,i ,i_usename ));
21512161tblinfo [i ].ncheck = atoi (PQgetvalue (res ,i ,i_relchecks ));
21522162tblinfo [i ].ntrig = atoi (PQgetvalue (res ,i ,i_reltriggers ));
21532163
2164+ /*
2165+ * Read-lock target tables to make sure they aren't DROPPED or
2166+ * altered in schema before we get around to dumping them.
2167+ *
2168+ * If no target tablename was specified, lock all tables we see,
2169+ * otherwise lock only the specified table. (This is incomplete
2170+ * because we'll still try to collect schema info about all tables,
2171+ * and could possibly lose during that phase. But for the typical
2172+ * use where we're dumping all tables anyway, it matters not.)
2173+ *
2174+ * NOTE: it'd be kinda nice to lock views and sequences too, not
2175+ * only plain tables, but the backend doesn't presently allow that.
2176+ */
2177+ if ((tblinfo [i ].relkind == RELKIND_RELATION )&&
2178+ (tablename == NULL || strcmp (tblinfo [i ].relname ,tablename )== 0 ))
2179+ {
2180+ PGresult * lres ;
2181+
2182+ resetPQExpBuffer (lockquery );
2183+ appendPQExpBuffer (lockquery ,
2184+ "LOCK TABLE %s IN ACCESS SHARE MODE" ,
2185+ fmtId (tblinfo [i ].relname ,force_quotes ));
2186+ lres = PQexec (g_conn ,lockquery -> data );
2187+ if (!lres || PQresultStatus (lres )!= PGRES_COMMAND_OK )
2188+ {
2189+ write_msg (NULL ,"Attempt to lock table \"%s\" failed. %s" ,
2190+ tblinfo [i ].relname ,PQerrorMessage (g_conn ));
2191+ exit_nicely ();
2192+ }
2193+ PQclear (lres );
2194+ }
2195+ }
2196+
2197+ PQclear (res );
2198+ res = NULL ;
2199+
2200+ /*
2201+ * Second pass: pick up additional information about each table,
2202+ * as required.
2203+ */
2204+ for (i = 0 ;i < * numTables ;i ++ )
2205+ {
2206+ /* Emit notice if join for owner failed */
21542207if (strlen (tblinfo [i ].usename )== 0 )
21552208write_msg (NULL ,"WARNING: owner of table \"%s\" appears to be invalid\n" ,
21562209tblinfo [i ].relname );
21572210
2158- /* Getview definition */
2159- if (strcmp ( PQgetvalue ( res , i , i_relkind ), relkindview ) == 0 )
2211+ /* Get definition if it's a view */
2212+ if (tblinfo [ i ]. relkind == RELKIND_VIEW )
21602213{
21612214PGresult * res2 ;
21622215
@@ -2208,6 +2261,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
22082261tblinfo [i ].relname );
22092262exit_nicely ();
22102263}
2264+ PQclear (res2 );
22112265}
22122266else
22132267tblinfo [i ].viewdef = NULL ;
@@ -2291,7 +2345,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
22912345tblinfo [i ].check_expr = NULL ;
22922346
22932347/* Get primary key */
2294- if (strcmp ( PQgetvalue ( res , i , i_relhasindex ), "t" ) == 0 )
2348+ if (tblinfo [ i ]. hasindex )
22952349{
22962350PGresult * res2 ;
22972351
@@ -2323,9 +2377,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
23232377else
23242378tblinfo [i ].pkIndexOid = NULL ;
23252379
2326- /* Has it got OIDs? */
2327- tblinfo [i ].hasoids = (strcmp (PQgetvalue (res ,i ,i_relhasoids ),"t" )== 0 );
2328-
23292380/* Get primary key name (if primary key exist) */
23302381if (tblinfo [i ].pkIndexOid != NULL )
23312382{
@@ -2643,10 +2694,9 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
26432694
26442695}
26452696
2646- PQclear (res );
2647-
26482697destroyPQExpBuffer (query );
26492698destroyPQExpBuffer (delqry );
2699+ destroyPQExpBuffer (lockquery );
26502700
26512701return tblinfo ;
26522702}