/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*-------------------------------------------------------------------------
 *
 * nodeSubplan.c
 *	  routines to support subselects
 *
 * Portions Copyright (c) 2005-2010, Greenplum inc
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *	  $PostgreSQL: pgsql/src/backend/executor/nodeSubplan.c,v 1.80.2.2 2007/02/02 00:07:28 tgl Exp $
 *
 *-------------------------------------------------------------------------
 */
/*
 *	 INTERFACE ROUTINES
 *		ExecSubPlan  - process a subselect
 *		ExecInitSubPlan - initialize a subselect
 *		ExecEndSubPlan	- shut down a subselect
 */
#include "postgres.h"

#include <math.h>

#include "access/heapam.h"
#include "executor/executor.h"
#include "executor/nodeSubplan.h"
#include "cdb/cdbexplain.h"             /* cdbexplain_recvSubplanStats */
#include "cdb/cdbvars.h"
#include "cdb/cdbsrlz.h"
#include "cdb/cdbdisp.h"
#include "cdb/ml_ipc.h"
#include "lib/stringinfo.h"
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "cdb/dispatcher.h"


#include <math.h>                       /* ceil() */


static Datum ExecHashSubPlan(SubPlanState *node,
				ExprContext *econtext,
				bool *isNull);
static Datum ExecScanSubPlan(SubPlanState *node,
				ExprContext *econtext,
				bool *isNull);
static void buildSubPlanHash(SubPlanState *node, ExprContext * econtext);
static bool findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot);
static bool slotAllNulls(TupleTableSlot *slot);
static bool slotNoNulls(TupleTableSlot *slot);


/* ----------------------------------------------------------------
 *		ExecSubPlan
 * ----------------------------------------------------------------
 */
Datum
ExecSubPlan(SubPlanState *node,
			ExprContext *econtext,
			bool *isNull,
			ExprDoneCond *isDone)
{
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;

	/* Set default values for result flags: non-null, not a set result */
	*isNull = false;
	if (isDone)
		*isDone = ExprSingleResult;

	insist_log(subplan->setParam == NIL, "cannot set parent parameters from subquery");

	if (subplan->useHashTable)
		return ExecHashSubPlan(node, econtext, isNull);
	else
		return ExecScanSubPlan(node, econtext, isNull);
}

/*
 * ExecHashSubPlan: store subselect result in an in-memory hash table
 */
static Datum
ExecHashSubPlan(SubPlanState *node,
				ExprContext *econtext,
				bool *isNull)
{
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
	PlanState  *planstate = node->planstate;
	TupleTableSlot *slot;

	/* Shouldn't have any direct correlation Vars */
	if (subplan->parParam != NIL || node->args != NIL)
		elog(ERROR, "hashed subplan with direct correlation not supported");

	/*
	 * If first time through or we need to rescan the subplan, build the hash
	 * table.
	 */
	if (node->hashtable == NULL || planstate->chgParam != NULL)
		buildSubPlanHash(node, econtext);

	/*
	 * The result for an empty subplan is always FALSE; no need to evaluate
	 * lefthand side.
	 */
	*isNull = false;
	if (!node->havehashrows && !node->havenullrows)
		return BoolGetDatum(false);

	/*
	 * Evaluate lefthand expressions and form a projection tuple. First we
	 * have to set the econtext to use (hack alert!).
	 */
	node->projLeft->pi_exprContext = econtext;
	slot = ExecProject(node->projLeft, NULL);

	/*
	 * Note: because we are typically called in a per-tuple context, we have
	 * to explicitly clear the projected tuple before returning. Otherwise,
	 * we'll have a double-free situation: the per-tuple context will probably
	 * be reset before we're called again, and then the tuple slot will think
	 * it still needs to free the tuple.
	 */

	/*
	 * If the LHS is all non-null, probe for an exact match in the main hash
	 * table.  If we find one, the result is TRUE. Otherwise, scan the
	 * partly-null table to see if there are any rows that aren't provably
	 * unequal to the LHS; if so, the result is UNKNOWN.  (We skip that part
	 * if we don't care about UNKNOWN.) Otherwise, the result is FALSE.
	 *
	 * Note: the reason we can avoid a full scan of the main hash table is
	 * that the combining operators are assumed never to yield NULL when both
	 * inputs are non-null.  If they were to do so, we might need to produce
	 * UNKNOWN instead of FALSE because of an UNKNOWN result in comparing the
	 * LHS to some main-table entry --- which is a comparison we will not even
	 * make, unless there's a chance match of hash keys.
	 */
	if (slotNoNulls(slot))
	{
		if (node->havehashrows &&
			LookupTupleHashEntry(node->hashtable, slot, NULL) != NULL)
		{
			ExecClearTuple(slot);
			return BoolGetDatum(true);
		}
		if (node->havenullrows &&
			findPartialMatch(node->hashnulls, slot))
		{
			ExecClearTuple(slot);
			*isNull = true;
			return BoolGetDatum(false);
		}
		ExecClearTuple(slot);
		return BoolGetDatum(false);
	}

	/*
	 * When the LHS is partly or wholly NULL, we can never return TRUE. If we
	 * don't care about UNKNOWN, just return FALSE.  Otherwise, if the LHS is
	 * wholly NULL, immediately return UNKNOWN.  (Since the combining
	 * operators are strict, the result could only be FALSE if the sub-select
	 * were empty, but we already handled that case.) Otherwise, we must scan
	 * both the main and partly-null tables to see if there are any rows that
	 * aren't provably unequal to the LHS; if so, the result is UNKNOWN.
	 * Otherwise, the result is FALSE.
	 */
	if (node->hashnulls == NULL)
	{
		ExecClearTuple(slot);
		return BoolGetDatum(false);
	}
	if (slotAllNulls(slot))
	{
		ExecClearTuple(slot);
		*isNull = true;
		return BoolGetDatum(false);
	}
	/* Scan partly-null table first, since more likely to get a match */
	if (node->havenullrows &&
		findPartialMatch(node->hashnulls, slot))
	{
		ExecClearTuple(slot);
		*isNull = true;
		return BoolGetDatum(false);
	}
	if (node->havehashrows &&
		findPartialMatch(node->hashtable, slot))
	{
		ExecClearTuple(slot);
		*isNull = true;
		return BoolGetDatum(false);
	}
	ExecClearTuple(slot);
	return BoolGetDatum(false);
}

