From 7119eefc94c255e75f8cf7d1c0f5fc4e9a516b9a Mon Sep 17 00:00:00 2001 From: Ildar Musin Date: Fri, 14 Feb 2025 15:29:16 +0100 Subject: [PATCH] Respect other extensions' ExecutorStart hooks When we override ExecutorStart hook that has been set by another extension we have to chain-call it not to disrupt other extension's integrity. (cherry picked from commit 0fc733e00e97ab27e73374bdf5b7cbf3919a701f) --- .unreleased/pr_7712 | 1 + tsl/src/hypercore/attr_capture.c | 24 ++++++++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 .unreleased/pr_7712 diff --git a/.unreleased/pr_7712 b/.unreleased/pr_7712 new file mode 100644 index 00000000000..0646135fc76 --- /dev/null +++ b/.unreleased/pr_7712 @@ -0,0 +1 @@ +Fixes: #7712 Respect other extensions' ExecutorStart hooks diff --git a/tsl/src/hypercore/attr_capture.c b/tsl/src/hypercore/attr_capture.c index 727def1b65f..f0f978bf1be 100644 --- a/tsl/src/hypercore/attr_capture.c +++ b/tsl/src/hypercore/attr_capture.c @@ -32,6 +32,7 @@ struct CaptureAttributesContext }; static ExecutorStart_hook_type prev_ExecutorStart = NULL; +static bool ExecutorStart_hook_initialized = false; static void capture_var(Var *node, struct CaptureAttributesContext *context) @@ -216,8 +217,15 @@ capture_ExecutorStart(QueryDesc *queryDesc, int eflags) ListCell *cell; #endif - /* Call the standard executor start function to set up plan states. */ - standard_ExecutorStart(queryDesc, eflags); + if (prev_ExecutorStart) + { + prev_ExecutorStart(queryDesc, eflags); + } + else + { + /* Call the standard executor start function to set up plan states. */ + standard_ExecutorStart(queryDesc, eflags); + } struct CaptureAttributesContext context = { .rtable = queryDesc->plannedstmt->rtable, @@ -245,6 +253,14 @@ capture_ExecutorStart(QueryDesc *queryDesc, int eflags) void _attr_capture_init(void) { - prev_ExecutorStart = ExecutorStart_hook; - ExecutorStart_hook = capture_ExecutorStart; + /* + * TSL init might be reexecuted so we need to make + * sure to not initialize hook multiple times + */ + if (!ExecutorStart_hook_initialized) + { + ExecutorStart_hook_initialized = true; + prev_ExecutorStart = ExecutorStart_hook; + ExecutorStart_hook = capture_ExecutorStart; + } }