8
8
*
9
9
*
10
10
* IDENTIFICATION
11
- * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.102 2000/06/18 22:44:17 tgl Exp $
11
+ * $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.103 2000/06/19 23:40:48 tgl Exp $
12
12
*
13
13
*-------------------------------------------------------------------------
14
14
*/
@@ -230,6 +230,7 @@ static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
230
230
static void IndexedAccessMethodInitialize (Relation relation );
231
231
static void AttrDefaultFetch (Relation relation );
232
232
static void RelCheckFetch (Relation relation );
233
+ static List * insert_ordered_oid (List * list ,Oid datum );
233
234
234
235
static bool criticalRelcacheBuild = false;
235
236
@@ -2078,6 +2079,12 @@ RelCheckFetch(Relation relation)
2078
2079
* so that we must recompute the index list on next request. This handles
2079
2080
* creation or deletion of an index.
2080
2081
*
2082
+ * The returned list is guaranteed to be sorted in order by OID. This is
2083
+ * needed by the executor, since for index types that we obtain exclusive
2084
+ * locks on when updating the index, all backends must lock the indexes in
2085
+ * the same order or we will get deadlocks (see ExecOpenIndices()). Any
2086
+ * consistent ordering would do, but ordering by OID is easy.
2087
+ *
2081
2088
* Since shared cache inval causes the relcache's copy of the list to go away,
2082
2089
* we return a copy of the list palloc'd in the caller's context. The caller
2083
2090
* may freeList() the returned list after scanning it. This is necessary
@@ -2163,7 +2170,7 @@ RelationGetIndexList(Relation relation)
2163
2170
2164
2171
index = (Form_pg_index )GETSTRUCT (htup );
2165
2172
2166
- result = lappendi (result ,index -> indexrelid );
2173
+ result = insert_ordered_oid (result ,index -> indexrelid );
2167
2174
2168
2175
if (hasindex )
2169
2176
ReleaseBuffer (buffer );
@@ -2178,7 +2185,7 @@ RelationGetIndexList(Relation relation)
2178
2185
heap_endscan (hscan );
2179
2186
heap_close (indrel ,AccessShareLock );
2180
2187
2181
- /* Nowwe can save the completed list in the relcache entry. */
2188
+ /* Nowsave a copy of the completed list in the relcache entry. */
2182
2189
oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
2183
2190
relation -> rd_indexlist = listCopy (result );
2184
2191
relation -> rd_indexfound = true;
@@ -2187,6 +2194,39 @@ RelationGetIndexList(Relation relation)
2187
2194
return result ;
2188
2195
}
2189
2196
2197
+ /*
2198
+ * insert_ordered_oid
2199
+ *Insert a new Oid into a sorted list of Oids, preserving ordering
2200
+ *
2201
+ * Building the ordered list this way is O(N^2), but with a pretty small
2202
+ * constant, so for the number of entries we expect it will probably be
2203
+ * faster than trying to apply qsort(). Most tables don't have very many
2204
+ * indexes...
2205
+ */
2206
+ static List *
2207
+ insert_ordered_oid (List * list ,Oid datum )
2208
+ {
2209
+ List * l ;
2210
+
2211
+ /* Does the datum belong at the front? */
2212
+ if (list == NIL || datum < (Oid )lfirsti (list ))
2213
+ return lconsi (datum ,list );
2214
+ /* No, so find the entry it belongs after */
2215
+ l = list ;
2216
+ for (;;)
2217
+ {
2218
+ List * n = lnext (l );
2219
+
2220
+ if (n == NIL || datum < (Oid )lfirsti (n ))
2221
+ break ;/* it belongs before n */
2222
+ l = n ;
2223
+ }
2224
+ /* Insert datum into list after item l */
2225
+ lnext (l )= lconsi (datum ,lnext (l ));
2226
+ return list ;
2227
+ }
2228
+
2229
+
2190
2230
/*
2191
2231
*init_irels(), write_irels() -- handle special-case initialization of
2192
2232
* index relation descriptors.
@@ -2412,7 +2452,14 @@ write_irels(void)
2412
2452
2413
2453
fd = PathNameOpenFile (tempfilename ,O_WRONLY |O_CREAT |O_TRUNC |PG_BINARY ,0600 );
2414
2454
if (fd < 0 )
2415
- elog (FATAL ,"cannot create init file %s" ,tempfilename );
2455
+ {
2456
+ /*
2457
+ * We used to consider this a fatal error, but we might as well
2458
+ * continue with backend startup ...
2459
+ */
2460
+ elog (NOTICE ,"Cannot create init file %s: %m\n\tContinuing anyway, but there's something wrong." ,tempfilename );
2461
+ return ;
2462
+ }
2416
2463
2417
2464
FileSeek (fd ,0L ,SEEK_SET );
2418
2465
@@ -2540,7 +2587,10 @@ write_irels(void)
2540
2587
2541
2588
/*
2542
2589
* And rename the temp file to its final name, deleting any
2543
- * previously- existing init file.
2590
+ * previously-existing init file.
2544
2591
*/
2545
- rename (tempfilename ,finalfilename );
2592
+ if (rename (tempfilename ,finalfilename )< 0 )
2593
+ {
2594
+ elog (NOTICE ,"Cannot rename init file %s to %s: %m\n\tContinuing anyway, but there's something wrong." ,tempfilename ,finalfilename );
2595
+ }
2546
2596
}