/*
 * ExecScanSubPlan: default case where we have to rescan subplan each time
 */
static Datum
ExecScanSubPlan(SubPlanState *node,
				ExprContext *econtext,
				bool *isNull)
{
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
	PlanState  *planstate = node->planstate;
	SubLinkType subLinkType = subplan->subLinkType;
	MemoryContext oldcontext;
	TupleTableSlot *slot;
	Datum		result;
	bool		found = false;	/* TRUE if got at least one subplan tuple */
	ListCell   *pvar;
	ListCell   *l;
	ArrayBuildState *astate = NULL;

	/*
	 * We are probably in a short-lived expression-evaluation context. Switch
	 * to the per-query context for manipulating the child plan's chgParam,
	 * calling ExecProcNode on it, etc.
	 */
	oldcontext = MemoryContextSwitchTo(node->sub_estate->es_query_cxt);

	/*
	 * Set Params of this plan from parent plan correlation values. (Any
	 * calculation we have to do is done in the parent econtext, since the
	 * Param values don't need to have per-query lifetime.)
	 */
	Assert(list_length(subplan->parParam) == list_length(node->args));

	forboth(l, subplan->parParam, pvar, node->args)
	{
		int			paramid = lfirst_int(l);
		ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);

		prm->value = ExecEvalExprSwitchContext((ExprState *) lfirst(pvar),
											   econtext,
											   &(prm->isnull),
											   NULL);
		planstate->chgParam = bms_add_member(planstate->chgParam, paramid);
	}

	/*
	 * Now that we've set up its parameters, we can reset the subplan.
	 */
	ExecReScan(planstate, NULL);

	/*
	 * For all sublink types except EXPR_SUBLINK and ARRAY_SUBLINK, the result
	 * is boolean as are the results of the combining operators. We combine
	 * results across tuples (if the subplan produces more than one) using OR
	 * semantics for ANY_SUBLINK or AND semantics for ALL_SUBLINK.
	 * (ROWCOMPARE_SUBLINK doesn't allow multiple tuples from the subplan.)
	 * NULL results from the combining operators are handled according to the
	 * usual SQL semantics for OR and AND.	The result for no input tuples is
	 * FALSE for ANY_SUBLINK, TRUE for {ALL_SUBLINK, NOT_EXISTS_SUBLINK}, NULL for
	 * ROWCOMPARE_SUBLINK.
	 *
	 * For EXPR_SUBLINK we require the subplan to produce no more than one
	 * tuple, else an error is raised.	If zero tuples are produced, we return
	 * NULL.  Assuming we get a tuple, we just use its first column (there can
	 * be only one non-junk column in this case).
	 *
	 * For ARRAY_SUBLINK we allow the subplan to produce any number of tuples,
	 * and form an array of the first column's values.  Note in particular
	 * that we produce a zero-element array if no tuples are produced (this is
	 * a change from pre-8.3 behavior of returning NULL).
	 */
	result = BoolGetDatum(subLinkType == ALL_SUBLINK || subLinkType == NOT_EXISTS_SUBLINK);
	*isNull = false;

	for (slot = ExecProcNode(planstate);
		 !TupIsNull(slot);
		 slot = ExecProcNode(planstate))
	{
		Datum		rowresult;
		bool		rownull;
		int			col;
		ListCell   *plst;

		if (subLinkType == EXISTS_SUBLINK || subLinkType == NOT_EXISTS_SUBLINK)
		{
			found = true;
			bool val = true;
			if (subLinkType == NOT_EXISTS_SUBLINK)
			{
				val = false;
			}
			result = BoolGetDatum(val);
			break;
		}

		if (subLinkType == EXPR_SUBLINK)
		{
			/* cannot allow multiple input tuples for EXPR sublink */
			if (found)
				ereport(ERROR,
						(errcode(ERRCODE_CARDINALITY_VIOLATION),
						 errmsg("more than one row returned by a subquery used as an expression")));
			found = true;

			/*
			 * We need to copy the subplan's tuple in case the result is of
			 * pass-by-ref type --- our return value will point into this
			 * copied tuple!  Can't use the subplan's instance of the tuple
			 * since it won't still be valid after next ExecProcNode() call.
			 * node->curTuple keeps track of the copied tuple for eventual
			 * freeing.
			 */
			MemoryContextSwitchTo(econtext->ecxt_per_query_memory);

			if (node->curTuple)
				pfree(node->curTuple);

			node->curTuple = ExecCopySlotMemTuple(slot);
			MemoryContextSwitchTo(node->sub_estate->es_query_cxt);

			result = memtuple_getattr(node->curTuple, slot->tts_mt_bind, 1, isNull);
			/* keep scanning subplan to make sure there's only one tuple */
			continue;
		}

		if (subLinkType == ARRAY_SUBLINK)
		{
			Datum		dvalue;
			bool		disnull;

			found = true;
			/* stash away current value */
			Assert(subplan->firstColType == slot->tts_tupleDescriptor->attrs[0]->atttypid);
			dvalue = slot_getattr(slot, 1, &disnull);
			astate = accumArrayResult(astate, dvalue, disnull,
									  subplan->firstColType, oldcontext);
			/* keep scanning subplan to collect all values */
			continue;
		}

		/* cannot allow multiple input tuples for ROWCOMPARE sublink either */
		if (subLinkType == ROWCOMPARE_SUBLINK && found)
			ereport(ERROR,
					(errcode(ERRCODE_CARDINALITY_VIOLATION),
					 errmsg("more than one row returned by a subquery used as an expression")));

		found = true;

		/*
		 * For ALL, ANY, and ROWCOMPARE sublinks, load up the Params
		 * representing the columns of the sub-select, and then evaluate the
		 * combining expression.
		 */
		col = 1;
		foreach(plst, subplan->paramIds)
		{
			int			paramid = lfirst_int(plst);
			ParamExecData *prmdata;

			prmdata = &(econtext->ecxt_param_exec_vals[paramid]);
			Assert(prmdata->execPlan == NULL);
			prmdata->value = slot_getattr(slot, col, &(prmdata->isnull));
			col++;
		}

		rowresult = ExecEvalExprSwitchContext(node->testexpr, econtext,
											  &rownull, NULL);

		if (subLinkType == ANY_SUBLINK)
		{
			/* combine across rows per OR semantics */
			if (rownull)
				*isNull = true;
			else if (DatumGetBool(rowresult))
			{
				result = BoolGetDatum(true);
				*isNull = false;
				break;			/* needn't look at any more rows */
			}
		}
		else if (subLinkType == ALL_SUBLINK)
		{
			/* combine across rows per AND semantics */
			if (rownull)
				*isNull = true;
			else if (!DatumGetBool(rowresult))
			{
				result = BoolGetDatum(false);
				*isNull = false;
				break;			/* needn't look at any more rows */
			}
		}
		else
		{
			/* must be ROWCOMPARE_SUBLINK */
			result = rowresult;
			*isNull = rownull;
		}
	}

	if (!found)
	{
		/*
		 * deal with empty subplan result.	result/isNull were previously
		 * initialized correctly for all sublink types except EXPR, ARRAY, and
		 * ROWCOMPARE; for those, return NULL.
		 */
		if (subLinkType == EXPR_SUBLINK ||
			subLinkType == ARRAY_SUBLINK ||
			subLinkType == ROWCOMPARE_SUBLINK)
		{
			result = (Datum) 0;
			*isNull = true;
		}
	}
	else if (subLinkType == ARRAY_SUBLINK)
	{
		Assert(astate != NULL);
		/* We return the result in the caller's context */
		result = makeArrayResult(astate, oldcontext);
	}

	MemoryContextSwitchTo(oldcontext);

	return result;
}

