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