|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.136 2002/05/2418:57:55 tgl Exp $ |
| 11 | + * $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.137 2002/05/2419:52:43 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *
|
14 | 14 | * INTERFACE ROUTINES
|
@@ -873,15 +873,24 @@ heap_getnext(HeapScanDesc scan, ScanDirection direction)
|
873 | 873 | * the tuple, fill in the remaining fields of *tuple, and check the tuple
|
874 | 874 | * against the specified snapshot.
|
875 | 875 | *
|
876 |
| - * If successful (tuple passes snapshot time qual), then *userbuf is set to |
877 |
| - * the buffer holding the tuple and TRUE is returned. The caller must |
878 |
| - * unpin the buffer when done with the tuple. |
| 876 | + * If successful (tuplefound andpasses snapshot time qual), then *userbuf |
| 877 | + *is set tothe buffer holding the tuple and TRUE is returned. The caller |
| 878 | + *mustunpin the buffer when done with the tuple. |
879 | 879 | *
|
880 |
| - * If the tuple fails the time qual check, then FALSE will be returned. |
881 |
| - * When the caller specifies keep_buf = true, we retain the pin on the |
882 |
| - * buffer and return it in *userbuf (so the caller can still access the |
883 |
| - * tuple); when keep_buf = false, the pin is released and *userbuf is set |
| 880 | + * If the tuple is not found, then tuple->t_data is set to NULL, *userbuf |
| 881 | + * is set to InvalidBuffer, and FALSE is returned. |
| 882 | + * |
| 883 | + * If the tuple is found but fails the time qual check, then FALSE will be |
| 884 | + * returned. When the caller specifies keep_buf = true, we retain the pin |
| 885 | + * on the buffer and return it in *userbuf (so the caller can still access |
| 886 | + * the tuple); when keep_buf = false, the pin is released and *userbuf is set |
884 | 887 | * to InvalidBuffer.
|
| 888 | + * |
| 889 | + * It is somewhat inconsistent that we elog() on invalid block number but |
| 890 | + * return false on invalid item number. This is historical. The only |
| 891 | + * justification I can see is that the caller can relatively easily check the |
| 892 | + * block number for validity, but cannot check the item number without reading |
| 893 | + * the page himself. |
885 | 894 | */
|
886 | 895 | bool
|
887 | 896 | heap_fetch(Relationrelation,
|
@@ -928,17 +937,18 @@ heap_fetch(Relation relation,
|
928 | 937 | lp=PageGetItemId(dp,offnum);
|
929 | 938 |
|
930 | 939 | /*
|
931 |
| - * more sanity checks |
| 940 | + * must check for deleted tuple (see for example analyze.c, which is |
| 941 | + * careful to pass an offnum in range, but doesn't know if the offnum |
| 942 | + * actually corresponds to an undeleted tuple). |
932 | 943 | */
|
933 | 944 | if (!ItemIdIsUsed(lp))
|
934 | 945 | {
|
935 | 946 | LockBuffer(buffer,BUFFER_LOCK_UNLOCK);
|
936 | 947 | ReleaseBuffer(buffer);
|
937 |
| - |
938 |
| -elog(ERROR,"heap_fetch: invalid tuple id (%s, %lu, %u)", |
939 |
| -RelationGetRelationName(relation), |
940 |
| - (unsigned long)ItemPointerGetBlockNumber(tid), |
941 |
| -offnum); |
| 948 | +*userbuf=InvalidBuffer; |
| 949 | +tuple->t_datamcxt=NULL; |
| 950 | +tuple->t_data=NULL; |
| 951 | +return false; |
942 | 952 | }
|
943 | 953 |
|
944 | 954 | /*
|
|