/*
 * buildSubPlanHash: load hash table by scanning subplan output.
 */
static void
buildSubPlanHash(SubPlanState *node, ExprContext *econtext)
{
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
	PlanState  *planstate = node->planstate;
	int			ncols = list_length(subplan->paramIds);
	ExprContext *innerecontext = node->innerecontext;
	MemoryContext oldcontext;
	int			nbuckets;
	TupleTableSlot *slot;

	Assert(subplan->subLinkType == ANY_SUBLINK);

	/*
	 * If we already had any hash tables, destroy 'em; then create empty hash
	 * table(s).
	 *
	 * If we need to distinguish accurately between FALSE and UNKNOWN (i.e.,
	 * NULL) results of the IN operation, then we have to store subplan output
	 * rows that are partly or wholly NULL.  We store such rows in a separate
	 * hash table that we expect will be much smaller than the main table. (We
	 * can use hashing to eliminate partly-null rows that are not distinct. We
	 * keep them separate to minimize the cost of the inevitable full-table
	 * searches; see findPartialMatch.)
	 *
	 * If it's not necessary to distinguish FALSE and UNKNOWN, then we don't
	 * need to store subplan output rows that contain NULL.
	 */
	ExecEagerFreeSubPlan(node);
	
	nbuckets = (int) ceil(planstate->plan->plan_rows);
	if (nbuckets < 1)
		nbuckets = 1;

	node->hashtable = BuildTupleHashTable(ncols,
										  node->keyColIdx,
										  node->eqfunctions,
										  node->hashfunctions,
										  nbuckets,
										  sizeof(TupleHashEntryData),
										  node->hashtablecxt,
										  node->hashtempcxt);

	if (!subplan->unknownEqFalse)
	{
		if (ncols == 1)
			nbuckets = 1;		/* there can only be one entry */
		else
		{
			nbuckets /= 16;
			if (nbuckets < 1)
				nbuckets = 1;
		}
		node->hashnulls = BuildTupleHashTable(ncols,
											  node->keyColIdx,
											  node->eqfunctions,
											  node->hashfunctions,
											  nbuckets,
											  sizeof(TupleHashEntryData),
											  node->hashtablecxt,
											  node->hashtempcxt);
	}

	/*
	 * We are probably in a short-lived expression-evaluation context. Switch
	 * to the child plan's per-query context for calling ExecProcNode.
	 */
	oldcontext = MemoryContextSwitchTo(node->sub_estate->es_query_cxt);

	/*
	 * Reset subplan to start.
	 */
	ExecReScan(planstate, NULL);

	/*
	 * Scan the subplan and load the hash table(s).  Note that when there are
	 * duplicate rows coming out of the sub-select, only one copy is stored.
	 */
	for (slot = ExecProcNode(planstate);
		 !TupIsNull(slot);
		 slot = ExecProcNode(planstate))
	{
		int			col = 1;
		ListCell   *plst;
		bool		isnew;

		/*
		 * Load up the Params representing the raw sub-select outputs, then
		 * form the projection tuple to store in the hashtable.
		 */
		foreach(plst, subplan->paramIds)
		{
			int			paramid = lfirst_int(plst);
			ParamExecData *prmdata;

			prmdata = &(innerecontext->ecxt_param_exec_vals[paramid]);
			Assert(prmdata->execPlan == NULL);
			prmdata->value = slot_getattr(slot, col,
										  &(prmdata->isnull));
			col++;
		}
		slot = ExecProject(node->projRight, NULL);

		/*
		 * If result contains any nulls, store separately or not at all.
		 */
		if (slotNoNulls(slot))
		{
			(void) LookupTupleHashEntry(node->hashtable, slot, &isnew);
			node->havehashrows = true;
		}
		else if (node->hashnulls)
		{
			(void) LookupTupleHashEntry(node->hashnulls, slot, &isnew);
			node->havenullrows = true;
		}

		/*
		 * Reset innerecontext after each inner tuple to free any memory used
		 * in hash computation or comparison routines.
		 */
		ResetExprContext(innerecontext);
	}

	/*
	 * Since the projected tuples are in the sub-query's context and not the
	 * main context, we'd better clear the tuple slot before there's any
	 * chance of a reset of the sub-query's context.  Else we will have the
	 * potential for a double free attempt.  (XXX possibly no longer needed,
	 * but can't hurt.)
	 */
	ExecClearTuple(node->projRight->pi_slot);

	MemoryContextSwitchTo(oldcontext);
}

/*
 * findPartialMatch: does the hashtable contain an entry that is not
 * provably distinct from the tuple?
 *
 * We have to scan the whole hashtable; we can't usefully use hashkeys
 * to guide probing, since we might get partial matches on tuples with
 * hashkeys quite unrelated to what we'd get from the given tuple.
 */
static bool
findPartialMatch(TupleHashTable hashtable, TupleTableSlot *slot)
{
	int			numCols = hashtable->numCols;
	AttrNumber *keyColIdx = hashtable->keyColIdx;
	TupleHashIterator hashiter;
	TupleHashEntry entry;

	InitTupleHashIterator(hashtable, &hashiter);
	while ((entry = ScanTupleHashTable(&hashiter)) != NULL)
	{
		ExecStoreMemTuple(entry->firstTuple, hashtable->tableslot, false);
		if (!execTuplesUnequal(hashtable->tableslot, slot,
							   numCols, keyColIdx,
							   hashtable->eqfunctions,
							   hashtable->tempcxt))
		{
			TermTupleHashIterator(&hashiter);
			return true;
		}
	}
	/* No TermTupleHashIterator call needed here */
	return false;
}

/*
 * slotAllNulls: is the slot completely NULL?
 *
 * This does not test for dropped columns, which is OK because we only
 * use it on projected tuples.
 */
static bool
slotAllNulls(TupleTableSlot *slot)
{
	int			ncols = slot->tts_tupleDescriptor->natts;
	int			i;

	for (i = 1; i <= ncols; i++)
	{
		if (!slot_attisnull(slot, i))
			return false;
	}
	return true;
}

/*
 * slotNoNulls: is the slot entirely not NULL?
 *
 * This does not test for dropped columns, which is OK because we only
 * use it on projected tuples.
 */
static bool
slotNoNulls(TupleTableSlot *slot)
{
	int			ncols = slot->tts_tupleDescriptor->natts;
	int			i;

	for (i = 1; i <= ncols; i++)
	{
		if (slot_attisnull(slot, i))
			return false;
	}
	return true;
}

/* ----------------------------------------------------------------
 *		ExecInitSubPlan
 *
 * Note: the eflags are those passed to the parent plan node of this
 * subplan; they don't directly describe the execution conditions the
 * subplan will face.
 * ----------------------------------------------------------------
 */
