Commit de09da54 authored by Tom Lane's avatar Tom Lane

Wups, managed to break ANALYZE with one aspect of that heap_fetch change.

parent 3f4d4880
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.136 2002/05/24 18:57:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.137 2002/05/24 19:52:43 tgl Exp $
* *
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
...@@ -873,15 +873,24 @@ heap_getnext(HeapScanDesc scan, ScanDirection direction) ...@@ -873,15 +873,24 @@ heap_getnext(HeapScanDesc scan, ScanDirection direction)
* the tuple, fill in the remaining fields of *tuple, and check the tuple * the tuple, fill in the remaining fields of *tuple, and check the tuple
* against the specified snapshot. * against the specified snapshot.
* *
* If successful (tuple passes snapshot time qual), then *userbuf is set to * If successful (tuple found and passes snapshot time qual), then *userbuf
* the buffer holding the tuple and TRUE is returned. The caller must * is set to the buffer holding the tuple and TRUE is returned. The caller
* unpin the buffer when done with the tuple. * must unpin the buffer when done with the tuple.
* *
* If the tuple fails the time qual check, then FALSE will be returned. * If the tuple is not found, then tuple->t_data is set to NULL, *userbuf
* When the caller specifies keep_buf = true, we retain the pin on the * is set to InvalidBuffer, and FALSE is returned.
* buffer and return it in *userbuf (so the caller can still access the *
* tuple); when keep_buf = false, the pin is released and *userbuf is set * If the tuple is found but fails the time qual check, then FALSE will be
* returned. When the caller specifies keep_buf = true, we retain the pin
* on the buffer and return it in *userbuf (so the caller can still access
* the tuple); when keep_buf = false, the pin is released and *userbuf is set
* to InvalidBuffer. * to InvalidBuffer.
*
* It is somewhat inconsistent that we elog() on invalid block number but
* return false on invalid item number. This is historical. The only
* justification I can see is that the caller can relatively easily check the
* block number for validity, but cannot check the item number without reading
* the page himself.
*/ */
bool bool
heap_fetch(Relation relation, heap_fetch(Relation relation,
...@@ -928,17 +937,18 @@ heap_fetch(Relation relation, ...@@ -928,17 +937,18 @@ heap_fetch(Relation relation,
lp = PageGetItemId(dp, offnum); lp = PageGetItemId(dp, offnum);
/* /*
* more sanity checks * must check for deleted tuple (see for example analyze.c, which is
* careful to pass an offnum in range, but doesn't know if the offnum
* actually corresponds to an undeleted tuple).
*/ */
if (!ItemIdIsUsed(lp)) if (!ItemIdIsUsed(lp))
{ {
LockBuffer(buffer, BUFFER_LOCK_UNLOCK); LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
ReleaseBuffer(buffer); ReleaseBuffer(buffer);
*userbuf = InvalidBuffer;
elog(ERROR, "heap_fetch: invalid tuple id (%s, %lu, %u)", tuple->t_datamcxt = NULL;
RelationGetRelationName(relation), tuple->t_data = NULL;
(unsigned long) ItemPointerGetBlockNumber(tid), return false;
offnum);
} }
/* /*
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.59 2002/05/24 18:57:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.60 2002/05/24 19:52:43 tgl Exp $
* *
* INTERFACE ROUTINES * INTERFACE ROUTINES
* index_open - open an index relation by relation OID * index_open - open an index relation by relation OID
...@@ -444,6 +444,10 @@ index_getnext(IndexScanDesc scan, ScanDirection direction) ...@@ -444,6 +444,10 @@ index_getnext(IndexScanDesc scan, ScanDirection direction)
&scan->xs_pgstat_info)) &scan->xs_pgstat_info))
break; break;
/* Skip if no tuple at this location */
if (heapTuple->t_data == NULL)
continue; /* should we raise an error instead? */
/* /*
* If we can't see it, maybe no one else can either. Check to see * If we can't see it, maybe no one else can either. Check to see
* if the tuple is dead to all transactions. If so, signal the * if the tuple is dead to all transactions. If so, signal the
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.91 2002/05/24 18:57:55 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.92 2002/05/24 19:52:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -248,7 +248,7 @@ _bt_check_unique(Relation rel, BTItem btitem, Relation heapRel, ...@@ -248,7 +248,7 @@ _bt_check_unique(Relation rel, BTItem btitem, Relation heapRel,
elog(ERROR, "Cannot insert a duplicate key into unique index %s", elog(ERROR, "Cannot insert a duplicate key into unique index %s",
RelationGetRelationName(rel)); RelationGetRelationName(rel));
} }
else else if (htup.t_data != NULL)
{ {
/* /*
* Hmm, if we can't see the tuple, maybe it can be * Hmm, if we can't see the tuple, maybe it can be
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment