summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2017-08-22 10:28:02 +0000
committerPavan Deolasee2017-08-22 10:28:02 +0000
commitd9f369f1af165fb6736899b021b55e152a03aff2 (patch)
treee2a7cc366ea545e0d73ef99ebbad373e467af007
parentdc14e7b45e9a7172339754c3baf6e25a84a43d5d (diff)
Handle rescan of RemoteQuery node correctly
We never had this support and we never felt the need because the use of FQS was limited for utility statements and simple queries which can be completed pushed down to the remote node. But in PG 10, we're seeing errors while using cursors for queries which are FQSed. So instead of forcing regular remote subplan on such queries, we are adding support for rescan of RemoteQuery node. Patch by Senhu <[email protected]>
-rw-r--r--src/backend/executor/execAmi.c3
-rw-r--r--src/backend/pgxc/pool/execRemote.c38
-rw-r--r--src/include/pgxc/execRemote.h1
3 files changed, 42 insertions, 0 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index b802ad6956..83e23da368 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -232,6 +232,9 @@ ExecReScan(PlanState *node)
case T_RemoteSubplanState:
ExecReScanRemoteSubplan((RemoteSubplanState *) node);
break;
+ case T_RemoteQueryState:
+ ExecReScanRemoteQuery((RemoteQueryState *) node);
+ break;
#endif
case T_CustomScanState:
ExecReScanCustomScan((CustomScanState *) node);
diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c
index 14067ee0af..0286337639 100644
--- a/src/backend/pgxc/pool/execRemote.c
+++ b/src/backend/pgxc/pool/execRemote.c
@@ -4763,6 +4763,44 @@ ExecRemoteQuery(PlanState *pstate)
return NULL;
}
+/* ----------------------------------------------------------------
+ * ExecReScanRemoteQuery
+ * ----------------------------------------------------------------
+ */
+void
+ExecReScanRemoteQuery(RemoteQueryState *node)
+{
+ ResponseCombiner *combiner = (ResponseCombiner *)node;
+
+ /*
+ * If we haven't queried remote nodes yet, just return. If outerplan'
+ * chgParam is not NULL then it will be re-scanned by ExecProcNode,
+ * else - no reason to re-scan it at all.
+ */
+ if (!node->query_Done)
+ return;
+
+ /*
+ * If we execute locally rescan local copy of the plan
+ */
+ if (outerPlanState(node))
+ ExecReScan(outerPlanState(node));
+
+ /*
+ * Consume any possible pending input
+ */
+ pgxc_connections_cleanup(combiner);
+
+ /* misc cleanup */
+ combiner->command_complete_count = 0;
+ combiner->description_count = 0;
+
+ /*
+ * Force query is re-bound with new parameters
+ */
+ node->query_Done = false;
+
+}
/*
* Clean up and discard any data on the data node connections that might not
diff --git a/src/include/pgxc/execRemote.h b/src/include/pgxc/execRemote.h
index 027b647c1b..b7c0f5b7a1 100644
--- a/src/include/pgxc/execRemote.h
+++ b/src/include/pgxc/execRemote.h
@@ -244,6 +244,7 @@ extern bool DataNodeCopyEnd(PGXCNodeHandle *handle, bool is_error);
extern RemoteQueryState *ExecInitRemoteQuery(RemoteQuery *node, EState *estate, int eflags);
extern TupleTableSlot* ExecRemoteQuery(PlanState *pstate);
+extern void ExecReScanRemoteQuery(RemoteQueryState *node);
extern void ExecEndRemoteQuery(RemoteQueryState *step);
extern void RemoteSubplanMakeUnique(Node *plan, int unique);
extern RemoteSubplanState *ExecInitRemoteSubplan(RemoteSubplan *node, EState *estate, int eflags);