void
ExecInitSubPlan(SubPlanState *node, EState *estate, int eflags)
{
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
	EState	   *sp_estate;

	/*
	 * initialize my state
	 */
	node->needShutdown = false;
	node->curTuple = NULL;
	node->projLeft = NULL;
	node->projRight = NULL;
	node->hashtable = NULL;
	node->hashnulls = NULL;
	node->hashtablecxt = NULL;
	node->hashtempcxt = NULL;
	node->innerecontext = NULL;
	node->keyColIdx = NULL;
	node->eqfunctions = NULL;
	node->hashfunctions = NULL;
    node->cdbextratextbuf = NULL;

	/*
	 * create an EState for the subplan
	 *
	 * The subquery needs its own EState because it has its own rangetable. It
	 * shares our Param ID space and es_query_cxt, however.  XXX if rangetable
	 * access were done differently, the subquery could share our EState,
	 * which would eliminate some thrashing about in this module...
	 */
	sp_estate = CreateSubExecutorState(estate);
	node->sub_estate = sp_estate;

	sp_estate->es_range_table = estate->es_range_table;
	sp_estate->es_plannedstmt = estate->es_plannedstmt;
	sp_estate->es_param_list_info = estate->es_param_list_info;
	sp_estate->es_param_exec_vals = estate->es_param_exec_vals;
	sp_estate->es_tupleTable =
		ExecCreateTupleTable(ExecCountSlotsNode(exec_subplan_get_plan(sp_estate->es_plannedstmt, subplan)) + 10);
	sp_estate->es_snapshot = estate->es_snapshot;
	sp_estate->es_crosscheck_snapshot = estate->es_crosscheck_snapshot;
	sp_estate->es_instrument = estate->es_instrument;

    sp_estate->es_sliceTable = estate->es_sliceTable;
	sp_estate->currentSliceIdInPlan = estate->currentSliceIdInPlan;
	sp_estate->currentExecutingSliceId = estate->currentExecutingSliceId;
	sp_estate->rootSliceId = estate->currentExecutingSliceId;
	sp_estate->motionlayer_context = estate->motionlayer_context;
	sp_estate->es_sharenode = estate->es_sharenode;

	/*
	 * Start up the subplan (this is a very cut-down form of InitPlan())
	 *
	 * The subplan will never need to do BACKWARD scan or MARK/RESTORE.
	 *
	 * We set the REWIND flag to notify the subplan that it is likely to be
	 * rescanned, and it must delay eagerfree.
	 */
	eflags &= EXEC_FLAG_EXPLAIN_ONLY;
	eflags |= EXEC_FLAG_REWIND;

	Plan *subplanplan = exec_subplan_get_plan(estate->es_plannedstmt, subplan);
	Assert(subplanplan);

	Assert(node->planstate == NULL);

	node->planstate = ExecInitNode(subplanplan, sp_estate, eflags);

	node->needShutdown = true;	/* now we need to shutdown the subplan */

	/*
	 * If this plan is un-correlated or undirect correlated one and want to
	 * set params for parent plan then mark parameters as needing evaluation.
	 *
	 * Note that in the case of un-correlated subqueries we don't care about
	 * setting parent->chgParam here: indices take care about it, for others -
	 * it doesn't matter...
	 */
	if (subplan->setParam != NIL)
	{
		ListCell   *lst;

		foreach(lst, subplan->setParam)
		{
			int			paramid = lfirst_int(lst);
			ParamExecData *prmExec = &(estate->es_param_exec_vals[paramid]);
			
			
			/**
			 * Has this parameter been already 
			 * evaluated as part of preprocess_initplan()? If so,
			 * we shouldn't re-evaluate it. If it has been evaluated,
			 * we will simply substitute the actual value from
			 * the external parameters.
			 */
			if (Gp_role == GP_ROLE_EXECUTE
					&& subplan->is_initplan)
			{	
				ParamListInfo paramInfo = estate->es_param_list_info;
				ParamExternData *prmExt = NULL;
				int extParamIndex = -1;
				
				Assert(paramInfo);
				Assert(paramInfo->numParams > 0);
				
				/* 
				 * To locate the value of this pre-evaluated parameter, we need to find
				 * its location in the external parameter list.  
				 */
				extParamIndex = paramInfo->numParams - estate->es_plannedstmt->nCrossLevelParams + paramid;
				
				/* Ensure that the plan is actually an initplan */
				Assert(subplan->is_initplan && "Subplan is not an initplan. Parameter has not been evaluated in preprocess_initplan.");
				
				prmExt = &paramInfo->params[extParamIndex];
								
				/* Make sure the types are valid */
				Assert(OidIsValid(prmExt->ptype) && "Invalid Oid for pre-evaluated parameter.");				
				
				/** Hurray! Copy value from external parameter and don't bother setting up execPlan. */
				prmExec->execPlan = NULL;
				prmExec->isnull = prmExt->isnull;
				prmExec->value = prmExt->value;
			}
			else
			{
				prmExec->execPlan = node;
			}
		}
	}

	/*
	 * If we are going to hash the subquery output, initialize relevant stuff.
	 * (We don't create the hashtable until needed, though.)
	 */
	if (subplan->useHashTable)
	{
		int			ncols,
					i;
		TupleDesc	tupDesc;
		TupleTable	tupTable;
		TupleTableSlot *slot;
		List	   *oplist,
				   *lefttlist,
				   *righttlist,
				   *leftptlist,
				   *rightptlist;
		ListCell   *l;

		/* We need a memory context to hold the hash table(s) */
		node->hashtablecxt =
			AllocSetContextCreate(CurrentMemoryContext,
								  "Subplan HashTable Context",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
		/* and a small one for the hash tables to use as temp storage */
 		node->hashtempcxt =
 			AllocSetContextCreate(CurrentMemoryContext,
 								  "Subplan HashTable Temp Context",
 								  ALLOCSET_SMALL_MINSIZE,
 								  ALLOCSET_SMALL_INITSIZE,
 								  ALLOCSET_SMALL_MAXSIZE);

		/* and a short-lived exprcontext for function evaluation */
		node->innerecontext = CreateExprContext(estate);
		/* Silly little array of column numbers 1..n */
		ncols = list_length(subplan->paramIds);
		node->keyColIdx = (AttrNumber *) palloc(ncols * sizeof(AttrNumber));
		for (i = 0; i < ncols; i++)
			node->keyColIdx[i] = i + 1;

		/*
		 * We use ExecProject to evaluate the lefthand and righthand
		 * expression lists and form tuples.  (You might think that we could
		 * use the sub-select's output tuples directly, but that is not the
		 * case if we had to insert any run-time coercions of the sub-select's
		 * output datatypes; anyway this avoids storing any resjunk columns
		 * that might be in the sub-select's output.) Run through the
		 * combining expressions to build tlists for the lefthand and
		 * righthand sides.  We need both the ExprState list (for ExecProject)
		 * and the underlying parse Exprs (for ExecTypeFromTL).
		 *
		 * We also extract the combining operators themselves to initialize
		 * the equality and hashing functions for the hash tables.
		 */
		if (IsA(node->testexpr->expr, OpExpr))
		{
			/* single combining operator */
			oplist = list_make1(node->testexpr);
		}
		else if (and_clause((Node *) node->testexpr->expr))
		{
			/* multiple combining operators */
			Assert(IsA(node->testexpr, BoolExprState));
			oplist = ((BoolExprState *) node->testexpr)->args;
		}
		else
		{
			/* shouldn't see anything else in a hashable subplan */
			insist_log(false, "unrecognized testexpr type: %d",
				 (int) nodeTag(node->testexpr->expr));
			oplist = NIL;		/* keep compiler quiet */
		}
		Assert(list_length(oplist) == ncols);

		lefttlist = righttlist = NIL;
		leftptlist = rightptlist = NIL;
		node->eqfunctions = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
		node->hashfunctions = (FmgrInfo *) palloc(ncols * sizeof(FmgrInfo));
		i = 1;
		foreach(l, oplist)
		{
			FuncExprState *fstate = (FuncExprState *) lfirst(l);
			OpExpr	   *opexpr = (OpExpr *) fstate->xprstate.expr;
			ExprState  *exstate;
			Expr	   *expr;
			TargetEntry *tle;
			GenericExprState *tlestate;
			Oid			hashfn;

			Assert(IsA(fstate, FuncExprState));
			Assert(IsA(opexpr, OpExpr));
			Assert(list_length(fstate->args) == 2);

			/* Process lefthand argument */
			exstate = (ExprState *) linitial(fstate->args);
			expr = exstate->expr;
			tle = makeTargetEntry(expr,
								  i,
								  NULL,
								  false);
			tlestate = makeNode(GenericExprState);
			tlestate->xprstate.expr = (Expr *) tle;
			tlestate->xprstate.evalfunc = NULL;
			tlestate->arg = exstate;
			lefttlist = lappend(lefttlist, tlestate);
			leftptlist = lappend(leftptlist, tle);

			/* Process righthand argument */
			exstate = (ExprState *) lsecond(fstate->args);
			expr = exstate->expr;
			tle = makeTargetEntry(expr,
								  i,
								  NULL,
								  false);
			tlestate = makeNode(GenericExprState);
			tlestate->xprstate.expr = (Expr *) tle;
			tlestate->xprstate.evalfunc = NULL;
			tlestate->arg = exstate;
			righttlist = lappend(righttlist, tlestate);
			rightptlist = lappend(rightptlist, tle);

			/* Lookup the combining function */
			fmgr_info(opexpr->opfuncid, &node->eqfunctions[i - 1]);
			node->eqfunctions[i - 1].fn_expr = (Node *) opexpr;

			/* Lookup the associated hash function */
			hashfn = get_op_hash_function(opexpr->opno);
			if (!OidIsValid(hashfn))
				elog(ERROR, "could not find hash function for hash operator %u",
					 opexpr->opno);
			fmgr_info(hashfn, &node->hashfunctions[i - 1]);

			i++;
		}

		/*
		 * Create a tupletable to hold these tuples.  (Note: we never bother
		 * to free the tupletable explicitly; that's okay because it will
		 * never store raw disk tuples that might have associated buffer pins.
		 * The only resource involved is memory, which will be cleaned up by
		 * freeing the query context.)
		 */
		tupTable = ExecCreateTupleTable(2);

		/*
		 * Construct tupdescs, slots and projection nodes for left and right
		 * sides.  The lefthand expressions will be evaluated in the parent
		 * plan node's exprcontext, which we don't have access to here.
		 * Fortunately we can just pass NULL for now and fill it in later
		 * (hack alert!).  The righthand expressions will be evaluated in our
		 * own innerecontext.
		 */
		tupDesc = ExecTypeFromTL(leftptlist, false);
		slot = ExecAllocTableSlot(tupTable);
		ExecSetSlotDescriptor(slot, tupDesc);
		node->projLeft = ExecBuildProjectionInfo(lefttlist,
												 NULL,
												 slot,
												 NULL);

		tupDesc = ExecTypeFromTL(rightptlist, false);
		slot = ExecAllocTableSlot(tupTable);
		ExecSetSlotDescriptor(slot, tupDesc);
		node->projRight = ExecBuildProjectionInfo(righttlist,
												  node->innerecontext,
												  slot,
												  NULL);
	}
}

/* ----------------------------------------------------------------
 *		ExecSetParamPlan
 *
 *		Executes an InitPlan subplan and sets its output parameters.
 *
 * This is called from ExecEvalParam() when the value of a PARAM_EXEC
 * parameter is requested and the param's execPlan field is set (indicating
 * that the param has not yet been evaluated).	This allows lazy evaluation
 * of initplans: we don't run the subplan until/unless we need its output.
 * Note that this routine MUST clear the execPlan fields of the plan's
 * output parameters after evaluating them!
 * ----------------------------------------------------------------
 */

/*
 * Greenplum Database Changes:
 * In the case where this is running on the dispatcher, and it's a parallel dispatch
 * subplan, we need to dispatch the query to the qExecs as well, like in ExecutorRun.
 * except in this case we don't have to worry about insert statements.
 * In order to serialize the parameters (including PARAM_EXEC parameters that
 * are converted into PARAM_EXEC_REMOTE parameters, I had to add a parameter to this
 * function: ParamListInfo p.  This may be NULL in the non-dispatch case.
 */

/* Helper: SubplanQueryDesc derives a QueryDesc for use by the subplan. */
static QueryDesc *SubplanQueryDesc(QueryDesc * qd)
{
	QueryDesc *subqd = NULL;
	PlannedStmt *substmt = NULL;
	PlannedStmt *stmt = qd->plannedstmt;
	
	Assert(stmt != NULL);
	
	/*
	 * MPP-2869 and MPP-2859, single-row parameter-subquery inside
	 * CTAS: we don't want to create the the table during the
	 * initPlan execution. */
	
	/* build the PlannedStmt substmt */
	substmt = makeNode(PlannedStmt);
	
	substmt->commandType = stmt->commandType;
	substmt->canSetTag = stmt->canSetTag;
	substmt->transientPlan = stmt->transientPlan;
	substmt->planTree = stmt->planTree;
	substmt->rtable = stmt->rtable;
	substmt->resultRelations = stmt->resultRelations;
	substmt->utilityStmt = stmt->utilityStmt;
	substmt->intoClause = NULL;
	substmt->subplans = stmt->subplans;
	substmt->rewindPlanIDs = stmt->rewindPlanIDs;
	substmt->returningLists = stmt->returningLists;
	substmt->rowMarks = stmt->rowMarks;
	substmt->relationOids = stmt->relationOids;
	substmt->invalItems = stmt->invalItems;
	substmt->nCrossLevelParams = stmt->nCrossLevelParams;
	substmt->nMotionNodes = stmt->nMotionNodes;
	substmt->nInitPlans = stmt->nInitPlans;
	substmt->contextdisp = stmt->contextdisp;
	substmt->scantable_splits = stmt->scantable_splits;
	substmt->resource = stmt->resource;
	
	/*
	 * Fake a QueryDesc stucture for CdbDispatchPlan call. It should
	 * look like the one passed in as the argument which carries the
	 * global query, plan, parameters, and slice table, and specifies
	 * the initplan root of interest.
	 */
	subqd = CreateQueryDesc(substmt,
							pstrdup("(internal SELECT query for initplan)"),
							qd->snapshot,
							qd->crosscheck_snapshot,
							NULL,		/* Null destination for the QE */
							qd->params,
							qd->doInstrument);
	
	return subqd;
}

void
ExecSetParamPlan(SubPlanState *node, ExprContext *econtext, QueryDesc *gbl_queryDesc)
{
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
	PlanState  *planstate = node->planstate;
	SubLinkType subLinkType = subplan->subLinkType;
	MemoryContext oldcontext = CurrentMemoryContext;
	TupleTableSlot *slot;
	ListCell   *l;
	bool		found = false;
	ArrayBuildState *astate = NULL;
    Size        savepeakspace = MemoryContextGetPeakSpace(planstate->state->es_query_cxt);

	QueryDesc  *queryDesc = NULL;

	bool		shouldDispatch = false;
	volatile bool   shouldTeardownInterconnect = false;
    volatile bool   explainRecvStats = false;

	if (Gp_role == GP_ROLE_DISPATCH &&
		planstate != NULL &&
		planstate->plan != NULL &&
		planstate->plan->dispatch == DISPATCH_PARALLEL)
		shouldDispatch = true;

    node->cdbextratextbuf = NULL;

    /* 
     * Reset memory high-water mark so EXPLAIN ANALYZE can report each
     * root slice's usage separately.
     */
    MemoryContextSetPeakSpace(planstate->state->es_query_cxt, 0);

	/*
	 * Let's initialize 'queryDesc' before our PG_TRY, to ensure the correct
	 * value will be seen inside the PG_CATCH block without having to declare
	 * it 'volatile'.  (setjmp/longjmp foolishness)
	 */
	if (shouldDispatch)
	{
		/*
		 * Fake a QueryDesc stucture for CdbDispatchPlan call. It should
		 * look like the one passed in as the argument which carries the
		 * global query, plan, parameters, and slice table, and specifies
		 * the initplan root of interest.
		 */
		queryDesc = SubplanQueryDesc(gbl_queryDesc);

        /* 
         * CDB TODO: Should this use CreateSubExecutorState()?  
         * Should FreeExecutorState() eventually be called?
         * Why do we need this at all?    ... kh 4/2007
         */
		queryDesc->estate = CreateExecutorState();

        queryDesc->showstatctx = gbl_queryDesc->showstatctx;
        queryDesc->estate->showstatctx = gbl_queryDesc->showstatctx;
		queryDesc->estate->es_sliceTable = gbl_queryDesc->estate->es_sliceTable;
		queryDesc->estate->es_param_exec_vals = gbl_queryDesc->estate->es_param_exec_vals;
		queryDesc->estate->motionlayer_context = gbl_queryDesc->estate->motionlayer_context;
		queryDesc->extended_query = gbl_queryDesc->extended_query;
		queryDesc->resource = gbl_queryDesc->resource;
		queryDesc->planner_segments = gbl_queryDesc->planner_segments;
	}

	/*
	 * Need a try/catch block here so that if an ereport is called from
	 * within ExecutePlan, we can clean up by calling CdbCheckDispatchResult.
	 * This cleans up the asynchronous commands running through the threads launched from
	 * CdbDispatchCommand.
	 */
	PG_TRY();
	{
		if (shouldDispatch)
		{			

			/*
			 * This call returns after launching the threads that send the
             * command to the appropriate segdbs.  It does not wait for them
             * to finish unless an error is detected before all are dispatched.
			 */
			queryDesc->estate->dispatch_data = initialize_dispatch_data(queryDesc->resource, false);
			prepare_dispatch_query_desc(queryDesc->estate->dispatch_data, queryDesc);
			dispatch_run(queryDesc->estate->dispatch_data);
			cleanup_dispatch_data(queryDesc->estate->dispatch_data);

			/*
			 * Set up the interconnect for execution of the initplan root slice.
			 */
			shouldTeardownInterconnect = true;
			Assert(!(queryDesc->estate->interconnect_context));
			SetupInterconnect(queryDesc->estate);
			Assert((queryDesc->estate->interconnect_context));

			ExecUpdateTransportState(planstate, queryDesc->estate->interconnect_context);
		}

		/*
		 * Must switch to child query's per-query memory context.
		 */
		oldcontext = MemoryContextSwitchTo(node->sub_estate->es_query_cxt);

		if (subLinkType == ANY_SUBLINK ||
			subLinkType == ALL_SUBLINK)
			elog(ERROR, "ANY/ALL subselect unsupported as initplan");

	    /*
	     * By definition, an initplan has no parameters from our query level, but
	     * it could have some from an outer level.	Rescan it if needed.
	     */
		if (planstate->chgParam != NULL)
			ExecReScan(planstate, NULL);

		for (slot = ExecProcNode(planstate);
			 !TupIsNull(slot);
			 slot = ExecProcNode(planstate))
		{
			int			i = 1;

			if (subLinkType == EXISTS_SUBLINK || subLinkType == NOT_EXISTS_SUBLINK)
			{
				/* There can be only one param... */
				int			paramid = linitial_int(subplan->setParam);
				ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);

				prm->execPlan = NULL;
				bool val = true;
				if (subLinkType == NOT_EXISTS_SUBLINK)
				{
					val = false;
				}
				prm->value = BoolGetDatum(val);
				prm->isnull = false;
				found = true;

				if (shouldDispatch)
				{
					/* Tell MPP we're done with this plan. */
					ExecSquelchNode(planstate);
				}

				break;
			}

			if (subLinkType == ARRAY_SUBLINK)
			{
				Datum		dvalue;
				bool		disnull;

				found = true;
				/* stash away current value */
			    Assert(subplan->firstColType == slot->tts_tupleDescriptor->attrs[0]->atttypid);
				dvalue = slot_getattr(slot, 1, &disnull);
				astate = accumArrayResult(astate, dvalue, disnull,
									  subplan->firstColType, oldcontext);
				/* keep scanning subplan to collect all values */
				continue;
			}

			if (found &&
				(subLinkType == EXPR_SUBLINK ||
				 subLinkType == ROWCOMPARE_SUBLINK))
				ereport(ERROR,
						(errcode(ERRCODE_CARDINALITY_VIOLATION),
						 errmsg("more than one row returned by a subquery used as an expression")));

			found = true;

			/*
		 	 * We need to copy the subplan's tuple into our own context, in case
		 	 * any of the params are pass-by-ref type --- the pointers stored in
		 	 * the param structs will point at this copied tuple! node->curTuple
		 	 * keeps track of the copied tuple for eventual freeing.
			 */
			MemoryContextSwitchTo(econtext->ecxt_per_query_memory);
			if (node->curTuple)
				pfree(node->curTuple);

			node->curTuple = ExecCopySlotMemTuple(slot);
			MemoryContextSwitchTo(node->sub_estate->es_query_cxt);

			/*
			 * Now set all the setParam params from the columns of the tuple
			 */
			foreach(l, subplan->setParam)
			{
				int			paramid = lfirst_int(l);
				ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);

				prm->execPlan = NULL;
				prm->value = memtuple_getattr(node->curTuple, slot->tts_mt_bind, i, &(prm->isnull));
				i++;
			}
		}

		if (!found)
		{
			if (subLinkType == EXISTS_SUBLINK || subLinkType == NOT_EXISTS_SUBLINK)
			{
				/* There can be only one param... */
				int			paramid = linitial_int(subplan->setParam);
				ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);

				prm->execPlan = NULL;
				bool val = false;
                                if (subLinkType == NOT_EXISTS_SUBLINK)
                                {
                                        val = true;
                                }
				prm->value = BoolGetDatum(val);
				prm->isnull = false;
			}
			else
			{
				foreach(l, subplan->setParam)
				{
					int			paramid = lfirst_int(l);
					ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);

					prm->execPlan = NULL;
					prm->value = (Datum) 0;
					prm->isnull = true;
				}
			}
		}
		else if (subLinkType == ARRAY_SUBLINK)
		{
			/* There can be only one param... */
			int			paramid = linitial_int(subplan->setParam);
			ParamExecData *prm = &(econtext->ecxt_param_exec_vals[paramid]);

			Assert(astate != NULL);
			prm->execPlan = NULL;
			/* We build the result in query context so it won't disappear */
			prm->value = makeArrayResult(astate, econtext->ecxt_per_query_memory);
			prm->isnull = false;
		}

        /*
         * If we dispatched to QEs, wait for completion and check for errors.
         */
        if (shouldDispatch && 
			queryDesc && queryDesc->estate &&
			queryDesc->estate->dispatch_data)
        {
            /* If EXPLAIN ANALYZE, collect execution stats from qExecs. */
            if (planstate->instrument)
            {
                MemoryContext   savecxt;

                /* Wait for all gangs to finish. */
                dispatch_wait(queryDesc->estate->dispatch_data);	

                /* Allocate buffer to pass extra message text to cdbexplain. */
                savecxt = MemoryContextSwitchTo(gbl_queryDesc->estate->es_query_cxt);
                node->cdbextratextbuf = makeStringInfo();
                MemoryContextSwitchTo(savecxt);

                /* Jam stats into subplan's Instrumentation nodes. */
                explainRecvStats = true;
                if (queryDesc->estate->dispatch_data &&
                    !dispatcher_has_error(queryDesc->estate->dispatch_data))
                {
                  cdbexplain_recvExecStats(planstate,
                                         dispatch_get_results(queryDesc->estate->dispatch_data),
                                         LocallyExecutingSliceIndex(queryDesc->estate),
                                         econtext->ecxt_estate->showstatctx,
                                         dispatch_get_segment_num(queryDesc->estate->dispatch_data));

                }
            }
            /*
             * Wait for all gangs to finish.  Check and free the results.
             * If the dispatcher or any QE had an error, report it and
             * exit to our error handler (below) via PG_THROW.
             */
            dispatch_wait(queryDesc->estate->dispatch_data);
            dispatch_cleanup(queryDesc->estate->dispatch_data);
			queryDesc->estate->dispatch_data = NULL;
        }

		/* teardown the sequence server */
		TeardownSequenceServer();
		
        /* Clean up the interconnect. */
        if (shouldTeardownInterconnect)
        {
        	shouldTeardownInterconnect = false;

	        TeardownInterconnect(queryDesc->estate->interconnect_context, 
								 queryDesc->estate->motionlayer_context,
								 false); /* following success on QD */	
		}

    }
	PG_CATCH();
	{

        /* If EXPLAIN ANALYZE, collect local and distributed execution stats. */
        if (planstate->instrument)
        {
            cdbexplain_localExecStats(planstate, econtext->ecxt_estate->showstatctx);
            if (!explainRecvStats &&
				shouldDispatch)
            {
				Assert(queryDesc != NULL &&
					   queryDesc->estate != NULL);
                /* Wait for all gangs to finish.  Cancel slowpokes. */
                dispatch_wait(queryDesc->estate->dispatch_data);

                cdbexplain_recvExecStats(planstate,
                                         dispatch_get_results(queryDesc->estate->dispatch_data),
                                         LocallyExecutingSliceIndex(queryDesc->estate),
                                         econtext->ecxt_estate->showstatctx,
                                         dispatch_get_segment_num(queryDesc->estate->dispatch_data));
            }
        }

        /* Restore memory high-water mark for root slice of main query. */
        MemoryContextSetPeakSpace(planstate->state->es_query_cxt, savepeakspace);

        /*
		 * Request any commands still executing on qExecs to stop.
		 * Wait for them to finish and clean up the dispatching structures.
         * Replace current error info with QE error info if more interesting.
		 */
        if (shouldDispatch && queryDesc && queryDesc->estate && queryDesc->estate->dispatch_data) {
			dispatch_catch_error(queryDesc->estate->dispatch_data);
			queryDesc->estate->dispatch_data = NULL;
        }
		
		/* teardown the sequence server */
		TeardownSequenceServer();
		
        /*
         * Clean up the interconnect.
         * CDB TODO: Is this needed following failure on QD?
         */
        if (shouldTeardownInterconnect)
			TeardownInterconnect(queryDesc->estate->interconnect_context,
								 queryDesc->estate->motionlayer_context,
								 true);
		PG_RE_THROW();
	}
	PG_END_TRY();

    /* If EXPLAIN ANALYZE, collect local execution stats. */
    if (planstate->instrument)
        cdbexplain_localExecStats(planstate, econtext->ecxt_estate->showstatctx);

    /* Restore memory high-water mark for root slice of main query. */
    MemoryContextSetPeakSpace(planstate->state->es_query_cxt, savepeakspace);

    MemoryContextSwitchTo(oldcontext);
}

/* ----------------------------------------------------------------
 *		ExecEndSubPlan
 * ----------------------------------------------------------------
 */
void
ExecEndSubPlan(SubPlanState *node)
{
	if (node->needShutdown)
	{
		ExecEndPlan(node->planstate, node->sub_estate);
		FreeExecutorState(node->sub_estate);
		node->sub_estate = NULL;
		node->planstate = NULL;
		node->needShutdown = false;
	}
}

/*
 * Mark an initplan as needing recalculation
 */
void
ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent)
{
	PlanState  *planstate = node->planstate;
	SubPlan    *subplan = (SubPlan *) node->xprstate.expr;
	EState	   *estate = parent->state;
	ListCell   *l;

	/* sanity checks */
	insist_log(subplan->parParam == NIL,
			"direct correlated subquery unsupported as initplan");
	insist_log(subplan->setParam != NIL,
			"setParam list of initplan is empty");
	insist_log(!bms_is_empty(planstate->plan->extParam),
		"extParam set of initplan is empty");

	/*
	 * Don't actually re-scan: ExecSetParamPlan does it if needed.
	 */

	/*
	 * Mark this subplan's output parameters as needing recalculation
	 */
	foreach(l, subplan->setParam)
	{
		int			paramid = lfirst_int(l);
		ParamExecData *prm = &(estate->es_param_exec_vals[paramid]);

		prm->execPlan = node;
		parent->chgParam = bms_add_member(parent->chgParam, paramid);
	}
}

void
ExecEagerFreeSubPlan(SubPlanState *node)
{
	Assert(node->hashtablecxt != NULL);
	MemoryContextReset(node->hashtablecxt);
	node->hashtable = NULL;
	node->hashnulls = NULL;
	node->havehashrows = false;
	node->havenullrows = false;
}
