Only copy distributed plan when modifying it

pull/2003/head
Marco Slot 2018-02-05 00:09:53 +01:00
parent bf1e492011
commit ee6a751798
2 changed files with 21 additions and 15 deletions

View File

@ -395,11 +395,21 @@ void
CitusModifyBeginScan(CustomScanState *node, EState *estate, int eflags) CitusModifyBeginScan(CustomScanState *node, EState *estate, int eflags)
{ {
CitusScanState *scanState = (CitusScanState *) node; CitusScanState *scanState = (CitusScanState *) node;
DistributedPlan *distributedPlan = scanState->distributedPlan; DistributedPlan *distributedPlan = NULL;
Job *workerJob = distributedPlan->workerJob; Job *workerJob = NULL;
Query *jobQuery = workerJob->jobQuery; Query *jobQuery = NULL;
List *taskList = workerJob->taskList; List *taskList = NIL;
bool deferredPruning = workerJob->deferredPruning;
/*
* We must not change the distributed plan since it may be reused across multiple
* executions of a prepared statement. Instead we create a deep copy that we only
* use for the current execution.
*/
distributedPlan = scanState->distributedPlan = copyObject(scanState->distributedPlan);
workerJob = distributedPlan->workerJob;
jobQuery = workerJob->jobQuery;
taskList = workerJob->taskList;
if (workerJob->requiresMasterEvaluation) if (workerJob->requiresMasterEvaluation)
{ {
@ -416,7 +426,7 @@ CitusModifyBeginScan(CustomScanState *node, EState *estate, int eflags)
*/ */
executorState->es_param_list_info = NULL; executorState->es_param_list_info = NULL;
if (deferredPruning) if (workerJob->deferredPruning)
{ {
DeferredErrorMessage *planningError = NULL; DeferredErrorMessage *planningError = NULL;

View File

@ -828,6 +828,9 @@ ResolveExternalParams(Node *inputNode, ParamListInfo boundParams)
/* /*
* GetDistributedPlan returns the associated DistributedPlan for a CustomScan. * GetDistributedPlan returns the associated DistributedPlan for a CustomScan.
*
* Callers should only read from the returned data structure, since it may be
* the plan of a prepared statement and may therefore be reused.
*/ */
DistributedPlan * DistributedPlan *
GetDistributedPlan(CustomScan *customScan) GetDistributedPlan(CustomScan *customScan)
@ -840,16 +843,9 @@ GetDistributedPlan(CustomScan *customScan)
node = (Node *) linitial(customScan->custom_private); node = (Node *) linitial(customScan->custom_private);
Assert(CitusIsA(node, DistributedPlan)); Assert(CitusIsA(node, DistributedPlan));
node = CheckNodeCopyAndSerialization(node); CheckNodeCopyAndSerialization(node);
/* distributedPlan = (DistributedPlan *) node;
* When using prepared statements the same plan gets reused across
* multiple statements and transactions. We make several modifications
* to the DistributedPlan during execution such as assigning task placements
* and evaluating functions and parameters. These changes should not
* persist, so we always work on a copy.
*/
distributedPlan = (DistributedPlan *) copyObject(node);
return distributedPlan; return distributedPlan;
} }