From 772f63dd6a4d57bc082d701fab4f9cca281efdc1 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Wed, 30 Apr 2008 23:28:32 +0000
Subject: [PATCH] Fix nodeTidscan.c to not trigger an error if the block number
 portion of a user-supplied TID is out of range for the relation.  This is
 needed to preserve compatibility with our pre-8.3 behavior, and it is
 sensible anyway since if the query were implemented by brute force rather
 than optimized into a TidScan, the behavior for a non-existent TID would be
 zero rows out, never an error.  Per gripe from Gurjeet Singh.

---
 src/backend/executor/nodeTidscan.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 1a126afc92f..a3bc45dfb7f 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.58 2008/01/01 19:45:49 momjian Exp $
+ *	  $PostgreSQL: pgsql/src/backend/executor/nodeTidscan.c,v 1.59 2008/04/30 23:28:32 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -54,11 +54,20 @@ TidListCreate(TidScanState *tidstate)
 {
 	List	   *evalList = tidstate->tss_tidquals;
 	ExprContext *econtext = tidstate->ss.ps.ps_ExprContext;
+	BlockNumber nblocks;
 	ItemPointerData *tidList;
 	int			numAllocTids;
 	int			numTids;
 	ListCell   *l;
 
+	/*
+	 * We silently discard any TIDs that are out of range at the time of
+	 * scan start.  (Since we hold at least AccessShareLock on the table,
+	 * it won't be possible for someone to truncate away the blocks we
+	 * intend to visit.)
+	 */
+	nblocks = RelationGetNumberOfBlocks(tidstate->ss.ss_currentRelation);
+
 	/*
 	 * We initialize the array with enough slots for the case that all quals
 	 * are simple OpExprs or CurrentOfExprs.  If there are any
@@ -97,7 +106,9 @@ TidListCreate(TidScanState *tidstate)
 														  econtext,
 														  &isNull,
 														  NULL));
-			if (!isNull && ItemPointerIsValid(itemptr))
+			if (!isNull &&
+				ItemPointerIsValid(itemptr) &&
+				ItemPointerGetBlockNumber(itemptr) < nblocks)
 			{
 				if (numTids >= numAllocTids)
 				{
@@ -142,7 +153,8 @@ TidListCreate(TidScanState *tidstate)
 				if (!ipnulls[i])
 				{
 					itemptr = (ItemPointer) DatumGetPointer(ipdatums[i]);
-					if (ItemPointerIsValid(itemptr))
+					if (ItemPointerIsValid(itemptr) &&
+						ItemPointerGetBlockNumber(itemptr) < nblocks)
 						tidList[numTids++] = *itemptr;
 				}
 			}
-- 
GitLab