mirror of https://github.com/citusdata/citus.git
Only copy distributed plan when modifying it
parent
bf1e492011
commit
ee6a751798
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue