Ejemplo n.º 1
0
/* ----------------------------------------------------------------
 *		ExecEndSort(node)
 * ----------------------------------------------------------------
 */
void
ExecEndSort(SortState *node)
{
	SO1_printf("ExecEndSort: %s\n",
			   "shutting down sort node");

	/*
	 * clean out the tuple table
	 */
	ExecClearTuple(node->ss.ss_ScanTupleSlot);
	/* must drop pointer to sort result tuple */
	ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	/*
	 * Release tuplesort resources
	 */
	if (node->tuplesortstate != NULL)
		tuplesort_end((Tuplesortstate *) node->tuplesortstate);
	node->tuplesortstate = NULL;

	/*
	 * shut down the subplan
	 */
	ExecEndNode(outerPlanState(node));

	SO1_printf("ExecEndSort: %s\n",
			   "sort node shutdown");
}
Ejemplo n.º 2
0
Archivo: nodeSort.c Proyecto: huor/gpdb
void
ExecEagerFreeSort(SortState *node)
{
	Sort	   *plan = (Sort *) node->ss.ps.plan;
	EState	   *estate = node->ss.ps.state;

	/*
	 * If we still have potential readers assocated with this node,
	 * we shouldn't free the tuplesort too early.  The eager-free message
	 * doesn't know about upper ShareInputScan nodes, but those nodes
	 * bumps up the reference count in their initializations and decrement
	 * it in either EagerFree or ExecEnd.
	 */
	Assert(SHARE_MATERIAL != plan->share_type && SHARE_MATERIAL_XSLICE != plan->share_type);
	if (SHARE_SORT == plan->share_type)
	{
		ShareNodeEntry	   *snEntry;

		snEntry = ExecGetShareNodeEntry(estate, plan->share_id, false);

		if (snEntry->refcount > 0)
		{
			return;
		}
	}

	/* clean out the tuple table */
	ExecClearTuple(node->ss.ss_ScanTupleSlot);

	/* must drop pointer to sort result tuple */
	ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	if (NULL != node->tuplesortstate->sortstore || NULL != node->tuplesortstate->sortstore_mk)
	{
		Sort *sort = (Sort *) node->ss.ps.plan;

		/* If this is a producer for a ShareScan, then wait for all consumers to be done */
		/* XXX gcaragea: In Materialize, we moved this to End instead of EF, since EF might be too early to do it */
		if(sort->share_type == SHARE_SORT_XSLICE && NULL != node->share_lk_ctxt)
		{
			shareinput_writer_waitdone(node->share_lk_ctxt, sort->share_id, sort->nsharer_xslice);
		}

		if(gp_enable_mk_sort)
		{
			tuplesort_end_mk(node->tuplesortstate->sortstore_mk);
			node->tuplesortstate->sortstore_mk = NULL;
		}
		else
		{
			tuplesort_end(node->tuplesortstate->sortstore);
			node->tuplesortstate->sortstore = NULL;

		}

		ExecSortResetWorkfileState(node);
	}
}
Ejemplo n.º 3
0
Archivo: nodeSort.c Proyecto: huor/gpdb
void
ExecReScanSort(SortState *node, ExprContext *exprCtxt)
{
	/*
	 * If we haven't sorted yet, just return. If outerplan' chgParam is not
	 * NULL then it will be re-scanned by ExecProcNode, else - no reason to
	 * re-scan it at all.
	 */
	if (!node->sort_Done)
		return;

	/* must drop pointer to sort result tuple */
	ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	/*
	 * If subnode is to be rescanned then we forget previous sort results; we
	 * have to re-read the subplan and re-sort.
	 *
	 * Otherwise we can just rewind and rescan the sorted output.
	 */
	if (((PlanState *) node)->lefttree->chgParam != NULL ||
		!node->randomAccess ||
		(NULL == node->tuplesortstate->sortstore_mk && NULL == node->tuplesortstate->sortstore))
	{
		node->sort_Done = false;

		if (gp_enable_mk_sort && NULL != node->tuplesortstate->sortstore_mk)
		{
			tuplesort_end_mk(node->tuplesortstate->sortstore_mk);
		}

		if (!gp_enable_mk_sort && NULL != node->tuplesortstate->sortstore)
		{
			tuplesort_end(node->tuplesortstate->sortstore);
		}

		/*
		 * if chgParam of subnode is not null then plan will be re-scanned by
		 * first ExecProcNode.
		 */
		if (((PlanState *) node)->lefttree->chgParam == NULL)
		{
			ExecReScan(((PlanState *) node)->lefttree, exprCtxt);
		}
	}
	else
	{
		if(gp_enable_mk_sort)
		{
			tuplesort_rescan_mk(node->tuplesortstate->sortstore_mk);
		}
		else
		{
			tuplesort_rescan(node->tuplesortstate->sortstore);
		}
	}
}
Ejemplo n.º 4
0
Archivo: nbtsort.c Proyecto: huor/gpdb
/*
 * clean up a spool structure and its substructures.
 */
