22
22
*
23
23
*
24
24
* 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 $
26
26
*
27
27
*-------------------------------------------------------------------------
28
28
*/
@@ -2035,13 +2035,14 @@ getFuncs(int *numFuncs)
2035
2035
* numTables is set to the number of tables read in
2036
2036
*/
2037
2037
TableInfo *
2038
- getTables (int * numTables , FuncInfo * finfo , int numFuncs )
2038
+ getTables (int * numTables , FuncInfo * finfo , int numFuncs , const char * tablename )
2039
2039
{
2040
2040
PGresult * res ;
2041
2041
int ntups ;
2042
2042
int i ;
2043
2043
PQExpBuffer query = createPQExpBuffer ();
2044
2044
PQExpBuffer delqry = createPQExpBuffer ();
2045
+ PQExpBuffer lockquery = createPQExpBuffer ();
2045
2046
TableInfo * tblinfo ;
2046
2047
2047
2048
int i_reloid ;
@@ -2054,11 +2055,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2054
2055
int i_relhasindex ;
2055
2056
int i_relhasoids ;
2056
2057
2057
- char relkindview [2 ];
2058
-
2059
- relkindview [0 ] = RELKIND_VIEW ;
2060
- relkindview [1 ] = '\0' ;
2061
-
2062
2058
/*
2063
2059
* find all the user-defined tables (no indexes and no catalogs),
2064
2060
* ordering by oid is important so that we always process the parent
@@ -2129,6 +2125,17 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2129
2125
2130
2126
* numTables = ntups ;
2131
2127
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
+ */
2132
2139
tblinfo = (TableInfo * ) malloc (ntups * sizeof (TableInfo ));
2133
2140
2134
2141
i_reloid = PQfnumber (res , "oid" );
@@ -2146,17 +2153,63 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2146
2153
tblinfo [i ].oid = strdup (PQgetvalue (res , i , i_reloid ));
2147
2154
tblinfo [i ].relname = strdup (PQgetvalue (res , i , i_relname ));
2148
2155
tblinfo [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 );
2150
2160
tblinfo [i ].usename = strdup (PQgetvalue (res , i , i_usename ));
2151
2161
tblinfo [i ].ncheck = atoi (PQgetvalue (res , i , i_relchecks ));
2152
2162
tblinfo [i ].ntrig = atoi (PQgetvalue (res , i , i_reltriggers ));
2153
2163
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 */
2154
2207
if (strlen (tblinfo [i ].usename ) == 0 )
2155
2208
write_msg (NULL , "WARNING: owner of table \"%s\" appears to be invalid\n" ,
2156
2209
tblinfo [i ].relname );
2157
2210
2158
- /* Get view 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 )
2160
2213
{
2161
2214
PGresult * res2 ;
2162
2215
@@ -2208,6 +2261,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2208
2261
tblinfo [i ].relname );
2209
2262
exit_nicely ();
2210
2263
}
2264
+ PQclear (res2 );
2211
2265
}
2212
2266
else
2213
2267
tblinfo [i ].viewdef = NULL ;
@@ -2291,7 +2345,7 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2291
2345
tblinfo [i ].check_expr = NULL ;
2292
2346
2293
2347
/* Get primary key */
2294
- if (strcmp ( PQgetvalue ( res , i , i_relhasindex ), "t" ) == 0 )
2348
+ if (tblinfo [ i ]. hasindex )
2295
2349
{
2296
2350
PGresult * res2 ;
2297
2351
@@ -2323,9 +2377,6 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2323
2377
else
2324
2378
tblinfo [i ].pkIndexOid = NULL ;
2325
2379
2326
- /* Has it got OIDs? */
2327
- tblinfo [i ].hasoids = (strcmp (PQgetvalue (res , i , i_relhasoids ), "t" ) == 0 );
2328
-
2329
2380
/* Get primary key name (if primary key exist) */
2330
2381
if (tblinfo [i ].pkIndexOid != NULL )
2331
2382
{
@@ -2643,10 +2694,9 @@ getTables(int *numTables, FuncInfo *finfo, int numFuncs)
2643
2694
2644
2695
}
2645
2696
2646
- PQclear (res );
2647
-
2648
2697
destroyPQExpBuffer (query );
2649
2698
destroyPQExpBuffer (delqry );
2699
+ destroyPQExpBuffer (lockquery );
2650
2700
2651
2701
return tblinfo ;
2652
2702
}
0 commit comments