77 *
88 *
99 * IDENTIFICATION
10- * $Id: hio.c,v 1.26 1999/07/19 07:07:18 momjian Exp $
10+ * $Id: hio.c,v 1.27 1999/11/29 04:34:55 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
@@ -107,10 +107,20 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
107107ItemId itemId ;
108108Item item ;
109109
110+ len = (unsigned )MAXALIGN (tuple -> t_len );/* be conservative */
111+
112+ /*
113+ * If we're gonna fail for oversize tuple, do it right away...
114+ * this code should go away eventually.
115+ */
116+ if (len > MaxTupleSize )
117+ elog (ERROR ,"Tuple is too big: size %d, max size %d" ,
118+ len ,MaxTupleSize );
119+
110120/*
111- * Lock relation forextention . We can use LockPage here as long as in
121+ * Lock relation forextension . We can use LockPage here as long as in
112122 * all other places we use page-level locking for indices only.
113- *Alternatevely , we could define pseudo-table as we do for
123+ *Alternatively , we could define pseudo-table as we do for
114124 * transactions with XactLockTable.
115125 */
116126if (!relation -> rd_myxactonly )
@@ -122,17 +132,17 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
122132 * relation. A good optimization would be to get this to actually
123133 * work properly.
124134 */
125-
126135lastblock = RelationGetNumberOfBlocks (relation );
127136
137+ /*
138+ * Get the last existing page --- may need to create the first one
139+ * if this is a virgin relation.
140+ */
128141if (lastblock == 0 )
129142{
143+ /* what exactly is this all about??? */
130144buffer = ReadBuffer (relation ,lastblock );
131145pageHeader = (Page )BufferGetPage (buffer );
132-
133- /*
134- * There was IF instead of ASSERT here ?!
135- */
136146Assert (PageIsNew ((PageHeader )pageHeader ));
137147buffer = ReleaseAndReadBuffer (buffer ,relation ,P_NEW );
138148pageHeader = (Page )BufferGetPage (buffer );
@@ -143,13 +153,10 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
143153
144154LockBuffer (buffer ,BUFFER_LOCK_EXCLUSIVE );
145155pageHeader = (Page )BufferGetPage (buffer );
146- len = (unsigned )MAXALIGN (tuple -> t_len );/* be conservative */
147156
148157/*
149- * Note that this is true if the above returned a bogus page, which it
150- * will do for a completely empty relation.
158+ * Is there room on the last existing page?
151159 */
152-
153160if (len > PageGetFreeSpace (pageHeader ))
154161{
155162LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
@@ -159,12 +166,18 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
159166PageInit (pageHeader ,BufferGetPageSize (buffer ),0 );
160167
161168if (len > PageGetFreeSpace (pageHeader ))
169+ {
170+ /*
171+ * BUG: by elog'ing here, we leave the new buffer locked and not
172+ * marked dirty, which may result in an invalid page header
173+ * being left on disk. But we should not get here given the
174+ * test at the top of the routine, and the whole deal should
175+ * go away when we implement tuple splitting anyway...
176+ */
162177elog (ERROR ,"Tuple is too big: size %d" ,len );
178+ }
163179}
164180
165- if (len > MaxTupleSize )
166- elog (ERROR ,"Tuple is too big: size %d, max size %d" ,len ,MaxTupleSize );
167-
168181if (!relation -> rd_myxactonly )
169182UnlockPage (relation ,0 ,ExclusiveLock );
170183
@@ -178,7 +191,7 @@ RelationPutHeapTupleAtEnd(Relation relation, HeapTuple tuple)
178191
179192ItemPointerSet (& ((HeapTupleHeader )item )-> t_ctid ,lastblock ,offnum );
180193
181- /* return an accurate tuple */
194+ /* return an accurate tupleself-pointer */
182195ItemPointerSet (& tuple -> t_self ,lastblock ,offnum );
183196
184197LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );