aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/executor/execTuples.c32
-rw-r--r--src/backend/executor/nodeBitmapHeapscan.c13
-rw-r--r--src/backend/executor/nodeIndexscan.c13
-rw-r--r--src/backend/executor/nodeSeqscan.c17
-rw-r--r--src/backend/executor/nodeTidscan.c13
5 files changed, 33 insertions, 55 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 7a4f11f5d9f..09c7dd55f50 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -15,7 +15,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.89 2005/11/22 18:17:10 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/execTuples.c,v 1.90 2005/11/25 04:24:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -402,28 +402,38 @@ ExecStoreTuple(HeapTuple tuple,
Assert(BufferIsValid(buffer) ? (!shouldFree) : true);
/*
- * clear out any old contents of the slot
+ * Free any old physical tuple belonging to the slot.
*/
- if (!slot->tts_isempty)
- ExecClearTuple(slot);
+ if (slot->tts_shouldFree)
+ heap_freetuple(slot->tts_tuple);
/*
- * store the new tuple into the specified slot.
+ * Store the new tuple into the specified slot.
*/
slot->tts_isempty = false;
slot->tts_shouldFree = shouldFree;
slot->tts_tuple = tuple;
+ /* Mark extracted state invalid */
+ slot->tts_nvalid = 0;
+
/*
* If tuple is on a disk page, keep the page pinned as long as we hold a
* pointer into it. We assume the caller already has such a pin.
+ *
+ * This is coded to optimize the case where the slot previously held a
+ * tuple on the same disk page: in that case releasing and re-acquiring
+ * the pin is a waste of cycles. This is a common situation during
+ * seqscans, so it's worth troubling over.
*/
- slot->tts_buffer = buffer;
- if (BufferIsValid(buffer))
- IncrBufferRefCount(buffer);
-
- /* Mark extracted state invalid */
- slot->tts_nvalid = 0;
+ if (slot->tts_buffer != buffer)
+ {
+ if (BufferIsValid(slot->tts_buffer))
+ ReleaseBuffer(slot->tts_buffer);
+ slot->tts_buffer = buffer;
+ if (BufferIsValid(buffer))
+ IncrBufferRefCount(buffer);
+ }
return slot;
}
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 5d92c19ea5e..3d4f7d38392 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -21,7 +21,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.4 2005/10/15 02:49:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.5 2005/11/25 04:24:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -76,15 +76,6 @@ BitmapHeapNext(BitmapHeapScanState *node)
tbmres = node->tbmres;
/*
- * Clear any reference to the previously returned tuple. The idea here is
- * to not have the tuple slot be the last holder of a pin on that tuple's
- * buffer; if it is, we'll need a separate visit to the bufmgr to release
- * the buffer. By clearing here, we get to have the release done by
- * ReleaseAndReadBuffer, below.
- */
- ExecClearTuple(slot);
-
- /*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
* introduce new nodes for this case and handle IndexScan --> NewNode
@@ -94,7 +85,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
estate->es_evTuple[scanrelid - 1] != NULL)
{
if (estate->es_evTupleNull[scanrelid - 1])
- return slot; /* return empty slot */
+ return ExecClearTuple(slot);
ExecStoreTuple(estate->es_evTuple[scanrelid - 1],
slot, InvalidBuffer, false);
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 6e639502c1d..4f6fadfde49 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.105 2005/11/22 18:17:10 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeIndexscan.c,v 1.106 2005/11/25 04:24:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -75,15 +75,6 @@ IndexNext(IndexScanState *node)
scanrelid = ((IndexScan *) node->ss.ps.plan)->scan.scanrelid;
/*
- * Clear any reference to the previously returned tuple. The idea here is
- * to not have the tuple slot be the last holder of a pin on that tuple's
- * buffer; if it is, we'll need a separate visit to the bufmgr to release
- * the buffer. By clearing here, we get to have the release done by
- * ReleaseAndReadBuffer inside index_getnext.
- */
- ExecClearTuple(slot);
-
- /*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
* introduce new nodes for this case and handle IndexScan --> NewNode
@@ -93,7 +84,7 @@ IndexNext(IndexScanState *node)
estate->es_evTuple[scanrelid - 1] != NULL)
{
if (estate->es_evTupleNull[scanrelid - 1])
- return slot; /* return empty slot */
+ return ExecClearTuple(slot);
ExecStoreTuple(estate->es_evTuple[scanrelid - 1],
slot, InvalidBuffer, false);
diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c
index 91e0c81e036..391fdf7e915 100644
--- a/src/backend/executor/nodeSeqscan.c
+++ b/src/backend/executor/nodeSeqscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.54 2005/10/15 02:49:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeSeqscan.c,v 1.55 2005/11/25 04:24:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -62,15 +62,6 @@ SeqNext(SeqScanState *node)
slot = node->ss_ScanTupleSlot;
/*
- * Clear any reference to the previously returned tuple. The idea here is
- * to not have the tuple slot be the last holder of a pin on that tuple's
- * buffer; if it is, we'll need a separate visit to the bufmgr to release
- * the buffer. By clearing here, we get to have the release done by
- * ReleaseAndReadBuffer inside heap_getnext.
- */
- ExecClearTuple(slot);
-
- /*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
* introduce new nodes for this case and handle SeqScan --> NewNode
@@ -80,7 +71,7 @@ SeqNext(SeqScanState *node)
estate->es_evTuple[scanrelid - 1] != NULL)
{
if (estate->es_evTupleNull[scanrelid - 1])
- return slot; /* return empty slot */
+ return ExecClearTuple(slot);
ExecStoreTuple(estate->es_evTuple[scanrelid - 1],
slot, InvalidBuffer, false);
@@ -93,7 +84,7 @@ SeqNext(SeqScanState *node)
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[scanrelid - 1] = true;
- return (slot);
+ return slot;
}
/*
@@ -115,6 +106,8 @@ SeqNext(SeqScanState *node)
scandesc->rs_cbuf, /* buffer associated with this
* tuple */
false); /* don't pfree this pointer */
+ else
+ ExecClearTuple(slot);
return slot;
}
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index c8708f58311..4b0775719e5 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.43 2005/10/15 02:49:17 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.44 2005/11/25 04:24:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -107,13 +107,6 @@ TidNext(TidScanState *node)
scanrelid = ((TidScan *) node->ss.ps.plan)->scan.scanrelid;
/*
- * Clear any reference to the previously returned tuple. This doesn't
- * offer any great performance benefit, but it keeps this code in sync
- * with SeqNext and IndexNext.
- */
- ExecClearTuple(slot);
-
- /*
* Check if we are evaluating PlanQual for tuple of this relation.
* Additional checking is not good, but no other way for now. We could
* introduce new nodes for this case and handle TidScan --> NewNode
@@ -123,7 +116,7 @@ TidNext(TidScanState *node)
estate->es_evTuple[scanrelid - 1] != NULL)
{
if (estate->es_evTupleNull[scanrelid - 1])
- return slot; /* return empty slot */
+ return ExecClearTuple(slot);
/*
* XXX shouldn't we check here to make sure tuple matches TID list? In
@@ -135,7 +128,7 @@ TidNext(TidScanState *node)
/* Flag for the next call that no more tuples */
estate->es_evTupleNull[scanrelid - 1] = true;
- return (slot);
+ return slot;
}
/*