Fix nodeTidscan.c to not trigger an error if the block number portion of
authorTom Lane
Wed, 30 Apr 2008 23:28:32 +0000 (23:28 +0000)
committerTom Lane
Wed, 30 Apr 2008 23:28:32 +0000 (23:28 +0000)
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

index 1a126afc92f225458e4d39507fb1d0a569db1581..a3bc45dfb7f76f95cf2f1fd88eda16e5ca46f02e 100644 (file)
@@ -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;
                }
            }