@ -604,6 +604,97 @@ RegisterSnapshotInvalidation(Oid dbId, Oid relId)
dbId , relId ) ;
}
/*
* PrepareInvalidationState
* Initialize inval data for the current ( sub ) transaction .
*/
static void
PrepareInvalidationState ( void )
{
TransInvalidationInfo * myInfo ;
if ( transInvalInfo ! = NULL & &
transInvalInfo - > my_level = = GetCurrentTransactionNestLevel ( ) )
return ;
myInfo = ( TransInvalidationInfo * )
MemoryContextAllocZero ( TopTransactionContext ,
sizeof ( TransInvalidationInfo ) ) ;
myInfo - > parent = transInvalInfo ;
myInfo - > my_level = GetCurrentTransactionNestLevel ( ) ;
/* Now, do we have a previous stack entry? */
if ( transInvalInfo ! = NULL )
{
/* Yes; this one should be for a deeper nesting level. */
Assert ( myInfo - > my_level > transInvalInfo - > my_level ) ;
/*
* The parent ( sub ) transaction must not have any current ( i . e . ,
* not - yet - locally - processed ) messages . If it did , we ' d have a
* semantic problem : the new subtransaction presumably ought not be
* able to see those events yet , but since the CommandCounter is
* linear , that can ' t work once the subtransaction advances the
* counter . This is a convenient place to check for that , as well as
* being important to keep management of the message arrays simple .
*/
if ( NumMessagesInGroup ( & transInvalInfo - > CurrentCmdInvalidMsgs ) ! = 0 )
elog ( ERROR , " cannot start a subtransaction when there are unprocessed inval messages " ) ;
/*
* MemoryContextAllocZero set firstmsg = nextmsg = 0 in each group ,
* which is fine for the first ( sub ) transaction , but otherwise we need
* to update them to follow whatever is already in the arrays .
*/
SetGroupToFollow ( & myInfo - > PriorCmdInvalidMsgs ,
& transInvalInfo - > CurrentCmdInvalidMsgs ) ;
SetGroupToFollow ( & myInfo - > CurrentCmdInvalidMsgs ,
& myInfo - > PriorCmdInvalidMsgs ) ;
}
else
{
/*
* Here , we need only clear any array pointers left over from a prior
* transaction .
*/
InvalMessageArrays [ CatCacheMsgs ] . msgs = NULL ;
InvalMessageArrays [ CatCacheMsgs ] . maxmsgs = 0 ;
InvalMessageArrays [ RelCacheMsgs ] . msgs = NULL ;
InvalMessageArrays [ RelCacheMsgs ] . maxmsgs = 0 ;
}
transInvalInfo = myInfo ;
}
/* ----------------------------------------------------------------
* public functions
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
void
InvalidateSystemCachesExtended ( bool debug_discard )
{
int i ;
InvalidateCatalogSnapshot ( ) ;
ResetCatalogCachesExt ( debug_discard ) ;
RelationCacheInvalidate ( debug_discard ) ; /* gets smgr and relmap too */
for ( i = 0 ; i < syscache_callback_count ; i + + )
{
struct SYSCACHECALLBACK * ccitem = syscache_callback_list + i ;
ccitem - > function ( ccitem - > arg , ccitem - > id , 0 ) ;
}
for ( i = 0 ; i < relcache_callback_count ; i + + )
{
struct RELCACHECALLBACK * ccitem = relcache_callback_list + i ;
ccitem - > function ( ccitem - > arg , InvalidOid ) ;
}
}
/*
* LocalExecuteInvalidationMessage
*
@ -704,36 +795,6 @@ InvalidateSystemCaches(void)
InvalidateSystemCachesExtended ( false ) ;
}
void
InvalidateSystemCachesExtended ( bool debug_discard )
{
int i ;
InvalidateCatalogSnapshot ( ) ;
ResetCatalogCachesExt ( debug_discard ) ;
RelationCacheInvalidate ( debug_discard ) ; /* gets smgr and relmap too */
for ( i = 0 ; i < syscache_callback_count ; i + + )
{
struct SYSCACHECALLBACK * ccitem = syscache_callback_list + i ;
ccitem - > function ( ccitem - > arg , ccitem - > id , 0 ) ;
}
for ( i = 0 ; i < relcache_callback_count ; i + + )
{
struct RELCACHECALLBACK * ccitem = relcache_callback_list + i ;
ccitem - > function ( ccitem - > arg , InvalidOid ) ;
}
}
/* ----------------------------------------------------------------
* public functions
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
/*
* AcceptInvalidationMessages
* Read and process invalidation messages from the shared invalidation
@ -787,68 +848,6 @@ AcceptInvalidationMessages(void)
# endif
}
/*
* PrepareInvalidationState
* Initialize inval data for the current ( sub ) transaction .
*/
static void
PrepareInvalidationState ( void )
{
TransInvalidationInfo * myInfo ;
if ( transInvalInfo ! = NULL & &
transInvalInfo - > my_level = = GetCurrentTransactionNestLevel ( ) )
return ;
myInfo = ( TransInvalidationInfo * )
MemoryContextAllocZero ( TopTransactionContext ,
sizeof ( TransInvalidationInfo ) ) ;
myInfo - > parent = transInvalInfo ;
myInfo - > my_level = GetCurrentTransactionNestLevel ( ) ;
/* Now, do we have a previous stack entry? */
if ( transInvalInfo ! = NULL )
{
/* Yes; this one should be for a deeper nesting level. */
Assert ( myInfo - > my_level > transInvalInfo - > my_level ) ;
/*
* The parent ( sub ) transaction must not have any current ( i . e . ,
* not - yet - locally - processed ) messages . If it did , we ' d have a
* semantic problem : the new subtransaction presumably ought not be
* able to see those events yet , but since the CommandCounter is
* linear , that can ' t work once the subtransaction advances the
* counter . This is a convenient place to check for that , as well as
* being important to keep management of the message arrays simple .
*/
if ( NumMessagesInGroup ( & transInvalInfo - > CurrentCmdInvalidMsgs ) ! = 0 )
elog ( ERROR , " cannot start a subtransaction when there are unprocessed inval messages " ) ;
/*
* MemoryContextAllocZero set firstmsg = nextmsg = 0 in each group ,
* which is fine for the first ( sub ) transaction , but otherwise we need
* to update them to follow whatever is already in the arrays .
*/
SetGroupToFollow ( & myInfo - > PriorCmdInvalidMsgs ,
& transInvalInfo - > CurrentCmdInvalidMsgs ) ;
SetGroupToFollow ( & myInfo - > CurrentCmdInvalidMsgs ,
& myInfo - > PriorCmdInvalidMsgs ) ;
}
else
{
/*
* Here , we need only clear any array pointers left over from a prior
* transaction .
*/
InvalMessageArrays [ CatCacheMsgs ] . msgs = NULL ;
InvalMessageArrays [ CatCacheMsgs ] . maxmsgs = 0 ;
InvalMessageArrays [ RelCacheMsgs ] . msgs = NULL ;
InvalMessageArrays [ RelCacheMsgs ] . maxmsgs = 0 ;
}
transInvalInfo = myInfo ;
}
/*
* PostPrepare_Inval
* Clean up after successful PREPARE .