@@ -115,6 +115,7 @@ static void validate_index_heapscan(Relation heapRelation,
115115Snapshot snapshot ,
116116v_i_state * state );
117117static Oid IndexGetRelation (Oid indexId );
118+ static bool ReindexIsCurrentlyProcessingIndex (Oid indexOid );
118119static void SetReindexProcessing (Oid heapOid ,Oid indexOid );
119120static void ResetReindexProcessing (void );
120121static void SetReindexPending (List * indexes );
@@ -1747,8 +1748,8 @@ index_build(Relation heapRelation,
17471748 * created it, or truncated twice in a subsequent transaction, the
17481749 * relfilenode won't change, and nothing needs to be done here.
17491750 */
1750- if (heapRelation -> rd_rel -> relpersistence == RELPERSISTENCE_UNLOGGED
1751- && !smgrexists (indexRelation -> rd_smgr ,INIT_FORKNUM ))
1751+ if (heapRelation -> rd_rel -> relpersistence == RELPERSISTENCE_UNLOGGED &&
1752+ !smgrexists (indexRelation -> rd_smgr ,INIT_FORKNUM ))
17521753{
17531754RegProcedure ambuildempty = indexRelation -> rd_am -> ambuildempty ;
17541755
@@ -1757,19 +1758,6 @@ index_build(Relation heapRelation,
17571758OidFunctionCall1 (ambuildempty ,PointerGetDatum (indexRelation ));
17581759}
17591760
1760- /*
1761- * If it's for an exclusion constraint, make a second pass over the heap
1762- * to verify that the constraint is satisfied.
1763- */
1764- if (indexInfo -> ii_ExclusionOps != NULL )
1765- IndexCheckExclusion (heapRelation ,indexRelation ,indexInfo );
1766-
1767- /* Roll back any GUC changes executed by index functions */
1768- AtEOXact_GUC (false,save_nestlevel );
1769-
1770- /* Restore userid and security context */
1771- SetUserIdAndSecContext (save_userid ,save_sec_context );
1772-
17731761/*
17741762 * If we found any potentially broken HOT chains, mark the index as not
17751763 * being usable until the current transaction is below the event horizon.
@@ -1824,8 +1812,23 @@ index_build(Relation heapRelation,
18241812InvalidOid ,
18251813stats -> index_tuples );
18261814
1827- /* Make the updated versions visible */
1815+ /* Make the updatedcatalog row versions visible */
18281816CommandCounterIncrement ();
1817+
1818+ /*
1819+ * If it's for an exclusion constraint, make a second pass over the heap
1820+ * to verify that the constraint is satisfied. We must not do this until
1821+ * the index is fully valid. (Broken HOT chains shouldn't matter, though;
1822+ * see comments for IndexCheckExclusion.)
1823+ */
1824+ if (indexInfo -> ii_ExclusionOps != NULL )
1825+ IndexCheckExclusion (heapRelation ,indexRelation ,indexInfo );
1826+
1827+ /* Roll back any GUC changes executed by index functions */
1828+ AtEOXact_GUC (false,save_nestlevel );
1829+
1830+ /* Restore userid and security context */
1831+ SetUserIdAndSecContext (save_userid ,save_sec_context );
18291832}
18301833
18311834
@@ -2269,6 +2272,15 @@ IndexCheckExclusion(Relation heapRelation,
22692272EState * estate ;
22702273ExprContext * econtext ;
22712274
2275+ /*
2276+ * If we are reindexing the target index, mark it as no longer being
2277+ * reindexed, to forestall an Assert in index_beginscan when we try to
2278+ * use the index for probes. This is OK because the index is now
2279+ * fully valid.
2280+ */
2281+ if (ReindexIsCurrentlyProcessingIndex (RelationGetRelid (indexRelation )))
2282+ ResetReindexProcessing ();
2283+
22722284/*
22732285 * Need an EState for evaluation of index expressions and partial-index
22742286 * predicates.Also a slot to hold the current tuple.
@@ -2989,8 +3001,8 @@ reindex_relation(Oid relid, int flags)
29893001
29903002CommandCounterIncrement ();
29913003
2992- if ( flags & REINDEX_REL_SUPPRESS_INDEX_USE )
2993- RemoveReindexPending ( indexOid );
3004+ /* Index should no longer be in the pending list */
3005+ Assert (! ReindexIsProcessingIndex ( indexOid ) );
29943006
29953007if (is_pg_class )
29963008doneIndexes = lappend_oid (doneIndexes ,indexOid );
@@ -3030,7 +3042,9 @@ reindex_relation(Oid relid, int flags)
30303042 *System index reindexing support
30313043 *
30323044 * When we are busy reindexing a system index, this code provides support
3033- * for preventing catalog lookups from using that index.
3045+ * for preventing catalog lookups from using that index. We also make use
3046+ * of this to catch attempted uses of user indexes during reindexing of
3047+ * those indexes.
30343048 * ----------------------------------------------------------------
30353049 */
30363050
@@ -3048,6 +3062,16 @@ ReindexIsProcessingHeap(Oid heapOid)
30483062return heapOid == currentlyReindexedHeap ;
30493063}
30503064
3065+ /*
3066+ * ReindexIsCurrentlyProcessingIndex
3067+ *True if index specified by OID is currently being reindexed.
3068+ */
3069+ static bool
3070+ ReindexIsCurrentlyProcessingIndex (Oid indexOid )
3071+ {
3072+ return indexOid == currentlyReindexedIndex ;
3073+ }
3074+
30513075/*
30523076 * ReindexIsProcessingIndex
30533077 *True if index specified by OID is currently being reindexed,
@@ -3075,6 +3099,8 @@ SetReindexProcessing(Oid heapOid, Oid indexOid)
30753099elog (ERROR ,"cannot reindex while reindexing" );
30763100currentlyReindexedHeap = heapOid ;
30773101currentlyReindexedIndex = indexOid ;
3102+ /* Index is no longer "pending" reindex. */
3103+ RemoveReindexPending (indexOid );
30783104}
30793105
30803106/*