diff --git a/src/backend/distributed/executor/multi_utility.c b/src/backend/distributed/executor/multi_utility.c index 05182dbba..c35290f4b 100644 --- a/src/backend/distributed/executor/multi_utility.c +++ b/src/backend/distributed/executor/multi_utility.c @@ -29,6 +29,7 @@ #include "catalog/pg_class.h" #include "commands/defrem.h" #include "commands/tablecmds.h" +#include "commands/prepare.h" #include "distributed/citus_ruleutils.h" #include "distributed/commit_protocol.h" #include "distributed/connection_cache.h" @@ -299,6 +300,39 @@ multi_ProcessUtility(Node *parsetree, " necessary users and roles."))); } + /* due to an explain-hook limitation we have to special-case EXPLAIN EXECUTE */ + if (IsA(parsetree, ExplainStmt) && IsA(((ExplainStmt*) parsetree)->query, Query)) + { + ExplainStmt *explainStmt = (ExplainStmt *) parsetree; + Query *query = (Query *) explainStmt->query; + + if (query->commandType == CMD_UTILITY && + IsA(query->utilityStmt, ExecuteStmt)) + { + ListCell *queryCell; + ExecuteStmt *execstmt = (ExecuteStmt *) query->utilityStmt; + PreparedStatement *entry = FetchPreparedStatement(execstmt->name, true); + + /* copied from ExplainExecuteQuery, will never trigger if you used PREPARE */ + if (!entry->plansource->fixed_result) + { + ereport(ERROR, (errmsg("EXPLAIN EXECUTE does not support variable-result" + " cached plans"))); + } + + foreach(queryCell, entry->plansource->query_list) + { + Query *query = (Query *) lfirst(queryCell); + explainStmt->query = (Node *) query; + + standard_ProcessUtility(parsetree, query_string, context, + params, dest, completionTag); + } + + return; + } + } + if (commandMustRunAsOwner) { GetUserIdAndSecContext(&savedUserId, &savedSecurityContext);