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)
{
CitusScanState *scanState = (CitusScanState *) node;
DistributedPlan *distributedPlan = scanState->distributedPlan;
Job *workerJob = distributedPlan->workerJob;
Query *jobQuery = workerJob->jobQuery;
List *taskList = workerJob->taskList;
bool deferredPruning = workerJob->deferredPruning;
DistributedPlan *distributedPlan = NULL;
Job *workerJob = NULL;
Query *jobQuery = NULL;
List *taskList = NIL;
/*
* 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)
{
@ -416,7 +426,7 @@ CitusModifyBeginScan(CustomScanState *node, EState *estate, int eflags)
*/
executorState->es_param_list_info = NULL;
if (deferredPruning)
if (workerJob->deferredPruning)
{
DeferredErrorMessage *planningError = NULL;

View File

@ -828,6 +828,9 @@ ResolveExternalParams(Node *inputNode, ParamListInfo boundParams)
/*
* 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 *
GetDistributedPlan(CustomScan *customScan)
@ -840,16 +843,9 @@ GetDistributedPlan(CustomScan *customScan)
node = (Node *) linitial(customScan->custom_private);
Assert(CitusIsA(node, DistributedPlan));
node = CheckNodeCopyAndSerialization(node);
CheckNodeCopyAndSerialization(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);
distributedPlan = (DistributedPlan *) node;
return distributedPlan;
}