/*
 * 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.
 */
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);
			}
		}
	}

	/* 
	 * 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;
}
Пример #2
0
/*
 * DestroyTupleStore
 * 		Helper function for destroying tuple store
 */
void
DestroyTupleStore(MaterialState *node)
{
	Assert(NULL != node);
	Assert(NULL != node->ts_state);
	Assert(NULL != node->ts_state->matstore);

	ntuplestore_destroy_accessor((NTupleStoreAccessor *) node->ts_pos);
	ntuplestore_destroy(node->ts_state->matstore);
	if(node->ts_markpos)
	{
		pfree(node->ts_markpos);
	}

	node->ts_state->matstore = NULL;
	node->ts_pos = NULL;
	node->ts_markpos = NULL;
	node->eof_underlying = false;
	node->ts_destroyed = true;
	ExecMaterialResetWorkfileState(node);
}