From 97fa4d98ba9fa904fd24b61c7d423a7ce3514cb0 Mon Sep 17 00:00:00 2001 From: Brian Cloutier Date: Thu, 20 Oct 2016 17:20:30 +0300 Subject: [PATCH 1/2] Disable EXPLAIN EXECUTE under citus --- .../distributed/executor/multi_utility.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/backend/distributed/executor/multi_utility.c b/src/backend/distributed/executor/multi_utility.c index 05182dbba..c0326786c 100644 --- a/src/backend/distributed/executor/multi_utility.c +++ b/src/backend/distributed/executor/multi_utility.c @@ -181,6 +181,23 @@ multi_ProcessUtility(Node *parsetree, return; } + if (IsA(parsetree, ExplainStmt)) + { + ExplainStmt *explainStmt = (ExplainStmt *) parsetree; + + if (IsA(explainStmt->query, Query)) + { + Query *query = (Query *) explainStmt->query; + + if (query->commandType == CMD_UTILITY && + IsA(query->utilityStmt, ExecuteStmt)) + { + /* Due to a postgres limitation these cause crashes. Skip them for now */ + ereport(ERROR, (errmsg("Citus does not support EXPLAIN EXECUTE"))); + } + } + } + if (IsA(parsetree, CopyStmt)) { parsetree = ProcessCopyStmt((CopyStmt *) parsetree, completionTag, From f3781ca66a45a0894600daee152fd4219b73c880 Mon Sep 17 00:00:00 2001 From: Brian Cloutier Date: Fri, 21 Oct 2016 15:19:21 +0300 Subject: [PATCH 2/2] Fix #866, supports EXPLAIN on simple distributed statements --- .../distributed/executor/multi_utility.c | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/backend/distributed/executor/multi_utility.c b/src/backend/distributed/executor/multi_utility.c index c0326786c..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" @@ -181,23 +182,6 @@ multi_ProcessUtility(Node *parsetree, return; } - if (IsA(parsetree, ExplainStmt)) - { - ExplainStmt *explainStmt = (ExplainStmt *) parsetree; - - if (IsA(explainStmt->query, Query)) - { - Query *query = (Query *) explainStmt->query; - - if (query->commandType == CMD_UTILITY && - IsA(query->utilityStmt, ExecuteStmt)) - { - /* Due to a postgres limitation these cause crashes. Skip them for now */ - ereport(ERROR, (errmsg("Citus does not support EXPLAIN EXECUTE"))); - } - } - } - if (IsA(parsetree, CopyStmt)) { parsetree = ProcessCopyStmt((CopyStmt *) parsetree, completionTag, @@ -316,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);