@ -2440,10 +2440,11 @@ RelationDestroyRelation(Relation relation, bool remember_tupdesc)
list_free_deep ( relation - > rd_fkeylist ) ;
list_free ( relation - > rd_indexlist ) ;
list_free ( relation - > rd_statlist ) ;
bms_free ( relation - > rd_indexattr ) ;
bms_free ( relation - > rd_keyattr ) ;
bms_free ( relation - > rd_pkattr ) ;
bms_free ( relation - > rd_idattr ) ;
bms_free ( relation - > rd_hotblockingattr ) ;
bms_free ( relation - > rd_summarizedattr ) ;
if ( relation - > rd_pubdesc )
pfree ( relation - > rd_pubdesc ) ;
if ( relation - > rd_options )
@ -5167,10 +5168,11 @@ RelationGetIndexPredicate(Relation relation)
Bitmapset *
RelationGetIndexAttrBitmap ( Relation relation , IndexAttrBitmapKind attrKind )
{
Bitmapset * indexattrs ; /* indexed columns */
Bitmapset * uindexattrs ; /* columns in unique indexes */
Bitmapset * pkindexattrs ; /* columns in the primary index */
Bitmapset * idindexattrs ; /* columns in the replica identity */
Bitmapset * hotblockingattrs ; /* columns with HOT blocking indexes */
Bitmapset * summarizedattrs ; /* columns with summarizing indexes */
List * indexoidlist ;
List * newindexoidlist ;
Oid relpkindex ;
@ -5179,18 +5181,20 @@ RelationGetIndexAttrBitmap(Relation relation, IndexAttrBitmapKind attrKind)
MemoryContext oldcxt ;
/* Quick exit if we already computed the result. */
if ( relation - > rd_indexattr ! = NULL )
if ( relation - > rd_attrsvalid )
{
switch ( attrKind )
{
case INDEX_ATTR_BITMAP_ALL :
return bms_copy ( relation - > rd_indexattr ) ;
case INDEX_ATTR_BITMAP_KEY :
return bms_copy ( relation - > rd_keyattr ) ;
case INDEX_ATTR_BITMAP_PRIMARY_KEY :
return bms_copy ( relation - > rd_pkattr ) ;
case INDEX_ATTR_BITMAP_IDENTITY_KEY :
return bms_copy ( relation - > rd_idattr ) ;
case INDEX_ATTR_BITMAP_HOT_BLOCKING :
return bms_copy ( relation - > rd_hotblockingattr ) ;
case INDEX_ATTR_BITMAP_SUMMARIZED :
return bms_copy ( relation - > rd_summarizedattr ) ;
default :
elog ( ERROR , " unknown attrKind %u " , attrKind ) ;
}
@ -5230,10 +5234,11 @@ restart:
* CONCURRENTLY is far enough along that we should ignore the index , it
* won ' t be returned at all by RelationGetIndexList .
*/
indexattrs = NULL ;
uindexattrs = NULL ;
pkindexattrs = NULL ;
idindexattrs = NULL ;
hotblockingattrs = NULL ;
summarizedattrs = NULL ;
foreach ( l , indexoidlist )
{
Oid indexOid = lfirst_oid ( l ) ;
@ -5246,6 +5251,7 @@ restart:
bool isKey ; /* candidate key */
bool isPK ; /* primary key */
bool isIDKey ; /* replica identity index */
Bitmapset * * attrs ;
indexDesc = index_open ( indexOid , AccessShareLock ) ;
@ -5283,6 +5289,16 @@ restart:
/* Is this index the configured (or default) replica identity? */
isIDKey = ( indexOid = = relreplindex ) ;
/*
* If the index is summarizing , it doesn ' t block HOT updates , but we
* may still need to update it ( if the attributes were modified ) . So
* decide which bitmap we ' ll update in the following loop .
*/
if ( indexDesc - > rd_indam - > amsummarizing )
attrs = & summarizedattrs ;
else
attrs = & hotblockingattrs ;
/* Collect simple attribute references */
for ( i = 0 ; i < indexDesc - > rd_index - > indnatts ; i + + )
{
@ -5291,15 +5307,21 @@ restart:
/*
* Since we have covering indexes with non - key columns , we must
* handle them accurately here . non - key columns must be added into
* indexattrs , since they are in index , and HOT - update shouldn ' t
* miss them . Obviously , non - key columns couldn ' t be referenced by
* hotblockingattrs or summarizedattrs , since they are in index ,
* and update shouldn ' t miss them .
*
* Summarizing indexes do not block HOT , but do need to be updated
* when the column value changes , thus require a separate
* attribute bitmapset .
*
* Obviously , non - key columns couldn ' t be referenced by
* foreign key or identity key . Hence we do not include them into
* uindexattrs , pkindexattrs and idindexattrs bitmaps .
*/
if ( attrnum ! = 0 )
{
indexattrs = bms_add_member ( indexattrs ,
attrnum - FirstLowInvalidHeapAttributeNumber ) ;
* attrs = bms_add_member ( * attrs ,
attrnum - FirstLowInvalidHeapAttributeNumber ) ;
if ( isKey & & i < indexDesc - > rd_index - > indnkeyatts )
uindexattrs = bms_add_member ( uindexattrs ,
@ -5316,10 +5338,10 @@ restart:
}
/* Collect all attributes used in expressions, too */
pull_varattnos ( indexExpressions , 1 , & index attrs) ;
pull_varattnos ( indexExpressions , 1 , attrs ) ;
/* Collect all attributes in the index predicate, too */
pull_varattnos ( indexPredicate , 1 , & index attrs) ;
pull_varattnos ( indexPredicate , 1 , attrs ) ;
index_close ( indexDesc , AccessShareLock ) ;
}
@ -5347,24 +5369,28 @@ restart:
bms_free ( uindexattrs ) ;
bms_free ( pkindexattrs ) ;
bms_free ( idindexattrs ) ;
bms_free ( indexattrs ) ;
bms_free ( hotblockingattrs ) ;
bms_free ( summarizedattrs ) ;
goto restart ;
}
/* Don't leak the old values of these bitmaps, if any */
bms_free ( relation - > rd_indexattr ) ;
relation - > rd_indexattr = NULL ;
relation - > rd_attrsvalid = false ;
bms_free ( relation - > rd_keyattr ) ;
relation - > rd_keyattr = NULL ;
bms_free ( relation - > rd_pkattr ) ;
relation - > rd_pkattr = NULL ;
bms_free ( relation - > rd_idattr ) ;
relation - > rd_idattr = NULL ;
bms_free ( relation - > rd_hotblockingattr ) ;
relation - > rd_hotblockingattr = NULL ;
bms_free ( relation - > rd_summarizedattr ) ;
relation - > rd_summarizedattr = NULL ;
/*
* Now save copies of the bitmaps in the relcache entry . We intentionally
* set rd_indexattr last , because that ' s the one that signals validity of
* set rd_attrsvalid last , because that ' s the one that signals validity of
* the values ; if we run out of memory before making that copy , we won ' t
* leave the relcache entry looking like the other ones are valid but
* empty .
@ -5373,20 +5399,24 @@ restart:
relation - > rd_keyattr = bms_copy ( uindexattrs ) ;
relation - > rd_pkattr = bms_copy ( pkindexattrs ) ;
relation - > rd_idattr = bms_copy ( idindexattrs ) ;
relation - > rd_indexattr = bms_copy ( indexattrs ) ;
relation - > rd_hotblockingattr = bms_copy ( hotblockingattrs ) ;
relation - > rd_summarizedattr = bms_copy ( summarizedattrs ) ;
relation - > rd_attrsvalid = true ;
MemoryContextSwitchTo ( oldcxt ) ;
/* We return our original working copy for caller to play with */
switch ( attrKind )
{
case INDEX_ATTR_BITMAP_ALL :
return indexattrs ;
case INDEX_ATTR_BITMAP_KEY :
return uindexattrs ;
case INDEX_ATTR_BITMAP_PRIMARY_KEY :
return pkindexattrs ;
case INDEX_ATTR_BITMAP_IDENTITY_KEY :
return idindexattrs ;
case INDEX_ATTR_BITMAP_HOT_BLOCKING :
return hotblockingattrs ;
case INDEX_ATTR_BITMAP_SUMMARIZED :
return summarizedattrs ;
default :
elog ( ERROR , " unknown attrKind %u " , attrKind ) ;
return NULL ;
@ -6307,7 +6337,7 @@ load_relcache_init_file(bool shared)
rel - > rd_indexlist = NIL ;
rel - > rd_pkindex = InvalidOid ;
rel - > rd_replidindex = InvalidOid ;
rel - > rd_index attr = NULL ;
rel - > rd_attrsvalid = false ;
rel - > rd_keyattr = NULL ;
rel - > rd_pkattr = NULL ;
rel - > rd_idattr = NULL ;