diff options
author | Pavan Deolasee | 2017-08-22 10:28:02 +0000 |
---|---|---|
committer | Pavan Deolasee | 2017-08-22 10:28:02 +0000 |
commit | d9f369f1af165fb6736899b021b55e152a03aff2 (patch) | |
tree | e2a7cc366ea545e0d73ef99ebbad373e467af007 | |
parent | dc14e7b45e9a7172339754c3baf6e25a84a43d5d (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.c | 3 | ||||
-rw-r--r-- | src/backend/pgxc/pool/execRemote.c | 38 | ||||
-rw-r--r-- | src/include/pgxc/execRemote.h | 1 |
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); |