@@ -604,6 +604,97 @@ RegisterSnapshotInvalidation(Oid dbId, Oid relId)
604
604
dbId , relId );
605
605
}
606
606
607
+ /*
608
+ * PrepareInvalidationState
609
+ * Initialize inval data for the current (sub)transaction.
610
+ */
611
+ static void
612
+ PrepareInvalidationState (void )
613
+ {
614
+ TransInvalidationInfo * myInfo ;
615
+
616
+ if (transInvalInfo != NULL &&
617
+ transInvalInfo -> my_level == GetCurrentTransactionNestLevel ())
618
+ return ;
619
+
620
+ myInfo = (TransInvalidationInfo * )
621
+ MemoryContextAllocZero (TopTransactionContext ,
622
+ sizeof (TransInvalidationInfo ));
623
+ myInfo -> parent = transInvalInfo ;
624
+ myInfo -> my_level = GetCurrentTransactionNestLevel ();
625
+
626
+ /* Now, do we have a previous stack entry? */
627
+ if (transInvalInfo != NULL )
628
+ {
629
+ /* Yes; this one should be for a deeper nesting level. */
630
+ Assert (myInfo -> my_level > transInvalInfo -> my_level );
631
+
632
+ /*
633
+ * The parent (sub)transaction must not have any current (i.e.,
634
+ * not-yet-locally-processed) messages. If it did, we'd have a
635
+ * semantic problem: the new subtransaction presumably ought not be
636
+ * able to see those events yet, but since the CommandCounter is
637
+ * linear, that can't work once the subtransaction advances the
638
+ * counter. This is a convenient place to check for that, as well as
639
+ * being important to keep management of the message arrays simple.
640
+ */
641
+ if (NumMessagesInGroup (& transInvalInfo -> CurrentCmdInvalidMsgs ) != 0 )
642
+ elog (ERROR , "cannot start a subtransaction when there are unprocessed inval messages" );
643
+
644
+ /*
645
+ * MemoryContextAllocZero set firstmsg = nextmsg = 0 in each group,
646
+ * which is fine for the first (sub)transaction, but otherwise we need
647
+ * to update them to follow whatever is already in the arrays.
648
+ */
649
+ SetGroupToFollow (& myInfo -> PriorCmdInvalidMsgs ,
650
+ & transInvalInfo -> CurrentCmdInvalidMsgs );
651
+ SetGroupToFollow (& myInfo -> CurrentCmdInvalidMsgs ,
652
+ & myInfo -> PriorCmdInvalidMsgs );
653
+ }
654
+ else
655
+ {
656
+ /*
657
+ * Here, we need only clear any array pointers left over from a prior
658
+ * transaction.
659
+ */
660
+ InvalMessageArrays [CatCacheMsgs ].msgs = NULL ;
661
+ InvalMessageArrays [CatCacheMsgs ].maxmsgs = 0 ;
662
+ InvalMessageArrays [RelCacheMsgs ].msgs = NULL ;
663
+ InvalMessageArrays [RelCacheMsgs ].maxmsgs = 0 ;
664
+ }
665
+
666
+ transInvalInfo = myInfo ;
667
+ }
668
+
669
+ /* ----------------------------------------------------------------
670
+ * public functions
671
+ * ----------------------------------------------------------------
672
+ */
673
+
674
+ void
675
+ InvalidateSystemCachesExtended (bool debug_discard )
676
+ {
677
+ int i ;
678
+
679
+ InvalidateCatalogSnapshot ();
680
+ ResetCatalogCaches ();
681
+ RelationCacheInvalidate (debug_discard ); /* gets smgr and relmap too */
682
+
683
+ for (i = 0 ; i < syscache_callback_count ; i ++ )
684
+ {
685
+ struct SYSCACHECALLBACK * ccitem = syscache_callback_list + i ;
686
+
687
+ ccitem -> function (ccitem -> arg , ccitem -> id , 0 );
688
+ }
689
+
690
+ for (i = 0 ; i < relcache_callback_count ; i ++ )
691
+ {
692
+ struct RELCACHECALLBACK * ccitem = relcache_callback_list + i ;
693
+
694
+ ccitem -> function (ccitem -> arg , InvalidOid );
695
+ }
696
+ }
697
+
607
698
/*
608
699
* LocalExecuteInvalidationMessage
609
700
*
@@ -704,36 +795,6 @@ InvalidateSystemCaches(void)
704
795
InvalidateSystemCachesExtended (false);
705
796
}
706
797
707
- void
708
- InvalidateSystemCachesExtended (bool debug_discard )
709
- {
710
- int i ;
711
-
712
- InvalidateCatalogSnapshot ();
713
- ResetCatalogCaches ();
714
- RelationCacheInvalidate (debug_discard ); /* gets smgr and relmap too */
715
-
716
- for (i = 0 ; i < syscache_callback_count ; i ++ )
717
- {
718
- struct SYSCACHECALLBACK * ccitem = syscache_callback_list + i ;
719
-
720
- ccitem -> function (ccitem -> arg , ccitem -> id , 0 );
721
- }
722
-
723
- for (i = 0 ; i < relcache_callback_count ; i ++ )
724
- {
725
- struct RELCACHECALLBACK * ccitem = relcache_callback_list + i ;
726
-
727
- ccitem -> function (ccitem -> arg , InvalidOid );
728
- }
729
- }
730
-
731
-
732
- /* ----------------------------------------------------------------
733
- * public functions
734
- * ----------------------------------------------------------------
735
- */
736
-
737
798
/*
738
799
* AcceptInvalidationMessages
739
800
* Read and process invalidation messages from the shared invalidation
@@ -787,68 +848,6 @@ AcceptInvalidationMessages(void)
787
848
#endif
788
849
}
789
850
790
- /*
791
- * PrepareInvalidationState
792
- * Initialize inval data for the current (sub)transaction.
793
- */
794
- static void
795
- PrepareInvalidationState (void )
796
- {
797
- TransInvalidationInfo * myInfo ;
798
-
799
- if (transInvalInfo != NULL &&
800
- transInvalInfo -> my_level == GetCurrentTransactionNestLevel ())
801
- return ;
802
-
803
- myInfo = (TransInvalidationInfo * )
804
- MemoryContextAllocZero (TopTransactionContext ,
805
- sizeof (TransInvalidationInfo ));
806
- myInfo -> parent = transInvalInfo ;
807
- myInfo -> my_level = GetCurrentTransactionNestLevel ();
808
-
809
- /* Now, do we have a previous stack entry? */
810
- if (transInvalInfo != NULL )
811
- {
812
- /* Yes; this one should be for a deeper nesting level. */
813
- Assert (myInfo -> my_level > transInvalInfo -> my_level );
814
-
815
- /*
816
- * The parent (sub)transaction must not have any current (i.e.,
817
- * not-yet-locally-processed) messages. If it did, we'd have a
818
- * semantic problem: the new subtransaction presumably ought not be
819
- * able to see those events yet, but since the CommandCounter is
820
- * linear, that can't work once the subtransaction advances the
821
- * counter. This is a convenient place to check for that, as well as
822
- * being important to keep management of the message arrays simple.
823
- */
824
- if (NumMessagesInGroup (& transInvalInfo -> CurrentCmdInvalidMsgs ) != 0 )
825
- elog (ERROR , "cannot start a subtransaction when there are unprocessed inval messages" );
826
-
827
- /*
828
- * MemoryContextAllocZero set firstmsg = nextmsg = 0 in each group,
829
- * which is fine for the first (sub)transaction, but otherwise we need
830
- * to update them to follow whatever is already in the arrays.
831
- */
832
- SetGroupToFollow (& myInfo -> PriorCmdInvalidMsgs ,
833
- & transInvalInfo -> CurrentCmdInvalidMsgs );
834
- SetGroupToFollow (& myInfo -> CurrentCmdInvalidMsgs ,
835
- & myInfo -> PriorCmdInvalidMsgs );
836
- }
837
- else
838
- {
839
- /*
840
- * Here, we need only clear any array pointers left over from a prior
841
- * transaction.
842
- */
843
- InvalMessageArrays [CatCacheMsgs ].msgs = NULL ;
844
- InvalMessageArrays [CatCacheMsgs ].maxmsgs = 0 ;
845
- InvalMessageArrays [RelCacheMsgs ].msgs = NULL ;
846
- InvalMessageArrays [RelCacheMsgs ].maxmsgs = 0 ;
847
- }
848
-
849
- transInvalInfo = myInfo ;
850
- }
851
-
852
851
/*
853
852
* PostPrepare_Inval
854
853
* Clean up after successful PREPARE.
0 commit comments