88 *
99 *
1010 * 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 $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -230,6 +230,7 @@ static Relation RelationBuildDesc(RelationBuildDescInfo buildinfo,
230230static void IndexedAccessMethodInitialize (Relation relation );
231231static void AttrDefaultFetch (Relation relation );
232232static void RelCheckFetch (Relation relation );
233+ static List * insert_ordered_oid (List * list ,Oid datum );
233234
234235static bool criticalRelcacheBuild = false;
235236
@@ -2078,6 +2079,12 @@ RelCheckFetch(Relation relation)
20782079 * so that we must recompute the index list on next request. This handles
20792080 * creation or deletion of an index.
20802081 *
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+ *
20812088 * Since shared cache inval causes the relcache's copy of the list to go away,
20822089 * we return a copy of the list palloc'd in the caller's context. The caller
20832090 * may freeList() the returned list after scanning it. This is necessary
@@ -2163,7 +2170,7 @@ RelationGetIndexList(Relation relation)
21632170
21642171index = (Form_pg_index )GETSTRUCT (htup );
21652172
2166- result = lappendi (result ,index -> indexrelid );
2173+ result = insert_ordered_oid (result ,index -> indexrelid );
21672174
21682175if (hasindex )
21692176ReleaseBuffer (buffer );
@@ -2178,7 +2185,7 @@ RelationGetIndexList(Relation relation)
21782185heap_endscan (hscan );
21792186heap_close (indrel ,AccessShareLock );
21802187
2181- /* Nowwe can save the completed list in the relcache entry. */
2188+ /* Nowsave a copy of the completed list in the relcache entry. */
21822189oldcxt = MemoryContextSwitchTo ((MemoryContext )CacheCxt );
21832190relation -> rd_indexlist = listCopy (result );
21842191relation -> rd_indexfound = true;
@@ -2187,6 +2194,39 @@ RelationGetIndexList(Relation relation)
21872194return result ;
21882195}
21892196
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+
21902230/*
21912231 *init_irels(), write_irels() -- handle special-case initialization of
21922232 * index relation descriptors.
@@ -2412,7 +2452,14 @@ write_irels(void)
24122452
24132453fd = PathNameOpenFile (tempfilename ,O_WRONLY |O_CREAT |O_TRUNC |PG_BINARY ,0600 );
24142454if (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+ }
24162463
24172464FileSeek (fd ,0L ,SEEK_SET );
24182465
@@ -2540,7 +2587,10 @@ write_irels(void)
25402587
25412588/*
25422589 * And rename the temp file to its final name, deleting any
2543- * previously- existing init file.
2590+ * previously-existing init file.
25442591 */
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+ }
25462596}