From bba43fb19391fd06765970856359b156c8827652 Mon Sep 17 00:00:00 2001 From: Pavan Deolasee Date: Wed, 20 Jul 2016 15:36:14 +0530 Subject: [PATCH] Explicitly track if a subplan has been executed and a valid value is computed or not. This works around a problem noted in issue #102, but not a full solution to the problem. It seems there are places where InitPlan is attached to a node which will be executed on the remote node. Even so coordinator tries to find push a PARAM_EXEC parameter value for a remote subplan and fails because the value is not and will never be computed on the coordinator. We for now send NULL value for such cases to avoid a server crash --- src/backend/executor/nodeNestloop.c | 1 + src/backend/executor/nodeSubplan.c | 7 +++++++ src/backend/pgxc/pool/execRemote.c | 3 +++ src/include/nodes/params.h | 1 + 4 files changed, 12 insertions(+) diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c index e66bcdade7..27fcf2e562 100644 --- a/src/backend/executor/nodeNestloop.c +++ b/src/backend/executor/nodeNestloop.c @@ -154,6 +154,7 @@ ExecNestLoop(NestLoopState *node) prm->value = slot_getattr(outerTupleSlot, nlp->paramval->varattno, &(prm->isnull)); + prm->done = true; /* Flag parameter value as changed */ innerPlan->chgParam = bms_add_member(innerPlan->chgParam, paramno); diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c index 4c6453766e..aaad6b2c19 100644 --- a/src/backend/executor/nodeSubplan.c +++ b/src/backend/executor/nodeSubplan.c @@ -289,6 +289,7 @@ ExecScanSubPlan(SubPlanState *node, econtext, &(prm->isnull), NULL); + prm->done = true; planstate->chgParam = bms_add_member(planstate->chgParam, paramid); } @@ -996,6 +997,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) econtext, &(prm->isnull), NULL); + prm->done = true; planstate->chgParam = bms_add_member(planstate->chgParam, paramid); } @@ -1017,6 +1019,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); prm->execPlan = NULL; + prm->done = true; prm->value = BoolGetDatum(true); prm->isnull = false; found = true; @@ -1067,6 +1070,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); prm->execPlan = NULL; + prm->done = true; prm->value = heap_getattr(node->curTuple, i, tdesc, &(prm->isnull)); i++; @@ -1090,6 +1094,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) econtext->ecxt_per_query_memory, true); prm->execPlan = NULL; + prm->done = true; prm->value = node->curArray; prm->isnull = false; } @@ -1102,6 +1107,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); prm->execPlan = NULL; + prm->done = true; prm->value = BoolGetDatum(false); prm->isnull = false; } @@ -1114,6 +1120,7 @@ ExecSetParamPlan(SubPlanState *node, ExprContext *econtext) ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]); prm->execPlan = NULL; + prm->done = true; prm->value = (Datum) 0; prm->isnull = true; } diff --git a/src/backend/pgxc/pool/execRemote.c b/src/backend/pgxc/pool/execRemote.c index 930dc2d52b..380626bea4 100644 --- a/src/backend/pgxc/pool/execRemote.c +++ b/src/backend/pgxc/pool/execRemote.c @@ -5712,7 +5712,10 @@ static int encode_parameters(int nparams, RemoteParam *remoteparams, /* ExecSetParamPlan should have processed this param... */ Assert(param->execPlan == NULL); } + if (!param->done) + param->isnull = true; append_param_data(&buf, ptype, param->value, param->isnull); + } } diff --git a/src/include/nodes/params.h b/src/include/nodes/params.h index 5f7df26ba8..96613c72c8 100644 --- a/src/include/nodes/params.h +++ b/src/include/nodes/params.h @@ -100,6 +100,7 @@ typedef struct ParamExecData bool isnull; #ifdef XCP Oid ptype; + bool done; #endif } ParamExecData; -- 2.39.5