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