|
48 | 48 | #include "commands/matview.h"
|
49 | 49 | #include "commands/trigger.h"
|
50 | 50 | #include "executor/execdebug.h"
|
| 51 | +#include "executor/nodeSubplan.h" |
51 | 52 | #include "foreign/fdwapi.h"
|
52 | 53 | #include "mb/pg_wchar.h"
|
53 | 54 | #include "miscadmin.h"
|
@@ -1728,8 +1729,8 @@ ExecutePlan(EState *estate,
|
1728 | 1729 | if (TupIsNull(slot))
|
1729 | 1730 | {
|
1730 | 1731 | /*
|
1731 |
| - * If we know we won't need to back up, we can release |
1732 |
| - * resources at this point. |
| 1732 | + * If we know we won't need to back up, we can release resources |
| 1733 | + * at this point. |
1733 | 1734 | */
|
1734 | 1735 | if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD))
|
1735 | 1736 | (void) ExecShutdownNode(planstate);
|
@@ -1779,8 +1780,8 @@ ExecutePlan(EState *estate,
|
1779 | 1780 | if (numberTuples && numberTuples == current_tuple_count)
|
1780 | 1781 | {
|
1781 | 1782 | /*
|
1782 |
| - * If we know we won't need to back up, we can release |
1783 |
| - * resources at this point. |
| 1783 | + * If we know we won't need to back up, we can release resources |
| 1784 | + * at this point. |
1784 | 1785 | */
|
1785 | 1786 | if (!(estate->es_top_eflags & EXEC_FLAG_BACKWARD))
|
1786 | 1787 | (void) ExecShutdownNode(planstate);
|
@@ -3042,7 +3043,17 @@ EvalPlanQualBegin(EPQState *epqstate, EState *parentestate)
|
3042 | 3043 | /* Recopy current values of parent parameters */
|
3043 | 3044 | if (parentestate->es_plannedstmt->nParamExec > 0)
|
3044 | 3045 | {
|
3045 |
| - int i = parentestate->es_plannedstmt->nParamExec; |
| 3046 | + int i; |
| 3047 | + |
| 3048 | + /* |
| 3049 | + * Force evaluation of any InitPlan outputs that could be needed |
| 3050 | + * by the subplan, just in case they got reset since |
| 3051 | + * EvalPlanQualStart (see comments therein). |
| 3052 | + */ |
| 3053 | + ExecSetParamPlanMulti(planstate->plan->extParam, |
| 3054 | + GetPerTupleExprContext(parentestate)); |
| 3055 | + |
| 3056 | + i = parentestate->es_plannedstmt->nParamExec; |
3046 | 3057 |
|
3047 | 3058 | while (--i >= 0)
|
3048 | 3059 | {
|
@@ -3132,10 +3143,34 @@ EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *planTree)
|
3132 | 3143 | estate->es_param_list_info = parentestate->es_param_list_info;
|
3133 | 3144 | if (parentestate->es_plannedstmt->nParamExec > 0)
|
3134 | 3145 | {
|
3135 |
| - int i = parentestate->es_plannedstmt->nParamExec; |
| 3146 | + int i; |
| 3147 | + |
| 3148 | + /* |
| 3149 | + * Force evaluation of any InitPlan outputs that could be needed by |
| 3150 | + * the subplan. (With more complexity, maybe we could postpone this |
| 3151 | + * till the subplan actually demands them, but it doesn't seem worth |
| 3152 | + * the trouble; this is a corner case already, since usually the |
| 3153 | + * InitPlans would have been evaluated before reaching EvalPlanQual.) |
| 3154 | + * |
| 3155 | + * This will not touch output params of InitPlans that occur somewhere |
| 3156 | + * within the subplan tree, only those that are attached to the |
| 3157 | + * ModifyTable node or above it and are referenced within the subplan. |
| 3158 | + * That's OK though, because the planner would only attach such |
| 3159 | + * InitPlans to a lower-level SubqueryScan node, and EPQ execution |
| 3160 | + * will not descend into a SubqueryScan. |
| 3161 | + * |
| 3162 | + * The EState's per-output-tuple econtext is sufficiently short-lived |
| 3163 | + * for this, since it should get reset before there is any chance of |
| 3164 | + * doing EvalPlanQual again. |
| 3165 | + */ |
| 3166 | + ExecSetParamPlanMulti(planTree->extParam, |
| 3167 | + GetPerTupleExprContext(parentestate)); |
3136 | 3168 |
|
| 3169 | + /* now make the internal param workspace ... */ |
| 3170 | + i = parentestate->es_plannedstmt->nParamExec; |
3137 | 3171 | estate->es_param_exec_vals = (ParamExecData *)
|
3138 | 3172 | palloc0(i * sizeof(ParamExecData));
|
| 3173 | + /* ... and copy down all values, whether really needed or not */ |
3139 | 3174 | while (--i >= 0)
|
3140 | 3175 | {
|
3141 | 3176 | /* copy value if any, but not execPlan link */
|
|
0 commit comments