|
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 | /* |
|