void
_bt_spooldestroy(BTSpool *btspool)
{
	if(gp_enable_mk_sort)
		tuplesort_end_mk((Tuplesortstate_mk *) btspool->sortstate);
	else
		tuplesort_end((Tuplesortstate *) btspool->sortstate);
	pfree(btspool);
}
Ejemplo n.º 5
0
void
ExecReScanSort(SortState *node)
{
	PlanState  *outerPlan = outerPlanState(node);

	/*
	 * If we haven't sorted yet, just return. If outerplan's chgParam is not
	 * NULL then it will be re-scanned by ExecProcNode, else no reason to
	 * re-scan it at all.
	 */
	if (!node->sort_Done)
		return;

	/* must drop pointer to sort result tuple */
	ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

	/*
	 * If subnode is to be rescanned then we forget previous sort results; we
	 * have to re-read the subplan and re-sort.  Also must re-sort if the
	 * bounded-sort parameters changed or we didn't select randomAccess.
	 *
	 * Otherwise we can just rewind and rescan the sorted output.
	 */
	if (outerPlan->chgParam != NULL ||
		node->bounded != node->bounded_Done ||
		node->bound != node->bound_Done ||
		!node->randomAccess)
	{
		node->sort_Done = false;
		tuplesort_end((Tuplesortstate *) node->tuplesortstate);
		node->tuplesortstate = NULL;

		/*
		 * if chgParam of subnode is not null then plan will be re-scanned by
		 * first ExecProcNode.
		 */
		if (outerPlan->chgParam == NULL)
			ExecReScan(outerPlan);
	}
	else
		tuplesort_rescan((Tuplesortstate *) node->tuplesortstate);
}
Ejemplo n.º 6
0
/*
 * clean up a spool structure and its substructures.
 */
void
_bt_spooldestroy(BTSpool *btspool)
{
	tuplesort_end(btspool->sortstate);
	pfree(btspool);
}
Ejemplo n.º 7
0
/*
 * clean up a spool structure and its substructures.
 */
void
_h_spooldestroy(HSpool *hspool)
{
	tuplesort_end(hspool->sortstate);
	pfree(hspool);
}
Ejemplo n.º 8
0
/*
 * During EagerFree ShareInputScan decrements the
 * reference count in ShareNodeEntry when its intra-slice share node.
 * The reference count tells the underlying Material/Sort node not to free
 * too eagerly as this node still needs to read its tuples.  Once this node
 * is freed, the underlying node can free its content.
 * We consider this reference counter only in intra-slice cases, because
 * inter-slice share nodes have their own pointer to the buffer and
 * there is not way to tell this reference over Motions anyway.
 */
static void
ExecEagerFreeShareInputScan(ShareInputScanState *node)
{
	/*
	 * no need to call tuplestore end.  Underlying ShareInput will take
	 * care of releasing tuplestore resources
	 */
	/*
	 * XXX Do we need to pfree the tuplestore_state and pos?
	 * XXX nodeMaterial.c does not, need to find out why
	 */

	ShareInputScan * sisc = (ShareInputScan *) node->ss.ps.plan;
	if(sisc->share_type == SHARE_MATERIAL || sisc->share_type == SHARE_MATERIAL_XSLICE)
	{
		if(node->ts_pos != NULL)
			ntuplestore_destroy_accessor((NTupleStoreAccessor *) node->ts_pos);
		if(node->ts_markpos != NULL)
			pfree(node->ts_markpos);

		if(NULL != node->ts_state && NULL != node->ts_state->matstore)
		{
			/* Check if shared X-SLICE. In that case, we can safely destroy our tuplestore */
			if(ntuplestore_is_readerwriter_reader(node->ts_state->matstore))
			{
				ntuplestore_destroy(node->ts_state->matstore);
			}
		}
	}
	if (sisc->share_type == SHARE_SORT_XSLICE)
	{
		if (NULL != node->ts_state && NULL != node->ts_state->sortstore)
		{
			tuplesort_end(node->ts_state->sortstore);
			node->ts_state->sortstore = NULL;
		}
	}

	/* 
	 * Reset our copy of the pointer to the the ts_state. The tuplestore can still be accessed by 
	 * the other consumers, but we don't have a pointer to it anymore
	 */ 
	node->ts_state = NULL; 
	node->ts_pos = NULL;
	node->ts_markpos = NULL;

	/* This can be called more than once */
	if (!node->freed &&
			(sisc->share_type == SHARE_MATERIAL || sisc->share_type == SHARE_SORT))
	{
		/*
		 * Decrement reference count when it's intra-slice.  We don't need
		 * two-pass tree descending because ShareInputScan should always appear
		 * before the underlying Material/Sort node.
		 */
		EState *estate = node->ss.ps.state;
		ShareNodeEntry *snEntry = ExecGetShareNodeEntry(estate, sisc->share_id, false);

		Assert(snEntry && snEntry->refcount > 0);
		snEntry->refcount--;
	}
	node->freed = true;
}