]> granicus.if.org Git - postgresql/commitdiff
Try to detect oversize tuple before corrupting relation, instead of
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 29 Nov 1999 04:34:55 +0000 (04:34 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 29 Nov 1999 04:34:55 +0000 (04:34 +0000)
after...

src/backend/access/heap/hio.c

index 595c79e0236f50ee380f1fd7e92129068b764a15..d21d219c10c9eea4941ba07ee703544d58eeba1e 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Id: hio.c,v 1.26 1999/07/19 07:07:18 momjian Exp $
+ *       $Id: hio.c,v 1.27 1999/11/29 04:34:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -107,10 +107,20 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
        ItemId          itemId;
        Item            item;
 
+       len = (unsigned) MAXALIGN(tuple->t_len); /* be conservative */
+
+       /*
+        * If we're gonna fail for oversize tuple, do it right away...
+        * this code should go away eventually.
+        */
+       if (len > MaxTupleSize)
+               elog(ERROR, "Tuple is too big: size %d, max size %d",
+                        len, MaxTupleSize);
+
        /*
-        * Lock relation for extention. We can use LockPage here as long as in
+        * Lock relation for extension. We can use LockPage here as long as in
         * all other places we use page-level locking for indices only.
-        * Alternatevely, we could define pseudo-table as we do for
+        * Alternatively, we could define pseudo-table as we do for
         * transactions with XactLockTable.
         */
        if (!relation->rd_myxactonly)
@@ -122,17 +132,17 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
         * relation.  A good optimization would be to get this to actually
         * work properly.
         */
-
        lastblock = RelationGetNumberOfBlocks(relation);
 
+       /*
+        * Get the last existing page --- may need to create the first one
+        * if this is a virgin relation.
+        */
        if (lastblock == 0)
        {
+               /* what exactly is this all about??? */
                buffer = ReadBuffer(relation, lastblock);
                pageHeader = (Page) BufferGetPage(buffer);
-
-               /*
-                * There was IF instead of ASSERT here ?!
-                */
                Assert(PageIsNew((PageHeader) pageHeader));
                buffer = ReleaseAndReadBuffer(buffer, relation, P_NEW);
                pageHeader = (Page) BufferGetPage(buffer);
@@ -143,13 +153,10 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
 
        LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
        pageHeader = (Page) BufferGetPage(buffer);
-       len = (unsigned) MAXALIGN(tuple->t_len); /* be conservative */
 
        /*
-        * Note that this is true if the above returned a bogus page, which it
-        * will do for a completely empty relation.
+        * Is there room on the last existing page?
         */
-
        if (len > PageGetFreeSpace(pageHeader))
        {
                LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
@@ -159,12 +166,18 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
                PageInit(pageHeader, BufferGetPageSize(buffer), 0);
 
                if (len > PageGetFreeSpace(pageHeader))
+               {
+                       /*
+                        * BUG: by elog'ing here, we leave the new buffer locked and not
+                        * marked dirty, which may result in an invalid page header
+                        * being left on disk.  But we should not get here given the
+                        * test at the top of the routine, and the whole deal should
+                        * go away when we implement tuple splitting anyway...
+                        */
                        elog(ERROR, "Tuple is too big: size %d", len);
+               }
        }
 
-       if (len > MaxTupleSize)
-               elog(ERROR, "Tuple is too big: size %d, max size %d", len, MaxTupleSize);
-
        if (!relation->rd_myxactonly)
                UnlockPage(relation, 0, ExclusiveLock);
 
@@ -178,7 +191,7 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
 
        ItemPointerSet(&((HeapTupleHeader) item)->t_ctid, lastblock, offnum);
 
-       /* return an accurate tuple */
+       /* return an accurate tuple self-pointer */
        ItemPointerSet(&tuple->t_self, lastblock, offnum);
 
        LockBuffer(buffer, BUFFER_LOCK_UNLOCK);