Skip to content

Commit 8766f08

Browse files
committedJan 25, 2019
Clean up hash table sequential scan status
1 parent c51714d commit 8766f08

File tree

1 file changed

+41
-0
lines changed

1 file changed

+41
-0
lines changed
 

‎pg_variables.c

+41
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ static void makePackHTAB(Package *package, bool is_trans);
8181
static inline ChangedObject *makeChangedObject(TransObject *object,
8282
MemoryContext ctx);
8383

84+
/* Hook functions */
85+
static void variable_ExecutorEnd(QueryDesc *queryDesc);
86+
8487
#define CHECK_ARGS_FOR_NULL() \
8588
do { \
8689
if (fcinfo->argnull[0]) \
@@ -103,6 +106,16 @@ static Variable *LastVariable = NULL;
103106
/* Recent row type id */
104107
static Oid LastTypeId = InvalidOid;
105108

109+
/*
110+
* Cache sequentially search through hash table status. It is necessary for
111+
* clean up if hash_seq_term() wasn't called or if we didn't scan the whole
112+
* table. In this case we need to manually call hash_seq_term() within
113+
* variable_ExecutorEnd().
114+
*/
115+
static HASH_SEQ_STATUS *LastHSeqStatus = NULL;
116+
117+
/* Saved hook values for recall */
118+
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
106119

107120
/* This stack contains lists of changed variables and packages per each subxact level */
108121
static dlist_head *changesStack = NULL;
@@ -596,6 +609,8 @@ variable_select(PG_FUNCTION_ARGS)
596609
MemoryContextSwitchTo(oldcontext);
597610
PG_FREE_IF_COPY(package_name, 0);
598611
PG_FREE_IF_COPY(var_name, 1);
612+
613+
LastHSeqStatus = rstat;
599614
}
600615

601616
funcctx = SRF_PERCALL_SETUP();
@@ -613,6 +628,7 @@ variable_select(PG_FUNCTION_ARGS)
613628
}
614629
else
615630
{
631+
LastHSeqStatus = NULL;
616632
pfree(rstat);
617633
SRF_RETURN_DONE(funcctx);
618634
}
@@ -1187,6 +1203,8 @@ get_packages_stats(PG_FUNCTION_ARGS)
11871203
hash_seq_init(pstat, packagesHash);
11881204

11891205
funcctx->user_fctx = pstat;
1206+
1207+
LastHSeqStatus = pstat;
11901208
}
11911209
else
11921210
funcctx->user_fctx = NULL;
@@ -1232,6 +1250,7 @@ get_packages_stats(PG_FUNCTION_ARGS)
12321250
}
12331251
else
12341252
{
1253+
LastHSeqStatus = NULL;
12351254
pfree(pstat);
12361255
SRF_RETURN_DONE(funcctx);
12371256
}
@@ -2093,6 +2112,23 @@ pgvTransCallback(XactEvent event, void *arg)
20932112
}
20942113
}
20952114

2115+
/*
2116+
* ExecutorEnd hook: clean up hash table sequential scan status
2117+
*/
2118+
static void
2119+
variable_ExecutorEnd(QueryDesc *queryDesc)
2120+
{
2121+
if (LastHSeqStatus)
2122+
{
2123+
hash_seq_term(LastHSeqStatus);
2124+
LastHSeqStatus = NULL;
2125+
}
2126+
if (prev_ExecutorEnd)
2127+
prev_ExecutorEnd(queryDesc);
2128+
else
2129+
standard_ExecutorEnd(queryDesc);
2130+
}
2131+
20962132
/*
20972133
* Register callback function when module starts
20982134
*/
@@ -2101,6 +2137,10 @@ _PG_init(void)
21012137
{
21022138
RegisterXactCallback(pgvTransCallback, NULL);
21032139
RegisterSubXactCallback(pgvSubTransCallback, NULL);
2140+
2141+
/* Install hooks. */
2142+
prev_ExecutorEnd = ExecutorEnd_hook;
2143+
ExecutorEnd_hook = variable_ExecutorEnd;
21042144
}
21052145

21062146
/*
@@ -2111,4 +2151,5 @@ _PG_fini(void)
21112151
{
21122152
UnregisterXactCallback(pgvTransCallback, NULL);
21132153
UnregisterSubXactCallback(pgvSubTransCallback, NULL);
2154+
ExecutorEnd_hook = prev_ExecutorEnd;
21142155
}

0 commit comments

Comments
 (0)
Please sign in to comment.