@@ -80,6 +80,9 @@ static void makePackHTAB(Package *package, bool is_trans);
80
80
static inline ChangedObject * makeChangedObject (TransObject * object ,
81
81
MemoryContext ctx );
82
82
83
+ /* Hook functions */
84
+ static void variable_ExecutorEnd (QueryDesc * queryDesc );
85
+
83
86
#define CHECK_ARGS_FOR_NULL () \
84
87
do { \
85
88
if (fcinfo->argnull[0]) \
@@ -110,6 +113,9 @@ static Oid LastTypeId = InvalidOid;
110
113
*/
111
114
static HASH_SEQ_STATUS * LastHSeqStatus = NULL ;
112
115
116
+ /* Saved hook values for recall */
117
+ static ExecutorEnd_hook_type prev_ExecutorEnd = NULL ;
118
+
113
119
/* This stack contains lists of changed variables and packages per each subxact level */
114
120
static dlist_head * changesStack = NULL ;
115
121
static MemoryContext changesStackContext = NULL ;
@@ -2125,6 +2131,23 @@ pgvTransCallback(XactEvent event, void *arg)
2125
2131
}
2126
2132
}
2127
2133
2134
+ /*
2135
+ * ExecutorEnd hook: clean up hash table sequential scan status
2136
+ */
2137
+ static void
2138
+ variable_ExecutorEnd (QueryDesc * queryDesc )
2139
+ {
2140
+ if (LastHSeqStatus )
2141
+ {
2142
+ hash_seq_term (LastHSeqStatus );
2143
+ LastHSeqStatus = NULL ;
2144
+ }
2145
+ if (prev_ExecutorEnd )
2146
+ prev_ExecutorEnd (queryDesc );
2147
+ else
2148
+ standard_ExecutorEnd (queryDesc );
2149
+ }
2150
+
2128
2151
/*
2129
2152
* Register callback function when module starts
2130
2153
*/
@@ -2133,6 +2156,10 @@ _PG_init(void)
2133
2156
{
2134
2157
RegisterXactCallback (pgvTransCallback ,NULL );
2135
2158
RegisterSubXactCallback (pgvSubTransCallback ,NULL );
2159
+
2160
+ /* Install hooks. */
2161
+ prev_ExecutorEnd = ExecutorEnd_hook ;
2162
+ ExecutorEnd_hook = variable_ExecutorEnd ;
2136
2163
}
2137
2164
2138
2165
/*
@@ -2143,4 +2170,5 @@ _PG_fini(void)
2143
2170
{
2144
2171
UnregisterXactCallback (pgvTransCallback ,NULL );
2145
2172
UnregisterSubXactCallback (pgvSubTransCallback ,NULL );
2173
+ ExecutorEnd_hook = prev_ExecutorEnd ;
2146
2174
}