@@ -32,6 +32,7 @@ struct CaptureAttributesContext
32
32
};
33
33
34
34
static ExecutorStart_hook_type prev_ExecutorStart = NULL ;
35
+ static bool ExecutorStart_hook_initialized = false;
35
36
36
37
static void
37
38
capture_var (Var * node , struct CaptureAttributesContext * context )
@@ -216,8 +217,15 @@ capture_ExecutorStart(QueryDesc *queryDesc, int eflags)
216
217
ListCell * cell ;
217
218
#endif
218
219
219
- /* Call the standard executor start function to set up plan states. */
220
- standard_ExecutorStart (queryDesc , eflags );
220
+ if (prev_ExecutorStart )
221
+ {
222
+ prev_ExecutorStart (queryDesc , eflags );
223
+ }
224
+ else
225
+ {
226
+ /* Call the standard executor start function to set up plan states. */
227
+ standard_ExecutorStart (queryDesc , eflags );
228
+ }
221
229
222
230
struct CaptureAttributesContext context = {
223
231
.rtable = queryDesc -> plannedstmt -> rtable ,
@@ -245,6 +253,14 @@ capture_ExecutorStart(QueryDesc *queryDesc, int eflags)
245
253
void
246
254
_attr_capture_init (void )
247
255
{
248
- prev_ExecutorStart = ExecutorStart_hook ;
249
- ExecutorStart_hook = capture_ExecutorStart ;
256
+ /*
257
+ * TSL init might be reexecuted so we need to make
258
+ * sure to not initialize hook multiple times
259
+ */
260
+ if (!ExecutorStart_hook_initialized )
261
+ {
262
+ ExecutorStart_hook_initialized = true;
263
+ prev_ExecutorStart = ExecutorStart_hook ;
264
+ ExecutorStart_hook = capture_ExecutorStart ;
265
+ }
250
266
}
0 commit comments